diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2009-04-27 22:55:01 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:48 -0400 |
commit | d2e9b4d6734db2327af3149d8ca7555307e10828 (patch) | |
tree | b5a37d14674e61b5342bf61056cf21bb21d6720a /drivers/usb | |
parent | 6b403b020c1f42180b14d28d832da61167cff822 (diff) |
USB: Add USB 3.0 roothub support to USB core.
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>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/hcd.c | 71 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 5 | ||||
-rw-r--r-- | drivers/usb/core/hub.h | 3 |
3 files changed, 77 insertions, 2 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 120bb56c4b84..823744d80cb9 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -128,6 +128,27 @@ static inline int is_root_hub(struct usb_device *udev) | |||
128 | #define KERNEL_REL ((LINUX_VERSION_CODE >> 16) & 0x0ff) | 128 | #define KERNEL_REL ((LINUX_VERSION_CODE >> 16) & 0x0ff) |
129 | #define KERNEL_VER ((LINUX_VERSION_CODE >> 8) & 0x0ff) | 129 | #define KERNEL_VER ((LINUX_VERSION_CODE >> 8) & 0x0ff) |
130 | 130 | ||
131 | /* usb 3.0 root hub device descriptor */ | ||
132 | static const u8 usb3_rh_dev_descriptor[18] = { | ||
133 | 0x12, /* __u8 bLength; */ | ||
134 | 0x01, /* __u8 bDescriptorType; Device */ | ||
135 | 0x00, 0x03, /* __le16 bcdUSB; v3.0 */ | ||
136 | |||
137 | 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ | ||
138 | 0x00, /* __u8 bDeviceSubClass; */ | ||
139 | 0x03, /* __u8 bDeviceProtocol; USB 3.0 hub */ | ||
140 | 0x09, /* __u8 bMaxPacketSize0; 2^9 = 512 Bytes */ | ||
141 | |||
142 | 0x6b, 0x1d, /* __le16 idVendor; Linux Foundation */ | ||
143 | 0x02, 0x00, /* __le16 idProduct; device 0x0002 */ | ||
144 | KERNEL_VER, KERNEL_REL, /* __le16 bcdDevice */ | ||
145 | |||
146 | 0x03, /* __u8 iManufacturer; */ | ||
147 | 0x02, /* __u8 iProduct; */ | ||
148 | 0x01, /* __u8 iSerialNumber; */ | ||
149 | 0x01 /* __u8 bNumConfigurations; */ | ||
150 | }; | ||
151 | |||
131 | /* usb 2.0 root hub device descriptor */ | 152 | /* usb 2.0 root hub device descriptor */ |
132 | static const u8 usb2_rh_dev_descriptor [18] = { | 153 | static const u8 usb2_rh_dev_descriptor [18] = { |
133 | 0x12, /* __u8 bLength; */ | 154 | 0x12, /* __u8 bLength; */ |
@@ -273,6 +294,47 @@ static const u8 hs_rh_config_descriptor [] = { | |||
273 | 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ | 294 | 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ |
274 | }; | 295 | }; |
275 | 296 | ||
297 | static const u8 ss_rh_config_descriptor[] = { | ||
298 | /* one configuration */ | ||
299 | 0x09, /* __u8 bLength; */ | ||
300 | 0x02, /* __u8 bDescriptorType; Configuration */ | ||
301 | 0x19, 0x00, /* __le16 wTotalLength; FIXME */ | ||
302 | 0x01, /* __u8 bNumInterfaces; (1) */ | ||
303 | 0x01, /* __u8 bConfigurationValue; */ | ||
304 | 0x00, /* __u8 iConfiguration; */ | ||
305 | 0xc0, /* __u8 bmAttributes; | ||
306 | Bit 7: must be set, | ||
307 | 6: Self-powered, | ||
308 | 5: Remote wakeup, | ||
309 | 4..0: resvd */ | ||
310 | 0x00, /* __u8 MaxPower; */ | ||
311 | |||
312 | /* one interface */ | ||
313 | 0x09, /* __u8 if_bLength; */ | ||
314 | 0x04, /* __u8 if_bDescriptorType; Interface */ | ||
315 | 0x00, /* __u8 if_bInterfaceNumber; */ | ||
316 | 0x00, /* __u8 if_bAlternateSetting; */ | ||
317 | 0x01, /* __u8 if_bNumEndpoints; */ | ||
318 | 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ | ||
319 | 0x00, /* __u8 if_bInterfaceSubClass; */ | ||
320 | 0x00, /* __u8 if_bInterfaceProtocol; */ | ||
321 | 0x00, /* __u8 if_iInterface; */ | ||
322 | |||
323 | /* one endpoint (status change endpoint) */ | ||
324 | 0x07, /* __u8 ep_bLength; */ | ||
325 | 0x05, /* __u8 ep_bDescriptorType; Endpoint */ | ||
326 | 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ | ||
327 | 0x03, /* __u8 ep_bmAttributes; Interrupt */ | ||
328 | /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) | ||
329 | * see hub.c:hub_configure() for details. */ | ||
330 | (USB_MAXCHILDREN + 1 + 7) / 8, 0x00, | ||
331 | 0x0c /* __u8 ep_bInterval; (256ms -- usb 2.0 spec) */ | ||
332 | /* | ||
333 | * All 3.0 hubs should have an endpoint companion descriptor, | ||
334 | * but we're ignoring that for now. FIXME? | ||
335 | */ | ||
336 | }; | ||
337 | |||
276 | /*-------------------------------------------------------------------------*/ | 338 | /*-------------------------------------------------------------------------*/ |
277 | 339 | ||
278 | /* | 340 | /* |
@@ -426,7 +488,9 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
426 | case DeviceRequest | USB_REQ_GET_DESCRIPTOR: | 488 | case DeviceRequest | USB_REQ_GET_DESCRIPTOR: |
427 | switch (wValue & 0xff00) { | 489 | switch (wValue & 0xff00) { |
428 | case USB_DT_DEVICE << 8: | 490 | case USB_DT_DEVICE << 8: |
429 | if (hcd->driver->flags & HCD_USB2) | 491 | if (hcd->driver->flags & HCD_USB3) |
492 | bufp = usb3_rh_dev_descriptor; | ||
493 | else if (hcd->driver->flags & HCD_USB2) | ||
430 | bufp = usb2_rh_dev_descriptor; | 494 | bufp = usb2_rh_dev_descriptor; |
431 | else if (hcd->driver->flags & HCD_USB11) | 495 | else if (hcd->driver->flags & HCD_USB11) |
432 | bufp = usb11_rh_dev_descriptor; | 496 | bufp = usb11_rh_dev_descriptor; |
@@ -437,7 +501,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
437 | patch_protocol = 1; | 501 | patch_protocol = 1; |
438 | break; | 502 | break; |
439 | case USB_DT_CONFIG << 8: | 503 | case USB_DT_CONFIG << 8: |
440 | if (hcd->driver->flags & HCD_USB2) { | 504 | if (hcd->driver->flags & HCD_USB3) { |
505 | bufp = ss_rh_config_descriptor; | ||
506 | len = sizeof ss_rh_config_descriptor; | ||
507 | } else if (hcd->driver->flags & HCD_USB2) { | ||
441 | bufp = hs_rh_config_descriptor; | 508 | bufp = hs_rh_config_descriptor; |
442 | len = sizeof hs_rh_config_descriptor; | 509 | len = sizeof hs_rh_config_descriptor; |
443 | } else { | 510 | } else { |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index fa0208e0da6a..f3fe8dfaaad1 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -155,6 +155,8 @@ static inline char *portspeed(int portstatus) | |||
155 | return "480 Mb/s"; | 155 | return "480 Mb/s"; |
156 | else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED)) | 156 | else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED)) |
157 | return "1.5 Mb/s"; | 157 | return "1.5 Mb/s"; |
158 | else if (portstatus & (1 << USB_PORT_FEAT_SUPERSPEED)) | ||
159 | return "5.0 Gb/s"; | ||
158 | else | 160 | else |
159 | return "12 Mb/s"; | 161 | return "12 Mb/s"; |
160 | } | 162 | } |
@@ -951,6 +953,9 @@ static int hub_configure(struct usb_hub *hub, | |||
951 | ret); | 953 | ret); |
952 | hub->tt.hub = hdev; | 954 | hub->tt.hub = hdev; |
953 | break; | 955 | break; |
956 | case 3: | ||
957 | /* USB 3.0 hubs don't have a TT */ | ||
958 | break; | ||
954 | default: | 959 | default: |
955 | dev_dbg(hub_dev, "Unrecognized hub protocol %d\n", | 960 | dev_dbg(hub_dev, "Unrecognized hub protocol %d\n", |
956 | hdev->descriptor.bDeviceProtocol); | 961 | hdev->descriptor.bDeviceProtocol); |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 2a116ce53c9b..889c0f32a40b 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
@@ -47,7 +47,10 @@ | |||
47 | #define USB_PORT_FEAT_L1 5 /* L1 suspend */ | 47 | #define USB_PORT_FEAT_L1 5 /* L1 suspend */ |
48 | #define USB_PORT_FEAT_POWER 8 | 48 | #define USB_PORT_FEAT_POWER 8 |
49 | #define USB_PORT_FEAT_LOWSPEED 9 | 49 | #define USB_PORT_FEAT_LOWSPEED 9 |
50 | /* This value was never in Table 11-17 */ | ||
50 | #define USB_PORT_FEAT_HIGHSPEED 10 | 51 | #define USB_PORT_FEAT_HIGHSPEED 10 |
52 | /* This value is also fake */ | ||
53 | #define USB_PORT_FEAT_SUPERSPEED 11 | ||
51 | #define USB_PORT_FEAT_C_CONNECTION 16 | 54 | #define USB_PORT_FEAT_C_CONNECTION 16 |
52 | #define USB_PORT_FEAT_C_ENABLE 17 | 55 | #define USB_PORT_FEAT_C_ENABLE 17 |
53 | #define USB_PORT_FEAT_C_SUSPEND 18 | 56 | #define USB_PORT_FEAT_C_SUSPEND 18 |