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);
_______________________________________________ freebsd-wireless@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-wireless To unsubscribe, send any mail to "freebsd-wireless-unsubscr...@freebsd.org"