Hello Currently qemu doesn't allow to use a usb device with multiple interfaces. Since I need multiple interface ( I'm trying to reverse engineering an HP printer/scanner device ), and the previous "multiple interface" patch is not available anymore, I've written one. It's a really dumb patch, all it does is removing the check for multiple interface and simply grabbing every interface on the device.
I really don't know if it's correct but winXP see the both interface and the HP driver see the device. I can print with it from qemu ( the printer interface is N°1, the scanner is N°0 ) so it seems to work. Saddly I cannot scan, windows reboot ( BSOD ) after a few USB transfer ( maybe because windows see the device as attached on a 12Mbit/s port but the _real_ device is on 480Mbit/s so the packet are comming too fast ? ). Hope it will help someone else. Regards, Couriousous
Index: qemu-0.9.0/usb-linux.c =================================================================== --- qemu-0.9.0/usb-linux.c +++ qemu-0.9.0/usb-linux.c 2007-04-28 22:02:15.000000000 +0200 @@ -186,18 +186,13 @@ if (i + config_descr_len > descr_len) goto fail; nb_interfaces = descr[i + 4]; - if (nb_interfaces != 1) { - /* NOTE: currently we grab only one interface */ - fprintf(stderr, "usb_host: only one interface supported\n"); - goto fail; - } #ifdef USBDEVFS_DISCONNECT /* earlier Linux 2.4 do not support that */ - { + for(i = 0; i < nb_interfaces; i++) { struct usbdevfs_ioctl ctrl; ctrl.ioctl_code = USBDEVFS_DISCONNECT; - ctrl.ifno = 0; + ctrl.ifno = i; ret = ioctl(fd, USBDEVFS_IOCTL, &ctrl); if (ret < 0 && errno != ENODATA) { perror("USBDEVFS_DISCONNECT"); @@ -206,18 +201,19 @@ } #endif - /* XXX: only grab if all interfaces are free */ - interface = 0; - ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface); - if (ret < 0) { - if (errno == EBUSY) { - fprintf(stderr, "usb_host: device already grabbed\n"); - } else { - perror("USBDEVFS_CLAIMINTERFACE"); - } - fail: - close(fd); - return NULL; + /* XXX: Grab every interfaces */ + for(interface = 0; interface < nb_interfaces; interface++) { + ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface); + if (ret < 0) { + if (errno == EBUSY) { + fprintf(stderr, "usb_host: device already grabbed\n"); + } else { + perror("USBDEVFS_CLAIMINTERFACE"); + } +fail: + close(fd); + return NULL; + } } ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);