diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-04-05 16:06:53 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-05-23 02:45:48 -0400 |
commit | 4fe5354f61cad4c0550285283c83c66c070c198e (patch) | |
tree | c8e3cfb80587124c6753e0ad7e64b84bf6834c9d /drivers/usb | |
parent | 36433127ae7a842482ba857f5ad3c431817a9542 (diff) |
EHCI: fix problem with BIOS handoff
This patch (as882) fixes a problem with the EHCI BIOS handoff. On my
machine, the BIOS configures the controller and the handoff fails,
leaving the controller configured. During resume-from-disk, this
confuses ehci-hcd into thinking that the controller has not been
tampered with.
The problem is fixed by turning off the Configured Flag whenever a
BIOS handoff is attempted, whether it succeeds or not.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/pci-quirks.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 20861650905e..c225159ca3d3 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #define EHCI_USBSTS 4 /* status register */ | 44 | #define EHCI_USBSTS 4 /* status register */ |
45 | #define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ | 45 | #define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ |
46 | #define EHCI_USBINTR 8 /* interrupt register */ | 46 | #define EHCI_USBINTR 8 /* interrupt register */ |
47 | #define EHCI_CONFIGFLAG 0x40 /* configured flag register */ | ||
47 | #define EHCI_USBLEGSUP 0 /* legacy support register */ | 48 | #define EHCI_USBLEGSUP 0 /* legacy support register */ |
48 | #define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ | 49 | #define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ |
49 | #define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ | 50 | #define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ |
@@ -216,6 +217,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
216 | u32 hcc_params, val; | 217 | u32 hcc_params, val; |
217 | u8 offset, cap_length; | 218 | u8 offset, cap_length; |
218 | int count = 256/4; | 219 | int count = 256/4; |
220 | int tried_handoff = 0; | ||
219 | 221 | ||
220 | if (!mmio_resource_enabled(pdev, 0)) | 222 | if (!mmio_resource_enabled(pdev, 0)) |
221 | return; | 223 | return; |
@@ -273,6 +275,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
273 | */ | 275 | */ |
274 | msec = 5000; | 276 | msec = 5000; |
275 | while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) { | 277 | while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) { |
278 | tried_handoff = 1; | ||
276 | msleep(10); | 279 | msleep(10); |
277 | msec -= 10; | 280 | msec -= 10; |
278 | pci_read_config_dword(pdev, offset, &cap); | 281 | pci_read_config_dword(pdev, offset, &cap); |
@@ -292,6 +295,12 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
292 | pci_write_config_dword(pdev, | 295 | pci_write_config_dword(pdev, |
293 | offset + EHCI_USBLEGCTLSTS, | 296 | offset + EHCI_USBLEGCTLSTS, |
294 | 0); | 297 | 0); |
298 | |||
299 | /* If the BIOS ever owned the controller then we | ||
300 | * can't expect any power sessions to remain intact. | ||
301 | */ | ||
302 | if (tried_handoff) | ||
303 | writel(0, op_reg_base + EHCI_CONFIGFLAG); | ||
295 | break; | 304 | break; |
296 | case 0: /* illegal reserved capability */ | 305 | case 0: /* illegal reserved capability */ |
297 | cap = 0; | 306 | cap = 0; |