public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 6/6] PCI Express Advanced Error Reporting Driver
@ 2005-03-12  0:17 long
  0 siblings, 0 replies; only message in thread
From: long @ 2005-03-12  0:17 UTC (permalink / raw)
  To: linux-kernel, linux-pci; +Cc: greg, tom.l.nguyen

This patch includes the source code of startup component (last patch
to be applied) of PCI Express Advanced Error Reporting driver.

Signed-off-by: T. Long Nguyen <tom.l.nguyen@intel.com>

--------------------------------------------------------------------
diff -urpN linux-2.6.11-rc5/arch/i386/Kconfig patch-2.6.11-rc5-aerc3-split6/arch/i386/Kconfig
--- linux-2.6.11-rc5/arch/i386/Kconfig	2005-02-24 11:39:54.000000000 -0500
+++ patch-2.6.11-rc5-aerc3-split6/arch/i386/Kconfig	2005-03-11 11:28:42.000000000 -0500
@@ -1131,8 +1131,6 @@ config PCI_MMCONFIG
 	select ACPI_BOOT
 	default y
 
-source "drivers/pci/pcie/Kconfig"
-
 source "drivers/pci/Kconfig"
 
 config ISA
diff -urpN linux-2.6.11-rc5/drivers/pci/Kconfig patch-2.6.11-rc5-aerc3-split6/drivers/pci/Kconfig
--- linux-2.6.11-rc5/drivers/pci/Kconfig	2005-02-24 11:40:05.000000000 -0500
+++ patch-2.6.11-rc5-aerc3-split6/drivers/pci/Kconfig	2005-03-11 12:17:29.000000000 -0500
@@ -1,4 +1,9 @@
 #
+# PCI Express configuration
+#
+source "drivers/pci/pcie/Kconfig"
+
+#
 # PCI configuration
 #
 config PCI_MSI
