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