X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fusb%2Fhost%2Fuhci-hub.c;h=f8347f1a10b6633303e333233e59ef8df5dd5d51;hb=a57bf8a4f23cca2b5be5446649bbe22d1440af5d;hp=c8451d9578f16ebd96df6501f058efbca031f24a;hpb=3145012c1c34a3504a2234bd2034ca6ea4767bc5;p=powerpc.git diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index c8451d9578..f8347f1a10 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -84,6 +84,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, unsigned long port_addr) { int status; + int i; if (inw(port_addr) & (USBPORTSC_SUSP | USBPORTSC_RD)) { CLR_RH_PORTSTAT(USBPORTSC_SUSP | USBPORTSC_RD); @@ -92,9 +93,14 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, /* The controller won't actually turn off the RD bit until * it has had a chance to send a low-speed EOP sequence, - * which takes 3 bit times (= 2 microseconds). We'll delay - * slightly longer for good luck. */ - udelay(4); + * which is supposed to take 3 bit times (= 2 microseconds). + * Experiments show that some controllers take longer, so + * we'll poll for completion. */ + for (i = 0; i < 10; ++i) { + if (!(inw(port_addr) & USBPORTSC_RD)) + break; + udelay(1); + } } clear_bit(port, &uhci->resuming_ports); } @@ -170,10 +176,9 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) spin_lock_irqsave(&uhci->lock, flags); - uhci_scan_schedule(uhci, NULL); - if (uhci->hc_inaccessible) + uhci_scan_schedule(uhci); + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead) goto done; - check_fsbr(uhci); uhci_check_ports(uhci); status = get_hub_status_data(uhci, buf); @@ -228,7 +233,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wPortChange, wPortStatus; unsigned long flags; - if (uhci->hc_inaccessible) + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead) return -ETIMEDOUT; spin_lock_irqsave(&uhci->lock, flags);