[coreboot-gerrit] Change in coreboot[master]: libpayload/usb: Disable ports for unused devices

Patrick Rudolph (Code Review) gerrit at coreboot.org
Thu Feb 15 07:48:45 CET 2018


Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/23768


Change subject: libpayload/usb: Disable ports for unused devices
......................................................................

libpayload/usb: Disable ports for unused devices

USB devices that aren't controlled by libpayload due to missing
driver support do have an address assigned libpayload doesn't know
about. To avoid address conflicts disable the hub port if no driver
is loaded after probing the device.

Change-Id: I4882ba81cc0bed8dc0001f31142dc783e1f4259d
Signed-off-by: Patrick Rudolph <siro at das-labor.org>
---
M payloads/libpayload/drivers/usb/ehci_rh.c
M payloads/libpayload/drivers/usb/generic_hub.c
M payloads/libpayload/drivers/usb/ohci_rh.c
M payloads/libpayload/drivers/usb/uhci_rh.c
M payloads/libpayload/drivers/usb/usbhub.c
M payloads/libpayload/drivers/usb/xhci_rh.c
6 files changed, 57 insertions(+), 2 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/68/23768/1

diff --git a/payloads/libpayload/drivers/usb/ehci_rh.c b/payloads/libpayload/drivers/usb/ehci_rh.c
index da8d8af..4eb8dfd 100644
--- a/payloads/libpayload/drivers/usb/ehci_rh.c
+++ b/payloads/libpayload/drivers/usb/ehci_rh.c
@@ -149,6 +149,22 @@
 		RH_INST(dev)->devices[port] = usb_attach_device(dev->controller
 			, dev->address, port, port_speed);
 	}
+
+	if (RH_INST(dev)->devices[port] == -1) {
+		// Keep software and hardware state in sync.
+		// Disable port to make sure that the assigned address isn't
+		// valid any more.
+		// Deassert enable, assert reset. These must change atomically.
+		RH_INST(dev)->ports[port] =
+		    (RH_INST(dev)->ports[port] & ~P_PORT_ENABLE) | P_PORT_RESET;
+
+		/* Wait a bit while reset is active (+1 to avoid Tegra race). */
+		mdelay(50 + 1); // usb20 spec 7.1.7.5 (TDRSTR)
+
+		/* Deassert reset. */
+		RH_INST(dev)->ports[port] &= ~P_PORT_RESET;
+	}
+
 	/* RW/C register, so clear it by writing 1 */
 	RH_INST(dev)->ports[port] |= P_CONN_STATUS_CHANGE;
 }
diff --git a/payloads/libpayload/drivers/usb/generic_hub.c b/payloads/libpayload/drivers/usb/generic_hub.c
index 9f86705..ea2b71f 100644
--- a/payloads/libpayload/drivers/usb/generic_hub.c
+++ b/payloads/libpayload/drivers/usb/generic_hub.c
@@ -177,6 +177,15 @@
 		hub->ports[port] = usb_attach_device(
 				dev->controller, dev->address, port, speed);
 	}
+
+	if ((hub->ports[port] == -1) && hub->ops->disable_port) {
+		// Keep software and hardware state in sync.
+		// Disable port to make sure that the assigned address isn't
+		// valid any more.
+		if (hub->ops->disable_port(dev, port) < 0)
+			return -1;
+	}
+
 	return 0;
 }
 
diff --git a/payloads/libpayload/drivers/usb/ohci_rh.c b/payloads/libpayload/drivers/usb/ohci_rh.c
index 5d82bd5..770a563 100644
--- a/payloads/libpayload/drivers/usb/ohci_rh.c
+++ b/payloads/libpayload/drivers/usb/ohci_rh.c
@@ -128,6 +128,13 @@
 
 	usb_speed speed = (OHCI_INST(dev->controller)->opreg->HcRhPortStatus[port] & LowSpeedDeviceAttached) != 0;
 	RH_INST (dev)->port[port] = usb_attach_device(dev->controller, dev->address, port, speed);
