Skip to content

Commit

Permalink
USB: Add USB 3.0 roothub support to USB core.
Browse files Browse the repository at this point in the history
Add USB 3.0 root hub descriptors.  This is a kludge because I reused the old
USB 2.0 descriptors, instead of using the new USB 3.0 hub descriptors with
endpoint companion descriptors and other descriptors.  I did this because I
wasn't ready to add USB 3.0 hub changes to khubd.  For now, a USB 3.0 roothub
looks like a USB 2.0 roothub, with a higher speed.

USB 3.0 hubs have no transaction translator (TT).

Make USB core debugging handle super speed ports.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Sarah Sharp authored and Greg Kroah-Hartman committed Jun 16, 2009
1 parent 6b403b0 commit d2e9b4d
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
71 changes: 69 additions & 2 deletions drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,27 @@ static inline int is_root_hub(struct usb_device *udev)
#define KERNEL_REL ((LINUX_VERSION_CODE >> 16) & 0x0ff)
#define KERNEL_VER ((LINUX_VERSION_CODE >> 8) & 0x0ff)

/* usb 3.0 root hub device descriptor */
static const u8 usb3_rh_dev_descriptor[18] = {
0x12, /* __u8 bLength; */
0x01, /* __u8 bDescriptorType; Device */
0x00, 0x03, /* __le16 bcdUSB; v3.0 */

0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
0x00, /* __u8 bDeviceSubClass; */
0x03, /* __u8 bDeviceProtocol; USB 3.0 hub */
0x09, /* __u8 bMaxPacketSize0; 2^9 = 512 Bytes */

0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */
0x02, 0x00, /* __le16 idProduct; device 0x0002 */
KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */

0x03, /* __u8 iManufacturer; */
0x02, /* __u8 iProduct; */
0x01, /* __u8 iSerialNumber; */
0x01 /* __u8 bNumConfigurations; */
};

/* usb 2.0 root hub device descriptor */
static const u8 usb2_rh_dev_descriptor [18] = {
0x12, /* __u8 bLength; */
Expand Down Expand Up @@ -273,6 +294,47 @@ static const u8 hs_rh_config_descriptor [] = {
0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */
};

static const u8 ss_rh_config_descriptor[] = {
/* one configuration */
0x09, /* __u8 bLength; */
0x02, /* __u8 bDescriptorType; Configuration */
0x19, 0x00, /* __le16 wTotalLength; FIXME */
0x01, /* __u8 bNumInterfaces; (1) */
0x01, /* __u8 bConfigurationValue; */
0x00, /* __u8 iConfiguration; */
0xc0, /* __u8 bmAttributes;
Bit 7: must be set,
6: Self-powered,
5: Remote wakeup,
4..0: resvd */
0x00, /* __u8 MaxPower; */

/* one interface */
0x09, /* __u8 if_bLength; */
0x04, /* __u8 if_bDescriptorType; Interface */
0x00, /* __u8 if_bInterfaceNumber; */
0x00, /* __u8 if_bAlternateSetting; */
0x01, /* __u8 if_bNumEndpoints; */
0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
0x00, /* __u8 if_bInterfaceSubClass; */
0x00, /* __u8 if_bInterfaceProtocol; */
0x00, /* __u8 if_iInterface; */

/* one endpoint (status change endpoint) */
0x07, /* __u8 ep_bLength; */
0x05, /* __u8 ep_bDescriptorType; Endpoint */
0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
0x03, /* __u8 ep_bmAttributes; Interrupt */
/* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8)
* see hub.c:hub_configure() for details. */
(USB_MAXCHILDREN + 1 + 7) / 8, 0x00,
0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */
/*
* All 3.0 hubs should have an endpoint companion descriptor,
* but we're ignoring that for now. FIXME?
*/
};

/*-------------------------------------------------------------------------*/

/*
Expand Down Expand Up @@ -426,7 +488,9 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
switch (wValue & 0xff00) {
case USB_DT_DEVICE << 8:
if (hcd->driver->flags & HCD_USB2)
if (hcd->driver->flags & HCD_USB3)
bufp = usb3_rh_dev_descriptor;
else if (hcd->driver->flags & HCD_USB2)
bufp = usb2_rh_dev_descriptor;
else if (hcd->driver->flags & HCD_USB11)
bufp = usb11_rh_dev_descriptor;
Expand All @@ -437,7 +501,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
patch_protocol = 1;
break;
case USB_DT_CONFIG << 8:
if (hcd->driver->flags & HCD_USB2) {
if (hcd->driver->flags & HCD_USB3) {
bufp = ss_rh_config_descriptor;
len = sizeof ss_rh_config_descriptor;
} else if (hcd->driver->flags & HCD_USB2) {
bufp = hs_rh_config_descriptor;
len = sizeof hs_rh_config_descriptor;
} else {
Expand Down
5 changes: 5 additions & 0 deletions drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ static inline char *portspeed(int portstatus)
return "480 Mb/s";
else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED))
return "1.5 Mb/s";
else if (portstatus & (1 << USB_PORT_FEAT_SUPERSPEED))
return "5.0 Gb/s";
else
return "12 Mb/s";
}
Expand Down Expand Up @@ -951,6 +953,9 @@ static int hub_configure(struct usb_hub *hub,
ret);
hub->tt.hub = hdev;
break;
case 3:
/* USB 3.0 hubs don't have a TT */
break;
default:
dev_dbg(hub_dev, "Unrecognized hub protocol %d\n",
hdev->descriptor.bDeviceProtocol);
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/core/hub.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@
#define USB_PORT_FEAT_L1 5 /* L1 suspend */
#define USB_PORT_FEAT_POWER 8
#define USB_PORT_FEAT_LOWSPEED 9
/* This value was never in Table 11-17 */
#define USB_PORT_FEAT_HIGHSPEED 10
/* This value is also fake */
#define USB_PORT_FEAT_SUPERSPEED 11
#define USB_PORT_FEAT_C_CONNECTION 16
#define USB_PORT_FEAT_C_ENABLE 17
#define USB_PORT_FEAT_C_SUSPEND 18
Expand Down

0 comments on commit d2e9b4d

Please sign in to comment.