On 04/07/18(Wed) 17:00, Martin Pieuchot wrote:
> 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?

Anyone?  Comments?  Oks?
 
> 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