summary refs log tree commit diff stats
path: root/hw/usb-desc.c
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2010-12-03 18:07:20 +0100
committerGerd Hoffmann <kraxel@redhat.com>2011-01-11 17:15:24 +0100
commit32d41919784abe56b10f6d7784c00bb27e4f4d39 (patch)
tree41416dca0d054a5557b22626e3ad8bb3ecdc8c9c /hw/usb-desc.c
parentb6f77fbe230ad3e9ec5c9115a1535137d5e5d04b (diff)
downloadfocaccia-qemu-32d41919784abe56b10f6d7784c00bb27e4f4d39.tar.gz
focaccia-qemu-32d41919784abe56b10f6d7784c00bb27e4f4d39.zip
usb: add usb_desc_attach
Add usb_desc_attach() which sets up the device according to the speed
the usb port is able to handle.  This function can be hooked into the
handle_attach callback.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb-desc.c')
-rw-r--r--hw/usb-desc.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index 56ef734bde..f01e1cf43d 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -153,16 +153,46 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len)
 
 /* ------------------------------------------------------------------ */
 
-void usb_desc_init(USBDevice *dev)
+static void usb_desc_setdefaults(USBDevice *dev)
 {
     const USBDesc *desc = dev->info->usb_desc;
 
     assert(desc != NULL);
-    dev->speed  = USB_SPEED_FULL;
-    dev->device = desc->full;
+    switch (dev->speed) {
+    case USB_SPEED_LOW:
+    case USB_SPEED_FULL:
+        dev->device = desc->full;
+        break;
+    case USB_SPEED_HIGH:
+        dev->device = desc->high;
+        break;
+    }
     dev->config = dev->device->confs;
 }
 
+void usb_desc_init(USBDevice *dev)
+{
+    dev->speed = USB_SPEED_FULL;
+    usb_desc_setdefaults(dev);
+}
+
+void usb_desc_attach(USBDevice *dev)
+{
+    const USBDesc *desc = dev->info->usb_desc;
+
+    assert(desc != NULL);
+    if (desc->high && (dev->port->speedmask & USB_SPEED_MASK_HIGH)) {
+        dev->speed = USB_SPEED_HIGH;
+    } else if (desc->full && (dev->port->speedmask & USB_SPEED_MASK_FULL)) {
+        dev->speed = USB_SPEED_FULL;
+    } else {
+        fprintf(stderr, "usb: port/device speed mismatch for \"%s\"\n",
+                dev->info->product_desc);
+        return;
+    }
+    usb_desc_setdefaults(dev);
+}
+
 void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str)
 {
     USBDescString *s;