From david-b@pacbell.net Fri Sep 23 00:30:27 2005 From: David Brownell Subject: [patch 8/12] update PCI early-handoff handling for OHCI Date: Thu, 22 Sep 2005 22:43:30 -0700 Cc: Greg KH Message-Id: <200509222243.30435.david-b@pacbell.net> From: David Brownell The PCI "early usb handoff" quirk logic didn't work like "ohci-hcd" ... This patch makes it do so by: - Resetting the controller after kicking BIOS off, matching the normal "chip in hardware reset" startup mode; - Reporting any BIOS that borks this simple handoff; it's likely got a few other surprises for us too. - Ignoring that handoff on HPPA; The diagnostic string is mostly shared with EHCI, saving a few bytes. Signed-off-by: Greg Kroah-Hartman drivers/usb/host/pci-quirks.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) --- --- gregkh-2.6.orig/drivers/usb/host/pci-quirks.c +++ gregkh-2.6/drivers/usb/host/pci-quirks.c @@ -60,6 +60,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I #define OHCI_INTRENABLE 0x10 #define OHCI_INTRDISABLE 0x14 #define OHCI_OCR (1 << 3) /* ownership change request */ +#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ #define OHCI_INTR_OC (1 << 30) /* ownership change */ @@ -140,13 +141,17 @@ static void __devinit quirk_usb_handoff_ { void __iomem *base; int wait_time; + u32 control; base = ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if (base == NULL) return; - if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { - wait_time = 500; /* 0.5 seconds */ +/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ +#ifndef __hppa__ + control = readl(base + OHCI_CONTROL); + if (control & OHCI_CTRL_IR) { + wait_time = 500; /* arbitrary; 5 seconds */ writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); writel(OHCI_OCR, base + OHCI_CMDSTATUS); while (wait_time > 0 && @@ -154,7 +159,15 @@ static void __devinit quirk_usb_handoff_ wait_time -= 10; msleep(10); } + if (wait_time <= 0) + printk(KERN_WARNING "%s %s: early BIOS handoff " + "failed (BIOS bug ?)\n", + pdev->dev.bus_id, "OHCI"); + + /* reset controller, preserving RWC */ + writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL); } +#endif /* * disable interrupts @@ -211,8 +224,9 @@ static void __devinit quirk_usb_disable_ /* * well, possibly buggy BIOS... */ - printk(KERN_WARNING "EHCI early BIOS handoff " - "failed (BIOS bug ?)\n"); + printk(KERN_WARNING "%s %s: early BIOS handoff " + "failed (BIOS bug ?)\n", + pdev->dev.bus_id, "EHCI"); pci_write_config_dword(pdev, hcc_params + EHCI_USBLEGSUP, EHCI_USBLEGSUP_OS);