diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-12-16 11:46:03 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-12-16 11:46:03 -0500 |
commit | d59abb9325ae5eb8fd28440d80f820b945887541 (patch) | |
tree | 6ba86796569a8b478a959c2c76c8bfb2bde34522 /drivers/usb/wusbcore | |
parent | 319e2e3f63c348a9b66db4667efa73178e18b17d (diff) | |
parent | 3d724fa513cd1bd06d3457ccda36941f3606d048 (diff) |
Merge branch 3.13-rc4 into usb-next
Diffstat (limited to 'drivers/usb/wusbcore')
-rw-r--r-- | drivers/usb/wusbcore/cbaf.c | 8 | ||||
-rw-r--r-- | drivers/usb/wusbcore/security.c | 22 | ||||
-rw-r--r-- | drivers/usb/wusbcore/wa-hc.h | 7 | ||||
-rw-r--r-- | drivers/usb/wusbcore/wa-rpipe.c | 10 | ||||
-rw-r--r-- | drivers/usb/wusbcore/wa-xfer.c | 209 |
5 files changed, 153 insertions, 103 deletions
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c index f06ed82e63d1..56310fc9b9c3 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/usb/wusbcore/cbaf.c | |||
@@ -144,7 +144,7 @@ static int cbaf_check(struct cbaf *cbaf) | |||
144 | CBAF_REQ_GET_ASSOCIATION_INFORMATION, | 144 | CBAF_REQ_GET_ASSOCIATION_INFORMATION, |
145 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 145 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
146 | 0, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber, | 146 | 0, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber, |
147 | cbaf->buffer, cbaf->buffer_size, 1000 /* FIXME: arbitrary */); | 147 | cbaf->buffer, cbaf->buffer_size, USB_CTRL_GET_TIMEOUT); |
148 | if (result < 0) { | 148 | if (result < 0) { |
149 | dev_err(dev, "Cannot get available association types: %d\n", | 149 | dev_err(dev, "Cannot get available association types: %d\n", |
150 | result); | 150 | result); |
@@ -265,7 +265,7 @@ static int cbaf_send_host_info(struct cbaf *cbaf) | |||
265 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 265 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
266 | 0x0101, | 266 | 0x0101, |
267 | cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber, | 267 | cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber, |
268 | hi, hi_size, 1000 /* FIXME: arbitrary */); | 268 | hi, hi_size, USB_CTRL_SET_TIMEOUT); |
269 | } | 269 | } |
270 | 270 | ||
271 | /* | 271 | /* |
@@ -288,7 +288,7 @@ static int cbaf_cdid_get(struct cbaf *cbaf) | |||
288 | CBAF_REQ_GET_ASSOCIATION_REQUEST, | 288 | CBAF_REQ_GET_ASSOCIATION_REQUEST, |
289 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 289 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
290 | 0x0200, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber, | 290 | 0x0200, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber, |
291 | di, cbaf->buffer_size, 1000 /* FIXME: arbitrary */); | 291 | di, cbaf->buffer_size, USB_CTRL_GET_TIMEOUT); |
292 | if (result < 0) { | 292 | if (result < 0) { |
293 | dev_err(dev, "Cannot request device information: %d\n", result); | 293 | dev_err(dev, "Cannot request device information: %d\n", result); |
294 | return result; | 294 | return result; |
@@ -536,7 +536,7 @@ static int cbaf_cc_upload(struct cbaf *cbaf) | |||
536 | CBAF_REQ_SET_ASSOCIATION_RESPONSE, | 536 | CBAF_REQ_SET_ASSOCIATION_RESPONSE, |
537 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 537 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
538 | 0x0201, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber, | 538 | 0x0201, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber, |
539 | ccd, sizeof(*ccd), 1000 /* FIXME: arbitrary */); | 539 | ccd, sizeof(*ccd), USB_CTRL_SET_TIMEOUT); |
540 | 540 | ||
541 | return result; | 541 | return result; |
542 | } | 542 | } |
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c index 4c40d0dbf53d..790c0b5c354c 100644 --- a/drivers/usb/wusbcore/security.c +++ b/drivers/usb/wusbcore/security.c | |||
@@ -165,7 +165,7 @@ static int wusb_dev_set_encryption(struct usb_device *usb_dev, int value) | |||
165 | result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | 165 | result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), |
166 | USB_REQ_SET_ENCRYPTION, | 166 | USB_REQ_SET_ENCRYPTION, |
167 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | 167 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, |
168 | value, 0, NULL, 0, 1000 /* FIXME: arbitrary */); | 168 | value, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); |
169 | if (result < 0) | 169 | if (result < 0) |
170 | dev_err(dev, "Can't set device's WUSB encryption to " | 170 | dev_err(dev, "Can't set device's WUSB encryption to " |
171 | "%s (value %d): %d\n", | 171 | "%s (value %d): %d\n", |
@@ -191,7 +191,7 @@ static int wusb_dev_set_gtk(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | |||
191 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | 191 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, |
192 | USB_DT_KEY << 8 | key_index, 0, | 192 | USB_DT_KEY << 8 | key_index, 0, |
193 | &wusbhc->gtk.descr, wusbhc->gtk.descr.bLength, | 193 | &wusbhc->gtk.descr, wusbhc->gtk.descr.bLength, |
194 | 1000); | 194 | USB_CTRL_SET_TIMEOUT); |
195 | } | 195 | } |
196 | 196 | ||
197 | 197 | ||
@@ -301,8 +301,9 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | |||
301 | 301 | ||
302 | /* Set address 0 */ | 302 | /* Set address 0 */ |
303 | result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | 303 | result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), |
304 | USB_REQ_SET_ADDRESS, 0, | 304 | USB_REQ_SET_ADDRESS, |
305 | 0, 0, NULL, 0, 1000 /* FIXME: arbitrary */); | 305 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, |
306 | 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
306 | if (result < 0) { | 307 | if (result < 0) { |
307 | dev_err(dev, "auth failed: can't set address 0: %d\n", | 308 | dev_err(dev, "auth failed: can't set address 0: %d\n", |
308 | result); | 309 | result); |
@@ -316,9 +317,10 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | |||
316 | 317 | ||
317 | /* Set new (authenticated) address. */ | 318 | /* Set new (authenticated) address. */ |
318 | result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | 319 | result = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), |
319 | USB_REQ_SET_ADDRESS, 0, | 320 | USB_REQ_SET_ADDRESS, |
320 | new_address, 0, NULL, 0, | 321 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, |
321 | 1000 /* FIXME: arbitrary */); | 322 | new_address, 0, NULL, 0, |
323 | USB_CTRL_SET_TIMEOUT); | ||
322 | if (result < 0) { | 324 | if (result < 0) { |
323 | dev_err(dev, "auth failed: can't set address %u: %d\n", | 325 | dev_err(dev, "auth failed: can't set address %u: %d\n", |
324 | new_address, result); | 326 | new_address, result); |
@@ -381,7 +383,7 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, | |||
381 | usb_dev, usb_sndctrlpipe(usb_dev, 0), | 383 | usb_dev, usb_sndctrlpipe(usb_dev, 0), |
382 | USB_REQ_SET_HANDSHAKE, | 384 | USB_REQ_SET_HANDSHAKE, |
383 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | 385 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, |
384 | 1, 0, &hs[0], sizeof(hs[0]), 1000 /* FIXME: arbitrary */); | 386 | 1, 0, &hs[0], sizeof(hs[0]), USB_CTRL_SET_TIMEOUT); |
385 | if (result < 0) { | 387 | if (result < 0) { |
386 | dev_err(dev, "Handshake1: request failed: %d\n", result); | 388 | dev_err(dev, "Handshake1: request failed: %d\n", result); |
387 | goto error_hs1; | 389 | goto error_hs1; |
@@ -392,7 +394,7 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, | |||
392 | usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 394 | usb_dev, usb_rcvctrlpipe(usb_dev, 0), |
393 | USB_REQ_GET_HANDSHAKE, | 395 | USB_REQ_GET_HANDSHAKE, |
394 | USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | 396 | USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE, |
395 | 2, 0, &hs[1], sizeof(hs[1]), 1000 /* FIXME: arbitrary */); | 397 | 2, 0, &hs[1], sizeof(hs[1]), USB_CTRL_GET_TIMEOUT); |
396 | if (result < 0) { | 398 | if (result < 0) { |
397 | dev_err(dev, "Handshake2: request failed: %d\n", result); | 399 | dev_err(dev, "Handshake2: request failed: %d\n", result); |
398 | goto error_hs2; | 400 | goto error_hs2; |
@@ -469,7 +471,7 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, | |||
469 | usb_dev, usb_sndctrlpipe(usb_dev, 0), | 471 | usb_dev, usb_sndctrlpipe(usb_dev, 0), |
470 | USB_REQ_SET_HANDSHAKE, | 472 | USB_REQ_SET_HANDSHAKE, |
471 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | 473 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, |
472 | 3, 0, &hs[2], sizeof(hs[2]), 1000 /* FIXME: arbitrary */); | 474 | 3, 0, &hs[2], sizeof(hs[2]), USB_CTRL_SET_TIMEOUT); |
473 | if (result < 0) { | 475 | if (result < 0) { |
474 | dev_err(dev, "Handshake3: request failed: %d\n", result); | 476 | dev_err(dev, "Handshake3: request failed: %d\n", result); |
475 | goto error_hs3; | 477 | goto error_hs3; |
diff --git a/drivers/usb/wusbcore/wa-hc.h b/drivers/usb/wusbcore/wa-hc.h index e614f02f0cf2..b93d2cbdf33f 100644 --- a/drivers/usb/wusbcore/wa-hc.h +++ b/drivers/usb/wusbcore/wa-hc.h | |||
@@ -332,7 +332,7 @@ static inline int rpipe_avail_inc(struct wa_rpipe *rpipe) | |||
332 | /* Transferring data */ | 332 | /* Transferring data */ |
333 | extern int wa_urb_enqueue(struct wahc *, struct usb_host_endpoint *, | 333 | extern int wa_urb_enqueue(struct wahc *, struct usb_host_endpoint *, |
334 | struct urb *, gfp_t); | 334 | struct urb *, gfp_t); |
335 | extern int wa_urb_dequeue(struct wahc *, struct urb *); | 335 | extern int wa_urb_dequeue(struct wahc *, struct urb *, int); |
336 | extern void wa_handle_notif_xfer(struct wahc *, struct wa_notif_hdr *); | 336 | extern void wa_handle_notif_xfer(struct wahc *, struct wa_notif_hdr *); |
337 | 337 | ||
338 | 338 | ||
@@ -366,7 +366,7 @@ static inline int __wa_feature(struct wahc *wa, unsigned op, u16 feature) | |||
366 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 366 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
367 | feature, | 367 | feature, |
368 | wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, | 368 | wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, |
369 | NULL, 0, 1000 /* FIXME: arbitrary */); | 369 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
370 | } | 370 | } |
371 | 371 | ||
372 | 372 | ||
@@ -400,8 +400,7 @@ s32 __wa_get_status(struct wahc *wa) | |||
400 | USB_REQ_GET_STATUS, | 400 | USB_REQ_GET_STATUS, |
401 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 401 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
402 | 0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, | 402 | 0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, |
403 | &wa->status, sizeof(wa->status), | 403 | &wa->status, sizeof(wa->status), USB_CTRL_GET_TIMEOUT); |
404 | 1000 /* FIXME: arbitrary */); | ||
405 | if (result >= 0) | 404 | if (result >= 0) |
406 | result = wa->status; | 405 | result = wa->status; |
407 | return result; | 406 | return result; |
diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c index b48e74cc54d7..accdd15f5393 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/usb/wusbcore/wa-rpipe.c | |||
@@ -80,7 +80,7 @@ static int __rpipe_get_descr(struct wahc *wa, | |||
80 | USB_REQ_GET_DESCRIPTOR, | 80 | USB_REQ_GET_DESCRIPTOR, |
81 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_RPIPE, | 81 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_RPIPE, |
82 | USB_DT_RPIPE<<8, index, descr, sizeof(*descr), | 82 | USB_DT_RPIPE<<8, index, descr, sizeof(*descr), |
83 | 1000 /* FIXME: arbitrary */); | 83 | USB_CTRL_GET_TIMEOUT); |
84 | if (result < 0) { | 84 | if (result < 0) { |
85 | dev_err(dev, "rpipe %u: get descriptor failed: %d\n", | 85 | dev_err(dev, "rpipe %u: get descriptor failed: %d\n", |
86 | index, (int)result); | 86 | index, (int)result); |
@@ -118,7 +118,7 @@ static int __rpipe_set_descr(struct wahc *wa, | |||
118 | USB_REQ_SET_DESCRIPTOR, | 118 | USB_REQ_SET_DESCRIPTOR, |
119 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, | 119 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, |
120 | USB_DT_RPIPE<<8, index, descr, sizeof(*descr), | 120 | USB_DT_RPIPE<<8, index, descr, sizeof(*descr), |
121 | HZ / 10); | 121 | USB_CTRL_SET_TIMEOUT); |
122 | if (result < 0) { | 122 | if (result < 0) { |
123 | dev_err(dev, "rpipe %u: set descriptor failed: %d\n", | 123 | dev_err(dev, "rpipe %u: set descriptor failed: %d\n", |
124 | index, (int)result); | 124 | index, (int)result); |
@@ -237,7 +237,7 @@ static int __rpipe_reset(struct wahc *wa, unsigned index) | |||
237 | wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), | 237 | wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), |
238 | USB_REQ_RPIPE_RESET, | 238 | USB_REQ_RPIPE_RESET, |
239 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, | 239 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, |
240 | 0, index, NULL, 0, 1000 /* FIXME: arbitrary */); | 240 | 0, index, NULL, 0, USB_CTRL_SET_TIMEOUT); |
241 | if (result < 0) | 241 | if (result < 0) |
242 | dev_err(dev, "rpipe %u: reset failed: %d\n", | 242 | dev_err(dev, "rpipe %u: reset failed: %d\n", |
243 | index, result); | 243 | index, result); |
@@ -527,7 +527,7 @@ void rpipe_ep_disable(struct wahc *wa, struct usb_host_endpoint *ep) | |||
527 | wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), | 527 | wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), |
528 | USB_REQ_RPIPE_ABORT, | 528 | USB_REQ_RPIPE_ABORT, |
529 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, | 529 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, |
530 | 0, index, NULL, 0, 1000 /* FIXME: arbitrary */); | 530 | 0, index, NULL, 0, USB_CTRL_SET_TIMEOUT); |
531 | rpipe_put(rpipe); | 531 | rpipe_put(rpipe); |
532 | } | 532 | } |
533 | mutex_unlock(&wa->rpipe_mutex); | 533 | mutex_unlock(&wa->rpipe_mutex); |
@@ -548,7 +548,7 @@ void rpipe_clear_feature_stalled(struct wahc *wa, struct usb_host_endpoint *ep) | |||
548 | wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), | 548 | wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), |
549 | USB_REQ_CLEAR_FEATURE, | 549 | USB_REQ_CLEAR_FEATURE, |
550 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, | 550 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, |
551 | RPIPE_STALL, index, NULL, 0, 1000); | 551 | RPIPE_STALL, index, NULL, 0, USB_CTRL_SET_TIMEOUT); |
552 | } | 552 | } |
553 | mutex_unlock(&wa->rpipe_mutex); | 553 | mutex_unlock(&wa->rpipe_mutex); |
554 | } | 554 | } |
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index ed5abe87b049..a70e142da330 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c | |||
@@ -124,6 +124,8 @@ struct wa_seg { | |||
124 | u8 index; /* which segment we are */ | 124 | u8 index; /* which segment we are */ |
125 | int isoc_frame_count; /* number of isoc frames in this segment. */ | 125 | int isoc_frame_count; /* number of isoc frames in this segment. */ |
126 | int isoc_frame_offset; /* starting frame offset in the xfer URB. */ | 126 | int isoc_frame_offset; /* starting frame offset in the xfer URB. */ |
127 | /* Isoc frame that the current transfer buffer corresponds to. */ | ||
128 | int isoc_frame_index; | ||
127 | int isoc_size; /* size of all isoc frames sent by this seg. */ | 129 | int isoc_size; /* size of all isoc frames sent by this seg. */ |
128 | enum wa_seg_status status; | 130 | enum wa_seg_status status; |
129 | ssize_t result; /* bytes xfered or error */ | 131 | ssize_t result; /* bytes xfered or error */ |
@@ -158,8 +160,6 @@ struct wa_xfer { | |||
158 | unsigned is_dma:1; | 160 | unsigned is_dma:1; |
159 | size_t seg_size; | 161 | size_t seg_size; |
160 | int result; | 162 | int result; |
161 | /* Isoc frame that the current transfer buffer corresponds to. */ | ||
162 | int dto_isoc_frame_index; | ||
163 | 163 | ||
164 | gfp_t gfp; /* allocation mask */ | 164 | gfp_t gfp; /* allocation mask */ |
165 | 165 | ||
@@ -282,6 +282,7 @@ static void wa_xfer_giveback(struct wa_xfer *xfer) | |||
282 | 282 | ||
283 | spin_lock_irqsave(&xfer->wa->xfer_list_lock, flags); | 283 | spin_lock_irqsave(&xfer->wa->xfer_list_lock, flags); |
284 | list_del_init(&xfer->list_node); | 284 | list_del_init(&xfer->list_node); |
285 | usb_hcd_unlink_urb_from_ep(&(xfer->wa->wusb->usb_hcd), xfer->urb); | ||
285 | spin_unlock_irqrestore(&xfer->wa->xfer_list_lock, flags); | 286 | spin_unlock_irqrestore(&xfer->wa->xfer_list_lock, flags); |
286 | /* FIXME: segmentation broken -- kills DWA */ | 287 | /* FIXME: segmentation broken -- kills DWA */ |
287 | wusbhc_giveback_urb(xfer->wa->wusb, xfer->urb, xfer->result); | 288 | wusbhc_giveback_urb(xfer->wa->wusb, xfer->urb, xfer->result); |
@@ -372,10 +373,10 @@ static unsigned __wa_xfer_is_done(struct wa_xfer *xfer) | |||
372 | seg->result); | 373 | seg->result); |
373 | goto out; | 374 | goto out; |
374 | case WA_SEG_ABORTED: | 375 | case WA_SEG_ABORTED: |
375 | dev_dbg(dev, "xfer %p ID %08X#%u ABORTED: result %d\n", | 376 | xfer->result = seg->result; |
376 | xfer, wa_xfer_id(xfer), seg->index, | 377 | dev_dbg(dev, "xfer %p ID %08X#%u: ABORTED result %zu(0x%08zX)\n", |
377 | urb->status); | 378 | xfer, wa_xfer_id(xfer), seg->index, seg->result, |
378 | xfer->result = urb->status; | 379 | seg->result); |
379 | goto out; | 380 | goto out; |
380 | default: | 381 | default: |
381 | dev_warn(dev, "xfer %p ID %08X#%u: is_done bad state %d\n", | 382 | dev_warn(dev, "xfer %p ID %08X#%u: is_done bad state %d\n", |
@@ -700,23 +701,23 @@ static void wa_seg_dto_cb(struct urb *urb) | |||
700 | if (usb_pipeisoc(xfer->urb->pipe)) { | 701 | if (usb_pipeisoc(xfer->urb->pipe)) { |
701 | /* Alereon HWA sends all isoc frames in a single transfer. */ | 702 | /* Alereon HWA sends all isoc frames in a single transfer. */ |
702 | if (wa->quirks & WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC) | 703 | if (wa->quirks & WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC) |
703 | xfer->dto_isoc_frame_index += seg->isoc_frame_count; | 704 | seg->isoc_frame_index += seg->isoc_frame_count; |
704 | else | 705 | else |
705 | xfer->dto_isoc_frame_index += 1; | 706 | seg->isoc_frame_index += 1; |
706 | if (xfer->dto_isoc_frame_index < seg->isoc_frame_count) { | 707 | if (seg->isoc_frame_index < seg->isoc_frame_count) { |
707 | data_send_done = 0; | 708 | data_send_done = 0; |
708 | holding_dto = 1; /* checked in error cases. */ | 709 | holding_dto = 1; /* checked in error cases. */ |
709 | /* | 710 | /* |
710 | * if this is the last isoc frame of the segment, we | 711 | * if this is the last isoc frame of the segment, we |
711 | * can release DTO after sending this frame. | 712 | * can release DTO after sending this frame. |
712 | */ | 713 | */ |
713 | if ((xfer->dto_isoc_frame_index + 1) >= | 714 | if ((seg->isoc_frame_index + 1) >= |
714 | seg->isoc_frame_count) | 715 | seg->isoc_frame_count) |
715 | release_dto = 1; | 716 | release_dto = 1; |
716 | } | 717 | } |
717 | dev_dbg(dev, "xfer 0x%08X#%u: isoc frame = %d, holding_dto = %d, release_dto = %d.\n", | 718 | dev_dbg(dev, "xfer 0x%08X#%u: isoc frame = %d, holding_dto = %d, release_dto = %d.\n", |
718 | wa_xfer_id(xfer), seg->index, | 719 | wa_xfer_id(xfer), seg->index, seg->isoc_frame_index, |
719 | xfer->dto_isoc_frame_index, holding_dto, release_dto); | 720 | holding_dto, release_dto); |
720 | } | 721 | } |
721 | spin_unlock_irqrestore(&xfer->lock, flags); | 722 | spin_unlock_irqrestore(&xfer->lock, flags); |
722 | 723 | ||
@@ -736,8 +737,7 @@ static void wa_seg_dto_cb(struct urb *urb) | |||
736 | * send the URB and release DTO if we no longer need it. | 737 | * send the URB and release DTO if we no longer need it. |
737 | */ | 738 | */ |
738 | __wa_populate_dto_urb_isoc(xfer, seg, | 739 | __wa_populate_dto_urb_isoc(xfer, seg, |
739 | seg->isoc_frame_offset + | 740 | seg->isoc_frame_offset + seg->isoc_frame_index); |
740 | xfer->dto_isoc_frame_index); | ||
741 | 741 | ||
742 | /* resubmit the URB with the next isoc frame. */ | 742 | /* resubmit the URB with the next isoc frame. */ |
743 | result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC); | 743 | result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC); |
@@ -1259,8 +1259,11 @@ static int __wa_xfer_setup(struct wa_xfer *xfer, struct urb *urb) | |||
1259 | for (cnt = 1; cnt < xfer->segs; cnt++) { | 1259 | for (cnt = 1; cnt < xfer->segs; cnt++) { |
1260 | struct wa_xfer_packet_info_hwaiso *packet_desc; | 1260 | struct wa_xfer_packet_info_hwaiso *packet_desc; |
1261 | struct wa_seg *seg = xfer->seg[cnt]; | 1261 | struct wa_seg *seg = xfer->seg[cnt]; |
1262 | struct wa_xfer_hwaiso *xfer_iso; | ||
1262 | 1263 | ||
1263 | xfer_hdr = &seg->xfer_hdr; | 1264 | xfer_hdr = &seg->xfer_hdr; |
1265 | xfer_iso = container_of(xfer_hdr, | ||
1266 | struct wa_xfer_hwaiso, hdr); | ||
1264 | packet_desc = ((void *)xfer_hdr) + xfer_hdr_size; | 1267 | packet_desc = ((void *)xfer_hdr) + xfer_hdr_size; |
1265 | /* | 1268 | /* |
1266 | * Copy values from the 0th header. Segment specific | 1269 | * Copy values from the 0th header. Segment specific |
@@ -1270,6 +1273,8 @@ static int __wa_xfer_setup(struct wa_xfer *xfer, struct urb *urb) | |||
1270 | xfer_hdr->bTransferSegment = cnt; | 1273 | xfer_hdr->bTransferSegment = cnt; |
1271 | xfer_hdr->dwTransferLength = | 1274 | xfer_hdr->dwTransferLength = |
1272 | cpu_to_le32(seg->isoc_size); | 1275 | cpu_to_le32(seg->isoc_size); |
1276 | xfer_iso->dwNumOfPackets = | ||
1277 | cpu_to_le32(seg->isoc_frame_count); | ||
1273 | __wa_setup_isoc_packet_descr(packet_desc, xfer, seg); | 1278 | __wa_setup_isoc_packet_descr(packet_desc, xfer, seg); |
1274 | seg->status = WA_SEG_READY; | 1279 | seg->status = WA_SEG_READY; |
1275 | } | 1280 | } |
@@ -1323,12 +1328,12 @@ static int __wa_seg_submit(struct wa_rpipe *rpipe, struct wa_xfer *xfer, | |||
1323 | struct wahc *wa = xfer->wa; | 1328 | struct wahc *wa = xfer->wa; |
1324 | 1329 | ||
1325 | result = usb_submit_urb(seg->isoc_pack_desc_urb, GFP_ATOMIC); | 1330 | result = usb_submit_urb(seg->isoc_pack_desc_urb, GFP_ATOMIC); |
1331 | seg->isoc_frame_index = 0; | ||
1326 | if (result < 0) { | 1332 | if (result < 0) { |
1327 | pr_err("%s: xfer %p#%u: ISO packet descriptor submit failed: %d\n", | 1333 | pr_err("%s: xfer %p#%u: ISO packet descriptor submit failed: %d\n", |
1328 | __func__, xfer, seg->index, result); | 1334 | __func__, xfer, seg->index, result); |
1329 | goto error_iso_pack_desc_submit; | 1335 | goto error_iso_pack_desc_submit; |
1330 | } | 1336 | } |
1331 | xfer->dto_isoc_frame_index = 0; | ||
1332 | /* | 1337 | /* |
1333 | * If this segment contains more than one isoc frame, hold | 1338 | * If this segment contains more than one isoc frame, hold |
1334 | * onto the dto resource until we send all frames. | 1339 | * onto the dto resource until we send all frames. |
@@ -1567,7 +1572,8 @@ static int wa_urb_enqueue_b(struct wa_xfer *xfer) | |||
1567 | wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); | 1572 | wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); |
1568 | if (wusb_dev == NULL) { | 1573 | if (wusb_dev == NULL) { |
1569 | mutex_unlock(&wusbhc->mutex); | 1574 | mutex_unlock(&wusbhc->mutex); |
1570 | pr_err("%s: error wusb dev gone\n", __func__); | 1575 | dev_err(&(urb->dev->dev), "%s: error wusb dev gone\n", |
1576 | __func__); | ||
1571 | goto error_dev_gone; | 1577 | goto error_dev_gone; |
1572 | } | 1578 | } |
1573 | mutex_unlock(&wusbhc->mutex); | 1579 | mutex_unlock(&wusbhc->mutex); |
@@ -1576,18 +1582,18 @@ static int wa_urb_enqueue_b(struct wa_xfer *xfer) | |||
1576 | xfer->wusb_dev = wusb_dev; | 1582 | xfer->wusb_dev = wusb_dev; |
1577 | result = urb->status; | 1583 | result = urb->status; |
1578 | if (urb->status != -EINPROGRESS) { | 1584 | if (urb->status != -EINPROGRESS) { |
1579 | pr_err("%s: error_dequeued\n", __func__); | 1585 | dev_err(&(urb->dev->dev), "%s: error_dequeued\n", __func__); |
1580 | goto error_dequeued; | 1586 | goto error_dequeued; |
1581 | } | 1587 | } |
1582 | 1588 | ||
1583 | result = __wa_xfer_setup(xfer, urb); | 1589 | result = __wa_xfer_setup(xfer, urb); |
1584 | if (result < 0) { | 1590 | if (result < 0) { |
1585 | pr_err("%s: error_xfer_setup\n", __func__); | 1591 | dev_err(&(urb->dev->dev), "%s: error_xfer_setup\n", __func__); |
1586 | goto error_xfer_setup; | 1592 | goto error_xfer_setup; |
1587 | } | 1593 | } |
1588 | result = __wa_xfer_submit(xfer); | 1594 | result = __wa_xfer_submit(xfer); |
1589 | if (result < 0) { | 1595 | if (result < 0) { |
1590 | pr_err("%s: error_xfer_submit\n", __func__); | 1596 | dev_err(&(urb->dev->dev), "%s: error_xfer_submit\n", __func__); |
1591 | goto error_xfer_submit; | 1597 | goto error_xfer_submit; |
1592 | } | 1598 | } |
1593 | spin_unlock_irqrestore(&xfer->lock, flags); | 1599 | spin_unlock_irqrestore(&xfer->lock, flags); |
@@ -1730,6 +1736,12 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep, | |||
1730 | dump_stack(); | 1736 | dump_stack(); |
1731 | } | 1737 | } |
1732 | 1738 | ||
1739 | spin_lock_irqsave(&wa->xfer_list_lock, my_flags); | ||
1740 | result = usb_hcd_link_urb_to_ep(&(wa->wusb->usb_hcd), urb); | ||
1741 | spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags); | ||
1742 | if (result < 0) | ||
1743 | goto error_link_urb; | ||
1744 | |||
1733 | result = -ENOMEM; | 1745 | result = -ENOMEM; |
1734 | xfer = kzalloc(sizeof(*xfer), gfp); | 1746 | xfer = kzalloc(sizeof(*xfer), gfp); |
1735 | if (xfer == NULL) | 1747 | if (xfer == NULL) |
@@ -1769,6 +1781,9 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep, | |||
1769 | __func__, result); | 1781 | __func__, result); |
1770 | wa_put(xfer->wa); | 1782 | wa_put(xfer->wa); |
1771 | wa_xfer_put(xfer); | 1783 | wa_xfer_put(xfer); |
1784 | spin_lock_irqsave(&wa->xfer_list_lock, my_flags); | ||
1785 | usb_hcd_unlink_urb_from_ep(&(wa->wusb->usb_hcd), urb); | ||
1786 | spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags); | ||
1772 | return result; | 1787 | return result; |
1773 | } | 1788 | } |
1774 | } | 1789 | } |
@@ -1777,6 +1792,10 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep, | |||
1777 | error_dequeued: | 1792 | error_dequeued: |
1778 | kfree(xfer); | 1793 | kfree(xfer); |
1779 | error_kmalloc: | 1794 | error_kmalloc: |
1795 | spin_lock_irqsave(&wa->xfer_list_lock, my_flags); | ||
1796 | usb_hcd_unlink_urb_from_ep(&(wa->wusb->usb_hcd), urb); | ||
1797 | spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags); | ||
1798 | error_link_urb: | ||
1780 | return result; | 1799 | return result; |
1781 | } | 1800 | } |
1782 | EXPORT_SYMBOL_GPL(wa_urb_enqueue); | 1801 | EXPORT_SYMBOL_GPL(wa_urb_enqueue); |
@@ -1799,7 +1818,7 @@ EXPORT_SYMBOL_GPL(wa_urb_enqueue); | |||
1799 | * asynch request] and then make sure we cancel each segment. | 1818 | * asynch request] and then make sure we cancel each segment. |
1800 | * | 1819 | * |
1801 | */ | 1820 | */ |
1802 | int wa_urb_dequeue(struct wahc *wa, struct urb *urb) | 1821 | int wa_urb_dequeue(struct wahc *wa, struct urb *urb, int status) |
1803 | { | 1822 | { |
1804 | unsigned long flags, flags2; | 1823 | unsigned long flags, flags2; |
1805 | struct wa_xfer *xfer; | 1824 | struct wa_xfer *xfer; |
@@ -1807,6 +1826,14 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb) | |||
1807 | struct wa_rpipe *rpipe; | 1826 | struct wa_rpipe *rpipe; |
1808 | unsigned cnt, done = 0, xfer_abort_pending; | 1827 | unsigned cnt, done = 0, xfer_abort_pending; |
1809 | unsigned rpipe_ready = 0; | 1828 | unsigned rpipe_ready = 0; |
1829 | int result; | ||
1830 | |||
1831 | /* check if it is safe to unlink. */ | ||
1832 | spin_lock_irqsave(&wa->xfer_list_lock, flags); | ||
1833 | result = usb_hcd_check_unlink_urb(&(wa->wusb->usb_hcd), urb, status); | ||
1834 | spin_unlock_irqrestore(&wa->xfer_list_lock, flags); | ||
1835 | if (result) | ||
1836 | return result; | ||
1810 | 1837 | ||
1811 | xfer = urb->hcpriv; | 1838 | xfer = urb->hcpriv; |
1812 | if (xfer == NULL) { | 1839 | if (xfer == NULL) { |
@@ -1822,9 +1849,10 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb) | |||
1822 | pr_debug("%s: DEQUEUE xfer id 0x%08X\n", __func__, wa_xfer_id(xfer)); | 1849 | pr_debug("%s: DEQUEUE xfer id 0x%08X\n", __func__, wa_xfer_id(xfer)); |
1823 | rpipe = xfer->ep->hcpriv; | 1850 | rpipe = xfer->ep->hcpriv; |
1824 | if (rpipe == NULL) { | 1851 | if (rpipe == NULL) { |
1825 | pr_debug("%s: xfer id 0x%08X has no RPIPE. %s", | 1852 | pr_debug("%s: xfer %p id 0x%08X has no RPIPE. %s", |
1826 | __func__, wa_xfer_id(xfer), | 1853 | __func__, xfer, wa_xfer_id(xfer), |
1827 | "Probably already aborted.\n" ); | 1854 | "Probably already aborted.\n" ); |
1855 | result = -ENOENT; | ||
1828 | goto out_unlock; | 1856 | goto out_unlock; |
1829 | } | 1857 | } |
1830 | /* Check the delayed list -> if there, release and complete */ | 1858 | /* Check the delayed list -> if there, release and complete */ |
@@ -1855,6 +1883,7 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb) | |||
1855 | * segments will be completed in the DTI interrupt. | 1883 | * segments will be completed in the DTI interrupt. |
1856 | */ | 1884 | */ |
1857 | seg->status = WA_SEG_ABORTED; | 1885 | seg->status = WA_SEG_ABORTED; |
1886 | seg->result = -ENOENT; | ||
1858 | spin_lock_irqsave(&rpipe->seg_lock, flags2); | 1887 | spin_lock_irqsave(&rpipe->seg_lock, flags2); |
1859 | list_del(&seg->list_node); | 1888 | list_del(&seg->list_node); |
1860 | xfer->segs_done++; | 1889 | xfer->segs_done++; |
@@ -1894,12 +1923,12 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb) | |||
1894 | wa_xfer_completion(xfer); | 1923 | wa_xfer_completion(xfer); |
1895 | if (rpipe_ready) | 1924 | if (rpipe_ready) |
1896 | wa_xfer_delayed_run(rpipe); | 1925 | wa_xfer_delayed_run(rpipe); |
1897 | return 0; | 1926 | return result; |
1898 | 1927 | ||
1899 | out_unlock: | 1928 | out_unlock: |
1900 | spin_unlock_irqrestore(&xfer->lock, flags); | 1929 | spin_unlock_irqrestore(&xfer->lock, flags); |
1901 | out: | 1930 | out: |
1902 | return 0; | 1931 | return result; |
1903 | 1932 | ||
1904 | dequeue_delayed: | 1933 | dequeue_delayed: |
1905 | list_del_init(&xfer->list_node); | 1934 | list_del_init(&xfer->list_node); |
@@ -1935,7 +1964,7 @@ static int wa_xfer_status_to_errno(u8 status) | |||
1935 | [WA_XFER_STATUS_NOT_FOUND] = 0, | 1964 | [WA_XFER_STATUS_NOT_FOUND] = 0, |
1936 | [WA_XFER_STATUS_INSUFFICIENT_RESOURCE] = -ENOMEM, | 1965 | [WA_XFER_STATUS_INSUFFICIENT_RESOURCE] = -ENOMEM, |
1937 | [WA_XFER_STATUS_TRANSACTION_ERROR] = -EILSEQ, | 1966 | [WA_XFER_STATUS_TRANSACTION_ERROR] = -EILSEQ, |
1938 | [WA_XFER_STATUS_ABORTED] = -EINTR, | 1967 | [WA_XFER_STATUS_ABORTED] = -ENOENT, |
1939 | [WA_XFER_STATUS_RPIPE_NOT_READY] = EINVAL, | 1968 | [WA_XFER_STATUS_RPIPE_NOT_READY] = EINVAL, |
1940 | [WA_XFER_INVALID_FORMAT] = EINVAL, | 1969 | [WA_XFER_INVALID_FORMAT] = EINVAL, |
1941 | [WA_XFER_UNEXPECTED_SEGMENT_NUMBER] = EINVAL, | 1970 | [WA_XFER_UNEXPECTED_SEGMENT_NUMBER] = EINVAL, |
@@ -1968,7 +1997,7 @@ static int wa_xfer_status_to_errno(u8 status) | |||
1968 | * the xfer will complete cleanly. | 1997 | * the xfer will complete cleanly. |
1969 | */ | 1998 | */ |
1970 | static void wa_complete_remaining_xfer_segs(struct wa_xfer *xfer, | 1999 | static void wa_complete_remaining_xfer_segs(struct wa_xfer *xfer, |
1971 | struct wa_seg *incoming_seg) | 2000 | struct wa_seg *incoming_seg, enum wa_seg_status status) |
1972 | { | 2001 | { |
1973 | int index; | 2002 | int index; |
1974 | struct wa_rpipe *rpipe = xfer->ep->hcpriv; | 2003 | struct wa_rpipe *rpipe = xfer->ep->hcpriv; |
@@ -1990,7 +2019,7 @@ static void wa_complete_remaining_xfer_segs(struct wa_xfer *xfer, | |||
1990 | */ | 2019 | */ |
1991 | case WA_SEG_DELAYED: | 2020 | case WA_SEG_DELAYED: |
1992 | xfer->segs_done++; | 2021 | xfer->segs_done++; |
1993 | current_seg->status = incoming_seg->status; | 2022 | current_seg->status = status; |
1994 | break; | 2023 | break; |
1995 | case WA_SEG_ABORTED: | 2024 | case WA_SEG_ABORTED: |
1996 | break; | 2025 | break; |
@@ -2003,6 +2032,58 @@ static void wa_complete_remaining_xfer_segs(struct wa_xfer *xfer, | |||
2003 | } | 2032 | } |
2004 | } | 2033 | } |
2005 | 2034 | ||
2035 | /* Populate the wa->buf_in_urb based on the current transfer state. */ | ||
2036 | static int wa_populate_buf_in_urb(struct wahc *wa, struct wa_xfer *xfer, | ||
2037 | unsigned int seg_idx, unsigned int bytes_transferred) | ||
2038 | { | ||
2039 | int result = 0; | ||
2040 | struct wa_seg *seg = xfer->seg[seg_idx]; | ||
2041 | |||
2042 | BUG_ON(wa->buf_in_urb->status == -EINPROGRESS); | ||
2043 | /* this should always be 0 before a resubmit. */ | ||
2044 | wa->buf_in_urb->num_mapped_sgs = 0; | ||
2045 | |||
2046 | if (xfer->is_dma) { | ||
2047 | wa->buf_in_urb->transfer_dma = xfer->urb->transfer_dma | ||
2048 | + (seg_idx * xfer->seg_size); | ||
2049 | wa->buf_in_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
2050 | wa->buf_in_urb->transfer_buffer = NULL; | ||
2051 | wa->buf_in_urb->sg = NULL; | ||
2052 | wa->buf_in_urb->num_sgs = 0; | ||
2053 | } else { | ||
2054 | /* do buffer or SG processing. */ | ||
2055 | wa->buf_in_urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP; | ||
2056 | |||
2057 | if (xfer->urb->transfer_buffer) { | ||
2058 | wa->buf_in_urb->transfer_buffer = | ||
2059 | xfer->urb->transfer_buffer | ||
2060 | + (seg_idx * xfer->seg_size); | ||
2061 | wa->buf_in_urb->sg = NULL; | ||
2062 | wa->buf_in_urb->num_sgs = 0; | ||
2063 | } else { | ||
2064 | /* allocate an SG list to store seg_size bytes | ||
2065 | and copy the subset of the xfer->urb->sg | ||
2066 | that matches the buffer subset we are | ||
2067 | about to read. */ | ||
2068 | wa->buf_in_urb->sg = wa_xfer_create_subset_sg( | ||
2069 | xfer->urb->sg, | ||
2070 | seg_idx * xfer->seg_size, | ||
2071 | bytes_transferred, | ||
2072 | &(wa->buf_in_urb->num_sgs)); | ||
2073 | |||
2074 | if (!(wa->buf_in_urb->sg)) { | ||
2075 | wa->buf_in_urb->num_sgs = 0; | ||
2076 | result = -ENOMEM; | ||
2077 | } | ||
2078 | wa->buf_in_urb->transfer_buffer = NULL; | ||
2079 | } | ||
2080 | } | ||
2081 | wa->buf_in_urb->transfer_buffer_length = bytes_transferred; | ||
2082 | wa->buf_in_urb->context = seg; | ||
2083 | |||
2084 | return result; | ||
2085 | } | ||
2086 | |||
2006 | /* | 2087 | /* |
2007 | * Process a xfer result completion message | 2088 | * Process a xfer result completion message |
2008 | * | 2089 | * |
@@ -2016,12 +2097,13 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer, | |||
2016 | int result; | 2097 | int result; |
2017 | struct device *dev = &wa->usb_iface->dev; | 2098 | struct device *dev = &wa->usb_iface->dev; |
2018 | unsigned long flags; | 2099 | unsigned long flags; |
2019 | u8 seg_idx; | 2100 | unsigned int seg_idx; |
2020 | struct wa_seg *seg; | 2101 | struct wa_seg *seg; |
2021 | struct wa_rpipe *rpipe; | 2102 | struct wa_rpipe *rpipe; |
2022 | unsigned done = 0; | 2103 | unsigned done = 0; |
2023 | u8 usb_status; | 2104 | u8 usb_status; |
2024 | unsigned rpipe_ready = 0; | 2105 | unsigned rpipe_ready = 0; |
2106 | unsigned bytes_transferred = le32_to_cpu(xfer_result->dwTransferLength); | ||
2025 | 2107 | ||
2026 | spin_lock_irqsave(&xfer->lock, flags); | 2108 | spin_lock_irqsave(&xfer->lock, flags); |
2027 | seg_idx = xfer_result->bTransferSegment & 0x7f; | 2109 | seg_idx = xfer_result->bTransferSegment & 0x7f; |
@@ -2054,66 +2136,33 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer, | |||
2054 | /* FIXME: we ignore warnings, tally them for stats */ | 2136 | /* FIXME: we ignore warnings, tally them for stats */ |
2055 | if (usb_status & 0x40) /* Warning?... */ | 2137 | if (usb_status & 0x40) /* Warning?... */ |
2056 | usb_status = 0; /* ... pass */ | 2138 | usb_status = 0; /* ... pass */ |
2139 | /* | ||
2140 | * If the last segment bit is set, complete the remaining segments. | ||
2141 | * When the current segment is completed, either in wa_buf_in_cb for | ||
2142 | * transfers with data or below for no data, the xfer will complete. | ||
2143 | */ | ||
2144 | if (xfer_result->bTransferSegment & 0x80) | ||
2145 | wa_complete_remaining_xfer_segs(xfer, seg, WA_SEG_DONE); | ||
2057 | if (usb_pipeisoc(xfer->urb->pipe)) { | 2146 | if (usb_pipeisoc(xfer->urb->pipe)) { |
2058 | /* set up WA state to read the isoc packet status next. */ | 2147 | /* set up WA state to read the isoc packet status next. */ |
2059 | wa->dti_isoc_xfer_in_progress = wa_xfer_id(xfer); | 2148 | wa->dti_isoc_xfer_in_progress = wa_xfer_id(xfer); |
2060 | wa->dti_isoc_xfer_seg = seg_idx; | 2149 | wa->dti_isoc_xfer_seg = seg_idx; |
2061 | wa->dti_state = WA_DTI_ISOC_PACKET_STATUS_PENDING; | 2150 | wa->dti_state = WA_DTI_ISOC_PACKET_STATUS_PENDING; |
2062 | } else if (xfer->is_inbound) { /* IN data phase: read to buffer */ | 2151 | } else if ((xfer->is_inbound) |
2152 | && (bytes_transferred > 0)) { | ||
2153 | /* IN data phase: read to buffer */ | ||
2063 | seg->status = WA_SEG_DTI_PENDING; | 2154 | seg->status = WA_SEG_DTI_PENDING; |
2064 | BUG_ON(wa->buf_in_urb->status == -EINPROGRESS); | 2155 | result = wa_populate_buf_in_urb(wa, xfer, seg_idx, |
2065 | /* this should always be 0 before a resubmit. */ | 2156 | bytes_transferred); |
2066 | wa->buf_in_urb->num_mapped_sgs = 0; | 2157 | if (result < 0) |
2067 | 2158 | goto error_buf_in_populate; | |
2068 | if (xfer->is_dma) { | ||
2069 | wa->buf_in_urb->transfer_dma = | ||
2070 | xfer->urb->transfer_dma | ||
2071 | + (seg_idx * xfer->seg_size); | ||
2072 | wa->buf_in_urb->transfer_flags | ||
2073 | |= URB_NO_TRANSFER_DMA_MAP; | ||
2074 | wa->buf_in_urb->transfer_buffer = NULL; | ||
2075 | wa->buf_in_urb->sg = NULL; | ||
2076 | wa->buf_in_urb->num_sgs = 0; | ||
2077 | } else { | ||
2078 | /* do buffer or SG processing. */ | ||
2079 | wa->buf_in_urb->transfer_flags | ||
2080 | &= ~URB_NO_TRANSFER_DMA_MAP; | ||
2081 | |||
2082 | if (xfer->urb->transfer_buffer) { | ||
2083 | wa->buf_in_urb->transfer_buffer = | ||
2084 | xfer->urb->transfer_buffer | ||
2085 | + (seg_idx * xfer->seg_size); | ||
2086 | wa->buf_in_urb->sg = NULL; | ||
2087 | wa->buf_in_urb->num_sgs = 0; | ||
2088 | } else { | ||
2089 | /* allocate an SG list to store seg_size bytes | ||
2090 | and copy the subset of the xfer->urb->sg | ||
2091 | that matches the buffer subset we are | ||
2092 | about to read. */ | ||
2093 | wa->buf_in_urb->sg = wa_xfer_create_subset_sg( | ||
2094 | xfer->urb->sg, | ||
2095 | seg_idx * xfer->seg_size, | ||
2096 | le32_to_cpu( | ||
2097 | xfer_result->dwTransferLength), | ||
2098 | &(wa->buf_in_urb->num_sgs)); | ||
2099 | |||
2100 | if (!(wa->buf_in_urb->sg)) { | ||
2101 | wa->buf_in_urb->num_sgs = 0; | ||
2102 | goto error_sg_alloc; | ||
2103 | } | ||
2104 | wa->buf_in_urb->transfer_buffer = NULL; | ||
2105 | } | ||
2106 | } | ||
2107 | wa->buf_in_urb->transfer_buffer_length = | ||
2108 | le32_to_cpu(xfer_result->dwTransferLength); | ||
2109 | wa->buf_in_urb->context = seg; | ||
2110 | result = usb_submit_urb(wa->buf_in_urb, GFP_ATOMIC); | 2159 | result = usb_submit_urb(wa->buf_in_urb, GFP_ATOMIC); |
2111 | if (result < 0) | 2160 | if (result < 0) |
2112 | goto error_submit_buf_in; | 2161 | goto error_submit_buf_in; |
2113 | } else { | 2162 | } else { |
2114 | /* OUT data phase, complete it -- */ | 2163 | /* OUT data phase or no data, complete it -- */ |
2115 | seg->status = WA_SEG_DONE; | 2164 | seg->status = WA_SEG_DONE; |
2116 | seg->result = le32_to_cpu(xfer_result->dwTransferLength); | 2165 | seg->result = bytes_transferred; |
2117 | xfer->segs_done++; | 2166 | xfer->segs_done++; |
2118 | rpipe_ready = rpipe_avail_inc(rpipe); | 2167 | rpipe_ready = rpipe_avail_inc(rpipe); |
2119 | done = __wa_xfer_is_done(xfer); | 2168 | done = __wa_xfer_is_done(xfer); |
@@ -2137,13 +2186,13 @@ error_submit_buf_in: | |||
2137 | seg->result = result; | 2186 | seg->result = result; |
2138 | kfree(wa->buf_in_urb->sg); | 2187 | kfree(wa->buf_in_urb->sg); |
2139 | wa->buf_in_urb->sg = NULL; | 2188 | wa->buf_in_urb->sg = NULL; |
2140 | error_sg_alloc: | 2189 | error_buf_in_populate: |
2141 | __wa_xfer_abort(xfer); | 2190 | __wa_xfer_abort(xfer); |
2142 | seg->status = WA_SEG_ERROR; | 2191 | seg->status = WA_SEG_ERROR; |
2143 | error_complete: | 2192 | error_complete: |
2144 | xfer->segs_done++; | 2193 | xfer->segs_done++; |
2145 | rpipe_ready = rpipe_avail_inc(rpipe); | 2194 | rpipe_ready = rpipe_avail_inc(rpipe); |
2146 | wa_complete_remaining_xfer_segs(xfer, seg); | 2195 | wa_complete_remaining_xfer_segs(xfer, seg, seg->status); |
2147 | done = __wa_xfer_is_done(xfer); | 2196 | done = __wa_xfer_is_done(xfer); |
2148 | /* | 2197 | /* |
2149 | * queue work item to clear STALL for control endpoints. | 2198 | * queue work item to clear STALL for control endpoints. |
@@ -2172,7 +2221,7 @@ error_complete: | |||
2172 | 2221 | ||
2173 | error_bad_seg: | 2222 | error_bad_seg: |
2174 | spin_unlock_irqrestore(&xfer->lock, flags); | 2223 | spin_unlock_irqrestore(&xfer->lock, flags); |
2175 | wa_urb_dequeue(wa, xfer->urb); | 2224 | wa_urb_dequeue(wa, xfer->urb, -ENOENT); |
2176 | if (printk_ratelimit()) | 2225 | if (printk_ratelimit()) |
2177 | dev_err(dev, "xfer %p#%u: bad segment\n", xfer, seg_idx); | 2226 | dev_err(dev, "xfer %p#%u: bad segment\n", xfer, seg_idx); |
2178 | if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { | 2227 | if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { |