summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2012-06-01 16:30:54 +0000
committerhselasky <hselasky@FreeBSD.org>2012-06-01 16:30:54 +0000
commitc91ed235af9ae58fcf3c90c7fa57273fcb544d6a (patch)
tree75e3211cb7444f7b12bf6281b1a38a81d3283478
parentc06b75c710d867f31adad483eecee3c5810905ab (diff)
downloadFreeBSD-src-c91ed235af9ae58fcf3c90c7fa57273fcb544d6a.zip
FreeBSD-src-c91ed235af9ae58fcf3c90c7fa57273fcb544d6a.tar.gz
Improve support for detaching kernel drivers on a per interface basis.
MFC after: 1 week
-rw-r--r--sys/dev/usb/usb_device.c14
-rw-r--r--sys/dev/usb/usb_generic.c9
2 files changed, 19 insertions, 4 deletions
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index 1a7c1b6..4cbf0da 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -750,10 +750,13 @@ usb_config_parse(struct usb_device *udev, uint8_t iface_index, uint8_t cmd)
if (do_init) {
/* setup the USB interface structure */
iface->idesc = id;
- /* default setting */
- iface->parent_iface_index = USB_IFACE_INDEX_ANY;
/* set alternate index */
iface->alt_index = alt_index;
+ /* set default interface parent */
+ if (iface_index == USB_IFACE_INDEX_ANY) {
+ iface->parent_iface_index =
+ USB_IFACE_INDEX_ANY;
+ }
}
DPRINTFN(5, "found idesc nendpt=%d\n", id->bNumEndpoints);
@@ -1229,10 +1232,13 @@ usbd_set_parent_iface(struct usb_device *udev, uint8_t iface_index,
{
struct usb_interface *iface;
+ if (udev == NULL) {
+ /* nothing to do */
+ return;
+ }
iface = usbd_get_iface(udev, iface_index);
- if (iface) {
+ if (iface != NULL)
iface->parent_iface_index = parent_index;
- }
}
static void
diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c
index f175eb9..5f156b1 100644
--- a/sys/dev/usb/usb_generic.c
+++ b/sys/dev/usb/usb_generic.c
@@ -2166,7 +2166,16 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags)
break;
}
+ /*
+ * Detach the currently attached driver.
+ */
usb_detach_device(f->udev, n, 0);
+
+ /*
+ * Set parent to self, this should keep attach away
+ * until the next set configuration event.
+ */
+ usbd_set_parent_iface(f->udev, n, n);
break;
case USB_SET_POWER_MODE:
OpenPOWER on IntegriCloud