Skip to content

Commit

Permalink
Merge pull request #35 from matnyman/master
Browse files Browse the repository at this point in the history
Add USB 3.1 SuperSpeedPlus capability descriptor to lsusb -v output
  • Loading branch information
gregkh committed Sep 14, 2015
2 parents 115695e + 21d0d7a commit 13ada67
Showing 1 changed file with 59 additions and 16 deletions.
75 changes: 59 additions & 16 deletions lsusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#define USB_DC_20_EXTENSION 0x02
#define USB_DC_SUPERSPEED 0x03
#define USB_DC_CONTAINER_ID 0x04
#define USB_DC_SUPERSPEEDPLUS 0x0a

/* Conventional codes for class-specific descriptors. The convention is
* defined in the USB "Common Class" Spec (3.11). Individual class specs
Expand Down Expand Up @@ -3718,6 +3719,42 @@ static void dump_ss_device_capability_desc(unsigned char *buf)
printf(" bU2DevExitLat %8u micro seconds\n", buf[8] + (buf[9] << 8));
}

static void dump_ssp_device_capability_desc(unsigned char *buf)
{
int i;
unsigned int bm_attr, ss_attr;
char bitrate_prefix[] = " KMG";

if (buf[0] < 12) {
printf(" Bad SuperSpeedPlus USB Device Capability descriptor.\n");
return;
}

bm_attr = convert_le_u32(buf + 4);
printf(" SuperSpeedPlus USB Device Capability:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" bDevCapabilityType %5u\n"
" bmAttributes 0x%08x\n",
buf[0], buf[1], buf[2], bm_attr);

printf(" Sublink Speed Attribute count %u\n", buf[4] & 0x1f);
printf(" Sublink Speed ID count %u\n", (bm_attr >> 5) & 0xf);
printf(" wFunctionalitySupport 0x%02x%02x\n", buf[9], buf[8]);

for (i = 0; i <= (buf[4] & 0x1f); i++) {
ss_attr = convert_le_u32(buf + 12 + (i * 4));
printf(" bmSublinkSpeedAttr[%u] 0x%08x\n", i, ss_attr);
printf(" Speed Attribute ID: %u %u%cb/s %s %s SuperSpeed%s\n",
ss_attr & 0x0f,
ss_attr >> 16,
(bitrate_prefix[((ss_attr >> 4) & 0x3)]),
(ss_attr & 0x40)? "Asymmetric" : "Symmetric",
(ss_attr & 0x80)? "TX" : "RX",
(ss_attr & 0x4000)? "Plus": "" );
}
}

static void dump_container_id_device_capability_desc(unsigned char *buf)
{
if (buf[0] < 20) {
Expand All @@ -3736,11 +3773,13 @@ static void dump_container_id_device_capability_desc(unsigned char *buf)

static void dump_bos_descriptor(libusb_device_handle *fd)
{
/* Total for all known BOS descriptors is 43 bytes:
* 6 bytes for Wireless USB, 7 bytes for USB 2.0 extension,
* 10 bytes for SuperSpeed, 20 bytes for Container ID.
/* Total length of BOS descriptors varies.
* Read first static 5 bytes which include the total length before
* allocating and readig the full BOS
*/
unsigned char bos_desc[43];

unsigned char bos_desc_static[5];
unsigned char *bos_desc;
unsigned int bos_desc_size;
int size, ret;
unsigned char *buf;
Expand All @@ -3750,32 +3789,31 @@ static void dump_bos_descriptor(libusb_device_handle *fd)
LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_DEVICE,
LIBUSB_REQUEST_GET_DESCRIPTOR,
USB_DT_BOS << 8, 0,
bos_desc, 5, CTRL_TIMEOUT);
bos_desc_static, 5, CTRL_TIMEOUT);
if (ret <= 0)
return;
else if (bos_desc[0] != 5 || bos_desc[1] != USB_DT_BOS)
else if (bos_desc_static[0] != 5 || bos_desc_static[1] != USB_DT_BOS)
return;

bos_desc_size = bos_desc[2] + (bos_desc[3] << 8);
bos_desc_size = bos_desc_static[2] + (bos_desc_static[3] << 8);
printf("Binary Object Store Descriptor:\n"
" bLength %5u\n"
" bDescriptorType %5u\n"
" wTotalLength %5u\n"
" bNumDeviceCaps %5u\n",
bos_desc[0], bos_desc[1],
bos_desc_size, bos_desc[4]);
bos_desc_static[0], bos_desc_static[1],
bos_desc_size, bos_desc_static[4]);

if (bos_desc_size <= 5) {
if (bos_desc[4] > 0)
if (bos_desc_static[4] > 0)
fprintf(stderr, "Couldn't get "
"device capability descriptors\n");
return;
}
if (bos_desc_size > sizeof bos_desc) {
fprintf(stderr, "FIXME: alloc bigger buffer for "
"device capability descriptors\n");
bos_desc = malloc(bos_desc_size);
if (!bos_desc)
return;
}
memset(bos_desc, 0, bos_desc_size);

ret = usb_control_msg(fd,
LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_DEVICE,
Expand All @@ -3784,7 +3822,7 @@ static void dump_bos_descriptor(libusb_device_handle *fd)
bos_desc, bos_desc_size, CTRL_TIMEOUT);
if (ret < 0) {
fprintf(stderr, "Couldn't get device capability descriptors\n");
return;
goto out;
}

size = bos_desc_size - 5;
Expand All @@ -3793,7 +3831,7 @@ static void dump_bos_descriptor(libusb_device_handle *fd)
while (size >= 3) {
if (buf[0] < 3) {
printf("buf[0] = %u\n", buf[0]);
return;
goto out;
}
switch (buf[2]) {
case USB_DC_WIRELESS_USB:
Expand All @@ -3805,6 +3843,9 @@ static void dump_bos_descriptor(libusb_device_handle *fd)
case USB_DC_SUPERSPEED:
dump_ss_device_capability_desc(buf);
break;
case USB_DC_SUPERSPEEDPLUS:
dump_ssp_device_capability_desc(buf);
break;
case USB_DC_CONTAINER_ID:
dump_container_id_device_capability_desc(buf);
break;
Expand All @@ -3816,6 +3857,8 @@ static void dump_bos_descriptor(libusb_device_handle *fd)
size -= buf[0];
buf += buf[0];
}
out:
free(bos_desc);
}

static void dumpdev(libusb_device *dev)
Expand Down

0 comments on commit 13ada67

Please sign in to comment.