From 5de915286f258aa3aae375f7c0c8ebc0fc339c19 Mon Sep 17 00:00:00 2001 From: cvsdist Date: Thu, 9 Sep 2004 13:52:04 +0000 Subject: [PATCH] auto-import changelog data from usbutils-0.11-4.src.rpm Tue May 04 2004 Bill Nottingham 0.11-4 - add patch from USB maintainer to fix various brokenness (#115694, ) --- usbutils-0214.patch | 537 ++++++++++++++++++++++++++++++++++++++++++++ usbutils.spec | 7 +- 2 files changed, 542 insertions(+), 2 deletions(-) create mode 100644 usbutils-0214.patch diff --git a/usbutils-0214.patch b/usbutils-0214.patch new file mode 100644 index 0000000..bacaf36 --- /dev/null +++ b/usbutils-0214.patch @@ -0,0 +1,537 @@ +--- usbutils-0.11/lsusb.c 2002-08-05 23:35:21.000000000 -0700 ++++ usbutils/lsusb.c 2004-02-14 13:00:41.531597608 -0800 +@@ -58,8 +58,8 @@ + #define _GNU_SOURCE + #include + +-#define CTRL_RETRIES 50 +-#define CTRL_TIMEOUT 100 /* milliseconds */ ++#define CTRL_RETRIES 2 ++#define CTRL_TIMEOUT (5*1000) /* milliseconds */ + + #define USB_DT_CS_DEVICE 0x21 + #define USB_DT_CS_CONFIG 0x22 +@@ -106,7 +106,6 @@ static int usb_control_msg(int fd, u_int + ctrl.value = value; + ctrl.index = index; + ctrl.length = size; +- ctrl.timeout = 1000; + ctrl.data = data; + ctrl.timeout = CTRL_TIMEOUT; + try = 0; +@@ -119,10 +118,11 @@ static int usb_control_msg(int fd, u_int + + /* ---------------------------------------------------------------------- */ + ++static int dev_has_strings; ++ + static int get_string(int fd, char *buf, size_t size, u_int8_t id, u_int16_t lang) + { + unsigned char b[256]; +- wchar_t w[128]; + unsigned int i; + int ret; + +@@ -133,17 +133,38 @@ static int get_string(int fd, char *buf, + if (!id || fd == -1) + return 0; + +- b[0] = b[1] = 0xbf; +- ret = usb_control_msg(fd, USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | id, 0, sizeof(b), b); ++ b[0] = b[1] = 0; ++ ++ /* try reading all at once ... some devices misbehave here */ ++ ret = usb_control_msg(fd, USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | id, lang, sizeof(b), b); ++ if (ret > 0) ++ goto got_all; ++ ++ /* read string length first ... most devices handle this ok */ ++ ret = usb_control_msg(fd, USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | id, lang, 2, b); ++ if (ret < 0) { ++ if (open_mode == O_RDWR) ++ fprintf(stderr, "cannot peek string descriptor %d, error = %s(%d)\n", id, strerror(errno), errno); ++ return 0; ++ } ++ if (ret < 2 || b[0] < 2 || b[1] != USB_DT_STRING) { ++ fprintf(stderr, "string descriptor %d invalid (%02x %02x; len=%d)\n", id, b[0], b[1], ret); ++ return 0; ++ } ++ ++ ret = usb_control_msg(fd, USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | id, lang, b[0], b); + if (ret < 0) { + if (open_mode == O_RDWR) + fprintf(stderr, "cannot get string descriptor %d, error = %s(%d)\n", id, strerror(errno), errno); + return 0; + } ++ ++got_all: + if (ret < 2 || b[0] < 2 || b[1] != USB_DT_STRING) { + fprintf(stderr, "string descriptor %d invalid (%02x %02x; len=%d)\n", id, b[0], b[1], ret); + return 0; + } ++ dev_has_strings = 1; + #if 0 + for (i = 0; i < ((b[0] - 2) / 2); i++) + w[i] = b[2+2*i] | (b[3+2*i] << 8); +@@ -151,7 +172,9 @@ static int get_string(int fd, char *buf, + return wcstombs(buf, w, size); + #else + for (i = 0; i < ((b[0] - 2) / 2); i++) +- buf[i] = b[2+2*i]; ++ buf[i] = b[3+2*i] ++ ? '?' /* character's not available in iso-8859/1 */ ++ : b[2+2*i]; + buf[i] = 0; + return i; + #endif +@@ -297,21 +320,25 @@ static void dump_device(int fd, unsigned + dump_junk(buf, " ", 18); + } + +-static void dump_config(int fd, unsigned char *buf) ++static void dump_config(int fd, unsigned char *buf, u_int16_t lang) + { ++ char str[128]; ++ + if (buf[1] != USB_DT_CONFIG) + printf(" Warning: Invalid descriptor\n"); + else if (buf[0] < 9) + printf(" Warning: Descriptor too short\n"); ++ get_string(fd, str, sizeof(str), buf[6], lang); + printf(" Configuration Descriptor:\n" + " bLength %5u\n" + " bDescriptorType %5u\n" + " wTotalLength %5u\n" + " bNumInterfaces %5u\n" + " bConfigurationValue %5u\n" +- " iConfiguration %5u\n" ++ " iConfiguration %5u %s\n" + " bmAttributes 0x%02x\n", +- buf[0], buf[1], buf[2] | (buf[3] << 8), buf[4], buf[5], buf[6], buf[7]); ++ buf[0], buf[1], buf[2] | (buf[3] << 8), buf[4], buf[5], ++ buf[6], str, buf[7]); + if (buf[7] & 0x40) + printf(" Self Powered\n"); + if (buf[7] & 0x20) +@@ -352,6 +379,9 @@ static void dump_endpoint(int fd, unsign + { + static const char *typeattr[] = { "Control", "Isochronous", "Bulk", "Interrupt" }; + static const char *syncattr[] = { "none", "Asynchronous", "Adaptive", "Synchronous" }; ++ static const char *usage[] = { "Data", "Feedback", "Implicit feedback Data", "(reserved)" }; ++ static const char *hb[] = { "once", "twice", "three times", "(?)" }; ++ unsigned wMaxPacket = buf[4] | (buf[5] << 8); + + if (buf[1] != USB_DT_ENDPOINT) + printf(" Warning: Invalid descriptor\n"); +@@ -364,15 +394,19 @@ static void dump_endpoint(int fd, unsign + " bmAttributes %5u\n" + " Transfer Type %s\n" + " Synch Type %s\n" +- " wMaxPacketSize %5u\n" ++ " Usage Type %s\n" ++ " wMaxPacketSize 0x%04x bytes %d %s\n" + " bInterval %5u\n", + buf[0], buf[1], buf[2], buf[2] & 15, (buf[2] & 0x80) ? "IN" : "OUT", + buf[3], typeattr[buf[3] & 3], syncattr[(buf[3] >> 2) & 3], +- buf[4] | (buf[5] << 8), buf[6]); ++ usage[(buf[3] >> 4) & 3], ++ wMaxPacket, wMaxPacket & 0x3ff, hb [(wMaxPacket >> 11) & 3], ++ buf[6]); + if (buf[0] < 9) { + dump_junk(buf, " ", 7); + return; + } ++ /* only for audio endpoints */ + printf(" bRefresh %5u\n" + " bSynchAddress %5u\n", + buf[7], buf[8]); +@@ -1017,23 +1051,53 @@ static void dump_midistreaming_endpoint( + dump_junk(buf, " ", 4+buf[3]); + } + +- +-static void dump_hub(char *p) ++static void dump_hub(char *prefix, unsigned char *p, int has_tt) + { + unsigned int l, i, j; ++ unsigned wHubChar = (p[4] << 8) | p[3]; + +- printf(" Hub Descriptor:\n"); +- printf(" bLength %3u\n",p[0]); +- printf(" bDesriptorType %3u\n",p[1]); +- printf(" nNbrPorts %3u\n",p[2]); +- printf(" wHubCharacteristic 0x%02x 0x%02x\n", p[3],p[4]); +- printf(" bPwrOn2PwrGood %3u * 2 milli seconds\n",p[5]); +- printf(" bHubContrCurrent %3u milli Ampere\n",p[6]); ++ printf("%sHub Descriptor:\n", prefix); ++ printf("%s bLength %3u\n", prefix, p[0]); ++ printf("%s bDescriptorType %3u\n", prefix, p[1]); ++ printf("%s nNbrPorts %3u\n", prefix, p[2]); ++ printf("%s wHubCharacteristic 0x%04x\n", prefix, wHubChar); ++ switch (wHubChar & 0x03) { ++ case 0: ++ printf("%s Ganged power switching\n", prefix); ++ break; ++ case 1: ++ printf("%s Per-port power switching\n", prefix); ++ break; ++ default: ++ printf("%s No power switching (usb 1.0)\n", prefix); ++ break; ++ } ++ if (wHubChar & 0x04) ++ printf("%s Compound device\n", prefix); ++ switch ((wHubChar >> 3) & 0x03) { ++ case 0: ++ printf("%s Ganged overcurrent protection\n", prefix); ++ break; ++ case 1: ++ printf("%s Per-port overcurrent protection\n", prefix); ++ break; ++ default: ++ printf("%s No overcurrent protection\n", prefix); ++ break; ++ } ++ if (has_tt) { ++ l = (wHubChar >> 5) & 0x03; ++ printf("%s TT think time %d FS bits\n", prefix, (l + 1) * 8); ++ } ++ if (wHubChar & (1<<7)) ++ printf("%s Port indicators\n", prefix); ++ printf("%s bPwrOn2PwrGood %3u * 2 milli seconds\n", prefix, p[5]); ++ printf("%s bHubContrCurrent %3u milli Ampere\n", prefix, p[6]); + l= (p[2] >> 3) + 1; /* this determines the variable number of bytes following */ +- printf(" DeviceRemovable "); ++ printf("%s DeviceRemovable ", prefix); + for(i = 0; i < l; i++) + printf(" 0x%02x", p[7+i]); +- printf("\n PortPwrCtrlMask "); ++ printf("\n%s PortPwrCtrlMask ", prefix); + for(j = 0; j < l; j++) + printf(" 0x%02x ", p[7+i+j]); + printf("\n"); +@@ -1047,7 +1111,7 @@ static void dump_hub(char *p) + + static void dump_report_desc(unsigned char *b, int l) + { +- unsigned int t, j, bsize, btag, btype, data, hut; ++ unsigned int t, j, bsize, btag, btype, data = 1000, hut = 1000; + int i; + char *types[4] = { "Main", "Global", "Local", "reserved" }; + char indent[] = " "; +@@ -1168,21 +1232,131 @@ static void dump_hid_device(int fd, unsi + } + } + ++static char * ++dump_comm_descriptor(int fd, unsigned char *buf, char *indent, u_int16_t lang) ++{ ++ int tmp; ++ char str [128]; ++ ++ switch (buf[2]) { ++ case 0: ++ if (buf[0] != 5) ++ goto bad; ++ printf( "%sCDC Header:\n" ++ "%s bcdCDC %x.%02x\n", ++ indent, ++ indent, buf[4], buf[3]); ++ break; ++ case 0x01: /* call management functional desc */ ++ if (buf [0] != 5) ++ goto bad; ++ printf( "%sCDC Call Management:\n" ++ "%s bmCapabilities 0x%02x\n", ++ indent, ++ indent, buf[3]); ++ if (buf[3] & 0x01) ++ printf( "%s call management\n", indent); ++ if (buf[3] & 0x02) ++ printf( "%s use DataInterface\n", indent); ++ printf("%s bDataInterface %d\n", indent, buf[4]); ++ break; ++ case 0x02: /* acm functional desc */ ++ if (buf [0] != 4) ++ goto bad; ++ printf( "%sCDC ACM:\n" ++ "%s bmCapabilities %02x\n", ++ indent, ++ indent, buf[3]); ++ if (buf[3] & 0x08) ++ printf( "%s connection notifications\n", indent); ++ if (buf[3] & 0x04) ++ printf( "%s sends break\n", indent); ++ if (buf[3] & 0x02) ++ printf( "%s line coding and serial state\n", indent); ++ if (buf[3] & 0x01) ++ printf( "%s get/set/clear comm features\n", indent); ++ break; ++ case 0x06: /* union desc */ ++ if (buf [0] < 5) ++ goto bad; ++ printf( "%sCDC Union:\n" ++ "%s bMasterInterface %d\n" ++ "%s bSlaveInterface ", ++ indent, ++ indent, buf [3], ++ indent); ++ for (tmp = 4; tmp < buf [0]; tmp++) ++ printf("%d ", buf [tmp]); ++ printf("\n"); ++ break; ++ case 0x0f: /* ethernet functional desc */ ++ if (buf [0] != 13) ++ goto bad; ++ get_string(fd, str, sizeof str, buf[3], lang); ++ tmp = buf [7] << 8; ++ tmp |= buf [6]; tmp <<= 8; ++ tmp |= buf [5]; tmp <<= 8; ++ tmp |= buf [4]; ++ printf( "%sCDC Ethernet:\n" ++ "%s iMacAddress %d %s\n" ++ "%s bmEthernetStatistics 0x%08x\n", ++ indent, ++ indent, buf[3], (buf[3] && *str) ? str : "(?)", ++ indent, tmp); ++ /* FIXME dissect ALL 28 bits */ ++ printf( "%s wMaxSegmentSize %d\n" ++ "%s wNumberMCFilters 0x%04x\n" ++ "%s bNumberPowerFilters %d\n", ++ indent, (buf[9]<<8)|buf[8], ++ indent, (buf[11]<<8)|buf[10], ++ indent, buf[12]); ++ break; ++ /* FIXME there are about a dozen more descriptor types */ ++ default: ++ return "unsupported comm descriptor"; ++ } ++ return 0; ++ ++bad: ++ return "corrupt comm descriptor"; ++} ++ + /* ---------------------------------------------------------------------- */ + ++static void do_hub(int fd, int has_tt) ++{ ++ unsigned char buf [7]; ++ int ret; ++ ++ ret = usb_control_msg(fd, USB_DIR_IN | USB_TYPE_CLASS, ++ USB_REQ_GET_DESCRIPTOR, 0x29 << 8, 0, ++ sizeof buf, buf); ++ if (ret != sizeof buf) { ++ perror ("can't get hub descriptor"); ++ return; ++ } ++ dump_hub("", buf, has_tt); ++} ++ + static void do_config(int fd, unsigned int nr, u_int16_t lang) + { +- unsigned char buf[1024],*p; +- unsigned int sz,curinterface; +- int l; ++ unsigned char buf[1024],*p, *err; ++ unsigned int sz,curinterface = 1000; + u_int8_t curclass = 0xff, cursubclass = 0xff; ++ unsigned retries = 0; + ++ for (;;) { + if (usb_control_msg(fd, USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_CONFIG << 8) | nr, + 0, USB_DT_CONFIG_SIZE, buf) < 0) { ++ if (retries++ >= 5) { + if (open_mode == O_RDWR) + fprintf(stdout, "cannot get config descriptor %d, %s (%d)\n", nr, strerror(errno), errno); + return; ++ } ++ continue; ++ } else break; + } ++ + if (buf[0] < USB_DT_CONFIG_SIZE || buf[1] != USB_DT_CONFIG) + fprintf(stderr, "Warning: invalid config descriptor\n"); + sz = buf[2] | buf[3] << 8; +@@ -1208,13 +1382,14 @@ static void do_config(int fd, unsigned i + } + switch (p[1]) { + case USB_DT_DEVICE: ++ /* NOTE: should NOT be found here! */ + dump_device(fd, p, lang); + curclass = p[4]; + cursubclass = p[5]; + break; + + case USB_DT_CONFIG: +- dump_config(fd, p); ++ dump_config(fd, p, lang); + break; + + case USB_DT_INTERFACE: +@@ -1229,39 +1404,39 @@ static void do_config(int fd, unsigned i + break; + + case USB_DT_CS_DEVICE: +- if (curclass == 3) { ++ if (curclass == USB_CLASS_HID) { + dump_hid_device(fd, p, curinterface); + break; + } +- printf(" unknown descriptor type:"); +- dump_junk2(p, p[0]); +- break; +- +- case USB_DT_CS_CONFIG: +- printf(" unknown descriptor type:"); +- dump_junk2(p, p[0]); +- break; +- +- case USB_DT_CS_STRING: +- printf(" unknown descriptor type:"); +- dump_junk2(p, p[0]); +- break; ++ err = "unknown device class descriptor"; ++ goto junk; + + case USB_DT_CS_INTERFACE: +- if (curclass == 1 && cursubclass == 1) { +- dump_audiocontrol_interface(fd, p, lang); ++ err = "unknown interface class descriptor"; ++ switch (curclass) { ++ case USB_CLASS_AUDIO: ++ switch (cursubclass) { ++ case 1: ++ dump_audiocontrol_interface(fd, p, lang); ++ break; ++ case 2: ++ dump_audiostreaming_interface(fd, p); ++ break; ++ case 3: ++ dump_midistreaming_interface(fd, p, lang); ++ break; ++ default: ++ goto junk; ++ } + break; +- } +- if (curclass == 1 && cursubclass == 2) { +- dump_audiostreaming_interface(fd, p); +- break; +- } +- if (curclass == 1 && cursubclass == 3) { +- dump_midistreaming_interface(fd, p, lang); ++ case USB_CLASS_COMM: ++ err = dump_comm_descriptor (fd, p, " ", lang); ++ if (err) ++ goto junk; + break; ++ default: ++ goto junk; + } +- printf(" unknown descriptor type:"); +- dump_junk2(p, p[0]); + break; + + case USB_DT_CS_ENDPOINT: +@@ -1273,16 +1448,20 @@ static void do_config(int fd, unsigned i + dump_midistreaming_endpoint(fd, p); + break; + } +- printf(" unknown descriptor type:"); +- dump_junk2(p, p[0]); +- break; ++ err = "unknown endpoint class descriptor"; ++ goto junk; + + case USB_DT_HUB: +- dump_hub(p); ++ /* NOTE only rather ancient hubs will include ++ * this with the config descriptor. ++ */ ++ dump_hub(" ", p, 0); + break; + + default: +- printf(" unknown descriptor type:"); ++ err = "unknown descriptor type"; ++junk: ++ printf(" %s:", err); + dump_junk2(p, p[0]); + } + sz -= p[0]; +@@ -1303,21 +1482,41 @@ static u_int16_t dump_langids(int fd, in + int i, l; + u_int16_t lang; + +- b[0] = b[1] = 0xbf; +- l = usb_control_msg(fd, USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_STRING << 8, 0, sizeof(b), b); ++ /* read string length first, like recent linuxes -- else some devices misbehave */ ++ b[0] = b[1] = 0; ++ l = usb_control_msg(fd, USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_STRING << 8, 0, 4, b); + ++ if (l < 0 && errno == EPIPE) ++ l = 0; + if (l < 0) { +- if (open_mode == O_RDWR) ++ if (open_mode == O_RDWR && !quiet) + printf(" Language IDs: none (cannot get min. string descriptor; got len=%d, error=%d:%s)\n", + l, errno, strerror(errno)); + return 0; + } +- if (l < 4 || b[0] != l) { ++ if (l == 0) { ++ if (!quiet) ++ printf(" Language IDs: none\n"); ++ return 0; ++ } ++ if (l < 4) { ++ if (!quiet) + printf(" Language IDs: none (invalid length string descriptor %02x; len=%d)\n", b[0], l); + return 0; + } + /* save first language ID for further get_string_descriptors */ + lang = b[2] | (b[3] << 8); ++ ++ /* maybe there's more than one */ ++ if (b[0] > 4) { ++ l = usb_control_msg(fd, USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_STRING << 8, 0, b[0], b); ++ if (l < 4 || b[0] != l) { ++ fprintf(stderr, "string 0 broken re-read, l = %d, b[0] = %d \n", l, b[0]); ++ b[0] = 4; ++ b[2] = lang; ++ b[3] = lang >> 8; ++ } ++ } + #if 0 + printf ("dump_langids: ret=%d:%d, lang=0x%x, length=%d\n", l, errno, lang, b[0]); + dump_junk2 (b, 32); +@@ -1342,11 +1541,17 @@ static void dumpdev(unsigned char *devde + maxcfg = devdesc[17]; + if (devdesc[0] < 18 || devdesc[1] != USB_DT_DEVICE) + maxcfg = 1; ++ dev_has_strings = 0; + lang = dump_langids(fd, 1); + dump_device(fd, devdesc, lang); + for (i = 0; i < maxcfg; i++) + do_config(fd, i, lang); +- lang = dump_langids(fd, 0); ++ if (devdesc[4] == USB_CLASS_HUB) ++ do_hub(fd, devdesc [6]); ++ /* FIXME if it's usb 2.0 and there's a device qualifier, ++ * optionally dump it and the other-speed config data ++ */ ++ lang = dump_langids(fd, !dev_has_strings); + } + + /* ---------------------------------------------------------------------- */ +@@ -1560,7 +1765,7 @@ int main(int argc, char *argv[]) + exit(1); + } + if ((err = names_init("./usb.ids")) != 0) +- if(err = names_init(USBIDS_FILE)) { ++ if((err = names_init(USBIDS_FILE)) != 0) { + printf("Error, cannot open USBIDS File \"%s\", %s\n", USBIDS_FILE, strerror(err)); + exit(1); + } diff --git a/usbutils.spec b/usbutils.spec index 32409c3..008734a 100644 --- a/usbutils.spec +++ b/usbutils.spec @@ -1,9 +1,9 @@ Name: usbutils Version: 0.11 -Release: 3.1 +Release: 4 Source: http://usb.cs.tum.edu/download/%{name}-%{version}.tar.gz Patch: usbutils-0.9-hwdata.patch -Patch2: usbutils-0.11-78462.patch +Patch2: usbutils-0214.patch License: GPL BuildRoot: %{_tmppath}/%{name}-%{version}-root Requires: hwdata @@ -47,6 +47,9 @@ rm -f $RPM_BUILD_ROOT%{_datadir}/usb.ids rm -rf $RPM_BUILD_ROOT %changelog +* Tue May 4 2004 Bill Nottingham 0.11-4 +- add patch from USB maintainer to fix various brokenness (#115694, ) + * Fri Feb 13 2004 Elliot Lee - rebuilt