diff -urpN linux-2.6.11-rc5/drivers/pci/pcie/aer/aerdrv.c patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/aer/aerdrv.c
--- linux-2.6.11-rc5/drivers/pci/pcie/aer/aerdrv.c	1969-12-31 19:00:00.000000000 -0500
+++ patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/aer/aerdrv.c	2005-03-10 10:25:15.000000000 -0500
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2005 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pcieport_if.h>
+
+#include "aerdrv.h"
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v1.0"
+#define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
+#define DRIVER_DESC "Root Port Advanced Error Reporting Driver"
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+static int __devinit aerdrv_probe (struct pcie_device *dev, 
+	const struct pcie_port_service_id *id );
+static void aerdrv_remove(struct pcie_device *dev);
+static int aerdrv_suspend(struct pcie_device *dev, u32 state) {return 0;}
+static int aerdrv_resume(struct pcie_device *dev) {return 0;}
+
+/*
+ * PCI Express bus's AER Root service driver data structure
+ */
+static struct pcie_port_service_id service_id[] = { { 
+	.vendor = PCI_ANY_ID, 
+	.device = PCI_ANY_ID,
+	.port_type = PCIE_RC_PORT, 
+	.service_type = PCIE_PORT_SERVICE_AER,
+	}, { /* end: all zeroes */ }
+};
+
+static struct pcie_port_service_driver root_aerdrv = {
+	.name		= "aer",
+	.id_table	= &service_id[0],
+
+	.probe		= aerdrv_probe,
+	.remove		= aerdrv_remove,
+
+	.suspend	= aerdrv_suspend,
+	.resume		= aerdrv_resume,
+};
+
+/**
+ * aerdrv_irq - Root Port's ISR
+ * @irq: IRQ assigned to Root Port
+ * @context: pointer to Root Port data structure
+ * @r: pointer struct pt_regs
+ *
+ * Invoked when Root Port detects AER messages.
+ **/
+irqreturn_t aerdrv_irq(int irq, void *context, struct pt_regs * r)
+{
+	unsigned int status, id;
+	struct pcie_device *pdev = (struct pcie_device *)context;
+	struct aer_rpc *rpc = get_service_data(pdev);
+	int next_prod_idx;
+	unsigned long flags;
+
+	/* 
+	 * Must lock access to Root Error Status Reg, Root Error ID Reg, 
+	 * and Root error producer/consumer index 
+	 */
+	spin_lock_irqsave(&rpc->e_lock, flags);
+
+	/* Read error status */
+	pci_read_config_dword(pdev->port, ROOT_ERROR_STATUS_REG, &status);
+	if (!(status & ROOT_ERR_STATUS_MASKS)) {
+		spin_unlock_irqrestore(&rpc->e_lock, flags);
+		return IRQ_NONE;
+	}
+
+	/* Read error source and clear error status */
+	pci_read_config_dword(pdev->port, CORRECTABLE_SOURCE_ID_REG, &id);
+	pci_write_config_dword(pdev->port, ROOT_ERROR_STATUS_REG, status);
+	
+	/* Store error source for later DPC handler */
+	next_prod_idx = rpc->prod_idx + 1;
+	if (next_prod_idx == AER_ERROR_SOURCES_MAX)
+		next_prod_idx = 0;
+	if (next_prod_idx == rpc->cons_idx) {
+		/* 
+		 * Error Storm Condition - possibly the same error occurred.
+		 * Drop the error.
+		 */
+		spin_unlock_irqrestore(&rpc->e_lock, flags);
+		return IRQ_HANDLED;
+	} 
+	rpc->e_sources[rpc->prod_idx].status =  status & ROOT_ERR_STATUS_MASKS;
+	rpc->e_sources[rpc->prod_idx].id =  id;
+	rpc->prod_idx = next_prod_idx;
+	spin_unlock_irqrestore(&rpc->e_lock, flags);
+	
+	/*  Invoke DPC handler */
+	schedule_work(&rpc->dpc_handler);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * aerdrv_alloc_rpc - allocate Root Port data structure
+ * @dev: pointer to the pcie_dev data structure
+ *
+ * Invoked when Root Port's AER service is loaded.
+ **/
+static struct aer_rpc* aerdrv_alloc_rpc(struct pcie_device *dev)
+{
+	struct aer_rpc *rpc;
+	struct pci_dev *pdev = dev->port;
+	unsigned int busnr;
+
+	if (!(rpc = (struct aer_rpc *)kmalloc(sizeof(struct aer_rpc), 
+		GFP_KERNEL)))
+		return NULL;
+
+	memset(rpc, 0, sizeof(struct aer_rpc));
+	/* 
+	 * Initialize Root lock access, e_lock, to Root Error Status Reg, 
+	 * Root Error ID Reg, and Root error producer/consumer index. 
+	 */
+	rpc->e_lock = SPIN_LOCK_UNLOCKED; 		
+
+	/* 
+	 * Initialize semaphore access required to access, add, remove,
+	 * or print AER aware devices in this RPC hierarchy 
+	 */
+	sema_init(&rpc->rpc_sema, 1);
+
+	INIT_LIST_HEAD(&rpc->node);
+	INIT_LIST_HEAD(&rpc->children);
+	rpc->rpd = dev;
+	rpc->self_id = (pdev->bus->number << 8) | pdev->devfn;	
+	pci_read_config_dword(pdev, PCI_PRIMARY_BUS, &busnr);
+	rpc->primary = busnr & 0xff;
+	rpc->secondary = (busnr >> 8) & 0xff;
+	rpc->subordinate = (busnr >> 16) & 0xff;
+	INIT_WORK(&rpc->dpc_handler, aer_isr, (void *)dev);
+	rpc->prod_idx = rpc->cons_idx = 0;
+
+	/* Use PCIE bus function to store rpc into PCIE device */
+	set_service_data(dev, rpc);	
+	
+	return rpc;
+}
+
+/**
+ * aerdrv_remove - clean up resources
+ * @dev: pointer to the pcie_dev data structure
+ *
+ * Invoked when PCI Express bus unloads or AER probe fails.
+ **/
+static void aerdrv_remove(struct pcie_device *dev)
+{
+	struct aer_rpc *rpc = get_service_data(dev);
+	struct device *device = &dev->device;
+
+	if (rpc) {
+		/* If register interrupt service, it must be free. */
+		if (rpc->isr)			
+			free_irq(dev->irq, dev);
+
+		/* Delete this node from a RC hierarchy */
+		aer_delete_rootport(rpc);
+		set_service_data(dev, NULL);
+	}
+
+	/* Clean up */
+	aer_cleanup(to_service_driver(device->driver));
+}
+
+/**
+ * aerdrv_probe - initialize resources
+ * @dev: pointer to the pcie_dev data structure
+ * @id: pointer to the service id data structure
+ *
+ * Invoked when PCI Express bus loads AER service driver.
+ **/
+static int __devinit aerdrv_probe (struct pcie_device *dev, 
+				const struct pcie_port_service_id *id )
+{
+	int status;
+	struct aer_rpc *rpc;
+	struct device *device = &dev->device;
+
+	/* Init */
+	if ((status = aer_init(&root_aerdrv))) {
+		printk(KERN_DEBUG "%s: AER service init fails - %s\n",
+			__FUNCTION__, (status == OSC_METHOD_NOT_SUPPORTED) ? 
+			"No ACPI _OSC support" : "Run ACPI _OSC fails");
+		return status;
+	}
+
+	/* Alloc rpc data structure */
+	if (!(rpc = aerdrv_alloc_rpc(dev))) {
+		printk(KERN_DEBUG "%s: Alloc rpc fails on PCIE device[%s]\n",
+			__FUNCTION__, device->bus_id);
+		aerdrv_remove(dev);
+		return -ENOMEM;
+	}
+
+	/* Request IRQ ISR */
+	if ((status = request_irq(dev->irq, aerdrv_irq, SA_SHIRQ, "aerdrv", 
+				dev))) {
+		printk(KERN_DEBUG "%s: Request ISR fails on PCIE device[%s]\n", 
+			__FUNCTION__, device->bus_id);
+		aerdrv_remove(dev);
+		return status;
+	}
+	rpc->isr = 1;	
+
+	/* Add rpc into a RC hierarchy */
+	if ((status = aer_add_rootport(rpc))) {
+		printk(KERN_DEBUG "%s: Add rpc fails on PCIE device[%s]\n", 
+			__FUNCTION__, device->bus_id);
+		aerdrv_remove(dev);
+	}
+
+	return status;
+}
+
+/**
+ * aerdrv_service_init - register AER root service driver
+ *
+ * Invoked when AER root service driver is loaded.
+ **/
+static int __init aerdrv_service_init(void)
+{
+	return pcie_port_service_register(&root_aerdrv);
+}
+
+/**
+ * aerdrv_service_exit - unregister AER root service driver
+ *
+ * Invoked when AER root service driver is unloaded.
+ **/
+static void __exit aerdrv_service_exit(void) 
+{
+	pcie_port_service_unregister(&root_aerdrv);
+}
+
+module_init(aerdrv_service_init);
+module_exit(aerdrv_service_exit);
diff -urpN linux-2.6.11-rc5/drivers/pci/pcie/aer/aerdrv.h patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/aer/aerdrv.h
--- linux-2.6.11-rc5/drivers/pci/pcie/aer/aerdrv.h	1969-12-31 19:00:00.000000000 -0500
+++ patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/aer/aerdrv.h	2005-03-10 10:32:52.000000000 -0500
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2005 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ *
+ */
+
+#ifndef _AERDRV_H_
+#define _AERDRV_H_
+
+#include <linux/pcieport_if.h>
+#include <linux/aer.h>
+#include "aerdrv_event.h"
+
+#define VERBOSE_LIMIT_DISPLAY		1
+#define VERBOSE_FULL_DISPLAY		2
+#define VERBOSE_RAW_DISPLAY		3
+#define VERBOSE_MASK			0x3 
+
+#define OSC_METHOD_RUN_SUCCESS		0
+#define OSC_METHOD_NOT_SUPPORTED	1
+#define OSC_METHOD_RUN_FAILURE		2
+
+#define PCIE_PORT_TYPE_MASK		0xf
+#define PCIE_PORT(d)			((d & 0x4) && (d != 0x7))
+#define PCIE_ROOT_PORT(d)		(d == PCIE_RC_PORT)
+#define PCIE_SWITCH_PORT(d)		(PCIE_PORT(d) && !PCIE_ROOT_PORT(d)) 
+
+/* Root Device Control Register Bits */
+#define ROOT_ERR_COR_REPORT_ENABLE_BIT		1
+#define ROOT_ERR_NONFATAL_REPORT_ENABLE_BIT	2
+#define ROOT_ERR_FATAL_REPORT_ENABLE_BIT	4
+#define ROOT_ERR_UR_REPORT_ENABLE_BIT		8
+#define ROOT_ERR_REPORT_ENABLE_BITS	(ROOT_ERR_COR_REPORT_ENABLE_BIT | \
+					ROOT_ERR_NONFATAL_REPORT_ENABLE_BIT | \
+					ROOT_ERR_FATAL_REPORT_ENABLE_BIT | \
+					ROOT_ERR_UR_REPORT_ENABLE_BIT)
+
+/* Root Error Status Register Bits */
+#define ROOT_ERR_STATUS_COR_BIT_MASK		0x01
+#define ROOT_ERR_STATUS_MULTI_COR_BIT_MASK	0x02
+#define ROOT_ERR_STATUS_UNCOR_BIT_MASK		0x04
+#define ROOT_ERR_STATUS_MULTI_UNCOR_BIT_MASK 	0x08
+#define ROOT_ERR_STATUS_MASKS			0x0f
+#define ROOT_ERR_STATUS_CORRECTABLE(d)	(d & (ROOT_ERR_STATUS_COR_BIT_MASK | \
+					ROOT_ERR_STATUS_MULTI_COR_BIT_MASK))
+#define ROOT_ERR_STATUS_UNCORRECTABLE(d) (d & (ROOT_ERR_STATUS_UNCOR_BIT_MASK |\
+					ROOT_ERR_STATUS_MULTI_UNCOR_BIT_MASK))
+
+#define SYSTEM_ERROR_INTR_ON_MESG_DISABLED	0xfff8
+#define ROOT_PORT_INTR_ON_MESG_ENABLED		0x7
+#define ERR_SOURCE_ID_MASK			0xffff
+#define ERR_COR_ID(d)			(d & ERR_SOURCE_ID_MASK)
+#define ERR_UNCOR_ID(d)			(d >> 16)
+#define FIRST_ERROR(d)			(d & 1)
+#define NEXT_ERROR(d)			((d >> 1) & 1)
+
+#define AER_DEVICE_BUS(id)		(id >> 8)
+#define AER_DEVICE_DEV(id)		((id >> 3) & 0x1f)
+#define AER_DEVICE_FUNC(id)		(id & 0x7)
+	
+#define ROOT_CONFIG_COR_ERROR_MASKS	0
+#define ROOT_CONFIG_UNCOR_ERROR_SEVERITY (ERR_TRAINING |		\
+					ERR_DATA_LINK_PROTOCOL | 	\
+					ERR_RECEIVER_OVERFLOW | 	\
+					ERR_MALFORMED_TLP)
+#define ROOT_CONFIG_UNCOR_ERROR_MASKS	0
+#define AER_SUCCESS			0
+#define AER_UNSUCCESS			1
+#define AER_ERROR_SOURCES_MAX		100
+
+#define AER_LOG_TLP_MASKS		(ERR_POISONED_TLP |		\
+					ERR_ECRC |			\
+					ERR_UNSUPPORTED_REQUEST	|	\
+					ERR_COMPLETION_ABORT |		\
+					ERR_COMPLETION_UNEXPECT |	\
+					ERR_MALFORMED_TLP)
+
+struct err_source {
+	unsigned int status;
+	unsigned int id;
+};
+
+struct aer_rpc {
+ 	struct list_head node;
+ 	struct list_head children;	/* AER children of this root port */
+	struct pcie_device *rpd;	/* Root Port device */
+	struct work_struct dpc_handler;
+	struct err_source e_sources[AER_ERROR_SOURCES_MAX];
+	unsigned short prod_idx;	/* Error Producer Index */
+	unsigned short cons_idx;	/* Error Consumer Index */
+	unsigned short self_id;
+	int isr;
+	int primary;			/* Primary bus of this node */
+	int secondary;			/* Secondary bus of this node */
+	int subordinate; 		/* Subordinate bus of this node */
+
+	spinlock_t e_lock;		/* 
+					 * Lock access to Error Status/ID Regs
+					 * and error producer/consumer index 
+					 */
+ 
+	struct semaphore rpc_sema;	/* 
+					 * Semaphore access required to
+					 * access, add, remove, or print AER 
+				 	 * aware devices in this RPC hierarchy 
+					 */
+};
+
+union aer_device_attrib {
+	int type;
+	struct {
+		int type;
+		struct {
+			unsigned int primary		: 8;
+			unsigned int secondary		: 8;
+			unsigned int subordinate	: 8;
+			unsigned int reserved		: 8;
+		} bus;
+	} p2p;
+};
+
+struct aer_device_flags {
+	unsigned short tlp 	: 1;	/* Whether TLP header is available */
+	unsigned short reset 	: 1;	/* Whether a link reset is performed */
+	unsigned short multi	: 1;	/* Whether an error is first or multi */
+	unsigned short reserved : 13;
+};
+
+struct aer_device {
+ 	struct aer_device *parent;
+ 	struct list_head node;
+	struct list_head children;
+	struct pcie_aer_handle *handle;
+	unsigned short vendor;
+	unsigned short device;
+	unsigned int class_code;
+	unsigned short requestor_id;
+	struct aer_device_flags flags;
+	struct header_log_regs tlp;
+	union aer_device_attrib attribute;
+	
+	/* Error Frequency */
+	int correctables;
+	int uncorrectables;
+	int nonfatals;
+	int fatals;
+
+	/* Last Recorded */
+	union aer_error last_recorded_err;	
+	struct aer_record_time_stamp time_stamp;
+	
+	struct semaphore d_sema;	/* 
+					 * Used when logging an error
+					 *  reported by this device 
+					 */	
+};
+#define to_aer_device(d) container_of(d, struct aer_device, gendev)
+
+extern struct pcie_aer_handle aer_root_handle;
+extern struct pci_dev* get_root_pci_dev(unsigned short requestor_id);
+extern int aer_get_verbose(void);
+extern int aer_get_auto_mode(void);
+extern void aer_log_event(struct aer_device *dev);
+extern void aer_send_alert(union aer_error *error);
+extern int aer_event_log_init(void);
+extern void aer_event_log_cleanup(void);
+extern int aer_get_record(char *page, int verbose);
+extern void aer_set_auto_consume(void);
+extern int aer_sysfs_init(struct device_driver *drv);
+extern void aer_sysfs_cleanup(struct device_driver *drv);
+extern int aer_add_rootport(struct aer_rpc *rpc);
+extern void aer_delete_rootport(struct aer_rpc *rpc);
+extern int aer_init(struct pcie_port_service_driver *drv);
+extern void aer_cleanup(struct pcie_port_service_driver *drv);
+extern void aer_isr(void *context);
+extern char* aer_get_error_source_name(union aer_error *error);
+
+#endif //_AERDRV_H_
diff -urpN linux-2.6.11-rc5/drivers/pci/pcie/aer/Kconfig patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/aer/Kconfig
--- linux-2.6.11-rc5/drivers/pci/pcie/aer/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/aer/Kconfig	2005-03-09 13:25:36.000000000 -0500
@@ -0,0 +1,13 @@
+#
+# Root Port Device Configuration
+#
+
+config PCIEAER
+	bool "Root Port Advanced Error Reporting support"
+	depends on PCIEPORTBUS 
+	default y
+
+	---help---
+	This enables Root Port Advanced Error Reporting (AER) driver
+	support. Error reporting messages sent to Root Port will be
+	handled by PCI Express AER driver.	
diff -urpN linux-2.6.11-rc5/drivers/pci/pcie/aer/Makefile patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/aer/Makefile
--- linux-2.6.11-rc5/drivers/pci/pcie/aer/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/aer/Makefile	2005-03-10 10:33:41.000000000 -0500
@@ -0,0 +1,8 @@
+#
+# Makefile for PCI-Express Root Port Advanced Error Reporting Driver
+#
+
+aerdriver-y		:= aerdrv_sysfs.o aerdrv_event.o aerdrv_core.o \
+			   aerdrv_rpc_handle.o aerdrv.o
+
+obj-$(CONFIG_PCIEAER)	+= aerdriver.o
diff -urpN linux-2.6.11-rc5/drivers/pci/pcie/Kconfig patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/Kconfig
--- linux-2.6.11-rc5/drivers/pci/pcie/Kconfig	2005-02-24 11:40:54.000000000 -0500
+++ patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/Kconfig	2005-03-11 11:25:29.000000000 -0500
@@ -36,3 +36,4 @@ config HOTPLUG_PCI_PCIE_POLL_EVENT_MODE
 	   
 	  When in doubt, say N.
 
