aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPrarit Bhargava <prarit@redhat.com>2011-01-11 15:34:35 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2011-03-04 13:41:02 -0500
commit457d9d088b026e26dbab98cad9d299c1faf4c343 (patch)
tree654406ce3724d90fe784446ef38c12605adb692e /drivers
parent3449248c8731e8474980856d76bbf9bac9b0682f (diff)
PCI: aer-inject: Override PCIe AER Mask Registers
I have several systems which have the same problem: The PCIe AER corrected and uncorrected masks have all the error bits set. This results in the inablility to test with the aer_inject module & utility on those systems. Add the 'aer_mask_override' module parameter which will override the corrected or uncorrected masks for a PCI device. The mask will have the bit corresponding to the status passed into the aer_inject() function. After this patch it is possible to successfully use the aer_inject utility on those PCI slots. Successfully tested by me on a Dell and Intel whitebox which exhibited the mask problem. Signed-off-by: Prarit Bhargava <prarit@redhat.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index b3cf6223f63..f62079ff06d 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -27,6 +27,10 @@
27#include <linux/stddef.h> 27#include <linux/stddef.h>
28#include "aerdrv.h" 28#include "aerdrv.h"
29 29
30/* Override the existing corrected and uncorrected error masks */
31static int aer_mask_override;
32module_param(aer_mask_override, bool, 0);
33
30struct aer_error_inj { 34struct aer_error_inj {
31 u8 bus; 35 u8 bus;
32 u8 dev; 36 u8 dev;
@@ -322,7 +326,7 @@ static int aer_inject(struct aer_error_inj *einj)
322 unsigned long flags; 326 unsigned long flags;
323 unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); 327 unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn);
324 int pos_cap_err, rp_pos_cap_err; 328 int pos_cap_err, rp_pos_cap_err;
325 u32 sever, cor_mask, uncor_mask; 329 u32 sever, cor_mask, uncor_mask, cor_mask_orig, uncor_mask_orig;
326 int ret = 0; 330 int ret = 0;
327 331
328 dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); 332 dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn);
@@ -361,6 +365,18 @@ static int aer_inject(struct aer_error_inj *einj)
361 goto out_put; 365 goto out_put;
362 } 366 }
363 367
368 if (aer_mask_override) {
369 cor_mask_orig = cor_mask;
370 cor_mask &= !(einj->cor_status);
371 pci_write_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK,
372 cor_mask);
373
374 uncor_mask_orig = uncor_mask;
375 uncor_mask &= !(einj->uncor_status);
376 pci_write_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK,
377 uncor_mask);
378 }
379
364 spin_lock_irqsave(&inject_lock, flags); 380 spin_lock_irqsave(&inject_lock, flags);
365 381
366 err = __find_aer_error_by_dev(dev); 382 err = __find_aer_error_by_dev(dev);
@@ -378,14 +394,16 @@ static int aer_inject(struct aer_error_inj *einj)
378 err->header_log2 = einj->header_log2; 394 err->header_log2 = einj->header_log2;
379 err->header_log3 = einj->header_log3; 395 err->header_log3 = einj->header_log3;
380 396
381 if (einj->cor_status && !(einj->cor_status & ~cor_mask)) { 397 if (!aer_mask_override && einj->cor_status &&
398 !(einj->cor_status & ~cor_mask)) {
382 ret = -EINVAL; 399 ret = -EINVAL;
383 printk(KERN_WARNING "The correctable error(s) is masked " 400 printk(KERN_WARNING "The correctable error(s) is masked "
384 "by device\n"); 401 "by device\n");
385 spin_unlock_irqrestore(&inject_lock, flags); 402 spin_unlock_irqrestore(&inject_lock, flags);
386 goto out_put; 403 goto out_put;
387 } 404 }
388 if (einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) { 405 if (!aer_mask_override && einj->uncor_status &&
406 !(einj->uncor_status & ~uncor_mask)) {
389 ret = -EINVAL; 407 ret = -EINVAL;
390 printk(KERN_WARNING "The uncorrectable error(s) is masked " 408 printk(KERN_WARNING "The uncorrectable error(s) is masked "
391 "by device\n"); 409 "by device\n");
@@ -425,6 +443,13 @@ static int aer_inject(struct aer_error_inj *einj)
425 } 443 }
426 spin_unlock_irqrestore(&inject_lock, flags); 444 spin_unlock_irqrestore(&inject_lock, flags);
427 445
446 if (aer_mask_override) {
447 pci_write_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK,
448 cor_mask_orig);
449 pci_write_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK,
450 uncor_mask_orig);
451 }
452
428 ret = pci_bus_set_aer_ops(dev->bus); 453 ret = pci_bus_set_aer_ops(dev->bus);
429 if (ret) 454 if (ret)
430 goto out_put; 455 goto out_put;