--- a/qemu/configure 2006-04-22 21:58:54.000000000 -0500 +++ b/qemu/configure 2006-04-22 22:00:43.000000000 -0500 @@ -105,7 +105,7 @@ ;; MINGW32*) mingw32="yes" -usb="linux" +usb="generic" ;; FreeBSD) bsd="yes" @@ -130,7 +130,7 @@ oss="yes" linux="yes" user="yes" -usb="generic" +usb="linux" if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then kqemu="yes" fi --- a/qemu/usb-linux.c 2006-04-22 21:58:54.000000000 -0500 +++ b/qemu/usb-linux.c 2006-04-22 22:02:10.000000000 -0500 @@ -42,11 +42,14 @@ void *data; }; -typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id, +typedef int USBScanFunc(void *opaque, int bus_num, int addr, int vendor_id, int product_id, - const char *product_name, int speed); + const char *spec_version, + const char *manf_string, + const char *prod_string); static int usb_host_find_device(int *pbus_num, int *paddr, const char *devname); +int usb_host_handle_close(USBDevice *opaque); //#define DEBUG @@ -63,32 +66,19 @@ "error code: %i\n", ret ); # endif switch(ret) { - case -ETIMEDOUT: + case ETIMEDOUT: # ifdef DEBUG printf( "USB_ERROR: ETIMEDOUT\n" ); #endif return USB_RET_NAK; break; - case -EIO: -# ifdef DEBUG - printf( "USB_ERROR: EIO\n" ); -#endif - /* stall condition on win32 */ - /* XXX: clear stall */ - return USB_RET_STALL; - break; - case -EBUSY: - /* stall on linux */ - /* XXX: clear stall */ - return USB_RET_STALL; - break; - case -EPIPE: + case EPIPE: default: return USB_RET_STALL; } } -static void usb_host_handle_reset(USBDevice *dev) +static int usb_host_handle_reset(USBDevice *dev) { #if 0 USBHostDevice *s = (USBHostDevice *)dev; @@ -96,6 +86,7 @@ done by the host OS */ ioctl(s->fd, USBDEVFS_RESET); #endif + return USB_RET_ACK; } static int usb_host_handle_control(USBDevice *dev, @@ -118,7 +109,7 @@ ct.data = data; ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct); if (ret < 0) { - usb_host_handle_error( ret ); + return usb_host_handle_error( errno ); } else { return ret; } @@ -142,14 +133,14 @@ bt.data = data; ret = ioctl(s->fd, USBDEVFS_BULK, &bt); if (ret < 0) { - usb_host_handle_error( ret ); + return usb_host_handle_error( errno ); } else { return ret; } } /* XXX: exclude high speed devices or implement EHCI */ -USBDevice *usb_host_device_open(const char *devname) +USBDevice *usb_host_init(const char *devname) { int fd, interface, ret, i; USBHostDevice *hostdev; @@ -162,7 +153,7 @@ if (usb_host_find_device(&bus_num, &addr, devname) < 0) return NULL; - + snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d", bus_num, addr); fd = open(buf, O_RDWR); @@ -272,12 +263,16 @@ return q - buf; } -void usb_host_device_close(USBDevice *opaque) +int usb_host_handle_close(USBDevice *opaque) { USBHostDevice *s = (USBHostDevice *)opaque; - if (s->fd >= 0) + if (s->fd >= 0) { close(s->fd); + return 1; + } + + return -1; } static int usb_host_scan(void *opaque, USBScanFunc *func) @@ -285,9 +280,11 @@ 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, device_count, product_id, vendor_id; int ret; - char product_name[512]; + char manf_name[512]; + char prod_name[512]; + char spec_version[6]; f = fopen(USBDEVFS_PATH "/devices", "r"); if (!f) { @@ -295,7 +292,7 @@ return 0; } device_count = 0; - bus_num = addr = speed = class_id = product_id = vendor_id = 0; + bus_num = addr = product_id = vendor_id = 0; ret = 0; for(;;) { if (fgets(line, sizeof(line), f) == NULL) @@ -305,8 +302,8 @@ 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); + ret = func(opaque, bus_num, addr, vendor_id, product_id, + spec_version, manf_name, prod_name); if (ret) goto the_end; } @@ -316,19 +313,17 @@ 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")) - speed = USB_SPEED_HIGH; - else if (!strcmp(buf, "1.5")) - speed = USB_SPEED_LOW; - else - speed = USB_SPEED_FULL; - product_name[0] = '\0'; - class_id = 0xff; + strcpy(spec_version, "01.10"); + strcpy(manf_name, "unknown"); + strcpy(prod_name, "unknown"); device_count++; product_id = 0; vendor_id = 0; + } else if (line[0] == 'D' && line[1] == ':') { + if (get_tag_value(&buf[1], sizeof(buf) - 1, line, "Ver=", " ") < 0) + goto fail; + buf[0] = '0'; + pstrcpy(spec_version, sizeof(spec_version), buf); } else if (line[0] == 'P' && line[1] == ':') { if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0) goto fail; @@ -337,20 +332,22 @@ 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); + if (get_tag_value(buf, sizeof(buf), line, "Manufacturer=", "") < 0) { + if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0) { + goto fail; + } else { + pstrcpy(prod_name, sizeof(prod_name), buf); + } + } else { + pstrcpy(manf_name, sizeof(manf_name), buf); + } } 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, vendor_id, product_id, spec_version, + manf_name, prod_name); } the_end: fclose(f); @@ -364,10 +361,11 @@ int addr; } FindDeviceState; -static int usb_host_find_device_scan(void *opaque, int bus_num, int addr, - int class_id, - int vendor_id, int product_id, - const char *product_name, int speed) +static int usb_host_find_device_scan(void *opaque, int bus_num, int addr, + int vendor_id, int product_id, + const char *spec_version, + const char *manf_string, + const char *prod_string) { FindDeviceState *s = opaque; if (vendor_id == s->vendor_id && @@ -386,108 +384,38 @@ static int usb_host_find_device(int *pbus_num, int *paddr, const char *devname) { - const char *p; - int ret; FindDeviceState fs; - p = strchr(devname, '.'); - if (p) { - *pbus_num = strtoul(devname, NULL, 0); - *paddr = strtoul(p + 1, NULL, 0); - return 0; - } - p = strchr(devname, ':'); - if (p) { - fs.vendor_id = strtoul(devname, NULL, 16); - fs.product_id = strtoul(p + 1, NULL, 16); - ret = usb_host_scan(&fs, usb_host_find_device_scan); - if (ret) { - *pbus_num = fs.bus_num; - *paddr = fs.addr; - return 0; + if (sscanf(devname, "host:%03d:%03d", pbus_num, paddr) != 2) { + if (sscanf(devname, "host:%04xx%04x", &fs.vendor_id, &fs.product_id) == 2) { + if (usb_host_scan(&fs, usb_host_find_device_scan)) { + *pbus_num = fs.bus_num; + *paddr = fs.addr; + return 0; + } else { + return -1; + } + } else { + return -1; } + } else { + return 0; } - return -1; } /**********************/ /* USB host device info */ -struct usb_class_info { - int class; - const char *class_name; -}; - -static const struct usb_class_info usb_class_info[] = { - { USB_CLASS_AUDIO, "Audio"}, - { USB_CLASS_COMM, "Communication"}, - { USB_CLASS_HID, "HID"}, - { USB_CLASS_HUB, "Hub" }, - { USB_CLASS_PHYSICAL, "Physical" }, - { USB_CLASS_PRINTER, "Printer" }, - { USB_CLASS_MASS_STORAGE, "Storage" }, - { USB_CLASS_CDC_DATA, "Data" }, - { USB_CLASS_APP_SPEC, "Application Specific" }, - { USB_CLASS_VENDOR_SPEC, "Vendor Specific" }, - { USB_CLASS_STILL_IMAGE, "Still Image" }, - { USB_CLASS_CSCID, "Smart Card" }, - { USB_CLASS_CONTENT_SEC, "Content Security" }, - { -1, NULL } -}; - -static const char *usb_class_str(uint8_t class) -{ - const struct usb_class_info *p; - for(p = usb_class_info; p->class != -1; p++) { - if (p->class == class) - break; - } - return p->class_name; -} - -void usb_info_device(int bus_num, int addr, int class_id, - int vendor_id, int product_id, - const char *product_name, - int speed) -{ - const char *class_str, *speed_str; - - switch(speed) { - case USB_SPEED_LOW: - speed_str = "1.5"; - break; - case USB_SPEED_FULL: - speed_str = "12"; - break; - case USB_SPEED_HIGH: - speed_str = "480"; - break; - default: - speed_str = "?"; - break; - } - - term_printf(" Device %d.%d, speed %s Mb/s\n", - bus_num, addr, speed_str); - class_str = usb_class_str(class_id); - if (class_str) - term_printf(" %s:", class_str); - else - term_printf(" Class %02x:", class_id); - term_printf(" USB device %04x:%04x", vendor_id, product_id); - if (product_name[0] != '\0') - term_printf(", %s", product_name); - term_printf("\n"); -} - static int usb_host_info_device(void *opaque, int bus_num, int addr, - int class_id, - int vendor_id, int product_id, - const char *product_name, - int speed) -{ - usb_info_device(bus_num, addr, class_id, vendor_id, product_id, - product_name, speed); + int vendor_id, int product_id, + const char *spec_ver, + const char *manf_string, + const char *prod_string) +{ + term_printf(" Device host:%03d:%03d, Manufacturer %s, Product %s\n", + bus_num, addr, manf_string, prod_string ); + term_printf(" VendorID:ProductID %04xx%04x, USB-Standard: %s\n", + vendor_id, product_id, spec_ver ); return 0; } --- a/qemu/usb-libusb.c 2006-04-22 21:59:14.000000000 -0500 +++ b/qemu/usb-libusb.c 2006-04-22 22:03:02.000000000 -0500 @@ -368,12 +368,7 @@ /**********************/ /* USB host device info */ -struct usb_class_info { - int class; - const char *class_name; -}; - void usb_host_info_device( struct usb_bus *bus, struct usb_device *dev, struct usb_dev_handle *handle ) { char str1[256], str2[256]; --- a/qemu/hw/usb-hub.c 2006-04-22 21:59:14.000000000 -0500 +++ b/qemu/hw/usb-hub.c 2006-04-22 13:51:23.000000000 -0500 @@ -177,7 +177,7 @@ int i; if (dev) { - if (portnum >= MAX_PORTS || portnum < 0) { + if (portnum >= s->nb_ports || portnum < 0) { #ifdef DEBUG printf( "This usb hub port does not exist.\n" ); #endif @@ -188,7 +188,7 @@ printf( "Hub Port %i is allready occupied! \n", portnum ); #endif portnum= -1; - for (i= 0; i < MAX_PORTS; i++) { + for (i= 0; i < s->nb_ports; i++) { if (s->ports[i].dev == NULL) { #ifdef DEBUG printf( "Will use Hub Port %i instead! \n", i );