summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-10-31 21:12:40 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-31 21:12:40 -0800
commit541ab4af11d5b41b95cd633e9b1d96cea9947ac2 (patch)
tree079228fafa21a7d2920525c9d1e4b5a3edbcf390 /drivers/usb
parent1e4c85f97fe26fbd70da12148b3992c0e00361fd (diff)
downloadlinux-3.10-541ab4af11d5b41b95cd633e9b1d96cea9947ac2.tar.gz
linux-3.10-541ab4af11d5b41b95cd633e9b1d96cea9947ac2.tar.bz2
linux-3.10-541ab4af11d5b41b95cd633e9b1d96cea9947ac2.zip
Don't touch USB controller IO registers when they are disabled
The USB "handoff" code is an early PCI quirk to make sure we own the USB controller (as opposed to the BIOS/SMM). But if the controller isn't even enabled yet, don't try to access it. Acked-by: Paul Mackerras <paulus@samba.org> (who had an alternate patch) Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/pci-quirks.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index b7fd3f644e1..b1aa350fd32 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -138,11 +138,23 @@ reset_needed:
}
EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
+static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
+{
+ u16 cmd;
+ return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
+}
+
+#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
+#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
+
static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
{
unsigned long base = 0;
int i;
+ if (!pio_enabled(pdev))
+ return;
+
for (i = 0; i < PCI_ROM_RESOURCE; i++)
if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
base = pci_resource_start(pdev, i);
@@ -153,12 +165,20 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
uhci_check_and_reset_hc(pdev, base);
}
+static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
+{
+ return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
+}
+
static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
{
void __iomem *base;
int wait_time;
u32 control;
+ if (!mmio_resource_enabled(pdev, 0))
+ return;
+
base = ioremap_nocache(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
if (base == NULL) return;
@@ -201,6 +221,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
u32 hcc_params, val, temp;
u8 cap_length;
+ if (!mmio_resource_enabled(pdev, 0))
+ return;
+
base = ioremap_nocache(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
if (base == NULL) return;