diff -u usbutils-0.73/devtree.c usbutils-0.73/devtree.c --- usbutils-0.73/devtree.c +++ usbutils-0.73/devtree.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include "devtree.h" @@ -117,118 +119,109 @@ /* ---------------------------------------------------------------------- */ -void devtree_parsedevfile(int fd) +int findtree(char *path, int level, int parentdevnum) +{ + int busnum, maxchild, productid, vendorid, devnum; + int fp, i; + char buffer[1024]; + char buf[100]; + char *cp; + + /* Read bus number */ + snprintf(buffer, sizeof(buffer), "%s/busnum", path); + + if ((fp = open(buffer, O_RDONLY)) == -1) + return(0); + read(fp, buf, sizeof(buf) - 1); + busnum = strtoul(buf, NULL, 0); + close(fp); + + /* Read max number of children. If >0 then it is a hub, so need to go + * through it again. + */ + snprintf(buffer, sizeof(buffer), "%s/maxchild", path); + if ((fp = open(buffer, O_RDONLY)) == -1) + return(0); + read(fp, buf, 4); + maxchild = strtoul(buf, NULL, 0); + close(fp); + + /* Read device number */ + snprintf(buffer, sizeof(buffer), "%s/devnum", path); + if ((fp = open(buffer, O_RDONLY)) == -1) + return(0); + read(fp, buf, 4); + devnum = strtoul(buf, NULL, 0); + close(fp); + + /* Read product id of device */ + snprintf(buffer, sizeof(buffer), "%s/idProduct", path); + if ((fp = open(buffer, O_RDONLY)) == -1) + return(0); + read(fp, buf, 8); + productid = strtoul(buf, NULL, 16); + close(fp); + + /* Read vendor id of device */ + snprintf(buffer, sizeof(buffer), "%s/idVendor", path); + if ((fp = open(buffer, O_RDONLY)) == -1) + return(0); + read(fp, buf, 8); + vendorid = strtoul(buf, NULL, 16); + close(fp); + + /* Add data to usb list */ + updateusblist(devnum, busnum, parentdevnum, level, vendorid, productid); + + /* Traverse through the connected devices */ + for (i = 1; i < maxchild; i++) { + if (level >= 1) { + cp = strrchr(path, '/'); + snprintf(buffer, sizeof(buffer), "%s/%s.%i", path, cp, i); + } else + snprintf(buffer, sizeof(buffer), "%s/%i-%i", path, busnum, i); + findtree(buffer, level + 1, devnum); + } + return(1); +} + +/*------------------------------------------------------------------*/ + +void updateusblist(unsigned int devnum, unsigned int busnum, unsigned int parentdevnum, unsigned int level, unsigned int vendor, unsigned int prodid) { - char buf[16384]; - char *start, *end, *lineend, *cp; - int ret; - unsigned int devnum = 0, busnum = 0, parentdevnum = 0, level = 0; - unsigned int class = 0xff, vendor = 0xffff, prodid = 0xffff, speed = 0; struct usbbusnode *bus; struct usbdevnode *dev, *dev2; devtree_markdeleted(); - if (lseek(fd, 0, SEEK_SET) == (off_t)-1) - lprintf(0, "lseek: %s (%d)\n", strerror(errno), errno); - ret = read(fd, buf, sizeof(buf)-1); - if (ret == -1) - lprintf(0, "read: %s (%d)\n", strerror(errno), errno); - end = buf + ret; - *end = 0; - start = buf; - while (start < end) { - lineend = strchr(start, '\n'); - if (!lineend) - break; - *lineend = 0; - switch (start[0]) { - case 'T': /* topology line */ - if ((cp = strstr(start, "Dev#="))) { - devnum = strtoul(cp + 5, NULL, 0); - } else - devnum = 0; - if ((cp = strstr(start, "Bus="))) { - busnum = strtoul(cp + 4, NULL, 10); - } else - busnum = 0; - if ((cp = strstr(start, "Prnt="))) { - parentdevnum = strtoul(cp + 5, NULL, 10); - } else - parentdevnum = 0; - if ((cp = strstr(start, "Lev="))) { - level = strtoul(cp + 4, NULL, 10); - } else - level = 0; - if (strstr(start, "Spd=1.5")) - speed = 1; - else if (strstr(start, "Spd=12")) - speed = 2; - else - speed = 0; - break; - - case 'D': - if ((cp = strstr(start, "Cls="))) { - class = strtoul(cp + 4, NULL, 16); - } else - class = 0xff; - break; - - case 'P': - if ((cp = strstr(start, "Vendor="))) { - vendor = strtoul(cp + 7, NULL, 16); - } else - vendor = 0xffff; - if ((cp = strstr(start, "ProdID="))) { - prodid = strtoul(cp + 7, NULL, 16); - } else - prodid = 0xffff; - /* print device */ -#if 0 - printf("Device %3d Vendor %04x Product ID %04x Class %02x Speed %s\n", - devnum, vendor, prodid, class, speed == 2 ? "12 MBPS" : speed == 1 ? "1.5 MBPS" : "unknown"); -#endif - if (!(bus = devtree_findbus(busnum))) { - if (!(bus = malloc(sizeof(struct usbbusnode)))) - lprintf(0, "Out of memory\n"); - bus->busnum = busnum; - bus->flags = USBFLG_NEW; - INIT_LIST_HEAD(&bus->childlist); - list_add_tail(&bus->list, &usbbuslist); - } else { - bus->flags &= ~USBFLG_DELETED; - } - if (!(dev = devtree_finddevice(bus, devnum)) || dev->vendorid != vendor || dev->productid != prodid) { - if (!(dev = malloc(sizeof(struct usbdevnode)))) - lprintf(0, "Out of memory\n"); - dev->devnum = devnum; - dev->flags = USBFLG_NEW; - dev->bus = bus; - dev->vendorid = vendor; - dev->productid = prodid; - INIT_LIST_HEAD(&dev->childlist); - if (level == 0 && parentdevnum == 0) { - list_add_tail(&dev->list, &bus->childlist); - dev->parent = NULL; - } else { - if (!(dev2 = devtree_finddevice(bus, parentdevnum))) - lprintf(0, "Bus %d Device %d Parent Device %d not found\n", busnum, devnum, parentdevnum); - dev->parent = dev2; - list_add_tail(&dev->list, &dev2->childlist); - } - } else { - dev->flags &= ~USBFLG_DELETED; - } - break; - - default: - break; + if (!(bus = devtree_findbus(busnum))) { + if (!(bus = malloc(sizeof(struct usbbusnode)))) + lprintf(0, "Out of memory\n"); + bus->busnum = busnum; + bus->flags = USBFLG_NEW; + INIT_LIST_HEAD(&bus->childlist); + list_add_tail(&bus->list, &usbbuslist); + } else + bus->flags &= ~USBFLG_DELETED; + if (!(dev = devtree_finddevice(bus, devnum)) || dev->vendorid != vendor || dev->productid != prodid) { + if (!(dev = malloc(sizeof(struct usbdevnode)))) + lprintf(0, "Out of memory\n"); + dev->devnum = devnum; + dev->flags = USBFLG_NEW; + dev->bus = bus; + dev->vendorid = vendor; + dev->productid = prodid; + INIT_LIST_HEAD(&dev->childlist); + if (level == 0 && parentdevnum == 0) { + list_add_tail(&dev->list, &bus->childlist); + dev->parent = NULL; + } else { + if (!(dev2 = devtree_finddevice(bus, parentdevnum))) + lprintf(0, "Bus %d Device %d Parent Device %d not found\n", busnum, devnum, parentdevnum); + dev->parent = dev2; + list_add_tail(&dev->list, &dev2->childlist); } -#if 0 - printf("line: %s\n", start); -#endif - start = lineend + 1; - } + } else + dev->flags &= ~USBFLG_DELETED; } /* ---------------------------------------------------------------------- */ diff -u usbutils-0.73/lsusb.c usbutils-0.73/lsusb.c --- usbutils-0.73/lsusb.c +++ usbutils-0.73/lsusb.c @@ -53,6 +53,7 @@ #include "names.h" #include "devtree.h" #include "usbmisc.h" +#include #define _GNU_SOURCE #include @@ -80,7 +81,7 @@ #define HUB_STATUS_BYTELEN 3 /* max 3 bytes status = hub + 23 ports */ -static const char *procbususb = "/proc/bus/usb"; +static const char *sysbususb = "/sys/bus/usb"; static unsigned int verblevel = VERBLEVEL_DEFAULT; static int do_report_desc = 1; @@ -97,6 +98,7 @@ static void dump_midistreaming_endpoint(unsigned char *buf); static void dump_hub(char *prefix, unsigned char *p, int has_tt); static void dump_ccid_device(unsigned char *buf); +static int file_select(struct dirent *entry); /* ---------------------------------------------------------------------- */ @@ -2765,20 +2767,31 @@ static int treedump(void) { - int fd; - char buf[512]; + int count, i; + struct dirent **files; + char path[1024]; + char buffer[1024]; - snprintf(buf, sizeof(buf), "%s/devices", procbususb); - if ((fd = open(buf, O_RDONLY)) == -1) { - fprintf(stderr, "cannot open %s, %s (%d)\n", buf, strerror(errno), errno); - return(1); + snprintf(path, sizeof(path), "%s/devices", sysbususb); + count = scandir(path, &files, &file_select, NULL); + for (i = 1; i < count + 1; i++) + { + /* Call the function to read the main hub data */ + snprintf(buffer, sizeof(buffer), "%s/usb%i", path, i); + findtree(buffer, 0, 0); } - devtree_parsedevfile(fd); - close(fd); devtree_dump(); return(0); } +static int file_select(struct dirent *entry) +{ + if (strncmp(entry->d_name, "usb", 3) == 0) + return (1); + else + return (0); +} + /* ---------------------------------------------------------------------- */ int main(int argc, char *argv[]) diff -u usbutils-0.73/debian/changelog usbutils-0.73/debian/changelog --- usbutils-0.73/debian/changelog +++ usbutils-0.73/debian/changelog @@ -1,3 +1,12 @@ +usbutils (0.73-8ubuntu2) intrepid; urgency=low + + * Apply patch from Ahmed Elhasairi , somewhat + modified by me, to fix 'lsusb -t' (LP: #159189): + - Remove dependency on usbfs. + - Add support for sysfs. + + -- Colin Watson Tue, 02 Sep 2008 18:20:06 +0100 + usbutils (0.73-8ubuntu1) intrepid; urgency=low * Merge from debian unstable, remaining changes: only in patch2: unchanged: --- usbutils-0.73.orig/devtree.h +++ usbutils-0.73/devtree.h @@ -73,7 +73,7 @@ extern void devtree_markdeleted(void); extern struct usbbusnode *devtree_findbus(unsigned int busn); extern struct usbdevnode *devtree_finddevice(struct usbbusnode *bus, unsigned int devn); -extern void devtree_parsedevfile(int fd); +extern void updateusblist(unsigned int devnum, unsigned int busnum, unsigned int parentdevnum, unsigned int level, unsigned int vendor, unsigned int prodid); extern void devtree_busconnect(struct usbbusnode *bus); extern void devtree_busdisconnect(struct usbbusnode *bus); extern void devtree_devconnect(struct usbdevnode *dev); @@ -81,6 +81,8 @@ extern void devtree_processchanges(void); extern void devtree_dump(void); +extern int findtree(char *path, int level, int parentdevnum); + extern int lprintf(unsigned int vl, const char *format, ...) __attribute__ ((format (printf, 2, 3))); /* ---------------------------------------------------------------------- */