+source "drivers/pci/pcie/aer/Kconfig"
diff -urpN linux-2.6.11-rc5/drivers/pci/pcie/Makefile patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/Makefile
--- linux-2.6.11-rc5/drivers/pci/pcie/Makefile	2005-02-24 11:39:47.000000000 -0500
+++ patch-2.6.11-rc5-aerc3-split6/drivers/pci/pcie/Makefile	2005-03-11 11:24:21.000000000 -0500
@@ -5,3 +5,6 @@
 pcieportdrv-y			:= portdrv_core.o portdrv_pci.o portdrv_bus.o
 
 obj-$(CONFIG_PCIEPORTBUS)	+= pcieportdrv.o
+
+# Build PCI Express AER if needed
+obj-$(CONFIG_PCIEAER)		+= aer/
diff -urpN linux-2.6.11-rc5/include/linux/aer.h patch-2.6.11-rc5-aerc3-split6/include/linux/aer.h
--- linux-2.6.11-rc5/include/linux/aer.h	1969-12-31 19:00:00.000000000 -0500
+++ patch-2.6.11-rc5-aerc3-split6/include/linux/aer.h	2005-03-11 11:27:27.000000000 -0500
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2005 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ *
+ */
+
+#ifndef _AER_H_
+#define _AER_H_
+
+/* PCI Express Capability Structure's Register Offset */
+#define PCIE_CAP_DEVICE_CONTROL_REG_OFF	0x08
+#define PCIE_CAP_DEVICE_STATUS_REG_OFF	0x0a
+#define PCIE_CAP_ROOT_CONTROL_REG_OFF	0x1c
+
+/* PCI Express Enhanced Capability Header */
+#define PCIE_ENHANCED_CAP_HEADER	0x100
+#define UNCORRECTABLE_ERROR_STATUS_REG	(PCIE_ENHANCED_CAP_HEADER | 0x04) 
+#define UNCORRECTABLE_ERROR_MASK_REG	(PCIE_ENHANCED_CAP_HEADER | 0x08) 
+#define UNCORRECTABLE_ERROR_SEVERITY_REG (PCIE_ENHANCED_CAP_HEADER | 0x0c) 
+#define CORRECTABLE_ERROR_STATUS_REG	(PCIE_ENHANCED_CAP_HEADER | 0x10) 
+#define CORRECTABLE_ERROR_MASK_REG	(PCIE_ENHANCED_CAP_HEADER | 0x14) 
+#define ADVANCE_CAPABILITY_CONTROL_REG	(PCIE_ENHANCED_CAP_HEADER | 0x18) 
+#define HEADER_LOG_REG			(PCIE_ENHANCED_CAP_HEADER | 0x1c) 
+#define ROOT_ERROR_COMMAND_REG		(PCIE_ENHANCED_CAP_HEADER | 0x2c) 
+#define ROOT_ERROR_STATUS_REG		(PCIE_ENHANCED_CAP_HEADER | 0x30) 
+#define CORRECTABLE_SOURCE_ID_REG	(PCIE_ENHANCED_CAP_HEADER | 0x34) 
+#define UNCORRECTABLE_SOURCE_ID_REG	(PCIE_ENHANCED_CAP_HEADER | 0x36) 
+
+#define AER_NONFATAL			0
+#define AER_FATAL			1
+#define AER_CORRECTABLE			2
+#define AER_UNCORRECTABLE		3
+#define AER_ERROR_MASK			0x001fffff
+#define AER_ERROR(d)			(d & AER_ERROR_MASK)			
+
+/* PCI Express AER Correctable Errors */
+#define ERR_RECEIVER			0x00000001	/* COR bit 0 	*/ 
+#define ERR_BAD_TLP			0x00000040  	/* COR bit 6 	*/
+#define ERR_BAD_DLLP			0x00000080	/* COR bit 7 	*/
+#define ERR_RELAY_NUM_ROLLOVER		0x00000100 	/* COR bit 8 	*/
+#define ERR_RELAY_TIMEOUT		0x00001000 	/* COR bit 12 	*/
+#define ERR_CORRECTABLE_ERROR_MASK	0x000011c1
+
+/* PCI Express AER UnCorrectable Errors */
+#define ERR_TRAINING			0x00000001	/* UNCOR bit 0	*/
+#define ERR_DATA_LINK_PROTOCOL		0x00000010	/* UNCOR bit 4	*/
+#define ERR_POISONED_TLP		0x00001000	/* UNCOR bit 12 */
+#define ERR_FLOW_CONTROL_PROTOCOL	0x00002000	/* UNCOR bit 13 */
+#define ERR_COMPLETION_TIMEOUT		0x00004000	/* UNCOR bit 14 */
+#define ERR_COMPLETION_ABORT		0x00008000	/* UNCOR bit 15 */
+#define ERR_COMPLETION_UNEXPECT		0x00010000	/* UNCOR bit 16 */
+#define ERR_RECEIVER_OVERFLOW		0x00020000	/* UNCOR bit 17 */
+#define ERR_MALFORMED_TLP		0x00040000	/* UNCOR bit 18 */
+#define ERR_ECRC			0x00080000	/* UNCOR bit 19 */
+#define ERR_UNSUPPORTED_REQUEST		0x00100000	/* UNCOR bit 20 */
+#define ERR_UNCORRECTABLE_ERROR_MASK	0x001ff011
+
+union aer_error {
+	unsigned int type;	     /*AER_CORRECTABLE|AER_UNCORRECTABLE*/
+	struct {
+		unsigned int type;   /*AER_CORRECTABLE|AER_NONFATAL|AER_FATAL*/
+		unsigned int status; /*Particular Error Status*/ 
+	}source;
+};
+
+union request_id {
+	unsigned short value;
+	struct {
+		unsigned short func	: 3;
+		unsigned short dev	: 5;
+		unsigned short bus	: 8;
+	}u;
+};
+
+struct header_log_regs {
+	unsigned int dw0;
+	unsigned int dw1;
+	unsigned int dw2;
+	unsigned int dw3;
+};
+
+struct pcie_aer_handle {
+	int (*notify) (unsigned short requestor_id, union aer_error *error);
+	int (*get_header) (unsigned short requestor_id, union aer_error *error,
+		struct header_log_regs *log);
+	int (*link_rec_prepare) (unsigned short requestor_id);
+	int (*link_rec_restart) (unsigned short requestor_id);
+	int (*link_reset) (unsigned short requestor_id);
+};
+
+#ifndef CONFIG_PCIEAER
+static inline int pcie_aer_register(struct pci_dev *dev,  
+	struct pcie_aer_handle *handle) {return -1;}
+static inline void pcie_aer_unregister(unsigned short requestor_id) {}
+#else
+extern int pcie_aer_register(struct pci_dev *dev, 
+	struct pcie_aer_handle *handle);
+extern void pcie_aer_unregister(unsigned short requestor_id);
+#endif
+
+#endif //_AER_H_

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-03-11 23:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-12  0:17 [PATCH 6/6] PCI Express Advanced Error Reporting Driver long

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox