--- ./qemu/usb-linux.c 2008-10-12 12:50:11.000000000 +0100 +++ usb-linux.c 2008-10-16 13:40:53.000000000 +0100 @@ -72,9 +72,9 @@ #define dprintf printf #else #define dprintf(...) -#endif +#endif return (USBDevice *)dev; -#define USBDEVFS_PATH "/proc/bus/usb" +#define USBDEVFS_PATH "/dev/bus/usb" #define PRODUCT_NAME_SZ 32 #define MAX_ENDPOINTS 16 @@ -1018,102 +1018,99 @@ return -1; } -static int get_tag_value(char *buf, int buf_size, - const char *str, const char *tag, - const char *stopchars) -{ - const char *p; - char *q; - p = strstr(str, tag); - if (!p) - return -1; - p += strlen(tag); - while (isspace(*p)) - p++; - q = buf; - while (*p != '\0' && !strchr(stopchars, *p)) { - if ((q - buf) < (buf_size - 1)) - *q++ = *p; - p++; - } - *q = '\0'; - return q - buf; -} - static int usb_host_scan(void *opaque, USBScanFunc *func) { FILE *f; char line[1024]; - char buf[1024]; - int bus_num, addr, speed, device_count, class_id, product_id, vendor_id; + int bus_num, addr, speed, class_id, product_id, vendor_id; int ret; char product_name[512]; + DIR* d; + struct dirent* de; + + d = opendir("/sys/bus/usb/devices"); + if (!d) { + term_printf("Could not open /sys/bus/usb/devices\n"); - f = fopen(USBDEVFS_PATH "/devices", "r"); - if (!f) { - term_printf("husb: could not open %s\n", USBDEVFS_PATH "/devices"); return 0; } - device_count = 0; - bus_num = addr = speed = class_id = product_id = vendor_id = 0; - ret = 0; - for(;;) { - if (fgets(line, sizeof(line), f) == NULL) - break; - if (strlen(line) > 0) - line[strlen(line) - 1] = '\0'; - if (line[0] == 'T' && line[1] == ':') { - if (device_count && (vendor_id || product_id)) { - /* New device. Add the previously discovered device. */ - ret = func(opaque, bus_num, addr, class_id, vendor_id, - product_id, product_name, speed); - if (ret) - goto the_end; - } - if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0) - goto fail; - bus_num = atoi(buf); - if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0) - goto fail; - addr = atoi(buf); - if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0) - goto fail; - if (!strcmp(buf, "480")) + while ((de = readdir(d))) { + if (de->d_name[0] != '.' && ! strchr(de->d_name, ':')) { + char filename[PATH_MAX]; + char* tmpstr = de->d_name; + if (!strncmp(de->d_name, "usb", 3)) + tmpstr += 3; + bus_num = atoi(tmpstr); + snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/devnum", de->d_name); + f = fopen(filename, "r"); + if (!f) { + term_printf("Could not open %s\n", filename); + return 0; + } + fgets(line, sizeof(line), f); + fclose(f); + addr = atoi(line); + snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/bDeviceClass", de->d_name); + f = fopen(filename, "r"); + if (!f) { + term_printf("Could not open %s\n", filename); + return 0; + } + fgets(line, sizeof(line), f); + fclose(f); + class_id = strtoul(line, NULL, 16); + snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/idVendor", de->d_name); + f = fopen(filename, "r"); + if (!f) { + term_printf("Could not open %s\n", filename); + return 0; + } + fgets(line, sizeof(line), f); + fclose(f); + vendor_id = strtoul(line, NULL, 16); + snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/idProduct", de->d_name); + f = fopen(filename, "r"); + if (!f) { + term_printf("Could not open %s\n", filename); + return 0; + } + fgets(line, sizeof(line), f); + fclose(f); + product_id = strtoul(line, NULL, 16); + snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/product", de->d_name); + f = fopen(filename, "r"); + if (f) { + fgets(line, sizeof(line), f); + fclose(f); + if (strlen(line) > 0) + line[strlen(line) - 1] = '\0'; + pstrcpy(product_name, sizeof(product_name), line); + } else + *product_name = 0; + snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/speed", de->d_name); + f = fopen(filename, "r"); + if (!f) { + term_printf("Could not open %s\n", filename); + return 0; + } + fgets(line, sizeof(line), f); + fclose(f); + if (!strcmp(line, "480\n")) speed = USB_SPEED_HIGH; - else if (!strcmp(buf, "1.5")) + else if (!strcmp(line, "1.5\n")) speed = USB_SPEED_LOW; else speed = USB_SPEED_FULL; - product_name[0] = '\0'; - class_id = 0xff; - device_count++; - product_id = 0; - vendor_id = 0; - } else if (line[0] == 'P' && line[1] == ':') { - if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0) - goto fail; - vendor_id = strtoul(buf, NULL, 16); - if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0) - goto fail; - product_id = strtoul(buf, NULL, 16); - } else if (line[0] == 'S' && line[1] == ':') { - if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0) - goto fail; - pstrcpy(product_name, sizeof(product_name), buf); - } else if (line[0] == 'D' && line[1] == ':') { - if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0) - goto fail; - class_id = strtoul(buf, NULL, 16); - } - fail: ; - } - if (device_count && (vendor_id || product_id)) { - /* Add the last device. */ - ret = func(opaque, bus_num, addr, class_id, vendor_id, - product_id, product_name, speed); - } + + ret = func(opaque, bus_num, addr, class_id, vendor_id, + product_id, product_name, speed); + if (ret) + goto the_end; + } + } + the_end: - fclose(f); + closedir(d); return ret; }