[linux-yocto] [PATCH 14/17] drivers/usb/core: fix over-current race condition
Daniel Dragomir
daniel.dragomir at windriver.com
Tue May 16 11:39:06 PDT 2017
From: Charlie Paul <cpaul.windriver at gmail.com>
There exists a race condition when an over-current fault is cleared,
between the event processing in the hub_event function and the setting
of the event bits in the hub_irq function. When the over-current is
cleared the hub_event call tries to read the event bits, which havent
been set by the hub_irq. In this patch when the over-current is
cleared the hub_event will check the event bits and if they are not
set it will pause and check again. It will sync the event bits.
Signed-off-by: Charlie Paul <cpaul.windriver at gmail.com>
---
drivers/usb/core/hub.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 35fb2bef..07da7ea 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -5019,8 +5019,8 @@ static void port_event(struct usb_hub *hub, int port1)
dev_dbg(&port_dev->dev, "over-current change\n");
usb_clear_port_feature(hdev, port1,
USB_PORT_FEAT_C_OVER_CURRENT);
- msleep(100); /* Cool down */
hub_power_on(hub, true);
+ msleep(100); /* Cool down */
hub_port_status(hub, port1, &status, &unused);
if (status & USB_PORT_STAT_OVERCURRENT)
dev_err(&port_dev->dev, "over-current condition\n");
@@ -5137,6 +5137,7 @@ static void hub_event(struct work_struct *work)
hub->error = 0;
}
+
/* deal with port status changes */
for (i = 1; i <= hdev->maxchild; i++) {
struct usb_port *port_dev = hub->ports[i - 1];
@@ -5159,7 +5160,9 @@ static void hub_event(struct work_struct *work)
port_event(hub, i);
usb_unlock_port(port_dev);
pm_runtime_put_sync(&port_dev->dev);
- }
+ } else
+ /* Wait for the hub_irq to finish then update the port status */
+ msleep(100);
}
/* deal with hub status changes */
--
2.7.4
More information about the linux-yocto
mailing list