Commit 541ab4af authored by Linus Torvalds's avatar Linus Torvalds

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: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1e4c85f9
...@@ -138,11 +138,23 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) ...@@ -138,11 +138,23 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
} }
EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); 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) static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
{ {
unsigned long base = 0; unsigned long base = 0;
int i; int i;
if (!pio_enabled(pdev))
return;
for (i = 0; i < PCI_ROM_RESOURCE; i++) for (i = 0; i < PCI_ROM_RESOURCE; i++)
if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
base = pci_resource_start(pdev, i); base = pci_resource_start(pdev, i);
...@@ -153,12 +165,20 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) ...@@ -153,12 +165,20 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
uhci_check_and_reset_hc(pdev, base); 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) static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
{ {
void __iomem *base; void __iomem *base;
int wait_time; int wait_time;
u32 control; u32 control;
if (!mmio_resource_enabled(pdev, 0))
return;
base = ioremap_nocache(pci_resource_start(pdev, 0), base = ioremap_nocache(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0)); pci_resource_len(pdev, 0));
if (base == NULL) return; if (base == NULL) return;
...@@ -201,6 +221,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) ...@@ -201,6 +221,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
u32 hcc_params, val, temp; u32 hcc_params, val, temp;
u8 cap_length; u8 cap_length;
if (!mmio_resource_enabled(pdev, 0))
return;
base = ioremap_nocache(pci_resource_start(pdev, 0), base = ioremap_nocache(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0)); pci_resource_len(pdev, 0));
if (base == NULL) return; if (base == NULL) return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment