This patch fixes bugs in usbdcore*.c related to the use of devices with multiple configurations. The original code made mistakes about the meaning of configuration value and configuration index, and the resulting off-by-one errors resulted in: * SET_CONFIGURATION always selected the first configuration, no matter what wValue is being passed. * GET_DESCRIPTOR/CONFIGURATION always returned the descriptor for the first configuration (index 0). Signed-off-by: Harald Welte Index: u-boot/drivers/usbdcore_ep0.c =================================================================== --- u-boot.orig/drivers/usbdcore_ep0.c 2007-03-14 20:29:05.000000000 +0100 +++ u-boot/drivers/usbdcore_ep0.c 2007-03-14 20:29:06.000000000 +0100 @@ -233,8 +233,8 @@ return -1; } /*dbg_ep0(2, "%d %d", index, device_descriptor->bNumConfigurations); */ - if (index > device_descriptor->bNumConfigurations) { - dbg_ep0 (0, "index too large: %d > %d", index, + if (index >= device_descriptor->bNumConfigurations) { + dbg_ep0 (0, "index too large: %d >= %d", index, device_descriptor-> bNumConfigurations); return -1; @@ -593,13 +593,8 @@ case USB_REQ_SET_CONFIGURATION: /* c.f. 9.4.7 - the top half of wValue is reserved */ - /* */ - if ((device->configuration = - le16_to_cpu (request->wValue) & 0x7f) != 0) { - /* c.f. 9.4.7 - zero is the default or addressed state, in our case this */ - /* is the same is configuration zero */ - device->configuration = 0; /* TBR - ?????? */ - } + device->configuration = le16_to_cpu(request->wValue) & 0xff; + /* reset interface and alternate settings */ device->interface = device->alternate = 0; Index: u-boot/drivers/usbdcore.c =================================================================== --- u-boot.orig/drivers/usbdcore.c 2007-03-14 20:29:05.000000000 +0100 +++ u-boot/drivers/usbdcore.c 2007-03-14 20:37:37.000000000 +0100 @@ -147,12 +147,9 @@ static struct usb_configuration_instance *usbd_device_configuration_instance (struct usb_device_instance *device, unsigned int port, unsigned int configuration) { - /* XXX */ - configuration = configuration ? configuration - 1 : 0; - - if (configuration >= device->configurations) { + if (configuration >= device->configurations) return NULL; - } + return device->configuration_instance_array + configuration; }