@@ -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;
@@ -79,6 +79,7 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
/* control message emulation helpers */
void usb_desc_init(USBDevice *dev);
+void usb_desc_attach(USBDevice *dev);
void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str);
const char *usb_desc_get_string(USBDevice *dev, uint8_t index);
int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len);
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> --- hw/usb-desc.c | 36 +++++++++++++++++++++++++++++++++--- hw/usb-desc.h | 1 + 2 files changed, 34 insertions(+), 3 deletions(-)