linux/drivers/pci/pcie/aer/aerdrv.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2006 Intel Corp.
   3 *      Tom Long Nguyen (tom.l.nguyen@intel.com)
   4 *      Zhang Yanmin (yanmin.zhang@intel.com)
   5 *
   6 */
   7
   8#ifndef _AERDRV_H_
   9#define _AERDRV_H_
  10
  11#include <linux/workqueue.h>
  12#include <linux/pcieport_if.h>
  13#include <linux/aer.h>
  14#include <linux/interrupt.h>
  15
  16#define AER_NONFATAL                    0
  17#define AER_FATAL                       1
  18#define AER_CORRECTABLE                 2
  19
  20#define SYSTEM_ERROR_INTR_ON_MESG_MASK  (PCI_EXP_RTCTL_SECEE|   \
  21                                        PCI_EXP_RTCTL_SENFEE|   \
  22                                        PCI_EXP_RTCTL_SEFEE)
  23#define ROOT_PORT_INTR_ON_MESG_MASK     (PCI_ERR_ROOT_CMD_COR_EN|       \
  24                                        PCI_ERR_ROOT_CMD_NONFATAL_EN|   \
  25                                        PCI_ERR_ROOT_CMD_FATAL_EN)
  26#define ERR_COR_ID(d)                   (d & 0xffff)
  27#define ERR_UNCOR_ID(d)                 (d >> 16)
  28
  29#define AER_ERROR_SOURCES_MAX           100
  30
  31#define AER_LOG_TLP_MASKS               (PCI_ERR_UNC_POISON_TLP|        \
  32                                        PCI_ERR_UNC_ECRC|               \
  33                                        PCI_ERR_UNC_UNSUP|              \
  34                                        PCI_ERR_UNC_COMP_ABORT|         \
  35                                        PCI_ERR_UNC_UNX_COMP|           \
  36                                        PCI_ERR_UNC_MALF_TLP)
  37
  38#define AER_MAX_MULTI_ERR_DEVICES       5       /* Not likely to have more */
  39struct aer_err_info {
  40        struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES];
  41        int error_dev_num;
  42
  43        unsigned int id:16;
  44
  45        unsigned int severity:2;        /* 0:NONFATAL | 1:FATAL | 2:COR */
  46        unsigned int __pad1:5;
  47        unsigned int multi_error_valid:1;
  48
  49        unsigned int first_error:5;
  50        unsigned int __pad2:2;
  51        unsigned int tlp_header_valid:1;
  52
  53        unsigned int status;            /* COR/UNCOR Error Status */
  54        unsigned int mask;              /* COR/UNCOR Error Mask */
  55        struct aer_header_log_regs tlp; /* TLP Header */
  56};
  57
  58struct aer_err_source {
  59        unsigned int status;
  60        unsigned int id;
  61};
  62
  63struct aer_rpc {
  64        struct pcie_device *rpd;        /* Root Port device */
  65        struct work_struct dpc_handler;
  66        struct aer_err_source e_sources[AER_ERROR_SOURCES_MAX];
  67        unsigned short prod_idx;        /* Error Producer Index */
  68        unsigned short cons_idx;        /* Error Consumer Index */
  69        int isr;
  70        spinlock_t e_lock;              /*
  71                                         * Lock access to Error Status/ID Regs
  72                                         * and error producer/consumer index
  73                                         */
  74        struct mutex rpc_mutex;         /*
  75                                         * only one thread could do
  76                                         * recovery on the same
  77                                         * root port hierarchy
  78                                         */
  79        wait_queue_head_t wait_release;
  80};
  81
  82struct aer_broadcast_data {
  83        enum pci_channel_state state;
  84        enum pci_ers_result result;
  85};
  86
  87static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
  88                enum pci_ers_result new)
  89{
  90        if (new == PCI_ERS_RESULT_NO_AER_DRIVER)
  91                return PCI_ERS_RESULT_NO_AER_DRIVER;
  92
  93        if (new == PCI_ERS_RESULT_NONE)
  94                return orig;
  95
  96        switch (orig) {
  97        case PCI_ERS_RESULT_CAN_RECOVER:
  98        case PCI_ERS_RESULT_RECOVERED:
  99                orig = new;
 100                break;
 101        case PCI_ERS_RESULT_DISCONNECT:
 102                if (new == PCI_ERS_RESULT_NEED_RESET)
 103                        orig = PCI_ERS_RESULT_NEED_RESET;
 104                break;
 105        default:
 106                break;
 107        }
 108
 109        return orig;
 110}
 111
 112extern struct bus_type pcie_port_bus_type;
 113extern void aer_do_secondary_bus_reset(struct pci_dev *dev);
 114extern int aer_init(struct pcie_device *dev);
 115extern void aer_isr(struct work_struct *work);
 116extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
 117extern void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info);
 118extern irqreturn_t aer_irq(int irq, void *context);
 119
 120#ifdef CONFIG_ACPI_APEI
 121extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev);
 122#else
 123static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev)
 124{
 125        if (pci_dev->__aer_firmware_first_valid)
 126                return pci_dev->__aer_firmware_first;
 127        return 0;
 128}
 129#endif
 130
 131static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev,
 132                                                 int enable)
 133{
 134        pci_dev->__aer_firmware_first = !!enable;
 135        pci_dev->__aer_firmware_first_valid = 1;
 136}
 137#endif /* _AERDRV_H_ */
 138