summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorn_hibma <n_hibma@FreeBSD.org>1999-05-30 18:49:17 +0000
committern_hibma <n_hibma@FreeBSD.org>1999-05-30 18:49:17 +0000
commit83ddff966ff871e381071960db841c30f77229b5 (patch)
treeab359062844ef6c9422574a36377740b1620fbab /sys/dev
parent26fb913de5b1084512973ba2177d8abb9d5a185e (diff)
downloadFreeBSD-src-83ddff966ff871e381071960db841c30f77229b5.zip
FreeBSD-src-83ddff966ff871e381071960db841c30f77229b5.tar.gz
Enable attachment of multiple drivers to a single device.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/usb_subr.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index cba6d3b..e212f2a 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -699,9 +699,7 @@ usbd_probe_and_attach(parent, dev, port, addr)
{
struct usb_attach_arg uaa;
usb_device_descriptor_t *dd = &dev->ddesc;
-#if defined(__NetBSD__)
int found = 0;
-#endif
int r, i, confi, nifaces;
usbd_interface_handle ifaces[256]; /* 256 is the absolute max */
@@ -755,20 +753,27 @@ usbd_probe_and_attach(parent, dev, port, addr)
uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
if (USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print,
usbd_submatch)) {
-#if defined(__NetBSD__)
found++;
ifaces[i] = 0; /* consumed */
-#elif defined(__FreeBSD__)
- /* XXX FreeBSD can't handle multiple intfaces
- * on 1 device yet */
- return (USBD_NORMAL_COMPLETION);
+
+#if defined(__FreeBSD__)
+ /* create another device for the next iface */
+ bdev = device_add_child(*parent, NULL, -1, &uaa);
+ if (!bdev) {
+ printf("%s: Device creation failed\n",
+ USBDEVNAME(dev->bus->bdev));
+ return (USBD_NORMAL_COMPLETION);
+ }
#endif
}
}
-#if defined(__NetBSD__)
- if (found != 0)
- return (USBD_NORMAL_COMPLETION);
+ if (found != 0) {
+#if defined(__FreeBSD__)
+ /* remove the last created child again, it is unused */
+ device_delete_child(*parent, bdev);
#endif
+ return (USBD_NORMAL_COMPLETION);
+ }
}
/* No interfaces were attached in any of the configurations. */
if (dd->bNumConfigurations > 1)/* don't change if only 1 config */
@@ -915,7 +920,7 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up)
/* Set the address */
r = usbd_set_address(dev, addr);
if (r != USBD_NORMAL_COMPLETION) {
- DPRINTFN(-1,("usb_new_device: set address %d failed\n",addr));
+ DPRINTFN(-1,("usbd_new_device: set address %d failed\n",addr));
r = USBD_SET_ADDR_FAILED;
usbd_remove_device(dev, up);
return (r);
OpenPOWER on IntegriCloud