Raul Rangel has uploaded this change for review. ( https://review.coreboot.org/27477
Change subject: libpayload/generic_hub: Detect port disconnect after reset ......................................................................
libpayload/generic_hub: Detect port disconnect after reset
If a port disconnects after a reset we should abort any initialization on the port. At the same time this might mean the device has re-enumerated as a 3.0 device so we should rescan all the ports.
I decided to not add a return status enum since that would require a lot of changes. I opted to just return 2 as the magic reenum value.
BUG=b:76831439 TEST=Verified USB-C devices that get detected correctly in depthcharge.
Change-Id: Iad899544684312df1bef08d69b5c7f41eac3a21c Signed-off-by: Raul E Rangel rrangel@chromium.org --- M payloads/libpayload/drivers/usb/generic_hub.c 1 file changed, 26 insertions(+), 8 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/77/27477/1
diff --git a/payloads/libpayload/drivers/usb/generic_hub.c b/payloads/libpayload/drivers/usb/generic_hub.c index 89da934..a2aea7c 100644 --- a/payloads/libpayload/drivers/usb/generic_hub.c +++ b/payloads/libpayload/drivers/usb/generic_hub.c @@ -157,6 +157,15 @@ if (hub->ops->reset_port) { if (hub->ops->reset_port(dev, port) < 0) return -1; + + if (!hub->ops->port_connected(dev, port)) { + usb_debug( + "generic_hub: Port %d disconnected after " + "reset. Possibly upgraded, rescan required.\n", + port); + return 2; + } + /* after reset the port will be enabled automatically */ const int ret = generic_hub_wait_for_port( /* time out after 1,000 * 10us = 10ms */ @@ -214,15 +223,24 @@ hub->ops->hub_status_changed(dev) != 1) return;
- int port; - for (port = 1; port <= hub->num_ports; ++port) { - const int ret = hub->ops->port_status_changed(dev, port); - if (ret < 0) { - return; - } else if (ret == 1) { - usb_debug("generic_hub: Port change at %d\n", port); - if (generic_hub_scanport(dev, port) < 0) + int reenum_limit = 1; + for (int i = 0; i < reenum_limit && i < 2; ++i) { + for (int port = 1; port <= hub->num_ports; ++port) { + const int ret = + hub->ops->port_status_changed(dev, port); + if (ret < 0) { return; + } else if (ret == 1) { + usb_debug("generic_hub: Port change at %d\n", + port); + int rtn = generic_hub_scanport(dev, port); + if (rtn == 2) { + reenum_limit++; + continue; + } else if (rtn < 0) { + return; + } + } } } }