diff options
Diffstat (limited to 'drivers/acpi/executer/exconfig.c')
-rw-r--r-- | drivers/acpi/executer/exconfig.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 734b2f24af48..d11e9ec827f1 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c | |||
@@ -99,6 +99,11 @@ acpi_ex_add_table ( | |||
99 | return_ACPI_STATUS (AE_NO_MEMORY); | 99 | return_ACPI_STATUS (AE_NO_MEMORY); |
100 | } | 100 | } |
101 | 101 | ||
102 | /* Init the table handle */ | ||
103 | |||
104 | obj_desc->reference.opcode = AML_LOAD_OP; | ||
105 | *ddb_handle = obj_desc; | ||
106 | |||
102 | /* Install the new table into the local data structures */ | 107 | /* Install the new table into the local data structures */ |
103 | 108 | ||
104 | ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc)); | 109 | ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc)); |
@@ -109,7 +114,14 @@ acpi_ex_add_table ( | |||
109 | table_info.allocation = ACPI_MEM_ALLOCATED; | 114 | table_info.allocation = ACPI_MEM_ALLOCATED; |
110 | 115 | ||
111 | status = acpi_tb_install_table (&table_info); | 116 | status = acpi_tb_install_table (&table_info); |
117 | obj_desc->reference.object = table_info.installed_desc; | ||
118 | |||
112 | if (ACPI_FAILURE (status)) { | 119 | if (ACPI_FAILURE (status)) { |
120 | if (status == AE_ALREADY_EXISTS) { | ||
121 | /* Table already exists, just return the handle */ | ||
122 | |||
123 | return_ACPI_STATUS (AE_OK); | ||
124 | } | ||
113 | goto cleanup; | 125 | goto cleanup; |
114 | } | 126 | } |
115 | 127 | ||
@@ -123,16 +135,12 @@ acpi_ex_add_table ( | |||
123 | goto cleanup; | 135 | goto cleanup; |
124 | } | 136 | } |
125 | 137 | ||
126 | /* Init the table handle */ | ||
127 | |||
128 | obj_desc->reference.opcode = AML_LOAD_OP; | ||
129 | obj_desc->reference.object = table_info.installed_desc; | ||
130 | *ddb_handle = obj_desc; | ||
131 | return_ACPI_STATUS (AE_OK); | 138 | return_ACPI_STATUS (AE_OK); |
132 | 139 | ||
133 | 140 | ||
134 | cleanup: | 141 | cleanup: |
135 | acpi_ut_remove_reference (obj_desc); | 142 | acpi_ut_remove_reference (obj_desc); |
143 | *ddb_handle = NULL; | ||
136 | return_ACPI_STATUS (status); | 144 | return_ACPI_STATUS (status); |
137 | } | 145 | } |
138 | 146 | ||
@@ -376,16 +384,22 @@ acpi_ex_load_op ( | |||
376 | */ | 384 | */ |
377 | status = acpi_ex_read_data_from_field (walk_state, obj_desc, &buffer_desc); | 385 | status = acpi_ex_read_data_from_field (walk_state, obj_desc, &buffer_desc); |
378 | if (ACPI_FAILURE (status)) { | 386 | if (ACPI_FAILURE (status)) { |
379 | goto cleanup; | 387 | return_ACPI_STATUS (status); |
380 | } | 388 | } |
381 | 389 | ||
382 | table_ptr = ACPI_CAST_PTR (struct acpi_table_header, | 390 | table_ptr = ACPI_CAST_PTR (struct acpi_table_header, |
383 | buffer_desc->buffer.pointer); | 391 | buffer_desc->buffer.pointer); |
384 | 392 | ||
385 | /* Sanity check the table length */ | 393 | /* All done with the buffer_desc, delete it */ |
394 | |||
395 | buffer_desc->buffer.pointer = NULL; | ||
396 | acpi_ut_remove_reference (buffer_desc); | ||
397 | |||
398 | /* Sanity check the table length */ | ||
386 | 399 | ||
387 | if (table_ptr->length < sizeof (struct acpi_table_header)) { | 400 | if (table_ptr->length < sizeof (struct acpi_table_header)) { |
388 | return_ACPI_STATUS (AE_BAD_HEADER); | 401 | status = AE_BAD_HEADER; |
402 | goto cleanup; | ||
389 | } | 403 | } |
390 | break; | 404 | break; |
391 | 405 | ||
@@ -413,7 +427,9 @@ acpi_ex_load_op ( | |||
413 | 427 | ||
414 | status = acpi_ex_add_table (table_ptr, acpi_gbl_root_node, &ddb_handle); | 428 | status = acpi_ex_add_table (table_ptr, acpi_gbl_root_node, &ddb_handle); |
415 | if (ACPI_FAILURE (status)) { | 429 | if (ACPI_FAILURE (status)) { |
416 | goto cleanup; | 430 | /* On error, table_ptr was deallocated above */ |
431 | |||
432 | return_ACPI_STATUS (status); | ||
417 | } | 433 | } |
418 | 434 | ||
419 | /* Store the ddb_handle into the Target operand */ | 435 | /* Store the ddb_handle into the Target operand */ |
@@ -421,17 +437,14 @@ acpi_ex_load_op ( | |||
421 | status = acpi_ex_store (ddb_handle, target, walk_state); | 437 | status = acpi_ex_store (ddb_handle, target, walk_state); |
422 | if (ACPI_FAILURE (status)) { | 438 | if (ACPI_FAILURE (status)) { |
423 | (void) acpi_ex_unload_table (ddb_handle); | 439 | (void) acpi_ex_unload_table (ddb_handle); |
424 | } | ||
425 | 440 | ||
426 | return_ACPI_STATUS (status); | 441 | /* table_ptr was deallocated above */ |
427 | 442 | ||
443 | return_ACPI_STATUS (status); | ||
444 | } | ||
428 | 445 | ||
429 | cleanup: | 446 | cleanup: |
430 | 447 | if (ACPI_FAILURE (status)) { | |
431 | if (buffer_desc) { | ||
432 | acpi_ut_remove_reference (buffer_desc); | ||
433 | } | ||
434 | else { | ||
435 | ACPI_MEM_FREE (table_ptr); | 448 | ACPI_MEM_FREE (table_ptr); |
436 | } | 449 | } |
437 | return_ACPI_STATUS (status); | 450 | return_ACPI_STATUS (status); |
@@ -482,7 +495,8 @@ acpi_ex_unload_table ( | |||
482 | * Delete the entire namespace under this table Node | 495 | * Delete the entire namespace under this table Node |
483 | * (Offset contains the table_id) | 496 | * (Offset contains the table_id) |
484 | */ | 497 | */ |
485 | acpi_ns_delete_namespace_by_owner (table_info->table_id); | 498 | acpi_ns_delete_namespace_by_owner (table_info->owner_id); |
499 | acpi_ut_release_owner_id (&table_info->owner_id); | ||
486 | 500 | ||
487 | /* Delete the table itself */ | 501 | /* Delete the table itself */ |
488 | 502 | ||