aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/probe.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 23:58:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 23:58:52 -0500
commitc75059c46293adf1560162c17148ab94624f5ed2 (patch)
tree75847b97da3477ce5c7aa32d81d0861f992e61ce /drivers/pci/probe.c
parentf74ea36848ad49cb011aae55f56b0475702ffb79 (diff)
parent149792795d2bab33954bc025fcf145a8009683f6 (diff)
Merge tag 'pci-v3.19-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas: "Here are the PCI changes intended for v3.19. I don't think there's anything very exciting here, but there was a lot of MSI-related stuff coming via Thomas. Details: NUMA - Allow numa_node override via sysfs (Prarit Bhargava) Resource management - Restore detection of read-only BARs (Myron Stowe) - Shrink decoding-disabled window while sizing BARs (Myron Stowe) - Add informational printk for invalid BARs (Myron Stowe) - Remove fixed parameter in pci_iov_resource_bar() (Myron Stowe) MSI - Add pci_msi_ignore_mask to prevent writes to MSI/MSI-X Mask Bits (Yijing Wang) - Revert "PCI: Add x86_msi.msi_mask_irq() and msix_mask_irq()" (Yijing Wang) - s390/MSI: Use __msi_mask_irq() instead of default_msi_mask_irq() (Yijing Wang) Virtualization - xen: Process failure for pcifront_(re)scan_root() (Chen Gang) - Make FLR and AF FLR reset warning messages different (Gavin Shan) Generic host bridge driver - Allocate config space windows after limiting bus number range (Lorenzo Pieralisi) - Convert to DT resource parsing API (Lorenzo Pieralisi) Freescale Layerscape - Add Freescale Layerscape PCIe driver (Minghuan Lian) NVIDIA Tegra - Do not build on 64-bit ARM (Thierry Reding) - Add Kconfig help text (Thierry Reding) Renesas R-Car - Make rcar_pci static (Jingoo Han) Samsung Exynos - Add exynos prefix to add_pcie_port(), pcie_init() (Jingoo Han) ST Microelectronics SPEAr13xx - Add spear prefix to add_pcie_port(), pcie_init() (Jingoo Han) - Make spear13xx_add_pcie_port() __init (Jingoo Han) - Remove unnecessary OOM message (Jingoo Han) TI DRA7xx - Add dra7xx prefix to add_pcie_port() (Jingoo Han) - Make dra7xx_add_pcie_port() __init (Jingoo Han) TI Keystone - Make ks_dw_pcie_msi_domain_ops static (Jingoo Han) - Remove unnecessary OOM message (Jingoo Han) Miscellaneous - Delete unnecessary NULL pointer checks (Markus Elfring) - Remove unused to_hotplug_slot() (Gavin Shan) - Whitespace cleanup (Jingoo Han) - Simplify if-return sequences (Quentin Lambert)" * tag 'pci-v3.19-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (28 commits) PCI: Remove fixed parameter in pci_iov_resource_bar() PCI: Add informational printk for invalid BARs PCI: tegra: Add Kconfig help text PCI: tegra: Do not build on 64-bit ARM PCI: spear: Remove unnecessary OOM message PCI: mvebu: Add a blank line after declarations PCI: designware: Add a blank line after declarations PCI: exynos: Remove unnecessary return statement PCI: imx6: Use tabs for indentation PCI: keystone: Remove unnecessary OOM message PCI: Remove unused and broken to_hotplug_slot() PCI: Make FLR and AF FLR reset warning messages different PCI: dra7xx: Add __init annotation to dra7xx_add_pcie_port() PCI: spear: Add __init annotation to spear13xx_add_pcie_port() PCI: spear: Rename add_pcie_port(), pcie_init() to spear13xx_add_pcie_port(), etc. PCI: dra7xx: Rename add_pcie_port() to dra7xx_add_pcie_port() PCI: layerscape: Add Freescale Layerscape PCIe driver PCI: Simplify if-return sequences PCI: Delete unnecessary NULL pointer checks PCI: Shrink decoding-disabled window while sizing BARs ...
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r--drivers/pci/probe.c80
1 files changed, 35 insertions, 45 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index c8ca98c2b480..23212f8ae09b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -87,8 +87,7 @@ static void release_pcibus_dev(struct device *dev)
87{ 87{
88 struct pci_bus *pci_bus = to_pci_bus(dev); 88 struct pci_bus *pci_bus = to_pci_bus(dev);
89 89
90 if (pci_bus->bridge) 90 put_device(pci_bus->bridge);
91 put_device(pci_bus->bridge);
92 pci_bus_remove_resources(pci_bus); 91 pci_bus_remove_resources(pci_bus);
93 pci_release_bus_of_node(pci_bus); 92 pci_release_bus_of_node(pci_bus);
94 kfree(pci_bus); 93 kfree(pci_bus);
@@ -175,7 +174,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
175 u64 l64, sz64, mask64; 174 u64 l64, sz64, mask64;
176 u16 orig_cmd; 175 u16 orig_cmd;
177 struct pci_bus_region region, inverted_region; 176 struct pci_bus_region region, inverted_region;
178 bool bar_too_big = false, bar_too_high = false, bar_invalid = false;
179 177
180 mask = type ? PCI_ROM_ADDRESS_MASK : ~0; 178 mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
181 179
@@ -201,8 +199,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
201 * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit 199 * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit
202 * 1 must be clear. 200 * 1 must be clear.
203 */ 201 */
204 if (!sz || sz == 0xffffffff) 202 if (sz == 0xffffffff)
205 goto fail; 203 sz = 0;
206 204
207 /* 205 /*
208 * I don't know how l can have all bits set. Copied from old code. 206 * I don't know how l can have all bits set. Copied from old code.
@@ -215,23 +213,22 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
215 res->flags = decode_bar(dev, l); 213 res->flags = decode_bar(dev, l);
216 res->flags |= IORESOURCE_SIZEALIGN; 214 res->flags |= IORESOURCE_SIZEALIGN;
217 if (res->flags & IORESOURCE_IO) { 215 if (res->flags & IORESOURCE_IO) {
218 l &= PCI_BASE_ADDRESS_IO_MASK; 216 l64 = l & PCI_BASE_ADDRESS_IO_MASK;
219 mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT; 217 sz64 = sz & PCI_BASE_ADDRESS_IO_MASK;
218 mask64 = PCI_BASE_ADDRESS_IO_MASK & (u32)IO_SPACE_LIMIT;
220 } else { 219 } else {
221 l &= PCI_BASE_ADDRESS_MEM_MASK; 220 l64 = l & PCI_BASE_ADDRESS_MEM_MASK;
222 mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; 221 sz64 = sz & PCI_BASE_ADDRESS_MEM_MASK;
222 mask64 = (u32)PCI_BASE_ADDRESS_MEM_MASK;
223 } 223 }
224 } else { 224 } else {
225 res->flags |= (l & IORESOURCE_ROM_ENABLE); 225 res->flags |= (l & IORESOURCE_ROM_ENABLE);
226 l &= PCI_ROM_ADDRESS_MASK; 226 l64 = l & PCI_ROM_ADDRESS_MASK;
227 mask = (u32)PCI_ROM_ADDRESS_MASK; 227 sz64 = sz & PCI_ROM_ADDRESS_MASK;
228 mask64 = (u32)PCI_ROM_ADDRESS_MASK;
228 } 229 }
229 230
230 if (res->flags & IORESOURCE_MEM_64) { 231 if (res->flags & IORESOURCE_MEM_64) {
231 l64 = l;
232 sz64 = sz;
233 mask64 = mask | (u64)~0 << 32;
234
235 pci_read_config_dword(dev, pos + 4, &l); 232 pci_read_config_dword(dev, pos + 4, &l);
236 pci_write_config_dword(dev, pos + 4, ~0); 233 pci_write_config_dword(dev, pos + 4, ~0);
237 pci_read_config_dword(dev, pos + 4, &sz); 234 pci_read_config_dword(dev, pos + 4, &sz);
@@ -239,18 +236,30 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
239 236
240 l64 |= ((u64)l << 32); 237 l64 |= ((u64)l << 32);
241 sz64 |= ((u64)sz << 32); 238 sz64 |= ((u64)sz << 32);
239 mask64 |= ((u64)~0 << 32);
240 }
242 241
243 sz64 = pci_size(l64, sz64, mask64); 242 if (!dev->mmio_always_on && (orig_cmd & PCI_COMMAND_DECODE_ENABLE))
243 pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
244 244
245 if (!sz64) 245 if (!sz64)
246 goto fail; 246 goto fail;
247 247
248 sz64 = pci_size(l64, sz64, mask64);
249 if (!sz64) {
250 dev_info(&dev->dev, FW_BUG "reg 0x%x: invalid BAR (can't size)\n",
251 pos);
252 goto fail;
253 }
254
255 if (res->flags & IORESOURCE_MEM_64) {
248 if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) && 256 if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) &&
249 sz64 > 0x100000000ULL) { 257 sz64 > 0x100000000ULL) {
250 res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; 258 res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
251 res->start = 0; 259 res->start = 0;
252 res->end = 0; 260 res->end = 0;
253 bar_too_big = true; 261 dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
262 pos, (unsigned long long)sz64);
254 goto out; 263 goto out;
255 } 264 }
256 265
@@ -259,22 +268,15 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
259 res->flags |= IORESOURCE_UNSET; 268 res->flags |= IORESOURCE_UNSET;
260 res->start = 0; 269 res->start = 0;
261 res->end = sz64; 270 res->end = sz64;
262 bar_too_high = true; 271 dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n",
272 pos, (unsigned long long)l64);
263 goto out; 273 goto out;
264 } else {
265 region.start = l64;
266 region.end = l64 + sz64;
267 } 274 }
268 } else {
269 sz = pci_size(l, sz, mask);
270
271 if (!sz)
272 goto fail;
273
274 region.start = l;
275 region.end = l + sz;
276 } 275 }
277 276
277 region.start = l64;
278 region.end = l64 + sz64;
279
278 pcibios_bus_to_resource(dev->bus, res, &region); 280 pcibios_bus_to_resource(dev->bus, res, &region);
279 pcibios_resource_to_bus(dev->bus, &inverted_region, res); 281 pcibios_resource_to_bus(dev->bus, &inverted_region, res);
280 282
@@ -293,7 +295,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
293 res->flags |= IORESOURCE_UNSET; 295 res->flags |= IORESOURCE_UNSET;
294 res->start = 0; 296 res->start = 0;
295 res->end = region.end - region.start; 297 res->end = region.end - region.start;
296 bar_invalid = true; 298 dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
299 pos, (unsigned long long)region.start);
297 } 300 }
298 301
299 goto out; 302 goto out;
@@ -302,19 +305,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
302fail: 305fail:
303 res->flags = 0; 306 res->flags = 0;
304out: 307out:
305 if (!dev->mmio_always_on &&
306 (orig_cmd & PCI_COMMAND_DECODE_ENABLE))
307 pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
308
309 if (bar_too_big)
310 dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
311 pos, (unsigned long long) sz64);
312 if (bar_too_high)
313 dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4G (bus address %#010llx)\n",
314 pos, (unsigned long long) l64);
315 if (bar_invalid)
316 dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
317 pos, (unsigned long long) region.start);
318 if (res->flags) 308 if (res->flags)
319 dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res); 309 dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res);
320 310