summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/uhub.c
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2004-06-30 02:56:24 +0000
committerimp <imp@FreeBSD.org>2004-06-30 02:56:24 +0000
commit30c1715cd91663c185bdae8b452a2508bd836f8d (patch)
tree412cbade423392b96854dc7ab4f6193f6fb19690 /sys/dev/usb/uhub.c
parent3e05633a44b7bc685841e376bd562e8fa5494038 (diff)
downloadFreeBSD-src-30c1715cd91663c185bdae8b452a2508bd836f8d.zip
FreeBSD-src-30c1715cd91663c185bdae8b452a2508bd836f8d.tar.gz
Add pnpinfo and location information to uhub. We also keep track of
the subdevices of uhub better now to accomplish this. Submitted by: Bernd Walter
Diffstat (limited to 'sys/dev/usb/uhub.c')
-rw-r--r--sys/dev/usb/uhub.c107
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)
OpenPOWER on IntegriCloud