+
+	if (RH_INST(dev)->port[port] == -1) {
+		// Keep software and hardware state in sync.
+		// Disable port to make sure that the assigned address isn't
+		// valid any more.
+		ohci_rh_disable_port(dev, port);
+	}
 }
 
 static int
diff --git a/payloads/libpayload/drivers/usb/uhci_rh.c b/payloads/libpayload/drivers/usb/uhci_rh.c
index e08cce1..742d491 100644
--- a/payloads/libpayload/drivers/usb/uhci_rh.c
+++ b/payloads/libpayload/drivers/usb/uhci_rh.c
@@ -137,6 +137,13 @@
 
 		RH_INST (dev)->port[offset] = usb_attach_device(dev->controller, dev->address, portsc, speed);
 	}
+
+	if (RH_INST(dev)->port[offset] == -1) {
+		// Keep software and hardware state in sync.
+		// Disable port to make sure that the assigned address isn't
+		// valid any more.
+		uhci_rh_disable_port(dev, port);
+	}
 }
 
 static int
diff --git a/payloads/libpayload/drivers/usb/usbhub.c b/payloads/libpayload/drivers/usb/usbhub.c
index 340e47a..18ed406 100644
--- a/payloads/libpayload/drivers/usb/usbhub.c
+++ b/payloads/libpayload/drivers/usb/usbhub.c
@@ -119,6 +119,12 @@
 }
 
 static int
+usb_hub_disable_port(usbdev_t *const dev, const int port)
+{
+	return clear_feature(dev, port, SEL_PORT_POWER, DR_PORT);
+}
+
+static int
 usb_hub_start_port_reset(usbdev_t *const dev, const int port)
 {
 	return set_feature (dev, port, SEL_PORT_RESET, DR_PORT);
@@ -153,7 +159,7 @@
 	.port_enabled		= usb_hub_port_enabled,
 	.port_speed		= usb_hub_port_speed,
 	.enable_port		= usb_hub_enable_port,
-	.disable_port		= NULL,
+	.disable_port		= usb_hub_disable_port,
 	.start_port_reset	= usb_hub_start_port_reset,
 	.reset_port		= generic_hub_resetport,
 };
diff --git a/payloads/libpayload/drivers/usb/xhci_rh.c b/payloads/libpayload/drivers/usb/xhci_rh.c
index d7ba82c..5650076 100644
--- a/payloads/libpayload/drivers/usb/xhci_rh.c
+++ b/payloads/libpayload/drivers/usb/xhci_rh.c
@@ -136,6 +136,16 @@
 	return 0;
 }
 
+static int
+xhci_rh_disable_port(usbdev_t *const dev, int port)
+{
+	xhci_t *const xhci = XHCI_INST(dev->controller);
+	volatile u32 *const portsc =
+		&xhci->opreg->prs[port - 1].portsc;
+
+	*portsc = ((*portsc & PORTSC_RW_MASK) | PORTSC_PED) & ~PORTSC_PP;
+	return 0;
+}
 
 static const generic_hub_ops_t xhci_rh_ops = {
 	.hub_status_changed	= xhci_rh_hub_status_changed,
@@ -145,7 +155,7 @@
 	.port_enabled		= xhci_rh_port_enabled,
 	.port_speed		= xhci_rh_port_speed,
 	.enable_port		= xhci_rh_enable_port,
-	.disable_port		= NULL,
+	.disable_port		= xhci_rh_disable_port,
 	.start_port_reset	= NULL,
 	.reset_port		= xhci_rh_reset_port,
 };

-- 
To view, visit https://review.coreboot.org/23768
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4882ba81cc0bed8dc0001f31142dc783e1f4259d
Gerrit-Change-Number: 23768
Gerrit-PatchSet: 1
Gerrit-Owner: Patrick Rudolph <siro at das-labor.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180215/4d4a64f2/attachment.html>


More information about the coreboot-gerrit mailing list