linux/drivers/pci/pcie/aer.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Implement the AER root port service driver. The driver registers an IRQ
 * handler. When a root port triggers an AER interrupt, the IRQ handler
 * collects root port status and schedules work.
 *
 * Copyright (C) 2006 Intel Corp.
 *	Tom Long Nguyen ([email protected])
 *	Zhang Yanmin ([email protected])
 *
 * (C) Copyright 2009 Hewlett-Packard Development Company, L.P.
 *    Andrew Patterson <[email protected]>
 */

#define pr_fmt(fmt)
#define dev_fmt

#include <linux/bitops.h>
#include <linux/cper.h>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/pm.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/kfifo.h>
#include <linux/slab.h>
#include <acpi/apei.h>
#include <acpi/ghes.h>
#include <ras/ras_event.h>

#include "../pci.h"
#include "portdrv.h"

#define AER_ERROR_SOURCES_MAX

#define AER_MAX_TYPEOF_COR_ERRS
#define AER_MAX_TYPEOF_UNCOR_ERRS

struct aer_err_source {};

struct aer_rpc {};

/* AER stats for the device */
struct aer_stats {};

#define AER_LOG_TLP_MASKS

#define SYSTEM_ERROR_INTR_ON_MESG_MASK
#define ROOT_PORT_INTR_ON_MESG_MASK
#define ERR_COR_ID(d)
#define ERR_UNCOR_ID(d)

#define AER_ERR_STATUS_MASK

static int pcie_aer_disable;
static pci_ers_result_t aer_root_reset(struct pci_dev *dev);

void pci_no_aer(void)
{}

bool pci_aer_available(void)
{}

#ifdef CONFIG_PCIE_ECRC

#define ECRC_POLICY_DEFAULT
#define ECRC_POLICY_OFF
#define ECRC_POLICY_ON

static int ecrc_policy =;

static const char * const ecrc_policy_str[] =;

/**
 * enable_ecrc_checking - enable PCIe ECRC checking for a device
 * @dev: the PCI device
 *
 * Returns 0 on success, or negative on failure.
 */
static int enable_ecrc_checking(struct pci_dev *dev)
{}

/**
 * disable_ecrc_checking - disables PCIe ECRC checking for a device
 * @dev: the PCI device
 *
 * Returns 0 on success, or negative on failure.
 */
static int disable_ecrc_checking(struct pci_dev *dev)
{}

/**
 * pcie_set_ecrc_checking - set/unset PCIe ECRC checking for a device based on global policy
 * @dev: the PCI device
 */
void pcie_set_ecrc_checking(struct pci_dev *dev)
{}

/**
 * pcie_ecrc_get_policy - parse kernel command-line ecrc option
 * @str: ECRC policy from kernel command line to use
 */
void pcie_ecrc_get_policy(char *str)
{}
#endif	/* CONFIG_PCIE_ECRC */

#define PCI_EXP_AER_FLAGS

int pcie_aer_is_native(struct pci_dev *dev)
{}
EXPORT_SYMBOL_NS_GPL();

static int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{}

int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
{}
EXPORT_SYMBOL_GPL();

void pci_aer_clear_fatal_status(struct pci_dev *dev)
{}

/**
 * pci_aer_raw_clear_status - Clear AER error registers.
 * @dev: the PCI device
 *
 * Clearing AER error status registers unconditionally, regardless of
 * whether they're owned by firmware or the OS.
 *
 * Returns 0 on success, or negative on failure.
 */
int pci_aer_raw_clear_status(struct pci_dev *dev)
{}

int pci_aer_clear_status(struct pci_dev *dev)
{}

void pci_save_aer_state(struct pci_dev *dev)
{}

void pci_restore_aer_state(struct pci_dev *dev)
{}

void pci_aer_init(struct pci_dev *dev)
{}

void pci_aer_exit(struct pci_dev *dev)
{}

#define AER_AGENT_RECEIVER
#define AER_AGENT_REQUESTER
#define AER_AGENT_COMPLETER
#define AER_AGENT_TRANSMITTER

