diff options
Diffstat (limited to 'drivers/pci/pcie/aer')
-rw-r--r-- | drivers/pci/pcie/aer/Kconfig.debug | 4 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aer_inject.c | 34 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv.c | 2 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_acpi.c | 2 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_core.c | 6 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_errprint.c | 4 |
6 files changed, 38 insertions, 14 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 | ||
5 | config PCIEAER_INJECT | 5 | config 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..223052b73563 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, cor_mask, uncor_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); |
@@ -339,6 +339,9 @@ static int aer_inject(struct aer_error_inj *einj) | |||
339 | goto out_put; | 339 | goto out_put; |
340 | } | 340 | } |
341 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); | 341 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); |
342 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &cor_mask); | ||
343 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK, | ||
344 | &uncor_mask); | ||
342 | 345 | ||
343 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); | 346 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); |
344 | if (!rp_pos_cap_err) { | 347 | if (!rp_pos_cap_err) { |
@@ -374,6 +377,21 @@ static int aer_inject(struct aer_error_inj *einj) | |||
374 | err->header_log2 = einj->header_log2; | 377 | err->header_log2 = einj->header_log2; |
375 | err->header_log3 = einj->header_log3; | 378 | err->header_log3 = einj->header_log3; |
376 | 379 | ||
380 | if (einj->cor_status && !(einj->cor_status & ~cor_mask)) { | ||
381 | ret = -EINVAL; | ||
382 | printk(KERN_WARNING "The correctable error(s) is masked " | ||
383 | "by device\n"); | ||
384 | spin_unlock_irqrestore(&inject_lock, flags); | ||
385 | goto out_put; | ||
386 | } | ||
387 | if (einj->uncor_status && !(einj->uncor_status & ~uncor_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; |
420 | out_put: | 444 | out_put: |
@@ -484,5 +508,5 @@ static void __exit aer_inject_exit(void) | |||
484 | module_init(aer_inject_init); | 508 | module_init(aer_inject_init); |
485 | module_exit(aer_inject_exit); | 509 | module_exit(aer_inject_exit); |
486 | 510 | ||
487 | MODULE_DESCRIPTION("PCIE AER software error injector"); | 511 | MODULE_DESCRIPTION("PCIe AER software error injector"); |
488 | MODULE_LICENSE("GPL"); | 512 | MODULE_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 | **/ |
30 | int aer_osc_setup(struct pcie_device *pciedev) | 30 | int 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 | */ |
592 | void aer_enable_rootport(struct aer_rpc *rpc) | 592 | void 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, ®16); | 601 | pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); |
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 | */ |
636 | static void disable_root_aer(struct aer_rpc *rpc) | 636 | static 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 | ||