[PATCH 02/10] usb/xhci: set root hub's DeviceRemovable according to usb port connect type

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch is to set xhci root hub's DeviceRemovable according to usb port's
connect type which currently comes from ACPI information rather than xhci PORTSC
register due to Windows prefers to ACPI information. If ACPI information was
different with PORTSC, there would be a warning.

Signed-off-by: Lan Tianyu <tianyu.lan@xxxxxxxxx>
---
 drivers/usb/host/xhci-hub.c |   24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index a686cf4..36c07aa 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -93,15 +93,25 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
 	 */
 	memset(port_removable, 0, sizeof(port_removable));
 	for (i = 0; i < ports; i++) {
+		struct usb_device *hdev = hcd->self.root_hub;
+		enum usb_port_connect_type connect_type
+			= usb_get_hub_port_connect_type(hdev, i + 1);
+
 		portsc = xhci_readl(xhci, xhci->usb2_ports[i]);
+
 		/* If a device is removable, PORTSC reports a 0, same as in the
 		 * hub descriptor DeviceRemovable bits.
 		 */
-		if (portsc & PORT_DEV_REMOVE)
+		if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
+			if (!(portsc & PORT_DEV_REMOVE))
+				xhci_warn(xhci, "usb2.0 port%d's connect type from ACPI is different with PORTSC register. ACPI returns hard-wired.\n",
+					i + 1);
+
 			/* This math is hairy because bit 0 of DeviceRemovable
 			 * is reserved, and bit 1 is for port 1, etc.
 			 */
 			port_removable[(i + 1) / 8] |= 1 << ((i + 1) % 8);
+		}
 	}
 
 	/* ch11.h defines a hub descriptor that has room for USB_MAXCHILDREN
@@ -147,9 +157,19 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
 	port_removable = 0;
 	/* bit 0 is reserved, bit 1 is for port 1, etc. */
 	for (i = 0; i < ports; i++) {
+		struct usb_device *hdev = hcd->self.root_hub;
+		enum usb_port_connect_type connect_type
+			= usb_get_hub_port_connect_type(hdev, i + 1);
+
 		portsc = xhci_readl(xhci, xhci->usb3_ports[i]);
-		if (portsc & PORT_DEV_REMOVE)
+
+		if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
+			if (!(portsc & PORT_DEV_REMOVE))
+				xhci_warn(xhci, "usb3.0 port%d's connect type from ACPI is different with PORTSC register. ACPI returns hard-wired.\n",
+					i + 1);
+
 			port_removable |= 1 << (i + 1);
+		}
 	}
 
 	desc->u.ss.DeviceRemovable = cpu_to_le16(port_removable);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux