Hi,
Can you test the attached patch? Does it solve your issue?
--HPS
Index: sys/dev/usb/usb_device.c
===================================================================
--- sys/dev/usb/usb_device.c (revision 304569)
+++ sys/dev/usb/usb_device.c (working copy)
@@ -1585,6 +1585,7 @@
/* initialise our SX-lock */
sx_init_flags(&udev->enum_sx, "USB config SX lock", SX_DUPOK);
sx_init_flags(&udev->sr_sx, "USB suspend and resume SX lock", SX_NOWITNESS);
+ sx_init_flags(&udev->ctrl_sx, "USB control transfer SX lock", SX_DUPOK);
cv_init(&udev->ctrlreq_cv, "WCTRL");
cv_init(&udev->ref_cv, "UGONE");
@@ -2195,6 +2196,7 @@
sx_destroy(&udev->enum_sx);
sx_destroy(&udev->sr_sx);
+ sx_destroy(&udev->ctrl_sx);
cv_destroy(&udev->ctrlreq_cv);
cv_destroy(&udev->ref_cv);
Index: sys/dev/usb/usb_device.h
===================================================================
--- sys/dev/usb/usb_device.h (revision 304569)
+++ sys/dev/usb/usb_device.h (working copy)
@@ -183,6 +183,7 @@
struct usb_udev_msg cs_msg[2];
struct sx enum_sx;
struct sx sr_sx;
+ struct sx ctrl_sx;
struct mtx device_mtx;
struct cv ctrlreq_cv;
struct cv ref_cv;
Index: sys/dev/usb/usb_request.c
===================================================================
--- sys/dev/usb/usb_request.c (revision 304569)
+++ sys/dev/usb/usb_request.c (working copy)
@@ -418,7 +418,6 @@
uint16_t length;
uint16_t temp;
uint16_t acttemp;
- uint8_t do_unlock;
if (timeout < 50) {
/* timeout is too small */
@@ -460,16 +459,16 @@
}
/*
- * Grab the USB device enumeration SX-lock serialization is
- * achieved when multiple threads are involved:
+ * Serialize access to this function:
*/
- do_unlock = usbd_enum_lock(udev);
+ sx_xlock(&udev->ctrl_sx);
/*
* We need to allow suspend and resume at this point, else the
* control transfer will timeout if the device is suspended!
*/
- usbd_sr_unlock(udev);
+ if (usbd_enum_is_locked(udev))
+ usbd_sr_unlock(udev);
hr_func = usbd_get_hr_func(udev);
@@ -713,10 +712,10 @@
USB_XFER_UNLOCK(xfer);
done:
- usbd_sr_lock(udev);
+ sx_xunlock(&udev->ctrl_sx);
- if (do_unlock)
- usbd_enum_unlock(udev);
+ if (usbd_enum_is_locked(udev))
+ usbd_sr_lock(udev);
if ((mtx != NULL) && (mtx != &Giant))
mtx_lock(mtx);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "[email protected]"