aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/executer/exconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/executer/exconfig.c')
-rw-r--r--drivers/acpi/executer/exconfig.c48
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
134cleanup: 141cleanup:
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
429cleanup: 446cleanup:
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