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 <[EMAIL PROTECTED]>

--------------------------------------------------------------------
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 ([EMAIL PROTECTED])
+ *
+ */
+
+#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 "[EMAIL PROTECTED]"
+#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 ([EMAIL PROTECTED])
+ *
+ */
+
+#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 ([EMAIL PROTECTED])
+ *
+ */
+
+#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_
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to