aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/acpi_pcihp.c
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2006-05-01 21:57:14 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-19 17:13:22 -0400
commite22b73501608901bab7ee9b1f8cb67f15e8efb7a (patch)
tree4edf850a0216b36c184b6abe43e32a600d4f7787 /drivers/pci/hotplug/acpi_pcihp.c
parentaad20cabaa3d6dfa1e0ebc8fb0537a96d3518b8f (diff)
[PATCH] acpi_pcihp: Add support for _HPX
This patch adds support for _HPX (Hot Plug Parameter Extensions) defined in ACPI3.0a spec. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Cc: Kristen Accardi <kristen.c.accardi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/hotplug/acpi_pcihp.c')
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c188
1 files changed, 180 insertions, 8 deletions
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index afac5c37325b..51cb9f817c22 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -47,6 +47,171 @@
47 47
48static int debug_acpi; 48static int debug_acpi;
49 49
50static acpi_status
51decode_type0_hpx_record(union acpi_object *record, struct hotplug_params *hpx)
52{
53 int i;
54 union acpi_object *fields = record->package.elements;
55 u32 revision = fields[1].integer.value;
56
57 switch (revision) {
58 case 1:
59 if (record->package.count != 6)
60 return AE_ERROR;
61 for (i = 2; i < 6; i++)
62 if (fields[i].type != ACPI_TYPE_INTEGER)
63 return AE_ERROR;
64 hpx->t0 = &hpx->type0_data;
65 hpx->t0->revision = revision;
66 hpx->t0->cache_line_size = fields[2].integer.value;
67 hpx->t0->latency_timer = fields[3].integer.value;
68 hpx->t0->enable_serr = fields[4].integer.value;
69 hpx->t0->enable_perr = fields[5].integer.value;
70 break;
71 default:
72 printk(KERN_WARNING
73 "%s: Type 0 Revision %d record not supported\n",
74 __FUNCTION__, revision);
75 return AE_ERROR;
76 }
77 return AE_OK;
78}
79
80static acpi_status
81decode_type1_hpx_record(union acpi_object *record, struct hotplug_params *hpx)
82{
83 int i;
84 union acpi_object *fields = record->package.elements;
85 u32 revision = fields[1].integer.value;
86
87 switch (revision) {
88 case 1:
89 if (record->package.count != 5)
90 return AE_ERROR;
91 for (i = 2; i < 5; i++)
92 if (fields[i].type != ACPI_TYPE_INTEGER)
93 return AE_ERROR;
94 hpx->t1 = &hpx->type1_data;
95 hpx->t1->revision = revision;
96 hpx->t1->max_mem_read = fields[2].integer.value;
97 hpx->t1->avg_max_split = fields[3].integer.value;
98 hpx->t1->tot_max_split = fields[4].integer.value;
99 break;
100 default:
101 printk(KERN_WARNING
102 "%s: Type 1 Revision %d record not supported\n",
103 __FUNCTION__, revision);
104 return AE_ERROR;
105 }
106 return AE_OK;
107}
108
109static acpi_status
110decode_type2_hpx_record(union acpi_object *record, struct hotplug_params *hpx)
111{
112 int i;
113 union acpi_object *fields = record->package.elements;
114 u32 revision = fields[1].integer.value;
115
116 switch (revision) {
117 case 1:
118 if (record->package.count != 18)
119 return AE_ERROR;
120 for (i = 2; i < 18; i++)
121 if (fields[i].type != ACPI_TYPE_INTEGER)
122 return AE_ERROR;
123 hpx->t2 = &hpx->type2_data;
124 hpx->t2->revision = revision;
125 hpx->t2->unc_err_mask_and = fields[2].integer.value;
126 hpx->t2->unc_err_mask_or = fields[3].integer.value;
127 hpx->t2->unc_err_sever_and = fields[4].integer.value;
128 hpx->t2->unc_err_sever_or = fields[5].integer.value;
129 hpx->t2->cor_err_mask_and = fields[6].integer.value;
130 hpx->t2->cor_err_mask_or = fields[7].integer.value;
131 hpx->t2->adv_err_cap_and = fields[8].integer.value;
132 hpx->t2->adv_err_cap_or = fields[9].integer.value;
133 hpx->t2->pci_exp_devctl_and = fields[10].integer.value;
134 hpx->t2->pci_exp_devctl_or = fields[11].integer.value;
135 hpx->t2->pci_exp_lnkctl_and = fields[12].integer.value;
136 hpx->t2->pci_exp_lnkctl_or = fields[13].integer.value;
137 hpx->t2->sec_unc_err_sever_and = fields[14].integer.value;
138 hpx->t2->sec_unc_err_sever_or = fields[15].integer.value;
139 hpx->t2->sec_unc_err_mask_and = fields[16].integer.value;
140 hpx->t2->sec_unc_err_mask_or = fields[17].integer.value;
141 break;
142 default:
143 printk(KERN_WARNING
144 "%s: Type 2 Revision %d record not supported\n",
145 __FUNCTION__, revision);
146 return AE_ERROR;
147 }
148 return AE_OK;
149}
150
151static acpi_status
152acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx)
153{
154 acpi_status status;
155 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
156 union acpi_object *package, *record, *fields;
157 u32 type;
158 int i;
159
160 /* Clear the return buffer with zeros */
161 memset(hpx, 0, sizeof(struct hotplug_params));
162
163 status = acpi_evaluate_object(handle, "_HPX", NULL, &buffer);
164 if (ACPI_FAILURE(status))
165 return status;
166
167 package = (union acpi_object *)buffer.pointer;
168 if (package->type != ACPI_TYPE_PACKAGE) {
169 status = AE_ERROR;
170 goto exit;
171 }
172
173 for (i = 0; i < package->package.count; i++) {
174 record = &package->package.elements[i];
175 if (record->type != ACPI_TYPE_PACKAGE) {
176 status = AE_ERROR;
177 goto exit;
178 }
179
180 fields = record->package.elements;
181 if (fields[0].type != ACPI_TYPE_INTEGER ||
182 fields[1].type != ACPI_TYPE_INTEGER) {
183 status = AE_ERROR;
184 goto exit;
185 }
186
187 type = fields[0].integer.value;
188 switch (type) {
189 case 0:
190 status = decode_type0_hpx_record(record, hpx);
191 if (ACPI_FAILURE(status))
192 goto exit;
193 break;
194 case 1:
195 status = decode_type1_hpx_record(record, hpx);
196 if (ACPI_FAILURE(status))
197 goto exit;
198 break;
199 case 2:
200 status = decode_type2_hpx_record(record, hpx);
201 if (ACPI_FAILURE(status))
202 goto exit;
203 break;
204 default:
205 printk(KERN_ERR "%s: Type %d record not supported\n",
206 __FUNCTION__, type);
207 status = AE_ERROR;
208 goto exit;
209 }
210 }
211 exit:
212 kfree(buffer.pointer);
213 return status;
214}
50 215
51static acpi_status 216static acpi_status
52acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) 217acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
@@ -60,6 +225,9 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
60 225
61 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); 226 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
62 227
228 /* Clear the return buffer with zeros */
229 memset(hpp, 0, sizeof(struct hotplug_params));
230
63 /* get _hpp */ 231 /* get _hpp */
64 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf); 232 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
65 switch (status) { 233 switch (status) {
@@ -108,15 +276,16 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
108 } 276 }
109 } 277 }
110 278
111 hpp->cache_line_size = nui[0]; 279 hpp->t0 = &hpp->type0_data;
112 hpp->latency_timer = nui[1]; 280 hpp->t0->cache_line_size = nui[0];
113 hpp->enable_serr = nui[2]; 281 hpp->t0->latency_timer = nui[1];
114 hpp->enable_perr = nui[3]; 282 hpp->t0->enable_serr = nui[2];
283 hpp->t0->enable_perr = nui[3];
115 284
116 pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size); 285 pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->t0->cache_line_size);
117 pr_debug(" _HPP: latency timer =0x%x\n", hpp->latency_timer); 286 pr_debug(" _HPP: latency timer =0x%x\n", hpp->t0->latency_timer);
118 pr_debug(" _HPP: enable SERR =0x%x\n", hpp->enable_serr); 287 pr_debug(" _HPP: enable SERR =0x%x\n", hpp->t0->enable_serr);
119 pr_debug(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); 288 pr_debug(" _HPP: enable PERR =0x%x\n", hpp->t0->enable_perr);
120 289
121free_and_return: 290free_and_return:
122 kfree(string.pointer); 291 kfree(string.pointer);
@@ -188,6 +357,9 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
188 * this pci dev. If we don't find any _HPP, use hardcoded defaults 357 * this pci dev. If we don't find any _HPP, use hardcoded defaults
189 */ 358 */
190 while (handle) { 359 while (handle) {
360 status = acpi_run_hpx(handle, hpp);
361 if (ACPI_SUCCESS(status))
362 break;
191 status = acpi_run_hpp(handle, hpp); 363 status = acpi_run_hpp(handle, hpp);
192 if (ACPI_SUCCESS(status)) 364 if (ACPI_SUCCESS(status))
193 break; 365 break;