qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Lonnie Mendez <lmendez19@austin.rr.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] Large USB patch
Date: Sat, 22 Apr 2006 22:38:31 -0500	[thread overview]
Message-ID: <444AF6B7.1030606@austin.rr.com> (raw)
In-Reply-To: <444A5B65.8010104@gmx.de>

[-- Attachment #1: Type: text/plain, Size: 2442 bytes --]

nix.wie.weg@gmx.de wrote:

>Lonnie Mendez wrote:
>  
>
>>nix.wie.weg@gmx.de wrote:
>>
>>Sorry about that.  I was used to the previous syntax:
>>usb_add host:04b6:0005
>>
>>  My guess is that the new syntax is to distinguish it from the
>>busaddr:addr syntax?  It would seem checking for length would
>>differentiate the two in that case.
>>    
>>
>Yes maybe, but not a real good solution, especially if you know that
>with the solution we have now, you can omit leading zeros.
>  
>
   Aye.

>
>I have attached a small patch, with which you can really add a device to
>a hub, if this is then working is another question, but it should only
>depend on the implementation of usb-hub.c
>  
>
   That works but not in the literal means of the attached device 
actually functioning (see below).  Here is something interesting:

(qemu) usb_add mouse
     Controller 001: uhci
          001:001 = mouse
     Summary: 1 USB Controller, 1 USB Devices
(qemu) usb_add tablet,addto 001:001:001
(qemu) info usb
     Controller 001: uhci
          001:001 = mouse
               001:001:001 = tablet
     Summary: 1 USB Controller, 2 USB Devices
(qemu)

  The device attached on the hub doesn't seem to be receiving 
transactions (like before with the emulated devices):

frame 1227: pid=SETUP addr=0x00 ep=0 len=8
     data_out= 80 06 00 01 00 00 40 00
uhci readw port=0x0002 val=0x0001
uhci writew port=0x0002 val=0x0001
uhci readw port=0x0006 val=0x04cc
frame 1228: pid=SETUP addr=0x00 ep=0 len=8
     data_out= 80 06 00 01 00 00 40 00
frame 1229: pid=SETUP addr=0x00 ep=0 len=8
     data_out= 80 06 00 01 00 00 40 00
uhci readw port=0x0002 val=0x0002
uhci writew port=0x0002 val=0x0002

   There are some problems with the port status request traffic from the 
hub as well:

frame 1174: pid=SETUP addr=0x03 ep=0 len=8
     data_out= 23 03 04 00 01 00 00 00
error usb_generic_handle_packet: unknown USB-Token - 258
     ret=0

   The interface is also giving incorrect errors at certain times:

(qemu) usb_add usbhub
usb_add: extraneous characters at the end of line
(qemu)


   Attached is a patch to get the linux redirector working with the 
changes.  It has a few other modifications as well but nothing radical.  
The default redirector for linux host was changed to the linux 
redirector as well (just a heads up).  I'm still using the libusb 
redirector for testing here but it's good to restore the linux 
redirector as default on linux host.


[-- Attachment #2: lusb-upd4.diff --]
[-- Type: text/plain, Size: 13121 bytes --]

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

  reply	other threads:[~2006-04-23  3:38 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-20 19:59 [Qemu-devel] Large USB patch nix.wie.weg
2006-04-21  2:23 ` Lonnie Mendez
2006-04-21  5:59   ` nix.wie.weg
2006-04-21  7:04     ` Lonnie Mendez
2006-04-21 14:53 ` Lonnie Mendez
2006-04-21 15:00   ` Lonnie Mendez
2006-04-21 15:50   ` Lonnie Mendez
2006-04-21 16:19     ` Lonnie Mendez
2006-04-21 16:29       ` nix.wie.weg
2006-04-21 17:28         ` Lonnie Mendez
2006-04-21 18:06           ` Lonnie Mendez
2006-04-21 18:38             ` Lonnie Mendez
2006-04-21 20:50               ` Lonnie Mendez
2006-04-22  9:33                 ` nix.wie.weg
2006-04-22 14:36                   ` Lonnie Mendez
2006-04-22 15:36                     ` nix.wie.weg
2006-04-22 15:38                       ` nix.wie.weg
2006-04-22 16:00                     ` nix.wie.weg
2006-04-22 16:19                       ` Lonnie Mendez
2006-04-22 16:35                         ` nix.wie.weg
2006-04-23  3:38                           ` Lonnie Mendez [this message]
2006-04-23 21:54                             ` nix.wie.weg
2006-04-29  1:03                             ` Lonnie Mendez
2006-04-29  3:29                               ` Lonnie Mendez
2006-04-30  0:46                                 ` Lonnie Mendez
2006-04-30 20:56                                   ` Lonnie Mendez
2006-04-21 16:26     ` nix.wie.weg
2006-04-22 14:15 ` nix.wie.weg
2006-04-23 15:02 ` Fabrice Bellard
2006-04-23 16:11   ` nix.wie.weg
2006-04-24 23:50 ` [Qemu-devel] Update for cvs 2006-04-24 nix.wie.weg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=444AF6B7.1030606@austin.rr.com \
    --to=lmendez19@austin.rr.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).