diff options
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 101 |
1 files changed, 74 insertions, 27 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index ef09f5f2fe6c..2bbf5221afb3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -171,9 +171,10 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
171 | struct resource *res, unsigned int pos) | 171 | struct resource *res, unsigned int pos) |
172 | { | 172 | { |
173 | u32 l, sz, mask; | 173 | u32 l, sz, mask; |
174 | u64 l64, sz64, mask64; | ||
174 | u16 orig_cmd; | 175 | u16 orig_cmd; |
175 | struct pci_bus_region region, inverted_region; | 176 | struct pci_bus_region region, inverted_region; |
176 | bool bar_too_big = false, bar_disabled = false; | 177 | bool bar_too_big = false, bar_too_high = false, bar_invalid = false; |
177 | 178 | ||
178 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; | 179 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; |
179 | 180 | ||
@@ -226,9 +227,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
226 | } | 227 | } |
227 | 228 | ||
228 | if (res->flags & IORESOURCE_MEM_64) { | 229 | if (res->flags & IORESOURCE_MEM_64) { |
229 | u64 l64 = l; | 230 | l64 = l; |
230 | u64 sz64 = sz; | 231 | sz64 = sz; |
231 | u64 mask64 = mask | (u64)~0 << 32; | 232 | mask64 = mask | (u64)~0 << 32; |
232 | 233 | ||
233 | pci_read_config_dword(dev, pos + 4, &l); | 234 | pci_read_config_dword(dev, pos + 4, &l); |
234 | pci_write_config_dword(dev, pos + 4, ~0); | 235 | pci_write_config_dword(dev, pos + 4, ~0); |
@@ -243,19 +244,22 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
243 | if (!sz64) | 244 | if (!sz64) |
244 | goto fail; | 245 | goto fail; |
245 | 246 | ||
246 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { | 247 | if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) && |
248 | sz64 > 0x100000000ULL) { | ||
249 | res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; | ||
250 | res->start = 0; | ||
251 | res->end = 0; | ||
247 | bar_too_big = true; | 252 | bar_too_big = true; |
248 | goto fail; | 253 | goto out; |
249 | } | 254 | } |
250 | 255 | ||
251 | if ((sizeof(resource_size_t) < 8) && l) { | 256 | if ((sizeof(dma_addr_t) < 8) && l) { |
252 | /* Address above 32-bit boundary; disable the BAR */ | 257 | /* Above 32-bit boundary; try to reallocate */ |
253 | pci_write_config_dword(dev, pos, 0); | ||
254 | pci_write_config_dword(dev, pos + 4, 0); | ||
255 | res->flags |= IORESOURCE_UNSET; | 258 | res->flags |= IORESOURCE_UNSET; |
256 | region.start = 0; | 259 | res->start = 0; |
257 | region.end = sz64; | 260 | res->end = sz64; |
258 | bar_disabled = true; | 261 | bar_too_high = true; |
262 | goto out; | ||
259 | } else { | 263 | } else { |
260 | region.start = l64; | 264 | region.start = l64; |
261 | region.end = l64 + sz64; | 265 | region.end = l64 + sz64; |
@@ -285,11 +289,10 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
285 | * be claimed by the device. | 289 | * be claimed by the device. |
286 | */ | 290 | */ |
287 | if (inverted_region.start != region.start) { | 291 | if (inverted_region.start != region.start) { |
288 | dev_info(&dev->dev, "reg 0x%x: initial BAR value %pa invalid; forcing reassignment\n", | ||
289 | pos, ®ion.start); | ||
290 | res->flags |= IORESOURCE_UNSET; | 292 | res->flags |= IORESOURCE_UNSET; |
291 | res->end -= res->start; | ||
292 | res->start = 0; | 293 | res->start = 0; |
294 | res->end = region.end - region.start; | ||
295 | bar_invalid = true; | ||
293 | } | 296 | } |
294 | 297 | ||
295 | goto out; | 298 | goto out; |
@@ -303,8 +306,15 @@ out: | |||
303 | pci_write_config_word(dev, PCI_COMMAND, orig_cmd); | 306 | pci_write_config_word(dev, PCI_COMMAND, orig_cmd); |
304 | 307 | ||
305 | if (bar_too_big) | 308 | if (bar_too_big) |
306 | dev_err(&dev->dev, "reg 0x%x: can't handle 64-bit BAR\n", pos); | 309 | dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n", |
307 | if (res->flags && !bar_disabled) | 310 | pos, (unsigned long long) sz64); |
311 | if (bar_too_high) | ||
312 | dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4G (bus address %#010llx)\n", | ||
313 | pos, (unsigned long long) l64); | ||
314 | if (bar_invalid) | ||
315 | dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n", | ||
316 | pos, (unsigned long long) region.start); | ||
317 | if (res->flags) | ||
308 | dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res); | 318 | dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res); |
309 | 319 | ||
310 | return (res->flags & IORESOURCE_MEM_64) ? 1 : 0; | 320 | return (res->flags & IORESOURCE_MEM_64) ? 1 : 0; |
@@ -465,7 +475,7 @@ void pci_read_bridge_bases(struct pci_bus *child) | |||
465 | 475 | ||
466 | if (dev->transparent) { | 476 | if (dev->transparent) { |
467 | pci_bus_for_each_resource(child->parent, res, i) { | 477 | pci_bus_for_each_resource(child->parent, res, i) { |
468 | if (res) { | 478 | if (res && res->flags) { |
469 | pci_bus_add_resource(child, res, | 479 | pci_bus_add_resource(child, res, |
470 | PCI_SUBTRACTIVE_DECODE); | 480 | PCI_SUBTRACTIVE_DECODE); |
471 | dev_printk(KERN_DEBUG, &dev->dev, | 481 | dev_printk(KERN_DEBUG, &dev->dev, |
@@ -719,7 +729,7 @@ add_dev: | |||
719 | return child; | 729 | return child; |
720 | } | 730 | } |
721 | 731 | ||
722 | struct pci_bus *__ref pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) | 732 | struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) |
723 | { | 733 | { |
724 | struct pci_bus *child; | 734 | struct pci_bus *child; |
725 | 735 | ||
@@ -984,6 +994,43 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev) | |||
984 | 994 | ||
985 | 995 | ||
986 | /** | 996 | /** |
997 | * pci_ext_cfg_is_aliased - is ext config space just an alias of std config? | ||
998 | * @dev: PCI device | ||
999 | * | ||
1000 | * PCI Express to PCI/PCI-X Bridge Specification, rev 1.0, 4.1.4 says that | ||
1001 | * when forwarding a type1 configuration request the bridge must check that | ||
1002 | * the extended register address field is zero. The bridge is not permitted | ||
1003 | * to forward the transactions and must handle it as an Unsupported Request. | ||
1004 | * Some bridges do not follow this rule and simply drop the extended register | ||
1005 | * bits, resulting in the standard config space being aliased, every 256 | ||
1006 | * bytes across the entire configuration space. Test for this condition by | ||
1007 | * comparing the first dword of each potential alias to the vendor/device ID. | ||
1008 | * Known offenders: | ||
1009 | * ASM1083/1085 PCIe-to-PCI Reversible Bridge (1b21:1080, rev 01 & 03) | ||
1010 | * AMD/ATI SBx00 PCI to PCI Bridge (1002:4384, rev 40) | ||
1011 | */ | ||
1012 | static bool pci_ext_cfg_is_aliased(struct pci_dev *dev) | ||
1013 | { | ||
1014 | #ifdef CONFIG_PCI_QUIRKS | ||
1015 | int pos; | ||
1016 | u32 header, tmp; | ||
1017 | |||
1018 | pci_read_config_dword(dev, PCI_VENDOR_ID, &header); | ||
1019 | |||
1020 | for (pos = PCI_CFG_SPACE_SIZE; | ||
1021 | pos < PCI_CFG_SPACE_EXP_SIZE; pos += PCI_CFG_SPACE_SIZE) { | ||
1022 | if (pci_read_config_dword(dev, pos, &tmp) != PCIBIOS_SUCCESSFUL | ||
1023 | || header != tmp) | ||
1024 | return false; | ||
1025 | } | ||
1026 | |||
1027 | return true; | ||
1028 | #else | ||
1029 | return false; | ||
1030 | #endif | ||
1031 | } | ||
1032 | |||
1033 | /** | ||
987 | * pci_cfg_space_size - get the configuration space size of the PCI device. | 1034 | * pci_cfg_space_size - get the configuration space size of the PCI device. |
988 | * @dev: PCI device | 1035 | * @dev: PCI device |
989 | * | 1036 | * |
@@ -1001,7 +1048,7 @@ static int pci_cfg_space_size_ext(struct pci_dev *dev) | |||
1001 | 1048 | ||
1002 | if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL) | 1049 | if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL) |
1003 | goto fail; | 1050 | goto fail; |
1004 | if (status == 0xffffffff) | 1051 | if (status == 0xffffffff || pci_ext_cfg_is_aliased(dev)) |
1005 | goto fail; | 1052 | goto fail; |
1006 | 1053 | ||
1007 | return PCI_CFG_SPACE_EXP_SIZE; | 1054 | return PCI_CFG_SPACE_EXP_SIZE; |
@@ -1215,6 +1262,7 @@ static void pci_release_dev(struct device *dev) | |||
1215 | pci_release_of_node(pci_dev); | 1262 | pci_release_of_node(pci_dev); |
1216 | pcibios_release_device(pci_dev); | 1263 | pcibios_release_device(pci_dev); |
1217 | pci_bus_put(pci_dev->bus); | 1264 | pci_bus_put(pci_dev->bus); |
1265 | kfree(pci_dev->driver_override); | ||
1218 | kfree(pci_dev); | 1266 | kfree(pci_dev); |
1219 | } | 1267 | } |
1220 | 1268 | ||
@@ -1369,7 +1417,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | |||
1369 | WARN_ON(ret < 0); | 1417 | WARN_ON(ret < 0); |
1370 | } | 1418 | } |
1371 | 1419 | ||
1372 | struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) | 1420 | struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn) |
1373 | { | 1421 | { |
1374 | struct pci_dev *dev; | 1422 | struct pci_dev *dev; |
1375 | 1423 | ||
@@ -1617,7 +1665,7 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data) | |||
1617 | */ | 1665 | */ |
1618 | void pcie_bus_configure_settings(struct pci_bus *bus) | 1666 | void pcie_bus_configure_settings(struct pci_bus *bus) |
1619 | { | 1667 | { |
1620 | u8 smpss; | 1668 | u8 smpss = 0; |
1621 | 1669 | ||
1622 | if (!bus->self) | 1670 | if (!bus->self) |
1623 | return; | 1671 | return; |
@@ -1670,8 +1718,7 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) | |||
1670 | 1718 | ||
1671 | for (pass=0; pass < 2; pass++) | 1719 | for (pass=0; pass < 2; pass++) |
1672 | list_for_each_entry(dev, &bus->devices, bus_list) { | 1720 | list_for_each_entry(dev, &bus->devices, bus_list) { |
1673 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | 1721 | if (pci_is_bridge(dev)) |
1674 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | ||
1675 | max = pci_scan_bridge(bus, dev, max, pass); | 1722 | max = pci_scan_bridge(bus, dev, max, pass); |
1676 | } | 1723 | } |
1677 | 1724 | ||
@@ -1958,7 +2005,7 @@ EXPORT_SYMBOL(pci_scan_bus); | |||
1958 | * | 2005 | * |
1959 | * Returns the max number of subordinate bus discovered. | 2006 | * Returns the max number of subordinate bus discovered. |
1960 | */ | 2007 | */ |
1961 | unsigned int __ref pci_rescan_bus_bridge_resize(struct pci_dev *bridge) | 2008 | unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge) |
1962 | { | 2009 | { |
1963 | unsigned int max; | 2010 | unsigned int max; |
1964 | struct pci_bus *bus = bridge->subordinate; | 2011 | struct pci_bus *bus = bridge->subordinate; |
@@ -1981,7 +2028,7 @@ unsigned int __ref pci_rescan_bus_bridge_resize(struct pci_dev *bridge) | |||
1981 | * | 2028 | * |
1982 | * Returns the max number of subordinate bus discovered. | 2029 | * Returns the max number of subordinate bus discovered. |
1983 | */ | 2030 | */ |
1984 | unsigned int __ref pci_rescan_bus(struct pci_bus *bus) | 2031 | unsigned int pci_rescan_bus(struct pci_bus *bus) |
1985 | { | 2032 | { |
1986 | unsigned int max; | 2033 | unsigned int max; |
1987 | 2034 | ||