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);

Reply via email to