aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-01-08 16:55:39 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-01-08 16:55:39 -0500
commit00cd25b29ba946b7d0907157577ab5cf421bd50e (patch)
tree57d76cf7a495ea8f1ac662e12442bf6164ea3024
parente2b6d02cca533715d6be40fdfc32d3cc47333358 (diff)
parentb49bfd32901625e4adcfee011d2b32a43b4db67d (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: PCIe AER: prevent AER injection if hardware masks error reporting PCI/PM: Use per-device D3 delays PCI: Check the node argument passed to cpumask_of_node PCI: AER: fix aer inject result in kernel oops PCI: pcie portdrv: style cleanup
-rw-r--r--drivers/net/sky2.c1
-rw-r--r--drivers/pci/pci-sysfs.c6
-rw-r--r--drivers/pci/pci.c19
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c28
-rw-r--r--drivers/pci/pcie/portdrv_core.c16
-rw-r--r--drivers/pci/pcie/portdrv_pci.c17
-rw-r--r--include/linux/pci.h1
7 files changed, 62 insertions, 26 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 1c01b96c9611..2d28d58200d0 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -4684,6 +4684,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
4684 INIT_WORK(&hw->restart_work, sky2_restart); 4684 INIT_WORK(&hw->restart_work, sky2_restart);
4685 4685
4686 pci_set_drvdata(pdev, hw); 4686 pci_set_drvdata(pdev, hw);
4687 pdev->d3_delay = 150;
4687 4688
4688 return 0; 4689 return 0;
4689 4690
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index c5df94e86678..807224ec8351 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -75,7 +75,8 @@ static ssize_t local_cpus_show(struct device *dev,
75 int len; 75 int len;
76 76
77#ifdef CONFIG_NUMA 77#ifdef CONFIG_NUMA
78 mask = cpumask_of_node(dev_to_node(dev)); 78 mask = (dev_to_node(dev) == -1) ? cpu_online_mask :
79 cpumask_of_node(dev_to_node(dev));
79#else 80#else
80 mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); 81 mask = cpumask_of_pcibus(to_pci_dev(dev)->bus);
81#endif 82#endif
@@ -93,7 +94,8 @@ static ssize_t local_cpulist_show(struct device *dev,
93 int len; 94 int len;
94 95
95#ifdef CONFIG_NUMA 96#ifdef CONFIG_NUMA
96 mask = cpumask_of_node(dev_to_node(dev)); 97 mask = (dev_to_node(dev) == -1) ? cpu_online_mask :
98 cpumask_of_node(dev_to_node(dev));
97#else 99#else
98 mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); 100 mask = cpumask_of_pcibus(to_pci_dev(dev)->bus);
99#endif 101#endif
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 0906599ebfde..315fea47e784 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -29,7 +29,17 @@ const char *pci_power_names[] = {
29}; 29};
30EXPORT_SYMBOL_GPL(pci_power_names); 30EXPORT_SYMBOL_GPL(pci_power_names);
31 31
32unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT; 32unsigned int pci_pm_d3_delay;
33
34static void pci_dev_d3_sleep(struct pci_dev *dev)
35{
36 unsigned int delay = dev->d3_delay;
37
38 if (delay < pci_pm_d3_delay)
39 delay = pci_pm_d3_delay;
40
41 msleep(delay);
42}
33 43
34#ifdef CONFIG_PCI_DOMAINS 44#ifdef CONFIG_PCI_DOMAINS
35int pci_domains_supported = 1; 45int pci_domains_supported = 1;
@@ -522,7 +532,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
522 /* Mandatory power management transition delays */ 532 /* Mandatory power management transition delays */
523 /* see PCI PM 1.1 5.6.1 table 18 */ 533 /* see PCI PM 1.1 5.6.1 table 18 */
524 if (state == PCI_D3hot || dev->current_state == PCI_D3hot) 534 if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
525 msleep(pci_pm_d3_delay); 535 pci_dev_d3_sleep(dev);
526 else if (state == PCI_D2 || dev->current_state == PCI_D2) 536 else if (state == PCI_D2 || dev->current_state == PCI_D2)
527 udelay(PCI_PM_D2_DELAY); 537 udelay(PCI_PM_D2_DELAY);
528 538
@@ -1409,6 +1419,7 @@ void pci_pm_init(struct pci_dev *dev)
1409 } 1419 }
1410 1420
1411 dev->pm_cap = pm; 1421 dev->pm_cap = pm;
1422 dev->d3_delay = PCI_PM_D3_WAIT;
1412 1423
1413 dev->d1_support = false; 1424 dev->d1_support = false;
1414 dev->d2_support = false; 1425 dev->d2_support = false;
@@ -2247,12 +2258,12 @@ static int pci_pm_reset(struct pci_dev *dev, int probe)
2247 csr &= ~PCI_PM_CTRL_STATE_MASK; 2258 csr &= ~PCI_PM_CTRL_STATE_MASK;
2248 csr |= PCI_D3hot; 2259 csr |= PCI_D3hot;
2249 pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); 2260 pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr);
2250 msleep(pci_pm_d3_delay); 2261 pci_dev_d3_sleep(dev);
2251 2262
2252 csr &= ~PCI_PM_CTRL_STATE_MASK; 2263 csr &= ~PCI_PM_CTRL_STATE_MASK;
2253 csr |= PCI_D0; 2264 csr |= PCI_D0;
2254 pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr); 2265 pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, csr);
2255 msleep(pci_pm_d3_delay); 2266 pci_dev_d3_sleep(dev);
2256 2267
2257 return 0; 2268 return 0;
2258} 2269}
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 797d47809f7a..8c30a9544d61 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -321,7 +321,7 @@ static int aer_inject(struct aer_error_inj *einj)
321 unsigned long flags; 321 unsigned long flags;
322 unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); 322 unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn);
323 int pos_cap_err, rp_pos_cap_err; 323 int pos_cap_err, rp_pos_cap_err;
324 u32 sever; 324 u32 sever, mask;
325 int ret = 0; 325 int ret = 0;
326 326
327 dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); 327 dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn);
@@ -374,6 +374,24 @@ static int aer_inject(struct aer_error_inj *einj)
374 err->header_log2 = einj->header_log2; 374 err->header_log2 = einj->header_log2;
375 err->header_log3 = einj->header_log3; 375 err->header_log3 = einj->header_log3;
376 376
377 pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &mask);
378 if (einj->cor_status && !(einj->cor_status & ~mask)) {
379 ret = -EINVAL;
380 printk(KERN_WARNING "The correctable error(s) is masked "
381 "by device\n");
382 spin_unlock_irqrestore(&inject_lock, flags);
383 goto out_put;
384 }
385
386 pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, &mask);
387 if (einj->uncor_status && !(einj->uncor_status & ~mask)) {
388 ret = -EINVAL;
389 printk(KERN_WARNING "The uncorrectable error(s) is masked "
390 "by device\n");
391 spin_unlock_irqrestore(&inject_lock, flags);
392 goto out_put;
393 }
394
377 rperr = __find_aer_error_by_dev(rpdev); 395 rperr = __find_aer_error_by_dev(rpdev);
378 if (!rperr) { 396 if (!rperr) {
379 rperr = rperr_alloc; 397 rperr = rperr_alloc;
@@ -413,8 +431,14 @@ static int aer_inject(struct aer_error_inj *einj)
413 if (ret) 431 if (ret)
414 goto out_put; 432 goto out_put;
415 433
416 if (find_aer_device(rpdev, &edev)) 434 if (find_aer_device(rpdev, &edev)) {
435 if (!get_service_data(edev)) {
436 printk(KERN_WARNING "AER service is not initialized\n");
437 ret = -EINVAL;
438 goto out_put;
439 }
417 aer_irq(-1, edev); 440 aer_irq(-1, edev);
441 }
418 else 442 else
419 ret = -EINVAL; 443 ret = -EINVAL;
420out_put: 444out_put:
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 413262eb95b7..b174188ac121 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -27,7 +27,7 @@
27 */ 27 */
28static void release_pcie_device(struct device *dev) 28static void release_pcie_device(struct device *dev)
29{ 29{
30 kfree(to_pcie_device(dev)); 30 kfree(to_pcie_device(dev));
31} 31}
32 32
33/** 33/**
@@ -346,12 +346,11 @@ static int suspend_iter(struct device *dev, void *data)
346{ 346{
347 struct pcie_port_service_driver *service_driver; 347 struct pcie_port_service_driver *service_driver;
348 348
349 if ((dev->bus == &pcie_port_bus_type) && 349 if ((dev->bus == &pcie_port_bus_type) && dev->driver) {
350 (dev->driver)) { 350 service_driver = to_service_driver(dev->driver);
351 service_driver = to_service_driver(dev->driver); 351 if (service_driver->suspend)
352 if (service_driver->suspend) 352 service_driver->suspend(to_pcie_device(dev));
353 service_driver->suspend(to_pcie_device(dev)); 353 }
354 }
355 return 0; 354 return 0;
356} 355}
357 356
@@ -494,6 +493,7 @@ int pcie_port_service_register(struct pcie_port_service_driver *new)
494 493
495 return driver_register(&new->driver); 494 return driver_register(&new->driver);
496} 495}
496EXPORT_SYMBOL(pcie_port_service_register);
497 497
498/** 498/**
499 * pcie_port_service_unregister - unregister PCI Express port service driver 499 * pcie_port_service_unregister - unregister PCI Express port service driver
@@ -503,6 +503,4 @@ void pcie_port_service_unregister(struct pcie_port_service_driver *drv)
503{ 503{
504 driver_unregister(&drv->driver); 504 driver_unregister(&drv->driver);
505} 505}
506
507EXPORT_SYMBOL(pcie_port_service_register);
508EXPORT_SYMBOL(pcie_port_service_unregister); 506EXPORT_SYMBOL(pcie_port_service_unregister);
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 34d65172a4d7..13c8972886e6 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -63,7 +63,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {
63 * pcie_portdrv_probe - Probe PCI-Express port devices 63 * pcie_portdrv_probe - Probe PCI-Express port devices
64 * @dev: PCI-Express port device being probed 64 * @dev: PCI-Express port device being probed
65 * 65 *
66 * If detected invokes the pcie_port_device_register() method for 66 * If detected invokes the pcie_port_device_register() method for
67 * this port device. 67 * this port device.
68 * 68 *
69 */ 69 */
@@ -78,7 +78,7 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev,
78 (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))) 78 (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)))
79 return -ENODEV; 79 return -ENODEV;
80 80
81 if (!dev->irq && dev->pin) { 81 if (!dev->irq && dev->pin) {
82 dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " 82 dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; "
83 "check vendor BIOS\n", dev->vendor, dev->device); 83 "check vendor BIOS\n", dev->vendor, dev->device);
84 } 84 }
@@ -91,7 +91,7 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev,
91 return 0; 91 return 0;
92} 92}
93 93
94static void pcie_portdrv_remove (struct pci_dev *dev) 94static void pcie_portdrv_remove(struct pci_dev *dev)
95{ 95{
96 pcie_port_device_remove(dev); 96 pcie_port_device_remove(dev);
97 pci_disable_device(dev); 97 pci_disable_device(dev);
@@ -129,14 +129,13 @@ static int error_detected_iter(struct device *device, void *data)
129static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, 129static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
130 enum pci_channel_state error) 130 enum pci_channel_state error)
131{ 131{
132 struct aer_broadcast_data result_data = 132 struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER};
133 {error, PCI_ERS_RESULT_CAN_RECOVER}; 133 int ret;
134 int retval;
135 134
136 /* can not fail */ 135 /* can not fail */
137 retval = device_for_each_child(&dev->dev, &result_data, error_detected_iter); 136 ret = device_for_each_child(&dev->dev, &data, error_detected_iter);
138 137
139 return result_data.result; 138 return data.result;
140} 139}
141 140
142static int mmio_enabled_iter(struct device *device, void *data) 141static int mmio_enabled_iter(struct device *device, void *data)
@@ -290,7 +289,7 @@ static int __init pcie_portdrv_init(void)
290 return retval; 289 return retval;
291} 290}
292 291
293static void __exit pcie_portdrv_exit(void) 292static void __exit pcie_portdrv_exit(void)
294{ 293{
295 pci_unregister_driver(&pcie_portdriver); 294 pci_unregister_driver(&pcie_portdriver);
296 pcie_port_bus_unregister(); 295 pcie_port_bus_unregister();
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5da0690d9cee..174e5392e51e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -243,6 +243,7 @@ struct pci_dev {
243 unsigned int d2_support:1; /* Low power state D2 is supported */ 243 unsigned int d2_support:1; /* Low power state D2 is supported */
244 unsigned int no_d1d2:1; /* Only allow D0 and D3 */ 244 unsigned int no_d1d2:1; /* Only allow D0 and D3 */
245 unsigned int wakeup_prepared:1; 245 unsigned int wakeup_prepared:1;
246 unsigned int d3_delay; /* D3->D0 transition time in ms */
246 247
247#ifdef CONFIG_PCIEASPM 248#ifdef CONFIG_PCIEASPM
248 struct pcie_link_state *link_state; /* ASPM link state. */ 249 struct pcie_link_state *link_state; /* ASPM link state. */