diff options
author | Huang Ying <ying.huang@intel.com> | 2010-05-18 02:35:16 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-05-19 22:40:14 -0400 |
commit | affb72c3a8984ba55e055b0a0228c3ea1a056758 (patch) | |
tree | a6d4c9051110c03f9222bde9c3dcea7822f8570c /drivers/acpi | |
parent | ea8c071cad789b1919355fc7a67182a5c9994e6b (diff) |
ACPI, APEI, PCIE AER, use general HEST table parsing in AER firmware_first setup
Now, a dedicated HEST tabling parsing code is used for PCIE AER
firmware_first setup. It is rebased on general HEST tabling parsing
code of APEI. The firmware_first setup code is moved from PCI core to
AER driver too, because it is only AER related.
Signed-off-by: Huang Ying <ying.huang@intel.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Reviewed-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/Makefile | 1 | ||||
-rw-r--r-- | drivers/acpi/hest.c | 139 |
2 files changed, 0 insertions, 140 deletions
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index d90af7fe8b98..e7cd919548e9 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -20,7 +20,6 @@ obj-y += acpi.o \ | |||
20 | # All the builtin files are in the "acpi." module_param namespace. | 20 | # All the builtin files are in the "acpi." module_param namespace. |
21 | acpi-y += osl.o utils.o reboot.o | 21 | acpi-y += osl.o utils.o reboot.o |
22 | acpi-y += atomicio.o | 22 | acpi-y += atomicio.o |
23 | acpi-y += hest.o | ||
24 | 23 | ||
25 | # sleep related files | 24 | # sleep related files |
26 | acpi-y += wakeup.o | 25 | acpi-y += wakeup.o |
diff --git a/drivers/acpi/hest.c b/drivers/acpi/hest.c deleted file mode 100644 index 1c527a192872..000000000000 --- a/drivers/acpi/hest.c +++ /dev/null | |||
@@ -1,139 +0,0 @@ | |||
1 | #include <linux/acpi.h> | ||
2 | #include <linux/pci.h> | ||
3 | |||
4 | #define PREFIX "ACPI: " | ||
5 | |||
6 | static inline unsigned long parse_acpi_hest_ia_machine_check(struct acpi_hest_ia_machine_check *p) | ||
7 | { | ||
8 | return sizeof(*p) + | ||
9 | (sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks); | ||
10 | } | ||
11 | |||
12 | static inline unsigned long parse_acpi_hest_ia_corrected(struct acpi_hest_ia_corrected *p) | ||
13 | { | ||
14 | return sizeof(*p) + | ||
15 | (sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks); | ||
16 | } | ||
17 | |||
18 | static inline unsigned long parse_acpi_hest_ia_nmi(struct acpi_hest_ia_nmi *p) | ||
19 | { | ||
20 | return sizeof(*p); | ||
21 | } | ||
22 | |||
23 | static inline unsigned long parse_acpi_hest_generic(struct acpi_hest_generic *p) | ||
24 | { | ||
25 | return sizeof(*p); | ||
26 | } | ||
27 | |||
28 | static inline unsigned int hest_match_pci(struct acpi_hest_aer_common *p, struct pci_dev *pci) | ||
29 | { | ||
30 | return (0 == pci_domain_nr(pci->bus) && | ||
31 | p->bus == pci->bus->number && | ||
32 | p->device == PCI_SLOT(pci->devfn) && | ||
33 | p->function == PCI_FUNC(pci->devfn)); | ||
34 | } | ||
35 | |||
36 | static unsigned long parse_acpi_hest_aer(void *hdr, int type, struct pci_dev *pci, int *firmware_first) | ||
37 | { | ||
38 | struct acpi_hest_aer_common *p = hdr + sizeof(struct acpi_hest_header); | ||
39 | unsigned long rc=0; | ||
40 | u8 pcie_type = 0; | ||
41 | u8 bridge = 0; | ||
42 | switch (type) { | ||
43 | case ACPI_HEST_TYPE_AER_ROOT_PORT: | ||
44 | rc = sizeof(struct acpi_hest_aer_root); | ||
45 | pcie_type = PCI_EXP_TYPE_ROOT_PORT; | ||
46 | break; | ||
47 | case ACPI_HEST_TYPE_AER_ENDPOINT: | ||
48 | rc = sizeof(struct acpi_hest_aer); | ||
49 | pcie_type = PCI_EXP_TYPE_ENDPOINT; | ||
50 | break; | ||
51 | case ACPI_HEST_TYPE_AER_BRIDGE: | ||
52 | rc = sizeof(struct acpi_hest_aer_bridge); | ||
53 | if ((pci->class >> 16) == PCI_BASE_CLASS_BRIDGE) | ||
54 | bridge = 1; | ||
55 | break; | ||
56 | } | ||
57 | |||
58 | if (p->flags & ACPI_HEST_GLOBAL) { | ||
59 | if ((pci->is_pcie && (pci->pcie_type == pcie_type)) || bridge) | ||
60 | *firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); | ||
61 | } | ||
62 | else | ||
63 | if (hest_match_pci(p, pci)) | ||
64 | *firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); | ||
65 | return rc; | ||
66 | } | ||
67 | |||
68 | static int acpi_hest_firmware_first(struct acpi_table_header *stdheader, struct pci_dev *pci) | ||
69 | { | ||
70 | struct acpi_table_hest *hest = (struct acpi_table_hest *)stdheader; | ||
71 | void *p = (void *)hest + sizeof(*hest); /* defined by the ACPI 4.0 spec */ | ||
72 | struct acpi_hest_header *hdr = p; | ||
73 | |||
74 | int i; | ||
75 | int firmware_first = 0; | ||
76 | static unsigned char printed_unused = 0; | ||
77 | static unsigned char printed_reserved = 0; | ||
78 | |||
79 | for (i=0, hdr=p; p < (((void *)hest) + hest->header.length) && i < hest->error_source_count; i++) { | ||
80 | switch (hdr->type) { | ||
81 | case ACPI_HEST_TYPE_IA32_CHECK: | ||
82 | p += parse_acpi_hest_ia_machine_check(p); | ||
83 | break; | ||
84 | case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: | ||
85 | p += parse_acpi_hest_ia_corrected(p); | ||
86 | break; | ||
87 | case ACPI_HEST_TYPE_IA32_NMI: | ||
88 | p += parse_acpi_hest_ia_nmi(p); | ||
89 | break; | ||
90 | /* These three should never appear */ | ||
91 | case ACPI_HEST_TYPE_NOT_USED3: | ||
92 | case ACPI_HEST_TYPE_NOT_USED4: | ||
93 | case ACPI_HEST_TYPE_NOT_USED5: | ||
94 | if (!printed_unused) { | ||
95 | printk(KERN_DEBUG PREFIX | ||
96 | "HEST Error Source list contains an obsolete type (%d).\n", hdr->type); | ||
97 | printed_unused = 1; | ||
98 | } | ||
99 | break; | ||
100 | case ACPI_HEST_TYPE_AER_ROOT_PORT: | ||
101 | case ACPI_HEST_TYPE_AER_ENDPOINT: | ||
102 | case ACPI_HEST_TYPE_AER_BRIDGE: | ||
103 | p += parse_acpi_hest_aer(p, hdr->type, pci, &firmware_first); | ||
104 | break; | ||
105 | case ACPI_HEST_TYPE_GENERIC_ERROR: | ||
106 | p += parse_acpi_hest_generic(p); | ||
107 | break; | ||
108 | /* These should never appear either */ | ||
109 | case ACPI_HEST_TYPE_RESERVED: | ||
110 | default: | ||
111 | if (!printed_reserved) { | ||
112 | printk(KERN_DEBUG PREFIX | ||
113 | "HEST Error Source list contains a reserved type (%d).\n", hdr->type); | ||
114 | printed_reserved = 1; | ||
115 | } | ||
116 | break; | ||
117 | } | ||
118 | } | ||
119 | return firmware_first; | ||
120 | } | ||
121 | |||
122 | int acpi_hest_firmware_first_pci(struct pci_dev *pci) | ||
123 | { | ||
124 | acpi_status status = AE_NOT_FOUND; | ||
125 | struct acpi_table_header *hest = NULL; | ||
126 | |||
127 | if (acpi_disabled) | ||
128 | return 0; | ||
129 | |||
130 | status = acpi_get_table(ACPI_SIG_HEST, 1, &hest); | ||
131 | |||
132 | if (ACPI_SUCCESS(status)) { | ||
133 | if (acpi_hest_firmware_first(hest, pci)) { | ||
134 | return 1; | ||
135 | } | ||
136 | } | ||
137 | return 0; | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(acpi_hest_firmware_first_pci); | ||