summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/controller/usb_controller.c
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2014-06-11 05:39:08 +0000
committerhselasky <hselasky@FreeBSD.org>2014-06-11 05:39:08 +0000
commit6976be81b3b183e75f2ecf2a0fe39136ace8cb9f (patch)
tree48132ba6c7f1af2727c50cd208afbfc29b212dd5 /sys/dev/usb/controller/usb_controller.c
parent150b18f93d81fc7c1cfeaaef8ccb23259a94e695 (diff)
downloadFreeBSD-src-6976be81b3b183e75f2ecf2a0fe39136ace8cb9f.zip
FreeBSD-src-6976be81b3b183e75f2ecf2a0fe39136ace8cb9f.tar.gz
MFC r267240:
Resolve a deadlock setting the USB configuration index from userspace on USB HUBs by moving the code into the USB explore threads. The deadlock happens because child devices of the USB HUB don't have the expected reference count when called from outside the explore thread. Only the HUB device itself, which the IOCTL interface locks, gets the correct reference count.
Diffstat (limited to 'sys/dev/usb/controller/usb_controller.c')
-rw-r--r--sys/dev/usb/controller/usb_controller.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c
index d51719e..0464b3d 100644
--- a/sys/dev/usb/controller/usb_controller.c
+++ b/sys/dev/usb/controller/usb_controller.c
@@ -366,7 +366,13 @@ usb_bus_explore(struct usb_proc_msg *pm)
if (bus->no_explore != 0)
return;
- if (udev && udev->hub) {
+ if (udev != NULL) {
+ USB_BUS_UNLOCK(bus);
+ uhub_explore_handle_re_enumerate(udev);
+ USB_BUS_LOCK(bus);
+ }
+
+ if (udev != NULL && udev->hub != NULL) {
if (bus->do_probe) {
bus->do_probe = 0;
OpenPOWER on IntegriCloud