aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hub.c
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2011-04-27 06:07:43 -0400
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2011-05-02 19:42:53 -0400
commit0ed9a57e052a3d20df052a2ff12a3b42380867aa (patch)
tree3e9f2abb102045cbd162a7ebe8563d4e9ee47148 /drivers/usb/host/xhci-hub.c
parent2c44178032b046c4113c40d0d459a0d36e39b920 (diff)
xHCI: report USB3.0 portstatus comply with USB3.0 specification
USB3.0 specification has different wPortStatus and wPortChange definitions from USB2.0 specification. Since USB3 root hub and USB2 root hub are split now and USB3 hub only has USB3 protocol ports, we should modify the portstatus and portchange report of USB3 ports to comply with USB3.0 specification. Signed-off-by: Andiry Xu <andiry.xu@amd.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host/xhci-hub.c')
-rw-r--r--drivers/usb/host/xhci-hub.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index b87535442386..4a3ca99fc64e 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -431,9 +431,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
431 } 431 }
432 xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp); 432 xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp);
433 433
434 /* FIXME - should we return a port status value like the USB
435 * 3.0 external hubs do?
436 */
437 /* wPortChange bits */ 434 /* wPortChange bits */
438 if (temp & PORT_CSC) 435 if (temp & PORT_CSC)
439 status |= USB_PORT_STAT_C_CONNECTION << 16; 436 status |= USB_PORT_STAT_C_CONNECTION << 16;
@@ -441,13 +438,21 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
441 status |= USB_PORT_STAT_C_ENABLE << 16; 438 status |= USB_PORT_STAT_C_ENABLE << 16;
442 if ((temp & PORT_OCC)) 439 if ((temp & PORT_OCC))
443 status |= USB_PORT_STAT_C_OVERCURRENT << 16; 440 status |= USB_PORT_STAT_C_OVERCURRENT << 16;
444 /* 441 if ((temp & PORT_RC))
445 * FIXME ignoring reset and USB 2.1/3.0 specific 442 status |= USB_PORT_STAT_C_RESET << 16;
446 * changes 443 /* USB3.0 only */
447 */ 444 if (hcd->speed == HCD_USB3) {
448 if ((temp & PORT_PLS_MASK) == XDEV_U3 445 if ((temp & PORT_PLC))
449 && (temp & PORT_POWER)) 446 status |= USB_PORT_STAT_C_LINK_STATE << 16;
450 status |= 1 << USB_PORT_FEAT_SUSPEND; 447 if ((temp & PORT_WRC))
448 status |= USB_PORT_STAT_C_BH_RESET << 16;
449 }
450
451 if (hcd->speed != HCD_USB3) {
452 if ((temp & PORT_PLS_MASK) == XDEV_U3
453 && (temp & PORT_POWER))
454 status |= USB_PORT_STAT_SUSPEND;
455 }
451 if ((temp & PORT_PLS_MASK) == XDEV_RESUME) { 456 if ((temp & PORT_PLS_MASK) == XDEV_RESUME) {
452 if ((temp & PORT_RESET) || !(temp & PORT_PE)) 457 if ((temp & PORT_RESET) || !(temp & PORT_PE))
453 goto error; 458 goto error;
@@ -490,8 +495,20 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
490 status |= USB_PORT_STAT_OVERCURRENT; 495 status |= USB_PORT_STAT_OVERCURRENT;
491 if (temp & PORT_RESET) 496 if (temp & PORT_RESET)
492 status |= USB_PORT_STAT_RESET; 497 status |= USB_PORT_STAT_RESET;
493 if (temp & PORT_POWER) 498 if (temp & PORT_POWER) {
494 status |= USB_PORT_STAT_POWER; 499 if (hcd->speed == HCD_USB3)
500 status |= USB_SS_PORT_STAT_POWER;
501 else
502 status |= USB_PORT_STAT_POWER;
503 }
504 /* Port Link State */
505 if (hcd->speed == HCD_USB3) {
506 /* resume state is a xHCI internal state.
507 * Do not report it to usb core.
508 */
509 if ((temp & PORT_PLS_MASK) != XDEV_RESUME)
510 status |= (temp & PORT_PLS_MASK);
511 }
495 if (bus_state->port_c_suspend & (1 << wIndex)) 512 if (bus_state->port_c_suspend & (1 << wIndex))
496 status |= 1 << USB_PORT_FEAT_C_SUSPEND; 513 status |= 1 << USB_PORT_FEAT_C_SUSPEND;
497 xhci_dbg(xhci, "Get port status returned 0x%x\n", status); 514 xhci_dbg(xhci, "Get port status returned 0x%x\n", status);