#define AER_AGENT_REQUESTER_MASK(t)
#define AER_AGENT_COMPLETER_MASK(t)
#define AER_AGENT_TRANSMITTER_MASK(t)

#define AER_GET_AGENT(t, e)

#define AER_PHYSICAL_LAYER_ERROR
#define AER_DATA_LINK_LAYER_ERROR
#define AER_TRANSACTION_LAYER_ERROR

#define AER_PHYSICAL_LAYER_ERROR_MASK(t)
#define AER_DATA_LINK_LAYER_ERROR_MASK(t)

#define AER_GET_LAYER_ERROR(t, e)

/*
 * AER error strings
 */
static const char * const aer_error_severity_string[] =;

static const char *aer_error_layer[] =;

static const char *aer_correctable_error_string[] =;

static const char *aer_uncorrectable_error_string[] =;

static const char *aer_agent_string[] =;

#define aer_stats_dev_attr(name, stats_array, strings_array,		\
			   total_string, total_field)

aer_stats_dev_attr();
aer_stats_dev_attr();
aer_stats_dev_attr();

#define aer_stats_rootport_attr(name, field)

aer_stats_rootport_attr();
aer_stats_rootport_attr();
aer_stats_rootport_attr();

static struct attribute *aer_stats_attrs[] __ro_after_init =;

static umode_t aer_stats_attrs_are_visible(struct kobject *kobj,
					   struct attribute *a, int n)
{}

const struct attribute_group aer_stats_attr_group =;

static void pci_dev_aer_stats_incr(struct pci_dev *pdev,
				   struct aer_err_info *info)
{}

static void pci_rootport_aer_stats_incr(struct pci_dev *pdev,
				 struct aer_err_source *e_src)
{}

static void __print_tlp_header(struct pci_dev *dev, struct pcie_tlp_log *t)
{}

static void __aer_print_error(struct pci_dev *dev,
			      struct aer_err_info *info)
{}

void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
{}

static void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
{}

#ifdef CONFIG_ACPI_APEI_PCIEAER
int cper_severity_to_aer(int cper_severity)
{}
EXPORT_SYMBOL_GPL();
#endif

void pci_print_aer(struct pci_dev *dev, int aer_severity,
		   struct aer_capability_regs *aer)
{}
EXPORT_SYMBOL_NS_GPL();

/**
 * add_error_device - list device to be handled
 * @e_info: pointer to error info
 * @dev: pointer to pci_dev to be added
 */
static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev)
{}

/**
 * is_error_source - check whether the device is source of reported error
 * @dev: pointer to pci_dev to be checked
 * @e_info: pointer to reported error info
 */
static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info)
{}

static int find_device_iter(struct pci_dev *dev, void *data)
{}

/**
 * find_source_device - search through device hierarchy for source device
 * @parent: pointer to Root Port pci_dev data structure
 * @e_info: including detailed error information such like id
 *
 * Return true if found.
 *
 * Invoked by DPC when error is detected at the Root Port.
 * Caller of this function must set id, severity, and multi_error_valid of
 * struct aer_err_info pointed by @e_info properly.  This function must fill
 * e_info->error_dev_num and e_info->dev[], based on the given information.
 */
static bool find_source_device(struct pci_dev *parent,
		struct aer_err_info *e_info)
{}

#ifdef CONFIG_PCIEAER_CXL

/**
 * pci_aer_unmask_internal_errors - unmask internal errors
 * @dev: pointer to the pcie_dev data structure
 *
 * Unmasks internal errors in the Uncorrectable and Correctable Error
 * Mask registers.
 *
 * Note: AER must be enabled and supported by the device which must be
 * checked in advance, e.g. with pcie_aer_is_native().
 */
static void pci_aer_unmask_internal_errors(struct pci_dev *dev)
{}

static bool is_cxl_mem_dev(struct pci_dev *dev)
{}

static bool cxl_error_is_native(struct pci_dev *dev)
{}

static bool is_internal_error(struct aer_err_info *info)
{}

static int cxl_rch_handle_error_iter(struct pci_dev *dev, void *data)
{}

static void cxl_rch_handle_error(struct pci_dev *dev, struct aer_err_info *info)
{}

