diff options
Diffstat (limited to 'sys/dev/usb/usb_hub.c')
-rw-r--r-- | sys/dev/usb/usb_hub.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index 0defc97..a09be96 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -234,8 +234,10 @@ uhub_explore_sub(struct uhub_softc *sc, struct usb_port *up) if (child->driver_added_refcount != refcount) { child->driver_added_refcount = refcount; + newbus_xlock(); err = usb_probe_and_attach(child, USB_IFACE_INDEX_ANY); + newbus_xunlock(); if (err) { goto done; } @@ -318,9 +320,11 @@ repeat: /* detach any existing devices */ if (child) { + newbus_xlock(); usb_free_device(child, USB_UNCFG_FLAG_FREE_SUBDEV | USB_UNCFG_FLAG_FREE_EP0); + newbus_xunlock(); child = NULL; } /* get fresh status */ @@ -428,9 +432,10 @@ repeat: mode = USB_MODE_HOST; /* need to create a new child */ - + newbus_xlock(); child = usb_alloc_device(sc->sc_dev, udev->bus, udev, udev->depth + 1, portno - 1, portno, speed, mode); + newbus_xunlock(); if (child == NULL) { DPRINTFN(0, "could not allocate new device!\n"); goto error; @@ -439,9 +444,11 @@ repeat: error: if (child) { + newbus_xlock(); usb_free_device(child, USB_UNCFG_FLAG_FREE_SUBDEV | USB_UNCFG_FLAG_FREE_EP0); + newbus_xunlock(); child = NULL; } if (err == 0) { @@ -980,7 +987,6 @@ uhub_child_location_string(device_t parent, device_t child, struct usb_hub *hub = sc->sc_udev->hub; struct hub_result res; - mtx_lock(&Giant); uhub_find_iface_index(hub, child, &res); if (!res.udev) { DPRINTF("device not on hub\n"); @@ -992,7 +998,6 @@ uhub_child_location_string(device_t parent, device_t child, snprintf(buf, buflen, "port=%u interface=%u", res.portno, res.iface_index); done: - mtx_unlock(&Giant); return (0); } @@ -1006,7 +1011,6 @@ uhub_child_pnpinfo_string(device_t parent, device_t child, struct usb_interface *iface; struct hub_result res; - mtx_lock(&Giant); uhub_find_iface_index(hub, child, &res); if (!res.udev) { DPRINTF("device not on hub\n"); @@ -1037,7 +1041,6 @@ uhub_child_pnpinfo_string(device_t parent, device_t child, goto done; } done: - mtx_unlock(&Giant); return (0); } @@ -1775,10 +1778,13 @@ usb_dev_resume_peer(struct usb_device *udev) /* always update hardware power! */ (bus->methods->set_hw_power) (bus); } + newbus_xlock(); sx_xlock(udev->default_sx + 1); + /* notify all sub-devices about resume */ err = usb_suspend_resume(udev, 0); sx_unlock(udev->default_sx + 1); + newbus_xunlock(); /* check if peer has wakeup capability */ if (usb_peer_can_wakeup(udev)) { @@ -1844,10 +1850,13 @@ repeat: } } + newbus_xlock(); sx_xlock(udev->default_sx + 1); + /* notify all sub-devices about suspend */ err = usb_suspend_resume(udev, 1); sx_unlock(udev->default_sx + 1); + newbus_xunlock(); if (usb_peer_can_wakeup(udev)) { /* allow device to do remote wakeup */ |