diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-01 00:12:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-01 00:12:40 -0500 |
commit | 541ab4af11d5b41b95cd633e9b1d96cea9947ac2 (patch) | |
tree | 079228fafa21a7d2920525c9d1e4b5a3edbcf390 /drivers/usb/host/pci-quirks.c | |
parent | 1e4c85f97fe26fbd70da12148b3992c0e00361fd (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.c | 23 |
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 | } |
139 | EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); | 139 | EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); |
140 | 140 | ||
141 | static 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 | |||
141 | static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) | 150 | static 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 | ||
168 | static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx) | ||
169 | { | ||
170 | return pci_resource_start(pdev, idx) && mmio_enabled(pdev); | ||
171 | } | ||
172 | |||
156 | static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | 173 | static 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; |