Diff below adds support for printing USB ports status.  It includes an
ABI change as we currently do not export port status/change to userland.

I'd really like to export the current cached value to userland via the
USB_DEVICEINFO ioctl(2) to reduce the numbers of I/O.

Note that this diff also fixes some link-status defines in usb.h

Since it includes an ABI break I cranked devel/libusb1.

  $ usbdevs -dvv 
  Controller /dev/usb0:
  addr 01: 8086:0000 Intel, xHCI root hub
           super speed, self powered, config 1, rev 1.00
           driver: uhub0
           port 01: 0000.02a0 power Rx.detect
           port 02: 0000.02a0 power Rx.detect
           port 03: 0000.02a0 power Rx.detect
           port 04: 0000.0503 connect enabled recovery
           port 05: 0000.02a0 power Rx.detect
        ...
  addr 02: 04f2:b45d Chicony Electronics Co.,Ltd., Integrated Camera
           high speed, power 500 mA, config 1, rev 0.29, iSerialNumber 0x0001
           driver: uvideo0

ok?

Index: src/usr.sbin/usbdevs/usbdevs.c
===================================================================
RCS file: /cvs/src/usr.sbin/usbdevs/usbdevs.c,v
retrieving revision 1.27
diff -u -p -r1.27 usbdevs.c
--- src/usr.sbin/usbdevs/usbdevs.c      3 Jul 2018 13:21:31 -0000       1.27
+++ src/usr.sbin/usbdevs/usbdevs.c      4 Jul 2018 14:46:08 -0000
@@ -54,7 +54,7 @@ int verbose = 0;
 int showdevs = 0;
 
 void usage(void);
-void usbdev(int f, uint8_t, int rec);
+void usbdev(int f, uint8_t);
 void usbdump(int f);
 void dumpone(char *name, int f, int addr);
 int main(int, char **);
@@ -69,13 +69,13 @@ usage(void)
 }
 
 char done[USB_MAX_DEVICES];
-int indent;
 
 void
