summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/usb/controller/usb_controller.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/dev/usb/controller/usb_controller.c')
-rw-r--r--freebsd/sys/dev/usb/controller/usb_controller.c67
1 files changed, 63 insertions, 4 deletions
diff --git a/freebsd/sys/dev/usb/controller/usb_controller.c b/freebsd/sys/dev/usb/controller/usb_controller.c
index 37f79364..c0fda652 100644
--- a/freebsd/sys/dev/usb/controller/usb_controller.c
+++ b/freebsd/sys/dev/usb/controller/usb_controller.c
@@ -288,6 +288,28 @@ usb_resume(device_t dev)
}
/*------------------------------------------------------------------------*
+ * usb_bus_reset_async_locked
+ *------------------------------------------------------------------------*/
+void
+usb_bus_reset_async_locked(struct usb_bus *bus)
+{
+ USB_BUS_LOCK_ASSERT(bus, MA_OWNED);
+
+ DPRINTF("\n");
+
+ if (bus->reset_msg[0].hdr.pm_qentry.tqe_prev != NULL ||
+ bus->reset_msg[1].hdr.pm_qentry.tqe_prev != NULL) {
+ DPRINTF("Reset already pending\n");
+ return;
+ }
+
+ device_printf(bus->parent, "Resetting controller\n");
+
+ usb_proc_msignal(&bus->explore_proc,
+ &bus->reset_msg[0], &bus->reset_msg[1]);
+}
+
+/*------------------------------------------------------------------------*
* usb_shutdown
*------------------------------------------------------------------------*/
static int
@@ -338,7 +360,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;
@@ -411,7 +439,7 @@ usb_bus_detach(struct usb_proc_msg *pm)
/*------------------------------------------------------------------------*
* usb_bus_suspend
*
- * This function is used to suspend the USB contoller.
+ * This function is used to suspend the USB controller.
*------------------------------------------------------------------------*/
static void
usb_bus_suspend(struct usb_proc_msg *pm)
@@ -421,6 +449,8 @@ usb_bus_suspend(struct usb_proc_msg *pm)
usb_error_t err;
uint8_t do_unlock;
+ DPRINTF("\n");
+
bus = ((struct usb_bus_msg *)pm)->bus;
udev = bus->devices[USB_ROOT_HUB_ADDR];
@@ -466,7 +496,7 @@ usb_bus_suspend(struct usb_proc_msg *pm)
/*------------------------------------------------------------------------*
* usb_bus_resume
*
- * This function is used to resume the USB contoller.
+ * This function is used to resume the USB controller.
*------------------------------------------------------------------------*/
static void
usb_bus_resume(struct usb_proc_msg *pm)
@@ -476,6 +506,8 @@ usb_bus_resume(struct usb_proc_msg *pm)
usb_error_t err;
uint8_t do_unlock;
+ DPRINTF("\n");
+
bus = ((struct usb_bus_msg *)pm)->bus;
udev = bus->devices[USB_ROOT_HUB_ADDR];
@@ -525,9 +557,31 @@ usb_bus_resume(struct usb_proc_msg *pm)
}
/*------------------------------------------------------------------------*
+ * usb_bus_reset
+ *
+ * This function is used to reset the USB controller.
+ *------------------------------------------------------------------------*/
+static void
+usb_bus_reset(struct usb_proc_msg *pm)
+{
+ struct usb_bus *bus;
+
+ DPRINTF("\n");
+
+ bus = ((struct usb_bus_msg *)pm)->bus;
+
+ if (bus->bdev == NULL || bus->no_explore != 0)
+ return;
+
+ /* a suspend and resume will reset the USB controller */
+ usb_bus_suspend(pm);
+ usb_bus_resume(pm);
+}
+
+/*------------------------------------------------------------------------*
* usb_bus_shutdown
*
- * This function is used to shutdown the USB contoller.
+ * This function is used to shutdown the USB controller.
*------------------------------------------------------------------------*/
static void
usb_bus_shutdown(struct usb_proc_msg *pm)
@@ -740,6 +794,11 @@ usb_attach_sub(device_t dev, struct usb_bus *bus)
bus->resume_msg[1].hdr.pm_callback = &usb_bus_resume;
bus->resume_msg[1].bus = bus;
+ bus->reset_msg[0].hdr.pm_callback = &usb_bus_reset;
+ bus->reset_msg[0].bus = bus;
+ bus->reset_msg[1].hdr.pm_callback = &usb_bus_reset;
+ bus->reset_msg[1].bus = bus;
+
bus->shutdown_msg[0].hdr.pm_callback = &usb_bus_shutdown;
bus->shutdown_msg[0].bus = bus;
bus->shutdown_msg[1].hdr.pm_callback = &usb_bus_shutdown;