ChangeSet 1.1743.3.13, 2004/05/25 11:37:59-07:00, stern@rowland.harvard.edu [PATCH] USB: Initially read 9 bytes of config descriptor This patch reads the full 9 bytes of a configuration descriptor during enumeration rather than just the first 8 bytes. That's how Windows does it, and today I ran across a device that doesn't work properly when asked to send only 8 bytes worth. I doubt very much this will cause any problems with currently-working devices; since the descriptor itself is 9 bytes long and since the devices are most likely to expect a 9-byte request, anything that can handle an 8-byte request should have no difficulty. (Also, some debugging messages have been slightly improved.) Incidentally, USB traces taken from Windows 2000 and Windows XP show that when those operating systems retrieve a string descriptor during enumeration, they do so by requesting a 255-byte transfer. They do not first ask just for the initial 2 bytes (which contain the actual length) and then ask for the actual length, which is what we do. Interestingly, back in 2.4 we _did_ do things the same as Windows. drivers/usb/core/config.c | 17 +++++++++-------- 1 files changed, 9 insertions(+), 8 deletions(-) diff -Nru a/drivers/usb/core/config.c b/drivers/usb/core/config.c --- a/drivers/usb/core/config.c Fri May 28 14:40:51 2004 +++ b/drivers/usb/core/config.c Fri May 28 14:40:51 2004 @@ -465,23 +465,24 @@ goto err2; memset(dev->rawdescriptors, 0, length); - buffer = kmalloc(8, GFP_KERNEL); + buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL); if (!buffer) goto err2; desc = (struct usb_config_descriptor *)buffer; for (cfgno = 0; cfgno < ncfg; cfgno++) { - /* We grab the first 8 bytes so we know how long the whole */ - /* configuration is */ + /* We grab just the first descriptor so we know how long + * the whole configuration is */ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, - buffer, 8); + buffer, USB_DT_CONFIG_SIZE); if (result < 0) { dev_err(ddev, "unable to read config index %d " - "descriptor\n", cfgno); + "descriptor/%s\n", cfgno, "start"); goto err; - } else if (result < 8) { + } else if (result < 4) { dev_err(ddev, "config index %d descriptor too short " - "(expected %i, got %i)\n", cfgno, 8, result); + "(expected %i, got %i)\n", cfgno, + USB_DT_CONFIG_SIZE, result); result = -EINVAL; goto err; } @@ -498,7 +499,7 @@ bigbuffer, length); if (result < 0) { dev_err(ddev, "unable to read config index %d " - "descriptor\n", cfgno); + "descriptor/%s\n", cfgno, "all"); kfree(bigbuffer); goto err; }