summaryrefslogtreecommitdiff
path: root/drivers/usb/core/urb.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-04-28 06:54:10 +0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 08:44:48 +0400
commit6b403b020c1f42180b14d28d832da61167cff822 (patch)
tree4b7271244f3b150a31c856970651d2171343d2c7 /drivers/usb/core/urb.c
parent7f84eef0dafb1d318263d8b71c38700aaf2d530d (diff)
downloadlinux-6b403b020c1f42180b14d28d832da61167cff822.tar.xz
USB: Add SuperSpeed to the list of USB device speeds.
Modify the USB core to handle the new USB 3.0 speed, "SuperSpeed". This is 5.0 Gbps (wire speed). There are probably more places that check for speed that I've missed. SuperSpeed devices have a 512 byte endpoint 0 max packet size. This shows up as a bMaxPacketSize0 set to 0x09 (see table 9-8 of the USB 3.0 bus spec). xHCI spec says that the xHC can handle intervals up to 2^15 microframes. That might change when real silicon becomes available. Add FIXME note for SuperSpeed isochronous endpoints. They can transmit up to 16 packets in one "burst" before they wait for an acknowledgment of the packets. They can do up to 3 bursts per microframe (determined by the mult value in the endpoint companion descriptor). The xHCI driver doesn't have support for isoc yet, so fix this later. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/urb.c')
-rw-r--r--drivers/usb/core/urb.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 3376055f36e7..02eb0ef7a4c3 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -351,6 +351,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
if (xfertype == USB_ENDPOINT_XFER_ISOC) {
int n, len;
+ /* FIXME SuperSpeed isoc endpoints have up to 16 bursts */
/* "high bandwidth" mode, 1-3 packets/uframe? */
if (dev->speed == USB_SPEED_HIGH) {
int mult = 1 + ((max >> 11) & 0x03);
@@ -426,6 +427,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
return -EINVAL;
/* too big? */
switch (dev->speed) {
+ case USB_SPEED_SUPER: /* units are 125us */
+ /* Handle up to 2^(16-1) microframes */
+ if (urb->interval > (1 << 15))
+ return -EINVAL;
+ max = 1 << 15;
case USB_SPEED_HIGH: /* units are microframes */
/* NOTE usb handles 2^15 */
if (urb->interval > (1024 * 8))