diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2010-11-26 20:20:41 +0100 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2011-01-11 15:56:01 +0100 |
commit | a980a065fb5e86d6dec337e6cb6ff432f1a143c9 (patch) | |
tree | 770139308761e2eb59bea5b1520e5b5dd7431308 /hw/usb-desc.c | |
parent | 41c6abbdeb5a86a135ee80a30541ecf52ffd3e23 (diff) | |
download | qemu-a980a065fb5e86d6dec337e6cb6ff432f1a143c9.zip qemu-a980a065fb5e86d6dec337e6cb6ff432f1a143c9.tar.gz qemu-a980a065fb5e86d6dec337e6cb6ff432f1a143c9.tar.bz2 |
usb: move USB_REQ_{GET,SET}_CONFIGURATION handling to common code
This patch adds fields to the USBDevice struct for the current
speed (hard-wired to full speed for now) and current device
configuration. Also a init function is added which inializes
these fields. This allows USB_REQ_{GET,SET}_CONFIGURATION
handling to be moved to common code.
For most drivers the conversion is trivial ad they support a single
configuration only anyway. One exception is bluetooth where some
device-specific setup code runs after get/set configuration. The
other is usb-net which actually has two configurations so the
the code to check for the active configuration has been adapted.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb-desc.c')
-rw-r--r-- | hw/usb-desc.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/hw/usb-desc.c b/hw/usb-desc.c index 3e87f46..14c9e11 100644 --- a/hw/usb-desc.c +++ b/hw/usb-desc.c @@ -153,6 +153,16 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len) /* ------------------------------------------------------------------ */ +void usb_desc_init(USBDevice *dev) +{ + const USBDesc *desc = dev->info->usb_desc; + + assert(desc != NULL); + dev->speed = USB_SPEED_FULL; + dev->device = desc->full; + dev->config = dev->device->confs; +} + void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str) { USBDescString *s; @@ -230,12 +240,12 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len switch(type) { case USB_DT_DEVICE: - ret = usb_desc_device(&desc->id, desc->full, buf, sizeof(buf)); + ret = usb_desc_device(&desc->id, dev->device, buf, sizeof(buf)); trace_usb_desc_device(dev->addr, len, ret); break; case USB_DT_CONFIG: - if (index < desc->full->bNumConfigurations) { - ret = usb_desc_config(desc->full->confs + index, buf, sizeof(buf)); + if (index < dev->device->bNumConfigurations) { + ret = usb_desc_config(dev->device->confs + index, buf, sizeof(buf)); } trace_usb_desc_config(dev->addr, index, len, ret); break; @@ -262,7 +272,7 @@ int usb_desc_handle_control(USBDevice *dev, int request, int value, int index, int length, uint8_t *data) { const USBDesc *desc = dev->info->usb_desc; - int ret = -1; + int i, ret = -1; assert(desc != NULL); switch(request) { @@ -275,6 +285,20 @@ int usb_desc_handle_control(USBDevice *dev, int request, int value, case DeviceRequest | USB_REQ_GET_DESCRIPTOR: ret = usb_desc_get_descriptor(dev, value, data, length); break; + + case DeviceRequest | USB_REQ_GET_CONFIGURATION: + data[0] = dev->config->bConfigurationValue; + ret = 1; + break; + case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: + for (i = 0; i < dev->device->bNumConfigurations; i++) { + if (dev->device->confs[i].bConfigurationValue == value) { + dev->config = dev->device->confs + i; + ret = 0; + } + } + trace_usb_set_config(dev->addr, value, ret); + break; } return ret; } |