diff options
| author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2009-09-14 18:35:40 -0400 |
|---|---|---|
| committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-09-14 20:39:14 -0400 |
| commit | 5e3573db2bd5db6925159279d99576a4635bdb66 (patch) | |
| tree | a90efab044203abfda470f464cd056fe97497121 | |
| parent | e81995bb1c0077a312cb621abc406a36f65a986a (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.c | 84 |
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 | ||
| 47 | static int debug_acpi; | 46 | static int debug_acpi; |
| @@ -215,80 +214,41 @@ acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx) | |||
| 215 | static acpi_status | 214 | static acpi_status |
| 216 | acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) | 215 | acpi_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 | ||
| 289 | free_and_return: | 250 | exit: |
| 290 | kfree(string.pointer); | 251 | kfree(buffer.pointer); |
| 291 | kfree(ret_buf.pointer); | ||
| 292 | return status; | 252 | return status; |
| 293 | } | 253 | } |
| 294 | 254 | ||
