aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2009-09-14 18:35:40 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-09-14 20:39:14 -0400
commit5e3573db2bd5db6925159279d99576a4635bdb66 (patch)
treea90efab044203abfda470f464cd056fe97497121
parente81995bb1c0077a312cb621abc406a36f65a986a (diff)
PCI hotplug: clean up acpi_run_hpp()
This patch cleans up acpi_run_hpp() and follows the style of acpi_run_hpx(): - remove unnecessary METHOD_NAME__HPP #define - use ACPI_ALLOCATE_BUFFER rather than evaluating _HPP twice - validate _HPP package length (defined as 4 by the spec) - avoid ref to undefined data if FW provides < 4 elements - remove temporary nui[] array Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Reviewed-by: Alex Chiang <achiang@hp.com> Reviewed-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Acked-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c84
1 files changed, 22 insertions, 62 deletions
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index ee24de1c5fae..a73028ec52e5 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -41,7 +41,6 @@
41#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg) 41#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
42 42
43#define METHOD_NAME__SUN "_SUN" 43#define METHOD_NAME__SUN "_SUN"
44#define METHOD_NAME__HPP "_HPP"
45#define METHOD_NAME_OSHP "OSHP" 44#define METHOD_NAME_OSHP "OSHP"
46 45
47static int debug_acpi; 46static int debug_acpi;
@@ -215,80 +214,41 @@ acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx)
215static acpi_status 214static acpi_status
216acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) 215acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
217{ 216{
218 acpi_status status; 217 acpi_status status;
219 u8 nui[4]; 218 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
220 struct acpi_buffer ret_buf = { 0, NULL}; 219 union acpi_object *package, *fields;
221 struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; 220 int i;
222 union acpi_object *ext_obj, *package;
223 int i, len = 0;
224
225 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
226 221
227 /* Clear the return buffer with zeros */
228 memset(hpp, 0, sizeof(struct hotplug_params)); 222 memset(hpp, 0, sizeof(struct hotplug_params));
229 223
230 /* get _hpp */ 224 status = acpi_evaluate_object(handle, "_HPP", NULL, &buffer);
231 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf); 225 if (ACPI_FAILURE(status))
232 switch (status) { 226 return status;
233 case AE_BUFFER_OVERFLOW:
234 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
235 if (!ret_buf.pointer) {
236 printk(KERN_ERR "%s:%s alloc for _HPP fail\n",
237 __func__, (char *)string.pointer);
238 kfree(string.pointer);
239 return AE_NO_MEMORY;
240 }
241 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
242 NULL, &ret_buf);
243 if (ACPI_SUCCESS(status))
244 break;
245 default:
246 if (ACPI_FAILURE(status)) {
247 pr_debug("%s:%s _HPP fail=0x%x\n", __func__,
248 (char *)string.pointer, status);
249 kfree(string.pointer);
250 return status;
251 }
252 }
253 227
254 ext_obj = (union acpi_object *) ret_buf.pointer; 228 package = (union acpi_object *) buffer.pointer;
255 if (ext_obj->type != ACPI_TYPE_PACKAGE) { 229 if (package->type != ACPI_TYPE_PACKAGE ||
256 printk(KERN_ERR "%s:%s _HPP obj not a package\n", __func__, 230 package->package.count != 4) {
257 (char *)string.pointer);
258 status = AE_ERROR; 231 status = AE_ERROR;
259 goto free_and_return; 232 goto exit;
260 } 233 }
261 234
262 len = ext_obj->package.count; 235 fields = package->package.elements;
263 package = (union acpi_object *) ret_buf.pointer; 236 for (i = 0; i < 4; i++) {
264 for ( i = 0; (i < len) || (i < 4); i++) { 237 if (fields[i].type != ACPI_TYPE_INTEGER) {
265 ext_obj = (union acpi_object *) &package->package.elements[i];
266 switch (ext_obj->type) {
267 case ACPI_TYPE_INTEGER:
268 nui[i] = (u8)ext_obj->integer.value;
269 break;
270 default:
271 printk(KERN_ERR "%s:%s _HPP obj type incorrect\n",
272 __func__, (char *)string.pointer);
273 status = AE_ERROR; 238 status = AE_ERROR;
274 goto free_and_return; 239 goto exit;
275 } 240 }
276 } 241 }
277 242
278 hpp->t0 = &hpp->type0_data; 243 hpp->t0 = &hpp->type0_data;
279 hpp->t0->cache_line_size = nui[0]; 244 hpp->t0->revision = 1;
280 hpp->t0->latency_timer = nui[1]; 245 hpp->t0->cache_line_size = fields[0].integer.value;
281 hpp->t0->enable_serr = nui[2]; 246 hpp->t0->latency_timer = fields[1].integer.value;
282 hpp->t0->enable_perr = nui[3]; 247 hpp->t0->enable_serr = fields[2].integer.value;
283 248 hpp->t0->enable_perr = fields[3].integer.value;
284 pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->t0->cache_line_size);
285 pr_debug(" _HPP: latency timer =0x%x\n", hpp->t0->latency_timer);
286 pr_debug(" _HPP: enable SERR =0x%x\n", hpp->t0->enable_serr);
287 pr_debug(" _HPP: enable PERR =0x%x\n", hpp->t0->enable_perr);
288 249
289free_and_return: 250exit:
290 kfree(string.pointer); 251 kfree(buffer.pointer);
291 kfree(ret_buf.pointer);
292 return status; 252 return status;
293} 253}
294 254