static int handles_cxl_error_iter(struct pci_dev *dev, void *data)
{}

static bool handles_cxl_errors(struct pci_dev *rcec)
{}

static void cxl_rch_enable_rcec(struct pci_dev *rcec)
{}

#else
static inline void cxl_rch_enable_rcec(struct pci_dev *dev) { }
static inline void cxl_rch_handle_error(struct pci_dev *dev,
					struct aer_err_info *info) { }
#endif

/**
 * pci_aer_handle_error - handle logging error into an event log
 * @dev: pointer to pci_dev data structure of error source device
 * @info: comprehensive error information
 *
 * Invoked when an error being detected by Root Port.
 */
static void pci_aer_handle_error(struct pci_dev *dev, struct aer_err_info *info)
{}

static void handle_error_source(struct pci_dev *dev, struct aer_err_info *info)
{}

#ifdef CONFIG_ACPI_APEI_PCIEAER

#define AER_RECOVER_RING_SIZE

struct aer_recover_entry {};

static DEFINE_KFIFO(aer_recover_ring, } ;

static void aer_recover_work_func(struct work_struct *work)
{}

/*
 * 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, struct aer_capability_regs *aer_regs)
{}
EXPORT_SYMBOL_GPL();
#endif

/**
 * aer_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
 * @info: pointer to structure to store the error record
 *
 * Return 1 on success, 0 on error.
 *
 * Note that @info is reused among all error devices. Clear fields properly.
 */
int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
{}

static inline void aer_process_err_devices(struct aer_err_info *e_info)
{}

/**
 * aer_isr_one_error - consume an error detected by root port
 * @rpc: pointer to the root port which holds an error
 * @e_src: pointer to an error source
 */
static void aer_isr_one_error(struct aer_rpc *rpc,
		struct aer_err_source *e_src)
{}

/**
 * aer_isr - consume errors detected by root port
 * @irq: IRQ assigned to Root Port
 * @context: pointer to Root Port data structure
 *
 * Invoked, as DPC, when root port records new detected error
 */
static irqreturn_t aer_isr(int irq, void *context)
{}

/**
 * aer_irq - Root Port's ISR
 * @irq: IRQ assigned to Root Port
 * @context: pointer to Root Port data structure
 *
 * Invoked when Root Port detects AER messages.
 */
static irqreturn_t aer_irq(int irq, void *context)
{}

static void aer_enable_irq(struct pci_dev *pdev)
{}

static void aer_disable_irq(struct pci_dev *pdev)
{}

/**
 * aer_enable_rootport - enable Root Port's interrupts when receiving messages
 * @rpc: pointer to a Root Port data structure
 *
 * Invoked when PCIe bus loads AER service driver.
 */
static void aer_enable_rootport(struct aer_rpc *rpc)
{}

/**
 * aer_disable_rootport - disable Root Port's interrupts when receiving messages
 * @rpc: pointer to a Root Port data structure
 *
 * Invoked when PCIe bus unloads AER service driver.
 */
static void aer_disable_rootport(struct aer_rpc *rpc)
{}

/**
 * aer_remove - clean up resources
 * @dev: pointer to the pcie_dev data structure
 *
 * Invoked when PCI Express bus unloads or AER probe fails.
 */
static void aer_remove(struct pcie_device *dev)
{}

/**
 * aer_probe - initialize resources
 * @dev: pointer to the pcie_dev data structure
 *
 * Invoked when PCI Express bus loads AER service driver.
 */
static int aer_probe(struct pcie_device *dev)
{}

static int aer_suspend(struct pcie_device *dev)
{}

static int aer_resume(struct pcie_device *dev)
{}

/**
 * aer_root_reset - reset Root Port hierarchy, RCEC, or RCiEP
 * @dev: pointer to Root Port, RCEC, or RCiEP
 *
 * Invoked by Port Bus driver when performing reset.
 */
static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
{}

static struct pcie_port_service_driver aerdriver =;

/**
 * pcie_aer_init - register AER root service driver
 *
 * Invoked when AER root service driver is loaded.
 */
int __init pcie_aer_init(void)
{}