diff options
author | David Brownell <david-b@pacbell.net> | 2008-02-08 23:08:44 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-04-25 04:16:35 (GMT) |
commit | caa9ef672a045ba0b19184cd3f872b583f066771 (patch) | |
tree | f55bc5f1e2597c947b00d813d9c7568a2d0af02b /drivers/usb/core/config.c | |
parent | e01e7fe3886715f083313da409c5850472455d06 (diff) | |
download | linux-fsl-qoriq-caa9ef672a045ba0b19184cd3f872b583f066771.tar.xz |
USB: ehci tolerates some buggy devices
This teaches EHCI how to to work around bugs in certain high speed
devices, by accomodating "bulk" packets that exceed the 512 byte
constant value required by the USB 2.0 specification. (Have a
look at section 5.8.3, paragraphs 1 and 3.)
It also makes the descriptor parsing code warn when it encounters
such bugs. (We've had reports of maybe two or three such devices,
all pretty recent.)
Such devices are nonconformant. The proper fix is have the vendors
of those devices do the simple, obvious, and correct thing ... which
will let them be used with USB hosts that don't have workarounds for
this particular vendor bug. But unless/until they do, we can at least
have one of the high speed HCDs work with such buggy devices.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/config.c')
-rw-r--r-- | drivers/usb/core/config.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index a92122a..568244c 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -145,6 +145,23 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, endpoint->desc.wMaxPacketSize = cpu_to_le16(8); } + /* + * Some buggy high speed devices have bulk endpoints using + * maxpacket sizes other than 512. High speed HCDs may not + * be able to handle that particular bug, so let's warn... + */ + if (to_usb_device(ddev)->speed == USB_SPEED_HIGH + && usb_endpoint_xfer_bulk(d)) { + unsigned maxp; + + maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize) & 0x07ff; + if (maxp != 512) + dev_warn(ddev, "config %d interface %d altsetting %d " + "bulk endpoint 0x%X has invalid maxpacket %d\n", + cfgno, inum, asnum, d->bEndpointAddress, + maxp); + } + /* Skip over any Class Specific or Vendor Specific descriptors; * find the next endpoint or interface descriptor */ endpoint->extra = buffer; |