Commit a8a5d436 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

[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.
parent ff9f1839
...@@ -465,23 +465,24 @@ int usb_get_configuration(struct usb_device *dev) ...@@ -465,23 +465,24 @@ int usb_get_configuration(struct usb_device *dev)
goto err2; goto err2;
memset(dev->rawdescriptors, 0, length); memset(dev->rawdescriptors, 0, length);
buffer = kmalloc(8, GFP_KERNEL); buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
if (!buffer) if (!buffer)
goto err2; goto err2;
desc = (struct usb_config_descriptor *)buffer; desc = (struct usb_config_descriptor *)buffer;
for (cfgno = 0; cfgno < ncfg; cfgno++) { for (cfgno = 0; cfgno < ncfg; cfgno++) {
/* We grab the first 8 bytes so we know how long the whole */ /* We grab just the first descriptor so we know how long
/* configuration is */ * the whole configuration is */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
buffer, 8); buffer, USB_DT_CONFIG_SIZE);
if (result < 0) { if (result < 0) {
dev_err(ddev, "unable to read config index %d " dev_err(ddev, "unable to read config index %d "
"descriptor\n", cfgno); "descriptor/%s\n", cfgno, "start");
goto err; goto err;
} else if (result < 8) { } else if (result < 4) {
dev_err(ddev, "config index %d descriptor too short " 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; result = -EINVAL;
goto err; goto err;
} }
...@@ -498,7 +499,7 @@ int usb_get_configuration(struct usb_device *dev) ...@@ -498,7 +499,7 @@ int usb_get_configuration(struct usb_device *dev)
bigbuffer, length); bigbuffer, length);
if (result < 0) { if (result < 0) {
dev_err(ddev, "unable to read config index %d " dev_err(ddev, "unable to read config index %d "
"descriptor\n", cfgno); "descriptor/%s\n", cfgno, "all");
kfree(bigbuffer); kfree(bigbuffer);
goto err; goto err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment