From ac79dc9b4a929bd8c0d9e4a2fccd3b7215cbaee4 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 7 Mar 2013 16:24:19 -0800 Subject: USB: Don't use EHCI port sempahore for USB 3.0 hubs. [This is upstream commit 0fe51aa5eee51db7c7ecd201d42a977ad79c58b6. It needs to be backported to kernels as old as 3.2, because it fixes the buggy commit 9dbcaec830cd97f44a0b91b315844e0d7144746b "USB: Handle warm reset failure on empty port."] The EHCI host controller needs to prevent EHCI initialization when the UHCI or OHCI companion controller is in the middle of a port reset. It uses ehci_cf_port_reset_rwsem to do this. USB 3.0 hubs can't be under an EHCI host controller, so it makes no sense to down the semaphore for USB 3.0 hubs. It also makes the warm port reset code more complex. Don't down ehci_cf_port_reset_rwsem for USB 3.0 hubs. Signed-off-by: Sarah Sharp Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 67dda0dbf81b..6aceaec90530 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2330,17 +2330,16 @@ static int hub_port_reset(struct usb_hub *hub, int port1, { int i, status; - if (!warm) { - /* Block EHCI CF initialization during the port reset. - * Some companion controllers don't like it when they mix. - */ - down_read(&ehci_cf_port_reset_rwsem); - } else { - if (!hub_is_superspeed(hub->hdev)) { + if (!hub_is_superspeed(hub->hdev)) { + if (warm) { dev_err(hub->intfdev, "only USB3 hub support " "warm reset\n"); return -EINVAL; } + /* Block EHCI CF initialization during the port reset. + * Some companion controllers don't like it when they mix. + */ + down_read(&ehci_cf_port_reset_rwsem); } /* Reset the port */ @@ -2378,7 +2377,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, port1); done: - if (!warm) + if (!hub_is_superspeed(hub->hdev)) up_read(&ehci_cf_port_reset_rwsem); return status; -- cgit v1.2.3