summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usb_hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/usb_hub.c')
-rw-r--r--sys/dev/usb/usb_hub.c19
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 */
OpenPOWER on IntegriCloud