aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-04-05 16:06:53 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-05-23 02:45:48 -0400
commit4fe5354f61cad4c0550285283c83c66c070c198e (patch)
treec8e3cfb80587124c6753e0ad7e64b84bf6834c9d /drivers/usb
parent36433127ae7a842482ba857f5ad3c431817a9542 (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.c9
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;