Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: PCI: remove printks about disabled bridge windows PCI: fold pci_calc_resource_flags() into decode_bar() PCI: treat mem BAR type "11" (reserved) as 32-bit, not 64-bit, BAR PCI: correct pcie_set_readrq write size PCI: pciehp: change wait time for valid configuration access x86/PCI: Preserve existing pci=bfsort whitelist for Dell systems PCI: ARI is a PCIe v2 feature x86/PCI: quirks: Use pci_dev->revision PCI: Make the struct pci_dev * argument of pci_fixup_irqs const. PCI hotplug: cpqphp: use pci_dev->vendor PCI hotplug: cpqphp: use pci_dev->subsystem_{vendor|device} x86/PCI: config space accessor functions should not ignore the segment argument PCI: Assign values to 'pci_obff_signal_type' enumeration constants x86/PCI: reduce severity of host bridge window conflict warnings PCI: enumerate the PCI device only removed out PCI hieratchy of OS when re-scanning PCI PCI: PCIe AER: add aer_recover_queue x86/PCI: select direct access mode for mmconfig option PCI hotplug: Rename is_ejectable which also exists in dock.c
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kfifo.h>
|
||||
#include "aerdrv.h"
|
||||
|
||||
static int forceload;
|
||||
@@ -445,8 +446,7 @@ static struct pcie_port_service_driver *find_aer_service(struct pci_dev *dev)
|
||||
return drv;
|
||||
}
|
||||
|
||||
static pci_ers_result_t reset_link(struct pcie_device *aerdev,
|
||||
struct pci_dev *dev)
|
||||
static pci_ers_result_t reset_link(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *udev;
|
||||
pci_ers_result_t status;
|
||||
@@ -486,7 +486,6 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev,
|
||||
|
||||
/**
|
||||
* do_recovery - handle nonfatal/fatal error recovery process
|
||||
* @aerdev: pointer to a pcie_device data structure of root port
|
||||
* @dev: pointer to a pci_dev data structure of agent detecting an error
|
||||
* @severity: error severity type
|
||||
*
|
||||
@@ -494,8 +493,7 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev,
|
||||
* error detected message to all downstream drivers within a hierarchy in
|
||||
* question and return the returned code.
|
||||
*/
|
||||
static void do_recovery(struct pcie_device *aerdev, struct pci_dev *dev,
|
||||
int severity)
|
||||
static void do_recovery(struct pci_dev *dev, int severity)
|
||||
{
|
||||
pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED;
|
||||
enum pci_channel_state state;
|
||||
@@ -511,7 +509,7 @@ static void do_recovery(struct pcie_device *aerdev, struct pci_dev *dev,
|
||||
report_error_detected);
|
||||
|
||||
if (severity == AER_FATAL) {
|
||||
result = reset_link(aerdev, dev);
|
||||
result = reset_link(dev);
|
||||
if (result != PCI_ERS_RESULT_RECOVERED)
|
||||
goto failed;
|
||||
}
|
||||
@@ -576,9 +574,73 @@ static void handle_error_source(struct pcie_device *aerdev,
|
||||
pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
|
||||
info->status);
|
||||
} else
|
||||
do_recovery(aerdev, dev, info->severity);
|
||||
do_recovery(dev, info->severity);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_APEI_PCIEAER
|
||||
static void aer_recover_work_func(struct work_struct *work);
|
||||
|
||||
#define AER_RECOVER_RING_ORDER 4
|
||||
#define AER_RECOVER_RING_SIZE (1 << AER_RECOVER_RING_ORDER)
|
||||
|
||||
struct aer_recover_entry
|
||||
{
|
||||
u8 bus;
|
||||
u8 devfn;
|
||||
u16 domain;
|
||||
int severity;
|
||||
};
|
||||
|
||||
static DEFINE_KFIFO(aer_recover_ring, struct aer_recover_entry,
|
||||
AER_RECOVER_RING_SIZE);
|
||||
/*
|
||||
* Mutual exclusion for writers of aer_recover_ring, reader side don't
|
||||
* need lock, because there is only one reader and lock is not needed
|
||||
* between reader and writer.
|
||||
*/
|
||||
static DEFINE_SPINLOCK(aer_recover_ring_lock);
|
||||
static DECLARE_WORK(aer_recover_work, aer_recover_work_func);
|
||||
|
||||
void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
|
||||
int severity)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct aer_recover_entry entry = {
|
||||
.bus = bus,
|
||||
.devfn = devfn,
|
||||
.domain = domain,
|
||||
.severity = severity,
|
||||
};
|
||||
|
||||
spin_lock_irqsave(&aer_recover_ring_lock, flags);
|
||||
if (kfifo_put(&aer_recover_ring, &entry))
|
||||
schedule_work(&aer_recover_work);
|
||||
else
|
||||
pr_err("AER recover: Buffer overflow when recovering AER for %04x:%02x:%02x:%x\n",
|
||||
domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
|
||||
spin_unlock_irqrestore(&aer_recover_ring_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aer_recover_queue);
|
||||
|
||||
static void aer_recover_work_func(struct work_struct *work)
|
||||
{
|
||||
struct aer_recover_entry entry;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
while (kfifo_get(&aer_recover_ring, &entry)) {
|
||||
pdev = pci_get_domain_bus_and_slot(entry.domain, entry.bus,
|
||||
entry.devfn);
|
||||
if (!pdev) {
|
||||
pr_err("AER recover: Can not find pci_dev for %04x:%02x:%02x:%x\n",
|
||||
entry.domain, entry.bus,
|
||||
PCI_SLOT(entry.devfn), PCI_FUNC(entry.devfn));
|
||||
continue;
|
||||
}
|
||||
do_recovery(pdev, entry.severity);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* get_device_error_info - read error status from dev and store it to info
|
||||
* @dev: pointer to the device expected to have a error record
|
||||
|
@@ -204,7 +204,7 @@ void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_APEI_PCIEAER
|
||||
static int cper_severity_to_aer(int cper_severity)
|
||||
int cper_severity_to_aer(int cper_severity)
|
||||
{
|
||||
switch (cper_severity) {
|
||||
case CPER_SEV_RECOVERABLE:
|
||||
@@ -215,6 +215,7 @@ static int cper_severity_to_aer(int cper_severity)
|
||||
return AER_CORRECTABLE;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cper_severity_to_aer);
|
||||
|
||||
void cper_print_aer(const char *prefix, int cper_severity,
|
||||
struct aer_capability_regs *aer)
|
||||
|
Reference in New Issue
Block a user