aerdrv.h 3.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/*
 * Copyright (C) 2006 Intel Corp.
 *	Tom Long Nguyen (tom.l.nguyen@intel.com)
 *	Zhang Yanmin (yanmin.zhang@intel.com)
 *
 */

#ifndef _AERDRV_H_
#define _AERDRV_H_

A
Alexey Dobriyan 已提交
11
#include <linux/workqueue.h>
12 13
#include <linux/pcieport_if.h>
#include <linux/aer.h>
H
Huang Ying 已提交
14
#include <linux/interrupt.h>
15 16 17 18 19 20

#define AER_NONFATAL			0
#define AER_FATAL			1
#define AER_CORRECTABLE			2

/* Root Error Status Register Bits */
21
#define ROOT_ERR_STATUS_MASKS		0x0f
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

#define SYSTEM_ERROR_INTR_ON_MESG_MASK	(PCI_EXP_RTCTL_SECEE|	\
					PCI_EXP_RTCTL_SENFEE|	\
					PCI_EXP_RTCTL_SEFEE)
#define ROOT_PORT_INTR_ON_MESG_MASK	(PCI_ERR_ROOT_CMD_COR_EN|	\
					PCI_ERR_ROOT_CMD_NONFATAL_EN|	\
					PCI_ERR_ROOT_CMD_FATAL_EN)
#define ERR_COR_ID(d)			(d & 0xffff)
#define ERR_UNCOR_ID(d)			(d >> 16)

#define AER_SUCCESS			0
#define AER_UNSUCCESS			1
#define AER_ERROR_SOURCES_MAX		100

#define AER_LOG_TLP_MASKS		(PCI_ERR_UNC_POISON_TLP|	\
					PCI_ERR_UNC_ECRC|		\
					PCI_ERR_UNC_UNSUP|		\
					PCI_ERR_UNC_COMP_ABORT|		\
					PCI_ERR_UNC_UNX_COMP|		\
					PCI_ERR_UNC_MALF_TLP)

/* AER Error Info Flags */
#define AER_TLP_HEADER_VALID_FLAG	0x00000001
#define AER_MULTI_ERROR_VALID_FLAG	0x00000002

struct header_log_regs {
	unsigned int dw0;
	unsigned int dw1;
	unsigned int dw2;
	unsigned int dw3;
};

Z
Zhang, Yanmin 已提交
54
#define AER_MAX_MULTI_ERR_DEVICES	5	/* Not likely to have more */
55
struct aer_err_info {
Z
Zhang, Yanmin 已提交
56 57
	struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES];
	int error_dev_num;
58
	u16 id;
59 60
	int severity;			/* 0:NONFATAL | 1:FATAL | 2:COR */
	int flags;
61
	int first;
62
	unsigned int status;		/* COR/UNCOR Error Status */
63
	unsigned int mask;		/* COR/UNCOR Error Mask */
64
	struct header_log_regs tlp;	/* TLP Header */
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
};

struct aer_err_source {
	unsigned int status;
	unsigned int id;
};

struct aer_rpc {
	struct pcie_device *rpd;	/* Root Port device */
	struct work_struct dpc_handler;
	struct aer_err_source e_sources[AER_ERROR_SOURCES_MAX];
	unsigned short prod_idx;	/* Error Producer Index */
	unsigned short cons_idx;	/* Error Consumer Index */
	int isr;
	spinlock_t e_lock;		/*
					 * Lock access to Error Status/ID Regs
					 * and error producer/consumer index
					 */
	struct mutex rpc_mutex;		/*
					 * only one thread could do
					 * recovery on the same
86
					 * root port hierarchy
87 88 89 90 91 92 93 94 95 96 97 98
					 */
	wait_queue_head_t wait_release;
};

struct aer_broadcast_data {
	enum pci_channel_state state;
	enum pci_ers_result result;
};

static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
		enum pci_ers_result new)
{
99 100 101
	if (new == PCI_ERS_RESULT_NONE)
		return orig;

102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
	switch (orig) {
	case PCI_ERS_RESULT_CAN_RECOVER:
	case PCI_ERS_RESULT_RECOVERED:
		orig = new;
		break;
	case PCI_ERS_RESULT_DISCONNECT:
		if (new == PCI_ERS_RESULT_NEED_RESET)
			orig = new;
		break;
	default:
		break;
	}

	return orig;
}

extern struct bus_type pcie_port_bus_type;
extern void aer_enable_rootport(struct aer_rpc *rpc);
extern void aer_delete_rootport(struct aer_rpc *rpc);
extern int aer_init(struct pcie_device *dev);
122
extern void aer_isr(struct work_struct *work);
123
extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
H
Huang Ying 已提交
124
extern irqreturn_t aer_irq(int irq, void *context);
125 126 127 128 129 130 131 132 133

#ifdef CONFIG_ACPI
extern int aer_osc_setup(struct pcie_device *pciedev);
#else
static inline int aer_osc_setup(struct pcie_device *pciedev)
{
	return 0;
}
#endif
134

135
#endif /* _AERDRV_H_ */