aboutsummaryrefslogtreecommitdiff
path: root/hw/usb-desc.c
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2010-11-26 20:20:41 +0100
committerGerd Hoffmann <kraxel@redhat.com>2011-01-11 15:56:01 +0100
commita980a065fb5e86d6dec337e6cb6ff432f1a143c9 (patch)
tree770139308761e2eb59bea5b1520e5b5dd7431308 /hw/usb-desc.c
parent41c6abbdeb5a86a135ee80a30541ecf52ffd3e23 (diff)
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.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index 3e87f46d7b..14c9e112ce 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;
}