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.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c
index 0defc97..2c81d97 100644
--- a/sys/dev/usb/usb_hub.c
+++ b/sys/dev/usb/usb_hub.c
@@ -96,6 +96,7 @@ struct uhub_current_state {
struct uhub_softc {
struct uhub_current_state sc_st;/* current state */
device_t sc_dev; /* base device */
+ struct mtx sc_mtx; /* our mutex */
struct usb_device *sc_udev; /* USB device */
struct usb_xfer *sc_xfer[UHUB_N_TRANSFER]; /* interrupt xfer */
uint8_t sc_flags;
@@ -428,7 +429,6 @@ repeat:
mode = USB_MODE_HOST;
/* need to create a new child */
-
child = usb_alloc_device(sc->sc_dev, udev->bus, udev,
udev->depth + 1, portno - 1, portno, speed, mode);
if (child == NULL) {
@@ -691,6 +691,8 @@ uhub_attach(device_t dev)
sc->sc_udev = udev;
sc->sc_dev = dev;
+ mtx_init(&sc->sc_mtx, "USB HUB mutex", NULL, MTX_DEF);
+
snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
device_get_nameunit(dev));
@@ -774,7 +776,7 @@ uhub_attach(device_t dev)
} else {
/* normal HUB */
err = usbd_transfer_setup(udev, &iface_index, sc->sc_xfer,
- uhub_config, UHUB_N_TRANSFER, sc, &Giant);
+ uhub_config, UHUB_N_TRANSFER, sc, &sc->sc_mtx);
}
if (err) {
DPRINTFN(0, "cannot setup interrupt transfer, "
@@ -850,9 +852,9 @@ uhub_attach(device_t dev)
/* Start the interrupt endpoint, if any */
if (sc->sc_xfer[0] != NULL) {
- USB_XFER_LOCK(sc->sc_xfer[0]);
+ mtx_lock(&sc->sc_mtx);
usbd_transfer_start(sc->sc_xfer[0]);
- USB_XFER_UNLOCK(sc->sc_xfer[0]);
+ mtx_unlock(&sc->sc_mtx);
}
/* Enable automatic power save on all USB HUBs */
@@ -868,6 +870,9 @@ error:
free(udev->hub, M_USBDEV);
udev->hub = NULL;
}
+
+ mtx_destroy(&sc->sc_mtx);
+
return (ENXIO);
}
@@ -908,6 +913,9 @@ uhub_detach(device_t dev)
free(hub, M_USBDEV);
sc->sc_udev->hub = NULL;
+
+ mtx_destroy(&sc->sc_mtx);
+
return (0);
}
@@ -1775,10 +1783,13 @@ usb_dev_resume_peer(struct usb_device *udev)
/* always update hardware power! */
(bus->methods->set_hw_power) (bus);
}
- sx_xlock(udev->default_sx + 1);
+
+ usbd_enum_lock(udev);
+
/* notify all sub-devices about resume */
err = usb_suspend_resume(udev, 0);
- sx_unlock(udev->default_sx + 1);
+
+ usbd_enum_unlock(udev);
/* check if peer has wakeup capability */
if (usb_peer_can_wakeup(udev)) {
@@ -1844,10 +1855,12 @@ repeat:
}
}
- sx_xlock(udev->default_sx + 1);
+ usbd_enum_lock(udev);
+
/* notify all sub-devices about suspend */
err = usb_suspend_resume(udev, 1);
- sx_unlock(udev->default_sx + 1);
+
+ usbd_enum_unlock(udev);
if (usb_peer_can_wakeup(udev)) {
/* allow device to do remote wakeup */
OpenPOWER on IntegriCloud