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}
>
>