-usbdev(int f, uint8_t addr, int rec)
+usbdev(int f, uint8_t addr)
 {
        struct usb_device_info di;
-       int e, p, i, s, nports;
+       int e, i, port, nports;
+       uint16_t change, status;
 
        di.udi_addr = addr;
        e = ioctl(f, USB_DEVICEINFO, &di);
@@ -89,6 +89,7 @@ usbdev(int f, uint8_t addr, int rec)
        done[addr] = 1;
        printf("%04x:%04x %s, %s", di.udi_vendorNo, di.udi_productNo,
            di.udi_vendor, di.udi_product);
+
        if (verbose) {
                printf("\n\t ");
                switch (di.udi_speed) {
@@ -122,48 +123,96 @@ usbdev(int f, uint8_t addr, int rec)
                        printf(", iSerialNumber %s", di.udi_serial);
        }
        printf("\n");
+
        if (showdevs) {
                for (i = 0; i < USB_MAX_DEVNAMES; i++)
                        if (di.udi_devnames[i][0])
-                               printf("%*s  %s\n", indent, "",
-                                   di.udi_devnames[i]);
+                               printf("\t driver: %s\n", di.udi_devnames[i]);
        }
-       if (!rec)
-               return;
 
-       nports = MINIMUM(di.udi_nports, nitems(di.udi_ports));
        if (verbose > 1) {
-               for (p = 0; p < nports; p++) {
-                       s = di.udi_ports[p];
-                       printf("\t port %02u:", p+1);
-                       if (s < USB_MAX_DEVICES)
-                               printf(" addr %02u\n", s);
-                       else {
-                               printf(" %s\n",
-                                   s == USB_PORT_ENABLED ? "enabled" :
-                                   s == USB_PORT_SUSPENDED ? "suspended" :
-                                   s == USB_PORT_POWERED ? "powered" :
-                                   s == USB_PORT_DISABLED ? "disabled" :
-                                   "???");
+               nports = MINIMUM(di.udi_nports, nitems(di.udi_ports));
+               for (port = 0; port < nports; port++) {
+                       status = di.udi_ports[port] & 0xffff;
+                       change = di.udi_ports[port] >> 16;
+                       printf("\t port %02u: %04x.%04x", port+1, change,
+                           status);
+
+                       if (status & UPS_CURRENT_CONNECT_STATUS)
+                               printf(" connect");
+
+                       if (status & UPS_PORT_ENABLED)
+                               printf(" enabled");
+
+                       if (status & UPS_SUSPEND)
+                               printf(" supsend");
+
+                       if (status & UPS_OVERCURRENT_INDICATOR)
+                               printf(" overcurrent");
+
+                       if (di.udi_speed < USB_SPEED_SUPER) {
+                               if (status & UPS_PORT_L1)
+                                       printf(" l1");
+
+                               if (status & UPS_PORT_POWER)
+                                       printf(" power");
+                       } else {
+                               if (status & UPS_PORT_POWER_SS)
+                                       printf(" power");
+
+                               switch (UPS_PORT_LS_GET(status)) {
+                               case UPS_PORT_LS_U0:
+                                       printf(" U0");
+                                       break;
+                               case UPS_PORT_LS_U1:
+                                       printf(" U1");
+                                       break;
+                               case UPS_PORT_LS_U2:
+                                       printf(" U2");
+                                       break;
+                               case UPS_PORT_LS_U3:
+                                       printf(" U3");
+                                       break;
+                               case UPS_PORT_LS_SS_DISABLED:
+                                       printf(" SS.disabled");
+                                       break;
+                               case UPS_PORT_LS_RX_DETECT:
+                                       printf(" Rx.detect");
+                                       break;
+                               case UPS_PORT_LS_SS_INACTIVE:
+                                       printf(" ss.inactive");
+                                       break;
+                               case UPS_PORT_LS_POLLING:
+                                       printf(" polling");
+                                       break;
+                               case UPS_PORT_LS_RECOVERY:
+                                       printf(" recovery");
+                                       break;
+                               case UPS_PORT_LS_HOT_RESET:
+                                       printf(" hot.reset");
+                                       break;
+                               case UPS_PORT_LS_COMP_MOD:
+                                       printf(" comp.mod");
+                                       break;
+                               case UPS_PORT_LS_LOOPBACK:
+                                       printf(" loopback");
+                                       break;
+                               }
                        }
-               }
-       }
 
-       for (p = 0; p < nports ; p++) {
-               s = di.udi_ports[p];
-               if (s < USB_MAX_DEVICES)
-                       usbdev(f, s, 1);
+                       printf("\n");
+               }
        }
 }
 
 void
 usbdump(int f)
 {
-       int a;
+       uint8_t addr;
 
-       for (a = 1; a < USB_MAX_DEVICES; a++) {
-               if (!done[a])
-                       usbdev(f, a, 1);
+       for (addr = 1; addr < USB_MAX_DEVICES; addr++) {
+               if (!done[addr])
+                       usbdev(f, addr);
        }
 }
 
@@ -172,10 +221,9 @@ dumpone(char *name, int f, int addr)
 {
        if (!addr)
                printf("Controller %s:\n", name);
-       indent = 0;
        memset(done, 0, sizeof done);
        if (addr)
-               usbdev(f, addr, 0);
+               usbdev(f, addr);
        else
                usbdump(f);
 }
Index: src/sys/dev/usb/usb.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb.h,v
retrieving revision 1.59
diff -u -p -r1.59 usb.h
--- src/sys/dev/usb/usb.h       1 Sep 2017 16:38:14 -0000       1.59
+++ src/sys/dev/usb/usb.h       4 Jul 2018 14:52:02 -0000
@@ -442,18 +442,19 @@ struct usb_port_status {
 #define UPS_PORT_L1                    0x0020  /* USB 2.0 only */
 
 /* Super-Speed port link state values. */
-#define UPS_PORT_LS_U0                 0x0000
-#define UPS_PORT_LS_U1                 0x0020
-#define UPS_PORT_LS_U2                 0x0040
-#define UPS_PORT_LS_U3                 0x0060
-#define UPS_PORT_LS_SS_DISABLED                0x0080
-#define UPS_PORT_LS_RX_DETECT          0x00a0
-#define UPS_PORT_LS_SS_INACTIVE                0x00c0
-#define UPS_PORT_LS_POLLING            0x00e0
-#define UPS_PORT_LS_RECOVERY           0x0100
-#define UPS_PORT_LS_HOT_RESET          0x0120
-#define UPS_PORT_LS_COMP_MOD           0x0140
-#define UPS_PORT_LS_LOOPBACK           0x0160
+#define UPS_PORT_LS_U0                 0x00
+#define UPS_PORT_LS_U1                 0x01
+#define UPS_PORT_LS_U2                 0x02
+#define UPS_PORT_LS_U3                 0x03
+#define UPS_PORT_LS_SS_DISABLED                0x04
+#define UPS_PORT_LS_RX_DETECT          0x05
+#define UPS_PORT_LS_SS_INACTIVE                0x06
+#define UPS_PORT_LS_POLLING            0x07
+#define UPS_PORT_LS_RECOVERY           0x08
+#define UPS_PORT_LS_HOT_RESET          0x09
+#define UPS_PORT_LS_COMP_MOD           0x0a
+#define UPS_PORT_LS_LOOPBACK           0x0b
+#define UPS_PORT_LS_RESUME             0x0f
 #define UPS_PORT_LS_GET(x)             (((x) >> 5) & 0xf)
 #define UPS_PORT_LS_SET(x)             (((x) & 0xf) << 5)
 
@@ -739,11 +740,7 @@ struct usb_device_info {
        int             udi_power;      /* power consumption in mA, 0 if 
selfpowered */
        int             udi_nports;
        char            udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN];
-       u_int8_t        udi_ports[16];/* hub only: addresses of devices on 
ports */
-#define USB_PORT_ENABLED 0xff
-#define USB_PORT_SUSPENDED 0xfe
-#define USB_PORT_POWERED 0xfd
-#define USB_PORT_DISABLED 0xfc
+       u_int32_t       udi_ports[16];  /* hub only: ports status/change */
        char            udi_serial[USB_MAX_STRING_LEN];
 };
 
Index: src/sys/dev/usb/usb_subr.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb_subr.c,v
retrieving revision 1.136
diff -u -p -r1.136 usb_subr.c
--- src/sys/dev/usb/usb_subr.c  1 May 2018 18:14:46 -0000       1.136
+++ src/sys/dev/usb/usb_subr.c  4 Jul 2018 14:18:36 -0000
@@ -1304,7 +1304,7 @@ void
 usbd_fill_deviceinfo(struct usbd_device *dev, struct usb_device_info *di)
 {
        struct usbd_port *p;
-       int i, err, s;
+       int i;
 
        di->udi_bus = dev->bus->usbctl->dv_unit;
        di->udi_addr = dev->address;
@@ -1338,20 +1338,8 @@ usbd_fill_deviceinfo(struct usbd_device 
                for (i = 0;
                    i < nitems(di->udi_ports) && i < dev->hub->nports; i++) {
                        p = &dev->hub->ports[i];
-                       if (p->device)
-                               err = p->device->address;
-                       else {
-                               s = UGETW(p->status.wPortStatus);
-                               if (s & UPS_PORT_ENABLED)
-                                       err = USB_PORT_ENABLED;
-                               else if (s & UPS_SUSPEND)
-                                       err = USB_PORT_SUSPENDED;
-                               else if (s & UPS_PORT_POWER)
-                                       err = USB_PORT_POWERED;
-                               else
-                                       err = USB_PORT_DISABLED;
-                       }
-                       di->udi_ports[i] = err;
+                       di->udi_ports[i] = UGETW(p->status.wPortChange) << 16 |
+                           UGETW(p->status.wPortStatus);
                }
                di->udi_nports = dev->hub->nports;
        } else
Index: ports/devel/libusb1/Makefile
===================================================================
RCS file: /cvs/ports/devel/libusb1/Makefile,v
retrieving revision 1.27
diff -u -p -r1.27 Makefile
--- ports/devel/libusb1/Makefile        19 Apr 2017 06:09:02 -0000      1.27
+++ ports/devel/libusb1/Makefile        4 Jul 2018 14:16:36 -0000
@@ -3,6 +3,7 @@
 COMMENT =              library for USB device access from userspace
 
 VERSION =              1.0.21
+REVISION =             0
 DISTNAME =             libusb-${VERSION}
 PKGNAME =              libusb1-${VERSION}
 

Reply via email to