aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-hub.c')
-rw-r--r--drivers/usb/host/xhci-hub.c165
1 files changed, 116 insertions, 49 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index a78f2ebd11b7..e3ddc6a95afe 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -50,7 +50,7 @@ static void xhci_common_hub_descriptor(struct xhci_hcd *xhci,
50 temp |= 0x0008; 50 temp |= 0x0008;
51 /* Bits 6:5 - no TTs in root ports */ 51 /* Bits 6:5 - no TTs in root ports */
52 /* Bit 7 - no port indicators */ 52 /* Bit 7 - no port indicators */
53 desc->wHubCharacteristics = (__force __u16) cpu_to_le16(temp); 53 desc->wHubCharacteristics = cpu_to_le16(temp);
54} 54}
55 55
56/* Fill in the USB 2.0 roothub descriptor */ 56/* Fill in the USB 2.0 roothub descriptor */
@@ -314,7 +314,7 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id)
314} 314}
315 315
316static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, 316static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
317 u16 wIndex, u32 __iomem *addr, u32 port_status) 317 u16 wIndex, __le32 __iomem *addr, u32 port_status)
318{ 318{
319 /* Don't allow the USB core to disable SuperSpeed ports. */ 319 /* Don't allow the USB core to disable SuperSpeed ports. */
320 if (hcd->speed == HCD_USB3) { 320 if (hcd->speed == HCD_USB3) {
@@ -331,7 +331,7 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
331} 331}
332 332
333static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, 333static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
334 u16 wIndex, u32 __iomem *addr, u32 port_status) 334 u16 wIndex, __le32 __iomem *addr, u32 port_status)
335{ 335{
336 char *port_change_bit; 336 char *port_change_bit;
337 u32 status; 337 u32 status;
@@ -341,6 +341,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
341 status = PORT_RC; 341 status = PORT_RC;
342 port_change_bit = "reset"; 342 port_change_bit = "reset";
343 break; 343 break;
344 case USB_PORT_FEAT_C_BH_PORT_RESET:
345 status = PORT_WRC;
346 port_change_bit = "warm(BH) reset";
347 break;
344 case USB_PORT_FEAT_C_CONNECTION: 348 case USB_PORT_FEAT_C_CONNECTION:
345 status = PORT_CSC; 349 status = PORT_CSC;
346 port_change_bit = "connect"; 350 port_change_bit = "connect";
@@ -357,6 +361,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
357 status = PORT_PLC; 361 status = PORT_PLC;
358 port_change_bit = "suspend/resume"; 362 port_change_bit = "suspend/resume";
359 break; 363 break;
364 case USB_PORT_FEAT_C_PORT_LINK_STATE:
365 status = PORT_PLC;
366 port_change_bit = "link state";
367 break;
360 default: 368 default:
361 /* Should never happen */ 369 /* Should never happen */
362 return; 370 return;
@@ -376,9 +384,10 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
376 unsigned long flags; 384 unsigned long flags;
377 u32 temp, temp1, status; 385 u32 temp, temp1, status;
378 int retval = 0; 386 int retval = 0;
379 u32 __iomem **port_array; 387 __le32 __iomem **port_array;
380 int slot_id; 388 int slot_id;
381 struct xhci_bus_state *bus_state; 389 struct xhci_bus_state *bus_state;
390 u16 link_state = 0;
382 391
383 if (hcd->speed == HCD_USB3) { 392 if (hcd->speed == HCD_USB3) {
384 ports = xhci->num_usb3_ports; 393 ports = xhci->num_usb3_ports;
@@ -422,9 +431,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
422 } 431 }
423 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);
424 433
425 /* FIXME - should we return a port status value like the USB
426 * 3.0 external hubs do?
427 */
428 /* wPortChange bits */ 434 /* wPortChange bits */
429 if (temp & PORT_CSC) 435 if (temp & PORT_CSC)
430 status |= USB_PORT_STAT_C_CONNECTION << 16; 436 status |= USB_PORT_STAT_C_CONNECTION << 16;
@@ -432,13 +438,21 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
432 status |= USB_PORT_STAT_C_ENABLE << 16; 438 status |= USB_PORT_STAT_C_ENABLE << 16;
433 if ((temp & PORT_OCC)) 439 if ((temp & PORT_OCC))
434 status |= USB_PORT_STAT_C_OVERCURRENT << 16; 440 status |= USB_PORT_STAT_C_OVERCURRENT << 16;
435 /* 441 if ((temp & PORT_RC))
436 * FIXME ignoring reset and USB 2.1/3.0 specific 442 status |= USB_PORT_STAT_C_RESET << 16;
437 * changes 443 /* USB3.0 only */
438 */ 444 if (hcd->speed == HCD_USB3) {
439 if ((temp & PORT_PLS_MASK) == XDEV_U3 445 if ((temp & PORT_PLC))
440 && (temp & PORT_POWER)) 446 status |= USB_PORT_STAT_C_LINK_STATE << 16;
441 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 }
442 if ((temp & PORT_PLS_MASK) == XDEV_RESUME) { 456 if ((temp & PORT_PLS_MASK) == XDEV_RESUME) {
443 if ((temp & PORT_RESET) || !(temp & PORT_PE)) 457 if ((temp & PORT_RESET) || !(temp & PORT_PE))
444 goto error; 458 goto error;
@@ -469,7 +483,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
469 && (temp & PORT_POWER) 483 && (temp & PORT_POWER)
470 && (bus_state->suspended_ports & (1 << wIndex))) { 484 && (bus_state->suspended_ports & (1 << wIndex))) {
471 bus_state->suspended_ports &= ~(1 << wIndex); 485 bus_state->suspended_ports &= ~(1 << wIndex);
472 bus_state->port_c_suspend |= 1 << wIndex; 486 if (hcd->speed != HCD_USB3)
487 bus_state->port_c_suspend |= 1 << wIndex;
473 } 488 }
474 if (temp & PORT_CONNECT) { 489 if (temp & PORT_CONNECT) {
475 status |= USB_PORT_STAT_CONNECTION; 490 status |= USB_PORT_STAT_CONNECTION;
@@ -481,14 +496,28 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
481 status |= USB_PORT_STAT_OVERCURRENT; 496 status |= USB_PORT_STAT_OVERCURRENT;
482 if (temp & PORT_RESET) 497 if (temp & PORT_RESET)
483 status |= USB_PORT_STAT_RESET; 498 status |= USB_PORT_STAT_RESET;
484 if (temp & PORT_POWER) 499 if (temp & PORT_POWER) {
485 status |= USB_PORT_STAT_POWER; 500 if (hcd->speed == HCD_USB3)
501 status |= USB_SS_PORT_STAT_POWER;
502 else
503 status |= USB_PORT_STAT_POWER;
504 }
505 /* Port Link State */
506 if (hcd->speed == HCD_USB3) {
507 /* resume state is a xHCI internal state.
508 * Do not report it to usb core.
509 */
510 if ((temp & PORT_PLS_MASK) != XDEV_RESUME)
511 status |= (temp & PORT_PLS_MASK);
512 }
486 if (bus_state->port_c_suspend & (1 << wIndex)) 513 if (bus_state->port_c_suspend & (1 << wIndex))
487 status |= 1 << USB_PORT_FEAT_C_SUSPEND; 514 status |= 1 << USB_PORT_FEAT_C_SUSPEND;
488 xhci_dbg(xhci, "Get port status returned 0x%x\n", status); 515 xhci_dbg(xhci, "Get port status returned 0x%x\n", status);
489 put_unaligned(cpu_to_le32(status), (__le32 *) buf); 516 put_unaligned(cpu_to_le32(status), (__le32 *) buf);
490 break; 517 break;
491 case SetPortFeature: 518 case SetPortFeature:
519 if (wValue == USB_PORT_FEAT_LINK_STATE)
520 link_state = (wIndex & 0xff00) >> 3;
492 wIndex &= 0xff; 521 wIndex &= 0xff;
493 if (!wIndex || wIndex > ports) 522 if (!wIndex || wIndex > ports)
494 goto error; 523 goto error;
@@ -537,6 +566,44 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
537 temp = xhci_readl(xhci, port_array[wIndex]); 566 temp = xhci_readl(xhci, port_array[wIndex]);
538 bus_state->suspended_ports |= 1 << wIndex; 567 bus_state->suspended_ports |= 1 << wIndex;
539 break; 568 break;
569 case USB_PORT_FEAT_LINK_STATE:
570 temp = xhci_readl(xhci, port_array[wIndex]);
571 /* Software should not attempt to set
572 * port link state above '5' (Rx.Detect) and the port
573 * must be enabled.
574 */
575 if ((temp & PORT_PE) == 0 ||
576 (link_state > USB_SS_PORT_LS_RX_DETECT)) {
577 xhci_warn(xhci, "Cannot set link state.\n");
578 goto error;
579 }
580
581 if (link_state == USB_SS_PORT_LS_U3) {
582 slot_id = xhci_find_slot_id_by_port(hcd, xhci,
583 wIndex + 1);
584 if (slot_id) {
585 /* unlock to execute stop endpoint
586 * commands */
587 spin_unlock_irqrestore(&xhci->lock,
588 flags);
589 xhci_stop_device(xhci, slot_id, 1);
590 spin_lock_irqsave(&xhci->lock, flags);
591 }
592 }
593
594 temp = xhci_port_state_to_neutral(temp);
595 temp &= ~PORT_PLS_MASK;
596 temp |= PORT_LINK_STROBE | link_state;
597 xhci_writel(xhci, temp, port_array[wIndex]);
598
599 spin_unlock_irqrestore(&xhci->lock, flags);
600 msleep(20); /* wait device to enter */
601 spin_lock_irqsave(&xhci->lock, flags);
602
603 temp = xhci_readl(xhci, port_array[wIndex]);
604 if (link_state == USB_SS_PORT_LS_U3)
605 bus_state->suspended_ports |= 1 << wIndex;
606 break;
540 case USB_PORT_FEAT_POWER: 607 case USB_PORT_FEAT_POWER:
541 /* 608 /*
542 * Turn on ports, even if there isn't per-port switching. 609 * Turn on ports, even if there isn't per-port switching.
@@ -557,6 +624,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
557 temp = xhci_readl(xhci, port_array[wIndex]); 624 temp = xhci_readl(xhci, port_array[wIndex]);
558 xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp); 625 xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp);
559 break; 626 break;
627 case USB_PORT_FEAT_BH_PORT_RESET:
628 temp |= PORT_WR;
629 xhci_writel(xhci, temp, port_array[wIndex]);
630
631 temp = xhci_readl(xhci, port_array[wIndex]);
632 break;
560 default: 633 default:
561 goto error; 634 goto error;
562 } 635 }
@@ -584,35 +657,27 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
584 if (temp & XDEV_U3) { 657 if (temp & XDEV_U3) {
585 if ((temp & PORT_PE) == 0) 658 if ((temp & PORT_PE) == 0)
586 goto error; 659 goto error;
587 if (DEV_SUPERSPEED(temp)) {
588 temp = xhci_port_state_to_neutral(temp);
589 temp &= ~PORT_PLS_MASK;
590 temp |= PORT_LINK_STROBE | XDEV_U0;
591 xhci_writel(xhci, temp,
592 port_array[wIndex]);
593 xhci_readl(xhci, port_array[wIndex]);
594 } else {
595 temp = xhci_port_state_to_neutral(temp);
596 temp &= ~PORT_PLS_MASK;
597 temp |= PORT_LINK_STROBE | XDEV_RESUME;
598 xhci_writel(xhci, temp,
599 port_array[wIndex]);
600 660
601 spin_unlock_irqrestore(&xhci->lock, 661 temp = xhci_port_state_to_neutral(temp);
602 flags); 662 temp &= ~PORT_PLS_MASK;
603 msleep(20); 663 temp |= PORT_LINK_STROBE | XDEV_RESUME;
604 spin_lock_irqsave(&xhci->lock, flags); 664 xhci_writel(xhci, temp,
665 port_array[wIndex]);
605 666
606 temp = xhci_readl(xhci, 667 spin_unlock_irqrestore(&xhci->lock,
607 port_array[wIndex]); 668 flags);
608 temp = xhci_port_state_to_neutral(temp); 669 msleep(20);
609 temp &= ~PORT_PLS_MASK; 670 spin_lock_irqsave(&xhci->lock, flags);
610 temp |= PORT_LINK_STROBE | XDEV_U0; 671
611 xhci_writel(xhci, temp, 672 temp = xhci_readl(xhci,
612 port_array[wIndex]); 673 port_array[wIndex]);
613 } 674 temp = xhci_port_state_to_neutral(temp);
614 bus_state->port_c_suspend |= 1 << wIndex; 675 temp &= ~PORT_PLS_MASK;
676 temp |= PORT_LINK_STROBE | XDEV_U0;
677 xhci_writel(xhci, temp,
678 port_array[wIndex]);
615 } 679 }
680 bus_state->port_c_suspend |= 1 << wIndex;
616 681
617 slot_id = xhci_find_slot_id_by_port(hcd, xhci, 682 slot_id = xhci_find_slot_id_by_port(hcd, xhci,
618 wIndex + 1); 683 wIndex + 1);
@@ -625,9 +690,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
625 case USB_PORT_FEAT_C_SUSPEND: 690 case USB_PORT_FEAT_C_SUSPEND:
626 bus_state->port_c_suspend &= ~(1 << wIndex); 691 bus_state->port_c_suspend &= ~(1 << wIndex);
627 case USB_PORT_FEAT_C_RESET: 692 case USB_PORT_FEAT_C_RESET:
693 case USB_PORT_FEAT_C_BH_PORT_RESET:
628 case USB_PORT_FEAT_C_CONNECTION: 694 case USB_PORT_FEAT_C_CONNECTION:
629 case USB_PORT_FEAT_C_OVER_CURRENT: 695 case USB_PORT_FEAT_C_OVER_CURRENT:
630 case USB_PORT_FEAT_C_ENABLE: 696 case USB_PORT_FEAT_C_ENABLE:
697 case USB_PORT_FEAT_C_PORT_LINK_STATE:
631 xhci_clear_port_change_bit(xhci, wValue, wIndex, 698 xhci_clear_port_change_bit(xhci, wValue, wIndex,
632 port_array[wIndex], temp); 699 port_array[wIndex], temp);
633 break; 700 break;
@@ -664,7 +731,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
664 int i, retval; 731 int i, retval;
665 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 732 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
666 int ports; 733 int ports;
667 u32 __iomem **port_array; 734 __le32 __iomem **port_array;
668 struct xhci_bus_state *bus_state; 735 struct xhci_bus_state *bus_state;
669 736
670 if (hcd->speed == HCD_USB3) { 737 if (hcd->speed == HCD_USB3) {
@@ -681,7 +748,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
681 memset(buf, 0, retval); 748 memset(buf, 0, retval);
682 status = 0; 749 status = 0;
683 750
684 mask = PORT_CSC | PORT_PEC | PORT_OCC; 751 mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC;
685 752
686 spin_lock_irqsave(&xhci->lock, flags); 753 spin_lock_irqsave(&xhci->lock, flags);
687 /* For each port, did anything change? If so, set that bit in buf. */ 754 /* For each port, did anything change? If so, set that bit in buf. */
@@ -709,7 +776,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
709{ 776{
710 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 777 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
711 int max_ports, port_index; 778 int max_ports, port_index;
712 u32 __iomem **port_array; 779 __le32 __iomem **port_array;
713 struct xhci_bus_state *bus_state; 780 struct xhci_bus_state *bus_state;
714 unsigned long flags; 781 unsigned long flags;
715 782
@@ -779,7 +846,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
779 846
780 if (DEV_HIGHSPEED(t1)) { 847 if (DEV_HIGHSPEED(t1)) {
781 /* enable remote wake up for USB 2.0 */ 848 /* enable remote wake up for USB 2.0 */
782 u32 __iomem *addr; 849 __le32 __iomem *addr;
783 u32 tmp; 850 u32 tmp;
784 851
785 /* Add one to the port status register address to get 852 /* Add one to the port status register address to get
@@ -801,7 +868,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
801{ 868{
802 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 869 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
803 int max_ports, port_index; 870 int max_ports, port_index;
804 u32 __iomem **port_array; 871 __le32 __iomem **port_array;
805 struct xhci_bus_state *bus_state; 872 struct xhci_bus_state *bus_state;
806 u32 temp; 873 u32 temp;
807 unsigned long flags; 874 unsigned long flags;
@@ -875,7 +942,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
875 942
876 if (DEV_HIGHSPEED(temp)) { 943 if (DEV_HIGHSPEED(temp)) {
877 /* disable remote wake up for USB 2.0 */ 944 /* disable remote wake up for USB 2.0 */
878 u32 __iomem *addr; 945 __le32 __iomem *addr;
879 u32 tmp; 946 u32 tmp;
880 947
881 /* Add one to the port status register address to get 948 /* Add one to the port status register address to get