aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r--drivers/pci/pcie/aer/Kconfig.debug4
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c34
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c6
-rw-r--r--drivers/pci/pcie/aer/aerdrv_errprint.c4
-rw-r--r--drivers/pci/pcie/aspm.c4
-rw-r--r--drivers/pci/pcie/portdrv_core.c16
-rw-r--r--drivers/pci/pcie/portdrv_pci.c19
9 files changed, 56 insertions, 35 deletions
diff --git a/drivers/pci/pcie/aer/Kconfig.debug b/drivers/pci/pcie/aer/Kconfig.debug
index b8c925c1f6aa..9142949734f5 100644
--- a/drivers/pci/pcie/aer/Kconfig.debug
+++ b/drivers/pci/pcie/aer/Kconfig.debug
@@ -3,14 +3,14 @@
3# 3#
4 4
5config PCIEAER_INJECT 5config PCIEAER_INJECT
6 tristate "PCIE AER error injector support" 6 tristate "PCIe AER error injector support"
7 depends on PCIEAER 7 depends on PCIEAER
8 default n 8 default n
9 help 9 help
10 This enables PCI Express Root Port Advanced Error Reporting 10 This enables PCI Express Root Port Advanced Error Reporting
11 (AER) software error injector. 11 (AER) software error injector.
12 12
13 Debuging PCIE AER code is quite difficult because it is hard 13 Debugging PCIe AER code is quite difficult because it is hard
14 to trigger various real hardware errors. Software based 14 to trigger various real hardware errors. Software based
15 error injection can fake almost all kinds of errors with the 15 error injection can fake almost all kinds of errors with the
16 help of a user space helper tool aer-inject, which can be 16 help of a user space helper tool aer-inject, which can be
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 7fcd5331b14c..8c30a9544d61 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * PCIE AER software error injection support. 2 * PCIe AER software error injection support.
3 * 3 *
4 * Debuging PCIE AER code is quite difficult because it is hard to 4 * Debuging PCIe AER code is quite difficult because it is hard to
5 * trigger various real hardware errors. Software based error 5 * trigger various real hardware errors. Software based error
6 * injection can fake almost all kinds of errors with the help of a 6 * injection can fake almost all kinds of errors with the help of a
7 * user space helper tool aer-inject, which can be gotten from: 7 * user space helper tool aer-inject, which can be gotten from:
@@ -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:
@@ -484,5 +508,5 @@ static void __exit aer_inject_exit(void)
484module_init(aer_inject_init); 508module_init(aer_inject_init);
485module_exit(aer_inject_exit); 509module_exit(aer_inject_exit);
486 510
487MODULE_DESCRIPTION("PCIE AER software error injector"); 511MODULE_DESCRIPTION("PCIe AER software error injector");
488MODULE_LICENSE("GPL"); 512MODULE_LICENSE("GPL");
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 97a345927b55..21f215f4daa3 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -155,7 +155,7 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev)
155 mutex_init(&rpc->rpc_mutex); 155 mutex_init(&rpc->rpc_mutex);
156 init_waitqueue_head(&rpc->wait_release); 156 init_waitqueue_head(&rpc->wait_release);
157 157
158 /* Use PCIE bus function to store rpc into PCIE device */ 158 /* Use PCIe bus function to store rpc into PCIe device */
159 set_service_data(dev, rpc); 159 set_service_data(dev, rpc);
160 160
161 return rpc; 161 return rpc;
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index 8edb2f300e8f..04814087658d 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -24,7 +24,7 @@
24 * 24 *
25 * @return: Zero on success. Nonzero otherwise. 25 * @return: Zero on success. Nonzero otherwise.
26 * 26 *
27 * Invoked when PCIE bus loads AER service driver. To avoid conflict with 27 * Invoked when PCIe bus loads AER service driver. To avoid conflict with
28 * BIOS AER support requires BIOS to yield AER control to OS native driver. 28 * BIOS AER support requires BIOS to yield AER control to OS native driver.
29 **/ 29 **/
30int aer_osc_setup(struct pcie_device *pciedev) 30int aer_osc_setup(struct pcie_device *pciedev)
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index ae672ca80333..c843a799814d 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -587,7 +587,7 @@ static void handle_error_source(struct pcie_device *aerdev,
587 * aer_enable_rootport - enable Root Port's interrupts when receiving messages 587 * aer_enable_rootport - enable Root Port's interrupts when receiving messages
588 * @rpc: pointer to a Root Port data structure 588 * @rpc: pointer to a Root Port data structure
589 * 589 *
590 * Invoked when PCIE bus loads AER service driver. 590 * Invoked when PCIe bus loads AER service driver.
591 */ 591 */
592void aer_enable_rootport(struct aer_rpc *rpc) 592void aer_enable_rootport(struct aer_rpc *rpc)
593{ 593{
@@ -597,7 +597,7 @@ void aer_enable_rootport(struct aer_rpc *rpc)
597 u32 reg32; 597 u32 reg32;
598 598
599 pos = pci_pcie_cap(pdev); 599 pos = pci_pcie_cap(pdev);
600 /* Clear PCIE Capability's Device Status */ 600 /* Clear PCIe Capability's Device Status */
601 pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, &reg16); 601 pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, &reg16);
602 pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); 602 pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16);
603 603
@@ -631,7 +631,7 @@ void aer_enable_rootport(struct aer_rpc *rpc)
631 * disable_root_aer - disable Root Port's interrupts when receiving messages 631 * disable_root_aer - disable Root Port's interrupts when receiving messages
632 * @rpc: pointer to a Root Port data structure 632 * @rpc: pointer to a Root Port data structure
633 * 633 *
634 * Invoked when PCIE bus unloads AER service driver. 634 * Invoked when PCIe bus unloads AER service driver.
635 */ 635 */
636static void disable_root_aer(struct aer_rpc *rpc) 636static void disable_root_aer(struct aer_rpc *rpc)
637{ 637{
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 44acde72294f..9d3e4c8d0184 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -184,7 +184,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
184 184
185 if (info->status == 0) { 185 if (info->status == 0) {
186 AER_PR(info, dev, 186 AER_PR(info, dev,
187 "PCIE Bus Error: severity=%s, type=Unaccessible, " 187 "PCIe Bus Error: severity=%s, type=Unaccessible, "
188 "id=%04x(Unregistered Agent ID)\n", 188 "id=%04x(Unregistered Agent ID)\n",
189 aer_error_severity_string[info->severity], id); 189 aer_error_severity_string[info->severity], id);
190 } else { 190 } else {
@@ -194,7 +194,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
194 agent = AER_GET_AGENT(info->severity, info->status); 194 agent = AER_GET_AGENT(info->severity, info->status);
195 195
196 AER_PR(info, dev, 196 AER_PR(info, dev,
197 "PCIE Bus Error: severity=%s, type=%s, id=%04x(%s)\n", 197 "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n",
198 aer_error_severity_string[info->severity], 198 aer_error_severity_string[info->severity],
199 aer_error_layer[layer], id, aer_agent_string[agent]); 199 aer_error_layer[layer], id, aer_agent_string[agent]);
200 200
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 5a01fc7fbf05..be53d98fa384 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * File: drivers/pci/pcie/aspm.c 2 * File: drivers/pci/pcie/aspm.c
3 * Enabling PCIE link L0s/L1 state and Clock Power Management 3 * Enabling PCIe link L0s/L1 state and Clock Power Management
4 * 4 *
5 * Copyright (C) 2007 Intel 5 * Copyright (C) 2007 Intel
6 * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com) 6 * Copyright (C) Zhang Yanmin (yanmin.zhang@intel.com)
@@ -499,7 +499,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
499 int pos; 499 int pos;
500 u32 reg32; 500 u32 reg32;
501 /* 501 /*
502 * Some functions in a slot might not all be PCIE functions, 502 * Some functions in a slot might not all be PCIe functions,
503 * very strange. Disable ASPM for the whole slot 503 * very strange. Disable ASPM for the whole slot
504 */ 504 */
505 list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { 505 list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
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 a49452e2aed9..13c8972886e6 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -24,7 +24,7 @@
24 */ 24 */
25#define DRIVER_VERSION "v1.0" 25#define DRIVER_VERSION "v1.0"
26#define DRIVER_AUTHOR "tom.l.nguyen@intel.com" 26#define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
27#define DRIVER_DESC "PCIE Port Bus Driver" 27#define DRIVER_DESC "PCIe Port Bus Driver"
28MODULE_AUTHOR(DRIVER_AUTHOR); 28MODULE_AUTHOR(DRIVER_AUTHOR);
29MODULE_DESCRIPTION(DRIVER_DESC); 29MODULE_DESCRIPTION(DRIVER_DESC);
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
@@ -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();