diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2010-10-26 19:47:13 -0400 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2010-11-19 19:23:18 -0500 |
commit | da6699ce4a889c3795624ccdcfe7181cc89f18e8 (patch) | |
tree | 05cd63ceb04825bda66d11175108b3b5510b1fe6 /drivers/usb/host/xhci.h | |
parent | 7a3783efffc7bc2e702d774e47fad5b8e37e9ad1 (diff) |
xhci: Setup array of USB 2.0 and USB 3.0 ports.
An xHCI host controller contains USB 2.0 and USB 3.0 ports, which can
occur in any order in the PORTSC registers. We cannot read the port speed
bits in the PORTSC registers at init time to determine the port speed,
since those bits are only valid when a USB device is plugged into the
port.
Instead, we read the "Supported Protocol Capability" registers in the xHC
Extended Capabilities space. Those describe the protocol, port offset in
the PORTSC registers, and port count. We use those registers to create
two arrays of pointers to the PORTSC registers, one for USB 3.0 ports, and
another for USB 2.0 ports. A third array keeps track of the port protocol
major revision, and is indexed with the internal xHCI port number.
This commit is a bit big, but it should be queued for stable because the "Don't
let the USB core disable SuperSpeed ports" patch depends on it. There is no
other way to determine which ports are SuperSpeed ports without this patch.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Tested-by: Don Zickus <dzickus@redhat.com>
Cc: stable@kernel.org
Diffstat (limited to 'drivers/usb/host/xhci.h')
-rw-r--r-- | drivers/usb/host/xhci.h | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 85e65647d445..170c367112d2 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -454,6 +454,24 @@ struct xhci_doorbell_array { | |||
454 | 454 | ||
455 | 455 | ||
456 | /** | 456 | /** |
457 | * struct xhci_protocol_caps | ||
458 | * @revision: major revision, minor revision, capability ID, | ||
459 | * and next capability pointer. | ||
460 | * @name_string: Four ASCII characters to say which spec this xHC | ||
461 | * follows, typically "USB ". | ||
462 | * @port_info: Port offset, count, and protocol-defined information. | ||
463 | */ | ||
464 | struct xhci_protocol_caps { | ||
465 | u32 revision; | ||
466 | u32 name_string; | ||
467 | u32 port_info; | ||
468 | }; | ||
469 | |||
470 | #define XHCI_EXT_PORT_MAJOR(x) (((x) >> 24) & 0xff) | ||
471 | #define XHCI_EXT_PORT_OFF(x) ((x) & 0xff) | ||
472 | #define XHCI_EXT_PORT_COUNT(x) (((x) >> 8) & 0xff) | ||
473 | |||
474 | /** | ||
457 | * struct xhci_container_ctx | 475 | * struct xhci_container_ctx |
458 | * @type: Type of context. Used to calculated offsets to contained contexts. | 476 | * @type: Type of context. Used to calculated offsets to contained contexts. |
459 | * @size: Size of the context data | 477 | * @size: Size of the context data |
@@ -1240,6 +1258,14 @@ struct xhci_hcd { | |||
1240 | u32 suspended_ports[8]; /* which ports are | 1258 | u32 suspended_ports[8]; /* which ports are |
1241 | suspended */ | 1259 | suspended */ |
1242 | unsigned long resume_done[MAX_HC_PORTS]; | 1260 | unsigned long resume_done[MAX_HC_PORTS]; |
1261 | /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ | ||
1262 | u8 *port_array; | ||
1263 | /* Array of pointers to USB 3.0 PORTSC registers */ | ||
1264 | u32 __iomem **usb3_ports; | ||
1265 | unsigned int num_usb3_ports; | ||
1266 | /* Array of pointers to USB 2.0 PORTSC registers */ | ||
1267 | u32 __iomem **usb2_ports; | ||
1268 | unsigned int num_usb2_ports; | ||
1243 | }; | 1269 | }; |
1244 | 1270 | ||
1245 | /* For testing purposes */ | 1271 | /* For testing purposes */ |