blob: fc68badd8636975445bd144ab9a7f1f8b84908f8 [file] [log] [blame]
Forest Bond92b96792009-06-13 07:38:31 -04001/*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 *
20 * File: usbpipe.c
21 *
22 * Purpose: Handle USB control endpoint
23 *
24 * Author: Warren Hsu
25 *
26 * Date: Mar. 29, 2005
27 *
28 * Functions:
Malcolm Priestley1390b022014-05-26 13:59:01 +010029 * vnt_control_out - Write variable length bytes to MEM/BB/MAC/EEPROM
Malcolm Priestley441c21c2014-05-26 13:59:02 +010030 * vnt_control_in - Read variable length bytes from MEM/BB/MAC/EEPROM
Malcolm Priestley285d58c2014-05-26 13:59:03 +010031 * vnt_control_out_u8 - Write one byte to MEM/BB/MAC/EEPROM
Malcolm Priestley53742902014-05-26 13:59:06 +010032 * vnt_control_in_u8 - Read one byte from MEM/BB/MAC/EEPROM
Forest Bond92b96792009-06-13 07:38:31 -040033 * ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set some bits in the same address
34 *
35 * Revision History:
36 * 04-05-2004 Jerry Chen: Initial release
37 * 11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte
38 *
39 */
40
Forest Bond92b96792009-06-13 07:38:31 -040041#include "int.h"
Forest Bond92b96792009-06-13 07:38:31 -040042#include "rxtx.h"
Forest Bond92b96792009-06-13 07:38:31 -040043#include "dpc.h"
Forest Bond92b96792009-06-13 07:38:31 -040044#include "desc.h"
Forest Bond92b96792009-06-13 07:38:31 -040045#include "device.h"
Forest Bond92b96792009-06-13 07:38:31 -040046
Forest Bond92b96792009-06-13 07:38:31 -040047//endpoint def
48//endpoint 0: control
49//endpoint 1: interrupt
50//endpoint 2: read bulk
51//endpoint 3: write bulk
52
Forest Bond92b96792009-06-13 07:38:31 -040053#define USB_CTL_WAIT 500 //ms
54
55#ifndef URB_ASYNC_UNLINK
56#define URB_ASYNC_UNLINK 0
57#endif
58
Malcolm Priestleyfe5d00e2012-12-10 22:14:36 +000059static void s_nsInterruptUsbIoCompleteRead(struct urb *urb);
60static void s_nsBulkInUsbIoCompleteRead(struct urb *urb);
61static void s_nsBulkOutIoCompleteWrite(struct urb *urb);
Forest Bond92b96792009-06-13 07:38:31 -040062
Malcolm Priestley1390b022014-05-26 13:59:01 +010063int vnt_control_out(struct vnt_private *priv, u8 request, u16 value,
Malcolm Priestley0f06a732014-05-17 09:50:21 +010064 u16 index, u16 length, u8 *buffer)
Forest Bond92b96792009-06-13 07:38:31 -040065{
Malcolm Priestley0f06a732014-05-17 09:50:21 +010066 int status = 0;
Forest Bond92b96792009-06-13 07:38:31 -040067
Malcolm Priestley0f06a732014-05-17 09:50:21 +010068 if (priv->Flags & fMP_DISCONNECTED)
Malcolm Priestleye1feda12013-10-14 19:44:13 +010069 return STATUS_FAILURE;
70
Malcolm Priestley0f06a732014-05-17 09:50:21 +010071 mutex_lock(&priv->usb_lock);
Malcolm Priestleyc91b1862014-05-15 22:49:19 +010072
Malcolm Priestley0f06a732014-05-17 09:50:21 +010073 status = usb_control_msg(priv->usb,
74 usb_sndctrlpipe(priv->usb, 0), request, 0x40, value,
75 index, buffer, length, USB_CTL_WAIT);
Forest Bond92b96792009-06-13 07:38:31 -040076
Malcolm Priestley0f06a732014-05-17 09:50:21 +010077 mutex_unlock(&priv->usb_lock);
Malcolm Priestleyc91b1862014-05-15 22:49:19 +010078
Malcolm Priestley0f06a732014-05-17 09:50:21 +010079 if (status < (int)length)
Malcolm Priestley7021b682014-05-15 22:49:22 +010080 return STATUS_FAILURE;
81
82 return STATUS_SUCCESS;
Forest Bond92b96792009-06-13 07:38:31 -040083}
84
Malcolm Priestley285d58c2014-05-26 13:59:03 +010085void vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data)
86{
87 vnt_control_out(priv, MESSAGE_TYPE_WRITE,
88 reg_off, reg, sizeof(u8), &data);
89}
90
Malcolm Priestley441c21c2014-05-26 13:59:02 +010091int vnt_control_in(struct vnt_private *priv, u8 request, u16 value,
Malcolm Priestley9af49fd2014-05-17 09:50:22 +010092 u16 index, u16 length, u8 *buffer)
Forest Bond92b96792009-06-13 07:38:31 -040093{
Malcolm Priestley9af49fd2014-05-17 09:50:22 +010094 int status;
Forest Bond92b96792009-06-13 07:38:31 -040095
Malcolm Priestley9af49fd2014-05-17 09:50:22 +010096 if (priv->Flags & fMP_DISCONNECTED)
Malcolm Priestleye1feda12013-10-14 19:44:13 +010097 return STATUS_FAILURE;
98
Malcolm Priestley9af49fd2014-05-17 09:50:22 +010099 mutex_lock(&priv->usb_lock);
Malcolm Priestleyc91b1862014-05-15 22:49:19 +0100100
Malcolm Priestley9af49fd2014-05-17 09:50:22 +0100101 status = usb_control_msg(priv->usb,
102 usb_rcvctrlpipe(priv->usb, 0), request, 0xc0, value,
103 index, buffer, length, USB_CTL_WAIT);
Forest Bond92b96792009-06-13 07:38:31 -0400104
Malcolm Priestley9af49fd2014-05-17 09:50:22 +0100105 mutex_unlock(&priv->usb_lock);
Malcolm Priestleyc91b1862014-05-15 22:49:19 +0100106
Malcolm Priestley9af49fd2014-05-17 09:50:22 +0100107 if (status < (int)length)
Malcolm Priestley0fb2af32014-05-15 22:49:23 +0100108 return STATUS_FAILURE;
Forest Bond92b96792009-06-13 07:38:31 -0400109
Malcolm Priestley0fb2af32014-05-15 22:49:23 +0100110 return STATUS_SUCCESS;
Forest Bond92b96792009-06-13 07:38:31 -0400111}
112
Malcolm Priestley53742902014-05-26 13:59:06 +0100113void vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data)
114{
115 vnt_control_in(priv, MESSAGE_TYPE_READ,
116 reg_off, reg, sizeof(u8), data);
117}
118
Forest Bond92b96792009-06-13 07:38:31 -0400119/*
120 * Description:
121 * Allocates an usb interrupt in irp and calls USBD.
122 *
123 * Parameters:
124 * In:
125 * pDevice - Pointer to the adapter
126 * Out:
127 * none
128 *
129 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
130 *
131 */
Malcolm Priestleyfe5d00e2012-12-10 22:14:36 +0000132
Malcolm Priestley5f38b782014-02-19 18:37:32 +0000133int PIPEnsInterruptRead(struct vnt_private *priv)
Forest Bond92b96792009-06-13 07:38:31 -0400134{
Malcolm Priestley5f38b782014-02-19 18:37:32 +0000135 int status = STATUS_FAILURE;
Forest Bond92b96792009-06-13 07:38:31 -0400136
Malcolm Priestleyf764e002014-02-19 18:39:09 +0000137 if (priv->int_buf.in_use == true)
Malcolm Priestley5f38b782014-02-19 18:37:32 +0000138 return STATUS_FAILURE;
Forest Bond92b96792009-06-13 07:38:31 -0400139
Malcolm Priestleyf764e002014-02-19 18:39:09 +0000140 priv->int_buf.in_use = true;
Forest Bond92b96792009-06-13 07:38:31 -0400141
Malcolm Priestley5f38b782014-02-19 18:37:32 +0000142 usb_fill_int_urb(priv->pInterruptURB,
143 priv->usb,
Malcolm Priestleyb9d93d12014-03-16 12:34:11 +0000144 usb_rcvintpipe(priv->usb, 1),
Malcolm Priestleyf764e002014-02-19 18:39:09 +0000145 priv->int_buf.data_buf,
Forest Bond92b96792009-06-13 07:38:31 -0400146 MAX_INTERRUPT_SIZE,
147 s_nsInterruptUsbIoCompleteRead,
Malcolm Priestley5f38b782014-02-19 18:37:32 +0000148 priv,
149 priv->int_interval);
Forest Bond92b96792009-06-13 07:38:31 -0400150
Malcolm Priestley5f38b782014-02-19 18:37:32 +0000151 status = usb_submit_urb(priv->pInterruptURB, GFP_ATOMIC);
152 if (status) {
Malcolm Priestley8a660262014-05-17 09:50:20 +0100153 dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status);
Malcolm Priestleyf764e002014-02-19 18:39:09 +0000154 priv->int_buf.in_use = false;
Malcolm Priestley59858f52014-02-19 18:36:37 +0000155 }
Forest Bond92b96792009-06-13 07:38:31 -0400156
Malcolm Priestley5f38b782014-02-19 18:37:32 +0000157 return status;
Forest Bond92b96792009-06-13 07:38:31 -0400158}
159
Forest Bond92b96792009-06-13 07:38:31 -0400160/*
161 * Description:
162 * Complete function of usb interrupt in irp.
163 *
164 * Parameters:
165 * In:
166 * pDevice - Pointer to the adapter
167 *
168 * Out:
169 * none
170 *
171 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
172 *
173 */
Forest Bond92b96792009-06-13 07:38:31 -0400174
Malcolm Priestleyfe5d00e2012-12-10 22:14:36 +0000175static void s_nsInterruptUsbIoCompleteRead(struct urb *urb)
Forest Bond92b96792009-06-13 07:38:31 -0400176{
Malcolm Priestley599e4b52014-02-25 20:51:51 +0000177 struct vnt_private *priv = urb->context;
Malcolm Priestleyd9ad7a92014-02-17 21:27:30 +0000178 int status;
Forest Bond92b96792009-06-13 07:38:31 -0400179
Malcolm Priestleyc98fbf92014-02-17 21:16:20 +0000180 switch (urb->status) {
181 case 0:
182 case -ETIMEDOUT:
183 break;
184 case -ECONNRESET:
185 case -ENOENT:
186 case -ESHUTDOWN:
Malcolm Priestleyf764e002014-02-19 18:39:09 +0000187 priv->int_buf.in_use = false;
Malcolm Priestleyc98fbf92014-02-17 21:16:20 +0000188 return;
189 default:
190 break;
191 }
192
Malcolm Priestleyd9ad7a92014-02-17 21:27:30 +0000193 status = urb->status;
Forest Bond92b96792009-06-13 07:38:31 -0400194
Malcolm Priestleyd9ad7a92014-02-17 21:27:30 +0000195 if (status != STATUS_SUCCESS) {
Malcolm Priestleyf764e002014-02-19 18:39:09 +0000196 priv->int_buf.in_use = false;
Forest Bond92b96792009-06-13 07:38:31 -0400197
Malcolm Priestley8a660262014-05-17 09:50:20 +0100198 dev_dbg(&priv->usb->dev, "%s status = %d\n", __func__, status);
Malcolm Priestley247b4b62014-02-17 21:12:51 +0000199 } else {
Malcolm Priestleyd9ad7a92014-02-17 21:27:30 +0000200 INTnsProcessData(priv);
Malcolm Priestley247b4b62014-02-17 21:12:51 +0000201 }
Malcolm Priestley749627f2014-02-17 21:24:33 +0000202
Malcolm Priestleyd9ad7a92014-02-17 21:27:30 +0000203 status = usb_submit_urb(priv->pInterruptURB, GFP_ATOMIC);
204 if (status) {
Malcolm Priestley8a660262014-05-17 09:50:20 +0100205 dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status);
Malcolm Priestleyd9ad7a92014-02-17 21:27:30 +0000206 } else {
Malcolm Priestleyf764e002014-02-19 18:39:09 +0000207 priv->int_buf.in_use = true;
Malcolm Priestleyd9ad7a92014-02-17 21:27:30 +0000208 }
209
210 return;
Forest Bond92b96792009-06-13 07:38:31 -0400211}
212
213/*
214 * Description:
215 * Allocates an usb BulkIn irp and calls USBD.
216 *
217 * Parameters:
218 * In:
219 * pDevice - Pointer to the adapter
220 * Out:
221 * none
222 *
223 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
224 *
225 */
Malcolm Priestleyfe5d00e2012-12-10 22:14:36 +0000226
Malcolm Priestley0b787d72014-02-25 20:51:50 +0000227int PIPEnsBulkInUsbRead(struct vnt_private *priv, struct vnt_rcb *rcb)
Forest Bond92b96792009-06-13 07:38:31 -0400228{
Malcolm Priestley0b787d72014-02-25 20:51:50 +0000229 int status = 0;
230 struct urb *urb;
Forest Bond92b96792009-06-13 07:38:31 -0400231
Malcolm Priestley0b787d72014-02-25 20:51:50 +0000232 if (priv->Flags & fMP_DISCONNECTED)
233 return STATUS_FAILURE;
Forest Bond92b96792009-06-13 07:38:31 -0400234
Malcolm Priestley0b787d72014-02-25 20:51:50 +0000235 urb = rcb->pUrb;
236 if (rcb->skb == NULL) {
Malcolm Priestley8a660262014-05-17 09:50:20 +0100237 dev_dbg(&priv->usb->dev, "rcb->skb is null\n");
Malcolm Priestley0b787d72014-02-25 20:51:50 +0000238 return status;
239 }
Forest Bond92b96792009-06-13 07:38:31 -0400240
Malcolm Priestley0b787d72014-02-25 20:51:50 +0000241 usb_fill_bulk_urb(urb,
242 priv->usb,
243 usb_rcvbulkpipe(priv->usb, 2),
244 (void *) (rcb->skb->data),
Forest Bond92b96792009-06-13 07:38:31 -0400245 MAX_TOTAL_SIZE_WITH_ALL_HEADERS,
246 s_nsBulkInUsbIoCompleteRead,
Malcolm Priestley0b787d72014-02-25 20:51:50 +0000247 rcb);
Forest Bond92b96792009-06-13 07:38:31 -0400248
Malcolm Priestley0b787d72014-02-25 20:51:50 +0000249 status = usb_submit_urb(urb, GFP_ATOMIC);
250 if (status != 0) {
Malcolm Priestley8a660262014-05-17 09:50:20 +0100251 dev_dbg(&priv->usb->dev, "Submit Rx URB failed %d\n", status);
Forest Bond92b96792009-06-13 07:38:31 -0400252 return STATUS_FAILURE ;
253 }
Forest Bond92b96792009-06-13 07:38:31 -0400254
Malcolm Priestley0b787d72014-02-25 20:51:50 +0000255 rcb->Ref = 1;
256 rcb->bBoolInUse = true;
257
258 return status;
Forest Bond92b96792009-06-13 07:38:31 -0400259}
260
Forest Bond92b96792009-06-13 07:38:31 -0400261/*
262 * Description:
263 * Complete function of usb BulkIn irp.
264 *
265 * Parameters:
266 * In:
267 * pDevice - Pointer to the adapter
268 *
269 * Out:
270 * none
271 *
272 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
273 *
274 */
Forest Bond92b96792009-06-13 07:38:31 -0400275
Malcolm Priestleyfe5d00e2012-12-10 22:14:36 +0000276static void s_nsBulkInUsbIoCompleteRead(struct urb *urb)
Forest Bond92b96792009-06-13 07:38:31 -0400277{
Malcolm Priestley599e4b52014-02-25 20:51:51 +0000278 struct vnt_rcb *rcb = urb->context;
Malcolm Priestleyd4fa2ab2014-02-25 20:51:49 +0000279 struct vnt_private *priv = rcb->pDevice;
Malcolm Priestley29b02372014-05-15 22:49:20 +0100280 unsigned long flags;
Malcolm Priestleyd4fa2ab2014-02-25 20:51:49 +0000281 int re_alloc_skb = false;
Forest Bond92b96792009-06-13 07:38:31 -0400282
Malcolm Priestley67638982014-02-25 20:51:48 +0000283 switch (urb->status) {
284 case 0:
Malcolm Priestley67638982014-02-25 20:51:48 +0000285 break;
286 case -ECONNRESET:
287 case -ENOENT:
288 case -ESHUTDOWN:
289 return;
290 case -ETIMEDOUT:
291 default:
Malcolm Priestley8a660262014-05-17 09:50:20 +0100292 dev_dbg(&priv->usb->dev, "BULK In failed %d\n", urb->status);
Malcolm Priestley67638982014-02-25 20:51:48 +0000293 break;
294 }
Forest Bond92b96792009-06-13 07:38:31 -0400295
Malcolm Priestleyd4fa2ab2014-02-25 20:51:49 +0000296 if (urb->actual_length) {
Malcolm Priestley29b02372014-05-15 22:49:20 +0100297 spin_lock_irqsave(&priv->lock, flags);
Forest Bond92b96792009-06-13 07:38:31 -0400298
Malcolm Priestleyd4fa2ab2014-02-25 20:51:49 +0000299 if (RXbBulkInProcessData(priv, rcb, urb->actual_length) == true)
300 re_alloc_skb = true;
301
Malcolm Priestley29b02372014-05-15 22:49:20 +0100302 spin_unlock_irqrestore(&priv->lock, flags);
Malcolm Priestleyd4fa2ab2014-02-25 20:51:49 +0000303 }
304
305 rcb->Ref--;
306 if (rcb->Ref == 0) {
Malcolm Priestley8a660262014-05-17 09:50:20 +0100307 dev_dbg(&priv->usb->dev,
308 "RxvFreeNormal %d\n", priv->NumRecvFreeList);
309
Malcolm Priestley29b02372014-05-15 22:49:20 +0100310 spin_lock_irqsave(&priv->lock, flags);
Malcolm Priestleyd4fa2ab2014-02-25 20:51:49 +0000311
312 RXvFreeRCB(rcb, re_alloc_skb);
313
Malcolm Priestley29b02372014-05-15 22:49:20 +0100314 spin_unlock_irqrestore(&priv->lock, flags);
Malcolm Priestleyd4fa2ab2014-02-25 20:51:49 +0000315 }
316
317 return;
Forest Bond92b96792009-06-13 07:38:31 -0400318}
319
320/*
321 * Description:
322 * Allocates an usb BulkOut irp and calls USBD.
323 *
324 * Parameters:
325 * In:
326 * pDevice - Pointer to the adapter
327 * Out:
328 * none
329 *
330 * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
331 *
332 */
Malcolm Priestleyfe5d00e2012-12-10 22:14:36 +0000333
Malcolm Priestley3f382902014-02-25 20:51:45 +0000334int PIPEnsSendBulkOut(struct vnt_private *priv,
335 struct vnt_usb_send_context *context)
Forest Bond92b96792009-06-13 07:38:31 -0400336{
Malcolm Priestleyfe5d00e2012-12-10 22:14:36 +0000337 int status;
Malcolm Priestley3f382902014-02-25 20:51:45 +0000338 struct urb *urb;
Forest Bond92b96792009-06-13 07:38:31 -0400339
Malcolm Priestley3f382902014-02-25 20:51:45 +0000340 priv->bPWBitOn = false;
Forest Bond92b96792009-06-13 07:38:31 -0400341
Malcolm Priestley3f382902014-02-25 20:51:45 +0000342 if (!(MP_IS_READY(priv) && priv->Flags & fMP_POST_WRITES)) {
Malcolm Priestley30a05b32014-05-15 22:49:11 +0100343 context->in_use = false;
Malcolm Priestley13338302014-02-25 20:51:43 +0000344 return STATUS_RESOURCES;
345 }
Forest Bond92b96792009-06-13 07:38:31 -0400346
Malcolm Priestley30a05b32014-05-15 22:49:11 +0100347 urb = context->urb;
Forest Bond92b96792009-06-13 07:38:31 -0400348
Malcolm Priestley3f382902014-02-25 20:51:45 +0000349 usb_fill_bulk_urb(urb,
350 priv->usb,
351 usb_sndbulkpipe(priv->usb, 3),
Malcolm Priestley30a05b32014-05-15 22:49:11 +0100352 context->data,
353 context->buf_len,
Malcolm Priestley3f382902014-02-25 20:51:45 +0000354 s_nsBulkOutIoCompleteWrite,
355 context);
356
357 status = usb_submit_urb(urb, GFP_ATOMIC);
358 if (status != 0) {
Malcolm Priestley8a660262014-05-17 09:50:20 +0100359 dev_dbg(&priv->usb->dev, "Submit Tx URB failed %d\n", status);
360
Malcolm Priestley30a05b32014-05-15 22:49:11 +0100361 context->in_use = false;
Malcolm Priestley3f382902014-02-25 20:51:45 +0000362 return STATUS_FAILURE;
363 }
364
365 return STATUS_PENDING;
Forest Bond92b96792009-06-13 07:38:31 -0400366}
367
368/*
369 * Description: s_nsBulkOutIoCompleteWrite
370 * 1a) Indicate to the protocol the status of the write.
371 * 1b) Return ownership of the packet to the protocol.
372 *
373 * 2) If any more packets are queue for sending, send another packet
374 * to USBD.
375 * If the attempt to send the packet to the driver fails,
376 * return ownership of the packet to the protocol and
377 * try another packet (until one succeeds).
378 *
379 * Parameters:
380 * In:
381 * pdoUsbDevObj - pointer to the USB device object which
382 * completed the irp
383 * pIrp - the irp which was completed by the
384 * device object
385 * pContext - the context given to IoSetCompletionRoutine
386 * before calling IoCallDriver on the irp
387 * The pContext is a pointer to the USB device object.
388 * Out:
389 * none
390 *
391 * Return Value: STATUS_MORE_PROCESSING_REQUIRED - allows the completion routine
392 * (IofCompleteRequest) to stop working on the irp.
393 *
394 */
Malcolm Priestleyfe5d00e2012-12-10 22:14:36 +0000395
396static void s_nsBulkOutIoCompleteWrite(struct urb *urb)
Forest Bond92b96792009-06-13 07:38:31 -0400397{
Malcolm Priestley599e4b52014-02-25 20:51:51 +0000398 struct vnt_usb_send_context *context = urb->context;
Malcolm Priestley30a05b32014-05-15 22:49:11 +0100399 struct vnt_private *priv = context->priv;
Malcolm Priestley1450ba62014-02-19 21:56:33 +0000400 u8 context_type = context->type;
Forest Bond92b96792009-06-13 07:38:31 -0400401
Malcolm Priestleye8152bf2014-02-19 21:53:35 +0000402 switch (urb->status) {
403 case 0:
Malcolm Priestley8a660262014-05-17 09:50:20 +0100404 dev_dbg(&priv->usb->dev, "Write %d bytes\n", context->buf_len);
Malcolm Priestleye8152bf2014-02-19 21:53:35 +0000405 break;
406 case -ECONNRESET:
407 case -ENOENT:
408 case -ESHUTDOWN:
Malcolm Priestley30a05b32014-05-15 22:49:11 +0100409 context->in_use = false;
Malcolm Priestleye8152bf2014-02-19 21:53:35 +0000410 return;
Malcolm Priestleyd1b2a112014-02-27 23:06:15 +0000411 case -ETIMEDOUT:
Malcolm Priestleye8152bf2014-02-19 21:53:35 +0000412 default:
Malcolm Priestley8a660262014-05-17 09:50:20 +0100413 dev_dbg(&priv->usb->dev, "BULK Out failed %d\n", urb->status);
Malcolm Priestleye8152bf2014-02-19 21:53:35 +0000414 break;
415 }
416
Malcolm Priestley21aa2122014-02-19 21:54:45 +0000417 if (!netif_device_present(priv->dev))
418 return;
Forest Bond92b96792009-06-13 07:38:31 -0400419
Malcolm Priestley21aa2122014-02-19 21:54:45 +0000420 if (CONTEXT_DATA_PACKET == context_type) {
Malcolm Priestley30a05b32014-05-15 22:49:11 +0100421 if (context->skb != NULL) {
422 dev_kfree_skb_irq(context->skb);
423 context->skb = NULL;
Malcolm Priestley8a660262014-05-17 09:50:20 +0100424 dev_dbg(&priv->usb->dev,
425 "tx %d bytes\n", context->buf_len);
Malcolm Priestley21aa2122014-02-19 21:54:45 +0000426 }
Forest Bond92b96792009-06-13 07:38:31 -0400427
Malcolm Priestley21aa2122014-02-19 21:54:45 +0000428 priv->dev->trans_start = jiffies;
Malcolm Priestley21aa2122014-02-19 21:54:45 +0000429 }
Forest Bond92b96792009-06-13 07:38:31 -0400430
Malcolm Priestley21aa2122014-02-19 21:54:45 +0000431 if (priv->bLinkPass == true) {
432 if (netif_queue_stopped(priv->dev))
433 netif_wake_queue(priv->dev);
434 }
435
Malcolm Priestley30a05b32014-05-15 22:49:11 +0100436 context->in_use = false;
Malcolm Priestley21aa2122014-02-19 21:54:45 +0000437
438 return;
Forest Bond92b96792009-06-13 07:38:31 -0400439}