| From f4424c228bbed295f805d1baa3b4a055a08af304 Mon Sep 17 00:00:00 2001 |
| From: Muthu M <muthu.lnx@gmail.com> |
| Date: Wed, 14 Oct 2015 01:16:37 +0530 |
| Subject: [PATCH 2/7] lsusb: Added support for Billboard Capability descriptor |
| |
| Added support for Billboard Capability descriptor as per Universal |
| Serial Bus Device Class Definition for Billboard Devices Revision 1.1 |
| |
| Signed-off-by: Muthu M <muthu.lnx@gmail.com> |
| Reviewed-by: Felipe Balbi <balbi@ti.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| (cherry picked from commit f69bf4f5d271e199dfcba7e5c765d810c536b117) |
| --- |
| lsusb.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
| 1 file changed, 111 insertions(+), 3 deletions(-) |
| |
| diff --git a/lsusb.c b/lsusb.c |
| index 1eadcf8..b7334d7 100644 |
| --- a/lsusb.c |
| +++ b/lsusb.c |
| @@ -70,6 +70,7 @@ |
| #define USB_DC_SUPERSPEED 0x03 |
| #define USB_DC_CONTAINER_ID 0x04 |
| #define USB_DC_SUPERSPEEDPLUS 0x0a |
| +#define USB_DC_BILLBOARD 0x0d |
| |
| /* Conventional codes for class-specific descriptors. The convention is |
| * defined in the USB "Common Class" Spec (3.11). Individual class specs |
| @@ -108,6 +109,8 @@ |
| |
| #define HUB_STATUS_BYTELEN 3 /* max 3 bytes status = hub + 23 ports */ |
| |
| +#define BILLBOARD_MAX_NUM_ALT_MODE (0x34) |
| + |
| static const char procbususb[] = "/proc/bus/usb"; |
| static unsigned int verblevel = VERBLEVEL_DEFAULT; |
| static int do_report_desc = 1; |
| @@ -119,6 +122,24 @@ static const char * const encryption_type[] = { |
| "RESERVED" |
| }; |
| |
| +static const char * const vconn_power[] = { |
| + "1W", |
| + "1.5W", |
| + "2W", |
| + "3W", |
| + "4W", |
| + "5W", |
| + "6W", |
| + "reserved" |
| +}; |
| + |
| +static const char * const alt_mode_state[] = { |
| + "Unspecified Error", |
| + "Alternate Mode configuration not attempted", |
| + "Alternate Mode configuration attempted but unsuccessful", |
| + "Alternate Mode configuration successful" |
| +}; |
| + |
| static void dump_interface(libusb_device_handle *dev, const struct libusb_interface *interface); |
| static void dump_endpoint(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface, const struct libusb_endpoint_descriptor *endpoint); |
| static void dump_audiocontrol_interface(libusb_device_handle *dev, const unsigned char *buf, int protocol); |
| @@ -133,6 +154,7 @@ static void dump_audiostreaming_endpoint(const unsigned char *buf, int protocol) |
| static void dump_midistreaming_endpoint(const unsigned char *buf); |
| static void dump_hub(const char *prefix, const unsigned char *p, int tt_type); |
| static void dump_ccid_device(const unsigned char *buf); |
| +static void dump_billboard_device_capability_desc(libusb_device_handle *dev, unsigned char *buf); |
| |
| /* ---------------------------------------------------------------------- */ |
| |
| @@ -141,6 +163,11 @@ static unsigned int convert_le_u32 (const unsigned char *buf) |
| return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); |
| } |
| |
| +static unsigned int convert_le_u16 (const unsigned char *buf) |
| +{ |
| + return buf[0] | (buf[1] << 8); |
| +} |
| + |
| /* ---------------------------------------------------------------------- */ |
| |
| /* workaround libusb API goofs: "byte" should never be sign extended; |
| @@ -3647,7 +3674,7 @@ static void dump_usb2_device_capability_desc(unsigned char *buf) |
| static void dump_ss_device_capability_desc(unsigned char *buf) |
| { |
| if (buf[0] < 10) { |
| - printf(" Bad SuperSpeed USB Device Capability descriptor.\n"); |
| + fprintf(stderr, " Bad SuperSpeed USB Device Capability descriptor.\n"); |
| return; |
| } |
| printf(" SuperSpeed USB Device Capability:\n" |
| @@ -3703,7 +3730,7 @@ static void dump_ssp_device_capability_desc(unsigned char *buf) |
| char bitrate_prefix[] = " KMG"; |
| |
| if (buf[0] < 12) { |
| - printf(" Bad SuperSpeedPlus USB Device Capability descriptor.\n"); |
| + fprintf(stderr, " Bad SuperSpeedPlus USB Device Capability descriptor.\n"); |
| return; |
| } |
| |
| @@ -3735,7 +3762,7 @@ static void dump_ssp_device_capability_desc(unsigned char *buf) |
| static void dump_container_id_device_capability_desc(unsigned char *buf) |
| { |
| if (buf[0] < 20) { |
| - printf(" Bad Container ID Device Capability descriptor.\n"); |
| + fprintf(stderr, " Bad Container ID Device Capability descriptor.\n"); |
| return; |
| } |
| printf(" Container ID Device Capability:\n" |
| @@ -3748,6 +3775,84 @@ static void dump_container_id_device_capability_desc(unsigned char *buf) |
| get_guid(&buf[4])); |
| } |
| |
| +static void dump_billboard_device_capability_desc(libusb_device_handle *dev, unsigned char *buf) |
| +{ |
| + char *url, *alt_mode_str; |
| + int w_vconn_power, alt_mode, i, svid, state; |
| + const char *vconn; |
| + unsigned char *bmConfigured; |
| + |
| + if (buf[0] < 48) { |
| + fprintf(stderr, " Bad Billboard Capability descriptor.\n"); |
| + return; |
| + } |
| + |
| + if (buf[4] > BILLBOARD_MAX_NUM_ALT_MODE) { |
| + fprintf(stderr, " Invalid value for bNumberOfAlternateModes.\n"); |
| + return; |
| + } |
| + |
| + if (buf[0] < (44 + buf[4] * 4)) { |
| + fprintf(stderr, " bLength does not match with bNumberOfAlternateModes.\n"); |
| + return; |
| + } |
| + |
| + url = get_dev_string(dev, buf[3]); |
| + w_vconn_power = convert_le_u16(buf+6); |
| + if (w_vconn_power & (1 << 15)) { |
| + vconn = "VCONN power not required"; |
| + } else if (w_vconn_power < 7) { |
| + vconn = vconn_power[w_vconn_power & 0x7]; |
| + } else { |
| + vconn = "reserved"; |
| + } |
| + printf(" Billboard Capability:\n" |
| + " bLength %5u\n" |
| + " bDescriptorType %5u\n" |
| + " bDevCapabilityType %5u\n" |
| + " iAddtionalInfoURL %5u %s\n" |
| + " bNumberOfAlternateModes %5u\n" |
| + " bPreferredAlternateMode %5u\n" |
| + " VCONN Power %5u %s\n", |
| + buf[0], buf[1], buf[2], |
| + buf[3], url, |
| + buf[4], buf[5], |
| + w_vconn_power, vconn); |
| + |
| + bmConfigured = &buf[8]; |
| + |
| + printf(" bmConfigured "); |
| + dump_bytes(bmConfigured, 32); |
| + |
| + printf( |
| + " bcdVersion %2x.%02x\n" |
| + " bAdditionalFailureInfo %5u\n" |
| + " bReserved %5u\n", |
| + (buf[41] == 0) ? 1 : buf[41], buf[40], |
| + buf[42], buf[43]); |
| + |
| + printf(" Alternate Modes supported by Device Container:\n"); |
| + i = 44; /* Alternate mode 0 starts at index 44 */ |
| + for (alt_mode = 0; alt_mode < buf[4]; alt_mode++) { |
| + svid = convert_le_u16(buf+i); |
| + alt_mode_str = get_dev_string(dev, buf[i+3]); |
| + state = ((bmConfigured[alt_mode >> 2]) >> ((alt_mode & 0x3) << 1)) & 0x3; |
| + printf( |
| + " Alternate Mode %d : %s\n" |
| + " wSVID[%d] 0x%04X\n" |
| + " bAlternateMode[%d] %5u\n" |
| + " iAlternateModeString[%d] %5u %s\n", |
| + alt_mode, alt_mode_state[state], |
| + alt_mode, svid, |
| + alt_mode, buf[i+2], |
| + alt_mode, buf[i+3], alt_mode_str); |
| + free(alt_mode_str); |
| + i += 4; |
| + } |
| + |
| + free (url); |
| +} |
| + |
| static void dump_bos_descriptor(libusb_device_handle *fd) |
| { |
| /* Total for all known BOS descriptors is 43 bytes: |
| @@ -3825,6 +3930,9 @@ static void dump_bos_descriptor(libusb_device_handle *fd) |
| case USB_DC_CONTAINER_ID: |
| dump_container_id_device_capability_desc(buf); |
| break; |
| + case USB_DC_BILLBOARD: |
| + dump_billboard_device_capability_desc(fd, buf); |
| + break; |
| default: |
| printf(" ** UNRECOGNIZED: "); |
| dump_bytes(buf, buf[0]); |
| -- |
| 2.12.2 |
| |