Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

xhci: move usb2 speficic bits to own function in get_port_status call

Mostly refactoring, with the exception that USB_PORT_STAT_L1 link state
is reported if xhci port link is in U2 AND port is powered.

Previously we did not check if the port was powered, but according to
xhci spec 4.19.1.1.6 All the 'Enabled' states, including
USB_PORT_STAT_L1 (U2), U1, U0 and U3 must have Port power bit set.

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Mathias Nyman and committed by
Greg Kroah-Hartman
70e9b53d 5f78a54f

+24 -20
+24 -20
drivers/usb/host/xhci-hub.c
··· 714 714 } 715 715 } 716 716 717 - /* Updates Link Status for USB 2.1 port */ 718 - static void xhci_hub_report_usb2_link_state(u32 *status, u32 status_reg) 719 - { 720 - if ((status_reg & PORT_PLS_MASK) == XDEV_U2) 721 - *status |= USB_PORT_STAT_L1; 722 - } 723 - 724 717 /* Updates Link Status for super Speed port */ 725 718 static void xhci_hub_report_usb3_link_state(struct xhci_hcd *xhci, 726 719 u32 *status, u32 status_reg) ··· 846 853 xhci_del_comp_mod_timer(xhci, portsc, portnum); 847 854 } 848 855 856 + static void xhci_get_usb2_port_status(struct xhci_port *port, u32 *status, 857 + u32 portsc) 858 + { 859 + u32 link_state; 860 + 861 + link_state = portsc & PORT_PLS_MASK; 862 + 863 + /* USB2 wPortStatus bits */ 864 + if (portsc & PORT_POWER) { 865 + *status |= USB_PORT_STAT_POWER; 866 + 867 + /* link state is only valid if port is powered */ 868 + if (link_state == XDEV_U3) 869 + *status |= USB_PORT_STAT_SUSPEND; 870 + if (link_state == XDEV_U2) 871 + *status |= USB_PORT_STAT_L1; 872 + } 873 + } 874 + 849 875 /* 850 876 * Converts a raw xHCI port status into the format that external USB 2.0 or USB 851 877 * 3.0 hubs use. ··· 900 888 status |= USB_PORT_STAT_C_OVERCURRENT << 16; 901 889 if ((raw_port_status & PORT_RC)) 902 890 status |= USB_PORT_STAT_C_RESET << 16; 903 - /* USB3.0 only */ 891 + 892 + /* USB2 and USB3 specific bits including Port Link State */ 904 893 if (hcd->speed >= HCD_USB3) 905 894 xhci_get_usb3_port_status(port, &status, raw_port_status); 906 - if (hcd->speed < HCD_USB3) { 907 - if ((raw_port_status & PORT_PLS_MASK) == XDEV_U3 908 - && (raw_port_status & PORT_POWER)) 909 - status |= USB_PORT_STAT_SUSPEND; 910 - } 895 + else 896 + xhci_get_usb2_port_status(port, &status, raw_port_status); 897 + 911 898 if ((raw_port_status & PORT_PLS_MASK) == XDEV_RESUME && 912 899 !DEV_SUPERSPEED_ANY(raw_port_status) && hcd->speed < HCD_USB3) { 913 900 if ((raw_port_status & PORT_RESET) || ··· 1020 1009 status |= USB_PORT_STAT_OVERCURRENT; 1021 1010 if (raw_port_status & PORT_RESET) 1022 1011 status |= USB_PORT_STAT_RESET; 1023 - if (raw_port_status & PORT_POWER) { 1024 - if (hcd->speed < HCD_USB3) 1025 - status |= USB_PORT_STAT_POWER; 1026 - } 1027 - /* Update Port Link State */ 1028 - if (hcd->speed < HCD_USB3) 1029 - xhci_hub_report_usb2_link_state(&status, raw_port_status); 1030 1012 1031 1013 if (bus_state->port_c_suspend & (1 << wIndex)) 1032 1014 status |= USB_PORT_STAT_C_SUSPEND << 16;