diff options
Diffstat (limited to 'sys/dev/usb/uhub.c')
-rw-r--r-- | sys/dev/usb/uhub.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c index e302183..77a2ead 100644 --- a/sys/dev/usb/uhub.c +++ b/sys/dev/usb/uhub.c @@ -93,6 +93,8 @@ Static void uhub_intr(usbd_xfer_handle, usbd_private_handle,usbd_status); #if defined(__FreeBSD__) Static bus_driver_added_t uhub_driver_added; Static bus_child_detached_t uhub_child_detached; +int uhub_child_location_str(device_t, device_t, char*, size_t); +int uhub_child_pnpinfo_str(device_t, device_t, char*, size_t); #endif @@ -112,6 +114,8 @@ CFATTACH_DECL(uhub_uhub, sizeof(struct uhub_softc), USB_DECLARE_DRIVER_INIT(uhub, DEVMETHOD(bus_driver_added, uhub_driver_added), DEVMETHOD(bus_child_detached, uhub_child_detached), + DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str), + DEVMETHOD(bus_child_location_str, uhub_child_location_str), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), DEVMETHOD(device_shutdown, bus_generic_shutdown) @@ -123,6 +127,8 @@ devclass_t uhubroot_devclass; Static device_method_t uhubroot_methods[] = { DEVMETHOD(device_probe, uhub_match), DEVMETHOD(device_attach, uhub_attach), + DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str), + DEVMETHOD(bus_child_location_str, uhub_child_location_str), /* detach is not allowed for a root hub */ DEVMETHOD(device_suspend, bus_generic_suspend), @@ -576,6 +582,107 @@ USB_DETACH(uhub) } #if defined(__FreeBSD__) +int +uhub_child_location_str(device_t cbdev, device_t child, char *buf, + size_t buflen) +{ + struct uhub_softc *sc = device_get_softc(cbdev); + usbd_device_handle devhub = sc->sc_hub; + usbd_device_handle dev; + int nports; + int port; + int i; + + nports = devhub->hub->hubdesc.bNbrPorts; + for (port = 0; port < nports; port++) { + dev = devhub->hub->ports[port].device; + if (dev && dev->subdevs) { + for (i = 0; dev->subdevs[i]; i++) { + if (dev->subdevs[i] == child) { + goto found_dev; + } + } + } + } + DPRINTFN(0,("uhub_child_location_str: device not on hub\n")); + buf[0] = '\0'; + return (0); + +found_dev: + if (dev->ifacenums == NULL) { + snprintf(buf, buflen, "port=%i", port); + } else { + snprintf(buf, buflen, "port=%i interface=%i", + port, dev->ifacenums[i]); + } + return (0); +} + +int +uhub_child_pnpinfo_str(device_t cbdev, device_t child, char *buf, + size_t buflen) +{ + struct uhub_softc *sc = device_get_softc(cbdev); + usbd_device_handle devhub = sc->sc_hub; + usbd_device_handle dev; + usb_string_descriptor_t us; + struct usbd_interface *iface; + char serial[128]; + int nports; + int port; + int i, j, size; + int err; + + nports = devhub->hub->hubdesc.bNbrPorts; + for (port = 0; port < nports; port++) { + dev = devhub->hub->ports[port].device; + if (dev && dev->subdevs) { + for (i = 0; dev->subdevs[i]; i++) { + if (dev->subdevs[i] == child) { + goto found_dev; + } + } + } + } + DPRINTFN(0,("uhub_child_pnpinfo_str: device not on hub\n")); + buf[0] = '\0'; + return (0); + +found_dev: + j = 0; + if (dev->ddesc.iSerialNumber != 0) { + err = usbd_get_string_desc(dev, dev->ddesc.iSerialNumber, 0, + &us, &size); + if (err == 0) { + do { + serial[j] = UGETW(us.bString[j]); + j++; + } while (j < ((us.bLength - 2) / 2)); + } + } + serial[j] = '\0'; + if (dev->ifacenums == NULL) { + snprintf(buf, buflen, "vendor=0x%04x product=0x%04x " + "devclass=0x%02x devsubclass=0x%02x " + "sernum=\"%s\"", + UGETW(dev->ddesc.idVendor), UGETW(dev->ddesc.idProduct), + dev->ddesc.bDeviceClass, dev->ddesc.bDeviceSubClass, + serial); + } else { + iface = &dev->ifaces[dev->ifacenums[i]]; + snprintf(buf, buflen, "vendor=0x%04x product=0x%04x " + "devclass=0x%02x devsubclass=0x%02x " + "sernum=\"%s\" " + "intclass=0x%02x intsubclass=0x%02x", + UGETW(dev->ddesc.idVendor), UGETW(dev->ddesc.idProduct), + dev->ddesc.bDeviceClass, dev->ddesc.bDeviceSubClass, + serial, + iface->idesc->bInterfaceClass, + iface->idesc->bInterfaceSubClass); + } + return (0); +} + /* Called when a device has been detached from it */ Static void uhub_child_detached(device_t self, device_t child) |