@@ -1052,7 +1052,7 @@ static int __wa_xfer_submit(struct wa_xfer *xfer)
10521052 * result never kicks in, the xfer will timeout from the USB code and
10531053 * dequeue() will be called.
10541054 */
1055- static void wa_urb_enqueue_b (struct wa_xfer * xfer )
1055+ static int wa_urb_enqueue_b (struct wa_xfer * xfer )
10561056{
10571057 int result ;
10581058 unsigned long flags ;
@@ -1063,40 +1063,51 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer)
10631063 unsigned done ;
10641064
10651065 result = rpipe_get_by_ep (wa , xfer -> ep , urb , xfer -> gfp );
1066- if (result < 0 )
1066+ if (result < 0 ) {
1067+ pr_err ("%s: error_rpipe_get\n" , __func__ );
10671068 goto error_rpipe_get ;
1069+ }
10681070 result = - ENODEV ;
10691071 /* FIXME: segmentation broken -- kills DWA */
10701072 mutex_lock (& wusbhc -> mutex ); /* get a WUSB dev */
10711073 if (urb -> dev == NULL ) {
10721074 mutex_unlock (& wusbhc -> mutex );
1075+ pr_err ("%s: error usb dev gone\n" , __func__ );
10731076 goto error_dev_gone ;
10741077 }
10751078 wusb_dev = __wusb_dev_get_by_usb_dev (wusbhc , urb -> dev );
10761079 if (wusb_dev == NULL ) {
10771080 mutex_unlock (& wusbhc -> mutex );
1081+ pr_err ("%s: error wusb dev gone\n" , __func__ );
10781082 goto error_dev_gone ;
10791083 }
10801084 mutex_unlock (& wusbhc -> mutex );
10811085
10821086 spin_lock_irqsave (& xfer -> lock , flags );
10831087 xfer -> wusb_dev = wusb_dev ;
10841088 result = urb -> status ;
1085- if (urb -> status != - EINPROGRESS )
1089+ if (urb -> status != - EINPROGRESS ) {
1090+ pr_err ("%s: error_dequeued\n" , __func__ );
10861091 goto error_dequeued ;
1092+ }
10871093
10881094 result = __wa_xfer_setup (xfer , urb );
1089- if (result < 0 )
1095+ if (result < 0 ) {
1096+ pr_err ("%s: error_xfer_setup\n" , __func__ );
10901097 goto error_xfer_setup ;
1098+ }
10911099 result = __wa_xfer_submit (xfer );
1092- if (result < 0 )
1100+ if (result < 0 ) {
1101+ pr_err ("%s: error_xfer_submit\n" , __func__ );
10931102 goto error_xfer_submit ;
1103+ }
10941104 spin_unlock_irqrestore (& xfer -> lock , flags );
1095- return ;
1105+ return 0 ;
10961106
1097- /* this is basically wa_xfer_completion() broken up wa_xfer_giveback()
1098- * does a wa_xfer_put() that will call wa_xfer_destroy() and clean
1099- * upundo setup().
1107+ /*
1108+ * this is basically wa_xfer_completion() broken up wa_xfer_giveback()
1109+ * does a wa_xfer_put() that will call wa_xfer_destroy() and undo
1110+ * setup().
11001111 */
11011112error_xfer_setup :
11021113error_dequeued :
@@ -1108,15 +1119,16 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer)
11081119 rpipe_put (xfer -> ep -> hcpriv );
11091120error_rpipe_get :
11101121 xfer -> result = result ;
1111- wa_xfer_giveback (xfer );
1112- return ;
1122+ return result ;
11131123
11141124error_xfer_submit :
11151125 done = __wa_xfer_is_done (xfer );
11161126 xfer -> result = result ;
11171127 spin_unlock_irqrestore (& xfer -> lock , flags );
11181128 if (done )
11191129 wa_xfer_completion (xfer );
1130+ /* return success since the completion routine will run. */
1131+ return 0 ;
11201132}
11211133
11221134/*
@@ -1150,7 +1162,8 @@ void wa_urb_enqueue_run(struct work_struct *ws)
11501162 list_del_init (& xfer -> list_node );
11511163
11521164 urb = xfer -> urb ;
1153- wa_urb_enqueue_b (xfer );
1165+ if (wa_urb_enqueue_b (xfer ) < 0 )
1166+ wa_xfer_giveback (xfer );
11541167 usb_put_urb (urb ); /* taken when queuing */
11551168 }
11561169}
@@ -1256,7 +1269,19 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep,
12561269 spin_unlock_irqrestore (& wa -> xfer_list_lock , my_flags );
12571270 queue_work (wusbd , & wa -> xfer_enqueue_work );
12581271 } else {
1259- wa_urb_enqueue_b (xfer );
1272+ result = wa_urb_enqueue_b (xfer );
1273+ if (result < 0 ) {
1274+ /*
1275+ * URB submit/enqueue failed. Clean up, return an
1276+ * error and do not run the callback. This avoids
1277+ * an infinite submit/complete loop.
1278+ */
1279+ dev_err (dev , "%s: URB enqueue failed: %d\n" ,
1280+ __func__ , result );
1281+ wa_put (xfer -> wa );
1282+ wa_xfer_put (xfer );
1283+ return result ;
1284+ }
12601285 }
12611286 return 0 ;
12621287
0 commit comments