summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2011-06-24 18:14:43 +0000
committerhselasky <hselasky@FreeBSD.org>2011-06-24 18:14:43 +0000
commita551321476aed54765a889e3b29a2a3781561950 (patch)
tree443132deb74be98698052db9923aaf2643a6b93f /sys
parent9fee05c0d9060f4a70a62c23c55eae9a40a1a153 (diff)
downloadFreeBSD-src-a551321476aed54765a889e3b29a2a3781561950.zip
FreeBSD-src-a551321476aed54765a889e3b29a2a3781561950.tar.gz
- Move execution of event handlers into the probe and attach function so that
dynamically loaded device drivers get a chance to run their event hooks. - Decouple the USB suspend and resume lock from witness. It produces some false warnings due to reusing the lock name among multiple devices. MFC after: 3 days
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/usb_device.c22
-rw-r--r--sys/dev/usb/usb_msctest.c18
2 files changed, 34 insertions, 6 deletions
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index 893e79d..76c976b 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -1297,6 +1297,21 @@ usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index)
usb_init_attach_arg(udev, &uaa);
+ /*
+ * If the whole USB device is targeted, invoke the USB event
+ * handler(s):
+ */
+ if (iface_index == USB_IFACE_INDEX_ANY) {
+
+ EVENTHANDLER_INVOKE(usb_dev_configured, udev, &uaa);
+
+ if (uaa.dev_state != UAA_DEV_READY) {
+ /* leave device unconfigured */
+ usb_unconfigure(udev, 0);
+ goto done;
+ }
+ }
+
/* Check if only one interface should be probed: */
if (iface_index != USB_IFACE_INDEX_ANY) {
i = iface_index;
@@ -1526,7 +1541,7 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
/* initialise our SX-lock */
sx_init_flags(&udev->enum_sx, "USB config SX lock", SX_DUPOK);
- sx_init_flags(&udev->sr_sx, "USB suspend and resume SX lock", SX_DUPOK);
+ sx_init_flags(&udev->sr_sx, "USB suspend and resume SX lock", SX_NOWITNESS);
cv_init(&udev->ctrlreq_cv, "WCTRL");
cv_init(&udev->ref_cv, "UGONE");
@@ -1834,11 +1849,6 @@ repeat_set_config:
}
}
}
- EVENTHANDLER_INVOKE(usb_dev_configured, udev, &uaa);
- if (uaa.dev_state != UAA_DEV_READY) {
- /* leave device unconfigured */
- usb_unconfigure(udev, 0);
- }
config_done:
DPRINTF("new dev (addr %d), udev=%p, parent_hub=%p\n",
diff --git a/sys/dev/usb/usb_msctest.c b/sys/dev/usb/usb_msctest.c
index 909615e..45bd363 100644
--- a/sys/dev/usb/usb_msctest.c
+++ b/sys/dev/usb/usb_msctest.c
@@ -489,6 +489,24 @@ bbb_attach(struct usb_device *udev, uint8_t iface_index)
struct usb_interface_descriptor *id;
struct bbb_transfer *sc;
usb_error_t err;
+ uint8_t do_unlock;
+
+ /* automatic locking */
+ if (usbd_enum_is_locked(udev)) {
+ do_unlock = 0;
+ } else {
+ do_unlock = 1;
+ usbd_enum_lock(udev);
+ }
+
+ /*
+ * Make sure any driver which is hooked up to this interface,
+ * like umass is gone:
+ */
+ usb_detach_device(udev, iface_index, 0);
+
+ if (do_unlock)
+ usbd_enum_unlock(udev);
iface = usbd_get_iface(udev, iface_index);
if (iface == NULL)
OpenPOWER on IntegriCloud