From 95e9e600fe1cb8270f7dbbd697f74b49508f54b0 Mon Sep 17 00:00:00 2001 From: Torleiv Sundre Date: Thu, 14 Nov 2024 20:37:52 +0100 Subject: [PATCH] lsusb: improve usb2 device capability descriptor Fix the following issues with the usb2 device capability descriptor dump: Currently, the BESL values claim to be in microseconds, but are actually the raw, unshifted values from the descriptor. Use a lookup table for the BESL values, based on Table X-X1 from "Errata for USB 2.0 ECN: Link Power Management (LPM) - 7/2007" to display the actual microsecond values. Currently, the BESL values are displayed at the same indentation level as bmAttributes, even though they are fields in bmAttributes. Adjust indentation to align all fields of bmAttributes. Change "BESL value" to "Baseline BESL value", to reflect the actual names of the field. Remove two unnecessary line breaks. Before change: USB 2.0 Extension Device Capability: bLength 7 bDescriptorType 16 bDevCapabilityType 2 bmAttributes 0x0000f41e BESL Link Power Management (LPM) Supported BESL value 1024 us Deep BESL value 61440 us After change: USB 2.0 Extension Device Capability: bLength 7 bDescriptorType 16 bDevCapabilityType 2 bmAttributes 0x0000f41e BESL Link Power Management (LPM) Supported Baseline BESL value 400 us Deep BESL value 10000 us --- lsusb.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lsusb.c b/lsusb.c index 0b74182..a987261 100644 --- a/lsusb.c +++ b/lsusb.c @@ -3217,7 +3217,10 @@ dump_device_status(libusb_device_handle *fd, int otg, int super_speed) static void dump_usb2_device_capability_desc(unsigned char *buf, bool lpm_required) { + static const uint16_t besl_us[16] = { 125, 150, 200, 300, 400, 500, 1000, 2000, + 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000 }; unsigned int wide; + unsigned int besl; wide = buf[3] + (buf[4] << 8) + (buf[5] << 16) + (buf[6] << 24); @@ -3232,16 +3235,17 @@ static void dump_usb2_device_capability_desc(unsigned char *buf, bool lpm_requir else if (!lpm_required && !(wide & 0x02)) printf(" Link Power Management (LPM) not supported\n"); else if (!(wide & 0x04)) - printf(" HIRD Link Power Management (LPM)" - " Supported\n"); + printf(" HIRD Link Power Management (LPM) Supported\n"); else { - printf(" BESL Link Power Management (LPM)" - " Supported\n"); - if (wide & 0x08) - printf(" BESL value %5u us \n", wide & 0xf00); - if (wide & 0x10) - printf(" Deep BESL value %5u us \n", - wide & 0xf000); + printf(" BESL Link Power Management (LPM) Supported\n"); + if (wide & 0x08) { + besl = (wide & 0xf00) >> 8; + printf(" Baseline BESL value %5hu us \n", besl_us[besl]); + } + if (wide & 0x10) { + besl = (wide & 0xf000) >> 12; + printf(" Deep BESL value %5hu us \n", besl_us[besl]); + } } }