From e73b5212e0463a3db0af0a5c95c75bfb762ca973 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 7 Jul 2008 00:58:05 +0800 Subject: [PATCH 1/2] fix USB devices with multiple configurations 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 Acked-by: Markus Klotzbuecher --- drivers/usb/usbdcore.c | 7 ++----- drivers/usb/usbdcore_ep0.c | 14 ++++---------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/usb/usbdcore.c b/drivers/usb/usbdcore.c index 308c7ceccc..a621ce7a39 100644 --- a/drivers/usb/usbdcore.c +++ b/drivers/usb/usbdcore.c @@ -146,12 +146,9 @@ struct usb_string_descriptor *usbd_get_string (__u8 index) 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; } diff --git a/drivers/usb/usbdcore_ep0.c b/drivers/usb/usbdcore_ep0.c index 1e44f322a7..cf3f3826cb 100644 --- a/drivers/usb/usbdcore_ep0.c +++ b/drivers/usb/usbdcore_ep0.c @@ -235,8 +235,8 @@ static int ep0_get_descriptor (struct usb_device_instance *device, 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; @@ -571,14 +571,8 @@ int ep0_recv_setup (struct urb *urb) 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) & 0xFF80) != 0) { - /* c.f. 9.4.7 - zero is the default or addressed state, in our case this */ - /* is the same is configuration zero */ - serial_printf("error setting dev->config to zero!\n"); - device->configuration = 0; /* TBR - ?????? */ - } + device->configuration = le16_to_cpu(request->wValue) & 0xff; + /* reset interface and alternate settings */ device->interface = device->alternate = 0; From d4b5f3fa001228d76e2c3380cedadf804b802c2a Mon Sep 17 00:00:00 2001 From: Christian Eggers Date: Fri, 27 Jun 2008 19:46:51 +0200 Subject: [PATCH 2/2] Fix "usb part" command Only print partition for selected device if user supplied the arg with the "usb part [dev]" command. Signed-off-by: Christian Eggers Acked-by: Markus Klotzbuecher --- common/cmd_usb.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/common/cmd_usb.c b/common/cmd_usb.c index f2795d3f40..30caa98ea7 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -554,13 +554,24 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } if (strncmp(argv[1],"part",4) == 0) { - int devno, ok; - for (ok=0, devno=0; devnotype!=DEV_TYPE_UNKNOWN) { + ok++; + if (devno) + printf("\n"); + printf("print_part of %x\n",devno); + print_part(stor_dev); + } + } + } + else { + devno=simple_strtoul(argv[2], NULL, 16); stor_dev=usb_stor_get_dev(devno); if (stor_dev->type!=DEV_TYPE_UNKNOWN) { ok++; - if (devno) - printf("\n"); printf("print_part of %x\n",devno); print_part(stor_dev); }