aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/pci-quirks.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-11-01 00:12:40 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-01 00:12:40 -0500
commit541ab4af11d5b41b95cd633e9b1d96cea9947ac2 (patch)
tree079228fafa21a7d2920525c9d1e4b5a3edbcf390 /drivers/usb/host/pci-quirks.c
parent1e4c85f97fe26fbd70da12148b3992c0e00361fd (diff)
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/host/pci-quirks.c')
-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 b7fd3f644e1e..b1aa350fd32f 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -138,11 +138,23 @@ reset_needed:
138} 138}
139EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); 139EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
140 140
141static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
142{
143 u16 cmd;
144 return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
145}
146
147#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
148#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
149
141static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) 150static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
142{ 151{
143 unsigned long base = 0; 152 unsigned long base = 0;
144 int i; 153 int i;
145 154
155 if (!pio_enabled(pdev))
156 return;
157
146 for (i = 0; i < PCI_ROM_RESOURCE; i++) 158 for (i = 0; i < PCI_ROM_RESOURCE; i++)
147 if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { 159 if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
148 base = pci_resource_start(pdev, i); 160 base = pci_resource_start(pdev, i);
@@ -153,12 +165,20 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
153 uhci_check_and_reset_hc(pdev, base); 165 uhci_check_and_reset_hc(pdev, base);
154} 166}
155 167
168static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
169{
170 return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
171}
172
156static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) 173static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
157{ 174{
158 void __iomem *base; 175 void __iomem *base;
159 int wait_time; 176 int wait_time;
160 u32 control; 177 u32 control;
161 178
179 if (!mmio_resource_enabled(pdev, 0))
180 return;
181
162 base = ioremap_nocache(pci_resource_start(pdev, 0), 182 base = ioremap_nocache(pci_resource_start(pdev, 0),
163 pci_resource_len(pdev, 0)); 183 pci_resource_len(pdev, 0));
164 if (base == NULL) return; 184 if (base == NULL) return;
@@ -201,6 +221,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
201 u32 hcc_params, val, temp; 221 u32 hcc_params, val, temp;
202 u8 cap_length; 222 u8 cap_length;
203 223
224 if (!mmio_resource_enabled(pdev, 0))
225 return;
226
204 base = ioremap_nocache(pci_resource_start(pdev, 0), 227 base = ioremap_nocache(pci_resource_start(pdev, 0),
205 pci_resource_len(pdev, 0)); 228 pci_resource_len(pdev, 0));
206 if (base == NULL) return; 229 if (base == NULL) return;