diff options
Diffstat (limited to 'drivers/acpi')
30 files changed, 1609 insertions, 3403 deletions
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c index 1888c055d10f..9db09de0073a 100644 --- a/drivers/acpi/dispatcher/dsinit.c +++ b/drivers/acpi/dispatcher/dsinit.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acdispat.h> | 45 | #include <acpi/acdispat.h> |
46 | #include <acpi/acnamesp.h> | 46 | #include <acpi/acnamesp.h> |
47 | #include <acpi/actables.h> | ||
47 | 48 | ||
48 | #define _COMPONENT ACPI_DISPATCHER | 49 | #define _COMPONENT ACPI_DISPATCHER |
49 | ACPI_MODULE_NAME("dsinit") | 50 | ACPI_MODULE_NAME("dsinit") |
@@ -90,7 +91,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, | |||
90 | * We are only interested in NS nodes owned by the table that | 91 | * We are only interested in NS nodes owned by the table that |
91 | * was just loaded | 92 | * was just loaded |
92 | */ | 93 | */ |
93 | if (node->owner_id != info->table_desc->owner_id) { | 94 | if (node->owner_id != info->owner_id) { |
94 | return (AE_OK); | 95 | return (AE_OK); |
95 | } | 96 | } |
96 | 97 | ||
@@ -150,14 +151,21 @@ acpi_ds_init_one_object(acpi_handle obj_handle, | |||
150 | ******************************************************************************/ | 151 | ******************************************************************************/ |
151 | 152 | ||
152 | acpi_status | 153 | acpi_status |
153 | acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, | 154 | acpi_ds_initialize_objects(acpi_native_uint table_index, |
154 | struct acpi_namespace_node * start_node) | 155 | struct acpi_namespace_node * start_node) |
155 | { | 156 | { |
156 | acpi_status status; | 157 | acpi_status status; |
157 | struct acpi_init_walk_info info; | 158 | struct acpi_init_walk_info info; |
159 | struct acpi_table_header *table; | ||
160 | acpi_owner_id owner_id; | ||
158 | 161 | ||
159 | ACPI_FUNCTION_TRACE(ds_initialize_objects); | 162 | ACPI_FUNCTION_TRACE(ds_initialize_objects); |
160 | 163 | ||
164 | status = acpi_tb_get_owner_id(table_index, &owner_id); | ||
165 | if (ACPI_FAILURE(status)) { | ||
166 | return_ACPI_STATUS(status); | ||
167 | } | ||
168 | |||
161 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 169 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
162 | "**** Starting initialization of namespace objects ****\n")); | 170 | "**** Starting initialization of namespace objects ****\n")); |
163 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:")); | 171 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:")); |
@@ -166,7 +174,8 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, | |||
166 | info.op_region_count = 0; | 174 | info.op_region_count = 0; |
167 | info.object_count = 0; | 175 | info.object_count = 0; |
168 | info.device_count = 0; | 176 | info.device_count = 0; |
169 | info.table_desc = table_desc; | 177 | info.table_index = table_index; |
178 | info.owner_id = owner_id; | ||
170 | 179 | ||
171 | /* Walk entire namespace from the supplied root */ | 180 | /* Walk entire namespace from the supplied root */ |
172 | 181 | ||
@@ -176,10 +185,14 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc, | |||
176 | ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); | 185 | ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); |
177 | } | 186 | } |
178 | 187 | ||
188 | status = acpi_get_table_by_index(table_index, &table); | ||
189 | if (ACPI_FAILURE(status)) { | ||
190 | return_ACPI_STATUS(status); | ||
191 | } | ||
192 | |||
179 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | 193 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
180 | "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n", | 194 | "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n", |
181 | table_desc->pointer->signature, | 195 | table->signature, owner_id, info.object_count, |
182 | table_desc->owner_id, info.object_count, | ||
183 | info.device_count, info.method_count, | 196 | info.device_count, info.method_count, |
184 | info.op_region_count)); | 197 | info.op_region_count)); |
185 | 198 | ||
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c index 919037d6acff..6b4bc99b1c2c 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/events/evevent.c | |||
@@ -70,13 +70,6 @@ acpi_status acpi_ev_initialize_events(void) | |||
70 | 70 | ||
71 | ACPI_FUNCTION_TRACE(ev_initialize_events); | 71 | ACPI_FUNCTION_TRACE(ev_initialize_events); |
72 | 72 | ||
73 | /* Make sure we have ACPI tables */ | ||
74 | |||
75 | if (!acpi_gbl_DSDT) { | ||
76 | ACPI_WARNING((AE_INFO, "No ACPI tables present!")); | ||
77 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
78 | } | ||
79 | |||
80 | /* | 73 | /* |
81 | * Initialize the Fixed and General Purpose Events. This is done prior to | 74 | * Initialize the Fixed and General Purpose Events. This is done prior to |
82 | * enabling SCIs to prevent interrupts from occurring before the handlers are | 75 | * enabling SCIs to prevent interrupts from occurring before the handlers are |
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index 95ddeb48bc0f..bb0eb50cd28f 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c | |||
@@ -529,7 +529,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 | |||
529 | 529 | ||
530 | /* Install new interrupt handler if not SCI_INT */ | 530 | /* Install new interrupt handler if not SCI_INT */ |
531 | 531 | ||
532 | if (interrupt_number != acpi_gbl_FADT->sci_int) { | 532 | if (interrupt_number != acpi_gbl_FADT.sci_interrupt) { |
533 | status = acpi_os_install_interrupt_handler(interrupt_number, | 533 | status = acpi_os_install_interrupt_handler(interrupt_number, |
534 | acpi_ev_gpe_xrupt_handler, | 534 | acpi_ev_gpe_xrupt_handler, |
535 | gpe_xrupt); | 535 | gpe_xrupt); |
@@ -567,7 +567,7 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) | |||
567 | 567 | ||
568 | /* We never want to remove the SCI interrupt handler */ | 568 | /* We never want to remove the SCI interrupt handler */ |
569 | 569 | ||
570 | if (gpe_xrupt->interrupt_number == acpi_gbl_FADT->sci_int) { | 570 | if (gpe_xrupt->interrupt_number == acpi_gbl_FADT.sci_interrupt) { |
571 | gpe_xrupt->gpe_block_list_head = NULL; | 571 | gpe_xrupt->gpe_block_list_head = NULL; |
572 | return_ACPI_STATUS(AE_OK); | 572 | return_ACPI_STATUS(AE_OK); |
573 | } | 573 | } |
@@ -803,17 +803,17 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) | |||
803 | (gpe_block->block_address.address | 803 | (gpe_block->block_address.address |
804 | + i + gpe_block->register_count)); | 804 | + i + gpe_block->register_count)); |
805 | 805 | ||
806 | this_register->status_address.address_space_id = | 806 | this_register->status_address.space_id = |
807 | gpe_block->block_address.address_space_id; | 807 | gpe_block->block_address.space_id; |
808 | this_register->enable_address.address_space_id = | 808 | this_register->enable_address.space_id = |
809 | gpe_block->block_address.address_space_id; | 809 | gpe_block->block_address.space_id; |
810 | this_register->status_address.register_bit_width = | 810 | this_register->status_address.bit_width = |
811 | ACPI_GPE_REGISTER_WIDTH; | 811 | ACPI_GPE_REGISTER_WIDTH; |
812 | this_register->enable_address.register_bit_width = | 812 | this_register->enable_address.bit_width = |
813 | ACPI_GPE_REGISTER_WIDTH; | 813 | ACPI_GPE_REGISTER_WIDTH; |
814 | this_register->status_address.register_bit_offset = | 814 | this_register->status_address.bit_offset = |
815 | ACPI_GPE_REGISTER_WIDTH; | 815 | ACPI_GPE_REGISTER_WIDTH; |
816 | this_register->enable_address.register_bit_offset = | 816 | this_register->enable_address.bit_offset = |
817 | ACPI_GPE_REGISTER_WIDTH; | 817 | ACPI_GPE_REGISTER_WIDTH; |
818 | 818 | ||
819 | /* Init the event_info for each GPE within this register */ | 819 | /* Init the event_info for each GPE within this register */ |
@@ -1109,11 +1109,12 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1109 | * If EITHER the register length OR the block address are zero, then that | 1109 | * If EITHER the register length OR the block address are zero, then that |
1110 | * particular block is not supported. | 1110 | * particular block is not supported. |
1111 | */ | 1111 | */ |
1112 | if (acpi_gbl_FADT->gpe0_blk_len && acpi_gbl_FADT->xgpe0_blk.address) { | 1112 | if (acpi_gbl_FADT.gpe0_block_length && |
1113 | acpi_gbl_FADT.xgpe0_block.address) { | ||
1113 | 1114 | ||
1114 | /* GPE block 0 exists (has both length and address > 0) */ | 1115 | /* GPE block 0 exists (has both length and address > 0) */ |
1115 | 1116 | ||
1116 | register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2); | 1117 | register_count0 = (u16) (acpi_gbl_FADT.gpe0_block_length / 2); |
1117 | 1118 | ||
1118 | gpe_number_max = | 1119 | gpe_number_max = |
1119 | (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1; | 1120 | (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1; |
@@ -1121,9 +1122,9 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1121 | /* Install GPE Block 0 */ | 1122 | /* Install GPE Block 0 */ |
1122 | 1123 | ||
1123 | status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, | 1124 | status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, |
1124 | &acpi_gbl_FADT->xgpe0_blk, | 1125 | &acpi_gbl_FADT.xgpe0_block, |
1125 | register_count0, 0, | 1126 | register_count0, 0, |
1126 | acpi_gbl_FADT->sci_int, | 1127 | acpi_gbl_FADT.sci_interrupt, |
1127 | &acpi_gbl_gpe_fadt_blocks[0]); | 1128 | &acpi_gbl_gpe_fadt_blocks[0]); |
1128 | 1129 | ||
1129 | if (ACPI_FAILURE(status)) { | 1130 | if (ACPI_FAILURE(status)) { |
@@ -1132,20 +1133,21 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1132 | } | 1133 | } |
1133 | } | 1134 | } |
1134 | 1135 | ||
1135 | if (acpi_gbl_FADT->gpe1_blk_len && acpi_gbl_FADT->xgpe1_blk.address) { | 1136 | if (acpi_gbl_FADT.gpe1_block_length && |
1137 | acpi_gbl_FADT.xgpe1_block.address) { | ||
1136 | 1138 | ||
1137 | /* GPE block 1 exists (has both length and address > 0) */ | 1139 | /* GPE block 1 exists (has both length and address > 0) */ |
1138 | 1140 | ||
1139 | register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2); | 1141 | register_count1 = (u16) (acpi_gbl_FADT.gpe1_block_length / 2); |
1140 | 1142 | ||
1141 | /* Check for GPE0/GPE1 overlap (if both banks exist) */ | 1143 | /* Check for GPE0/GPE1 overlap (if both banks exist) */ |
1142 | 1144 | ||
1143 | if ((register_count0) && | 1145 | if ((register_count0) && |
1144 | (gpe_number_max >= acpi_gbl_FADT->gpe1_base)) { | 1146 | (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) { |
1145 | ACPI_ERROR((AE_INFO, | 1147 | ACPI_ERROR((AE_INFO, |
1146 | "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1", | 1148 | "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1", |
1147 | gpe_number_max, acpi_gbl_FADT->gpe1_base, | 1149 | gpe_number_max, acpi_gbl_FADT.gpe1_base, |
1148 | acpi_gbl_FADT->gpe1_base + | 1150 | acpi_gbl_FADT.gpe1_base + |
1149 | ((register_count1 * | 1151 | ((register_count1 * |
1150 | ACPI_GPE_REGISTER_WIDTH) - 1))); | 1152 | ACPI_GPE_REGISTER_WIDTH) - 1))); |
1151 | 1153 | ||
@@ -1157,10 +1159,11 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1157 | 1159 | ||
1158 | status = | 1160 | status = |
1159 | acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, | 1161 | acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device, |
1160 | &acpi_gbl_FADT->xgpe1_blk, | 1162 | &acpi_gbl_FADT.xgpe1_block, |
1161 | register_count1, | 1163 | register_count1, |
1162 | acpi_gbl_FADT->gpe1_base, | 1164 | acpi_gbl_FADT.gpe1_base, |
1163 | acpi_gbl_FADT->sci_int, | 1165 | acpi_gbl_FADT. |
1166 | sci_interrupt, | ||
1164 | &acpi_gbl_gpe_fadt_blocks | 1167 | &acpi_gbl_gpe_fadt_blocks |
1165 | [1]); | 1168 | [1]); |
1166 | 1169 | ||
@@ -1173,7 +1176,7 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1173 | * GPE0 and GPE1 do not have to be contiguous in the GPE number | 1176 | * GPE0 and GPE1 do not have to be contiguous in the GPE number |
1174 | * space. However, GPE0 always starts at GPE number zero. | 1177 | * space. However, GPE0 always starts at GPE number zero. |
1175 | */ | 1178 | */ |
1176 | gpe_number_max = acpi_gbl_FADT->gpe1_base + | 1179 | gpe_number_max = acpi_gbl_FADT.gpe1_base + |
1177 | ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1); | 1180 | ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1); |
1178 | } | 1181 | } |
1179 | } | 1182 | } |
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index 00f33ed4c12e..21449f36b5f8 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c | |||
@@ -63,6 +63,10 @@ static const char *acpi_notify_value_names[] = { | |||
63 | }; | 63 | }; |
64 | #endif | 64 | #endif |
65 | 65 | ||
66 | /* Pointer to FACS needed for the Global Lock */ | ||
67 | |||
68 | static struct acpi_table_facs *facs = NULL; | ||
69 | |||
66 | /* Local prototypes */ | 70 | /* Local prototypes */ |
67 | 71 | ||
68 | static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); | 72 | static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); |
@@ -306,7 +310,7 @@ static u32 acpi_ev_global_lock_handler(void *context) | |||
306 | * If we don't get it now, it will be marked pending and we will | 310 | * If we don't get it now, it will be marked pending and we will |
307 | * take another interrupt when it becomes free. | 311 | * take another interrupt when it becomes free. |
308 | */ | 312 | */ |
309 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); | 313 | ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired); |
310 | if (acquired) { | 314 | if (acquired) { |
311 | 315 | ||
312 | /* Got the lock, now wake all threads waiting for it */ | 316 | /* Got the lock, now wake all threads waiting for it */ |
@@ -342,6 +346,13 @@ acpi_status acpi_ev_init_global_lock_handler(void) | |||
342 | 346 | ||
343 | ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); | 347 | ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); |
344 | 348 | ||
349 | status = | ||
350 | acpi_get_table(ACPI_SIG_FACS, 0, | ||
351 | (struct acpi_table_header **)&facs); | ||
352 | if (ACPI_FAILURE(status)) { | ||
353 | return_ACPI_STATUS(status); | ||
354 | } | ||
355 | |||
345 | acpi_gbl_global_lock_present = TRUE; | 356 | acpi_gbl_global_lock_present = TRUE; |
346 | status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, | 357 | status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, |
347 | acpi_ev_global_lock_handler, | 358 | acpi_ev_global_lock_handler, |
@@ -414,7 +425,7 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
414 | 425 | ||
415 | /* Attempt to acquire the actual hardware lock */ | 426 | /* Attempt to acquire the actual hardware lock */ |
416 | 427 | ||
417 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); | 428 | ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired); |
418 | if (acquired) { | 429 | if (acquired) { |
419 | 430 | ||
420 | /* We got the lock */ | 431 | /* We got the lock */ |
@@ -438,6 +449,7 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
438 | */ | 449 | */ |
439 | status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, | 450 | status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, |
440 | ACPI_WAIT_FOREVER); | 451 | ACPI_WAIT_FOREVER); |
452 | |||
441 | return_ACPI_STATUS(status); | 453 | return_ACPI_STATUS(status); |
442 | } | 454 | } |
443 | 455 | ||
@@ -472,8 +484,7 @@ acpi_status acpi_ev_release_global_lock(void) | |||
472 | 484 | ||
473 | /* Allow any thread to release the lock */ | 485 | /* Allow any thread to release the lock */ |
474 | 486 | ||
475 | ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, | 487 | ACPI_RELEASE_GLOBAL_LOCK(facs, pending); |
476 | pending); | ||
477 | 488 | ||
478 | /* | 489 | /* |
479 | * If the pending bit was set, we must write GBL_RLS to the control | 490 | * If the pending bit was set, we must write GBL_RLS to the control |
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c index 8106215ad554..d7680ac684a6 100644 --- a/drivers/acpi/events/evsci.c +++ b/drivers/acpi/events/evsci.c | |||
@@ -142,9 +142,10 @@ u32 acpi_ev_install_sci_handler(void) | |||
142 | 142 | ||
143 | ACPI_FUNCTION_TRACE(ev_install_sci_handler); | 143 | ACPI_FUNCTION_TRACE(ev_install_sci_handler); |
144 | 144 | ||
145 | status = acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT->sci_int, | 145 | status = |
146 | acpi_ev_sci_xrupt_handler, | 146 | acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, |
147 | acpi_gbl_gpe_xrupt_list_head); | 147 | acpi_ev_sci_xrupt_handler, |
148 | acpi_gbl_gpe_xrupt_list_head); | ||
148 | return_ACPI_STATUS(status); | 149 | return_ACPI_STATUS(status); |
149 | } | 150 | } |
150 | 151 | ||
@@ -175,8 +176,9 @@ acpi_status acpi_ev_remove_sci_handler(void) | |||
175 | 176 | ||
176 | /* Just let the OS remove the handler and disable the level */ | 177 | /* Just let the OS remove the handler and disable the level */ |
177 | 178 | ||
178 | status = acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT->sci_int, | 179 | status = |
179 | acpi_ev_sci_xrupt_handler); | 180 | acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, |
181 | acpi_ev_sci_xrupt_handler); | ||
180 | 182 | ||
181 | return_ACPI_STATUS(status); | 183 | return_ACPI_STATUS(status); |
182 | } | 184 | } |
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 7ebc2efac936..91e5f5b53a97 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c | |||
@@ -65,13 +65,6 @@ acpi_status acpi_enable(void) | |||
65 | 65 | ||
66 | ACPI_FUNCTION_TRACE(acpi_enable); | 66 | ACPI_FUNCTION_TRACE(acpi_enable); |
67 | 67 | ||
68 | /* Make sure we have the FADT */ | ||
69 | |||
70 | if (!acpi_gbl_FADT) { | ||
71 | ACPI_WARNING((AE_INFO, "No FADT information present!")); | ||
72 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
73 | } | ||
74 | |||
75 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { | 68 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { |
76 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 69 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
77 | "System is already in ACPI mode\n")); | 70 | "System is already in ACPI mode\n")); |
@@ -111,11 +104,6 @@ acpi_status acpi_disable(void) | |||
111 | 104 | ||
112 | ACPI_FUNCTION_TRACE(acpi_disable); | 105 | ACPI_FUNCTION_TRACE(acpi_disable); |
113 | 106 | ||
114 | if (!acpi_gbl_FADT) { | ||
115 | ACPI_WARNING((AE_INFO, "No FADT information present!")); | ||
116 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
117 | } | ||
118 | |||
119 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { | 107 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { |
120 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 108 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
121 | "System is already in legacy (non-ACPI) mode\n")); | 109 | "System is already in legacy (non-ACPI) mode\n")); |
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index c8341fa5fe01..dd43b00e18b5 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c | |||
@@ -54,7 +54,7 @@ ACPI_MODULE_NAME("exconfig") | |||
54 | 54 | ||
55 | /* Local prototypes */ | 55 | /* Local prototypes */ |
56 | static acpi_status | 56 | static acpi_status |
57 | acpi_ex_add_table(struct acpi_table_header *table, | 57 | acpi_ex_add_table(acpi_native_uint table_index, |
58 | struct acpi_namespace_node *parent_node, | 58 | struct acpi_namespace_node *parent_node, |
59 | union acpi_operand_object **ddb_handle); | 59 | union acpi_operand_object **ddb_handle); |
60 | 60 | ||
@@ -74,12 +74,11 @@ acpi_ex_add_table(struct acpi_table_header *table, | |||
74 | ******************************************************************************/ | 74 | ******************************************************************************/ |
75 | 75 | ||
76 | static acpi_status | 76 | static acpi_status |
77 | acpi_ex_add_table(struct acpi_table_header *table, | 77 | acpi_ex_add_table(acpi_native_uint table_index, |
78 | struct acpi_namespace_node *parent_node, | 78 | struct acpi_namespace_node *parent_node, |
79 | union acpi_operand_object **ddb_handle) | 79 | union acpi_operand_object **ddb_handle) |
80 | { | 80 | { |
81 | acpi_status status; | 81 | acpi_status status; |
82 | struct acpi_table_desc table_info; | ||
83 | union acpi_operand_object *obj_desc; | 82 | union acpi_operand_object *obj_desc; |
84 | 83 | ||
85 | ACPI_FUNCTION_TRACE(ex_add_table); | 84 | ACPI_FUNCTION_TRACE(ex_add_table); |
@@ -98,42 +97,16 @@ acpi_ex_add_table(struct acpi_table_header *table, | |||
98 | 97 | ||
99 | /* Install the new table into the local data structures */ | 98 | /* Install the new table into the local data structures */ |
100 | 99 | ||
101 | ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc)); | 100 | obj_desc->reference.object = ACPI_CAST_PTR(void, table_index); |
102 | |||
103 | table_info.type = ACPI_TABLE_ID_SSDT; | ||
104 | table_info.pointer = table; | ||
105 | table_info.length = (acpi_size) table->length; | ||
106 | table_info.allocation = ACPI_MEM_ALLOCATED; | ||
107 | |||
108 | status = acpi_tb_install_table(&table_info); | ||
109 | obj_desc->reference.object = table_info.installed_desc; | ||
110 | |||
111 | if (ACPI_FAILURE(status)) { | ||
112 | if (status == AE_ALREADY_EXISTS) { | ||
113 | |||
114 | /* Table already exists, just return the handle */ | ||
115 | |||
116 | return_ACPI_STATUS(AE_OK); | ||
117 | } | ||
118 | goto cleanup; | ||
119 | } | ||
120 | 101 | ||
121 | /* Add the table to the namespace */ | 102 | /* Add the table to the namespace */ |
122 | 103 | ||
123 | status = acpi_ns_load_table(table_info.installed_desc, parent_node); | 104 | status = acpi_ns_load_table(table_index, parent_node); |
124 | if (ACPI_FAILURE(status)) { | 105 | if (ACPI_FAILURE(status)) { |
125 | 106 | acpi_ut_remove_reference(obj_desc); | |
126 | /* Uninstall table on error */ | 107 | *ddb_handle = NULL; |
127 | |||
128 | (void)acpi_tb_uninstall_table(table_info.installed_desc); | ||
129 | goto cleanup; | ||
130 | } | 108 | } |
131 | 109 | ||
132 | return_ACPI_STATUS(AE_OK); | ||
133 | |||
134 | cleanup: | ||
135 | acpi_ut_remove_reference(obj_desc); | ||
136 | *ddb_handle = NULL; | ||
137 | return_ACPI_STATUS(status); | 110 | return_ACPI_STATUS(status); |
138 | } | 111 | } |
139 | 112 | ||
@@ -156,11 +129,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
156 | { | 129 | { |
157 | acpi_status status; | 130 | acpi_status status; |
158 | union acpi_operand_object **operand = &walk_state->operands[0]; | 131 | union acpi_operand_object **operand = &walk_state->operands[0]; |
159 | struct acpi_table_header *table; | 132 | acpi_native_uint table_index; |
160 | struct acpi_namespace_node *parent_node; | 133 | struct acpi_namespace_node *parent_node; |
161 | struct acpi_namespace_node *start_node; | 134 | struct acpi_namespace_node *start_node; |
162 | struct acpi_namespace_node *parameter_node = NULL; | 135 | struct acpi_namespace_node *parameter_node = NULL; |
163 | union acpi_operand_object *ddb_handle; | 136 | union acpi_operand_object *ddb_handle; |
137 | struct acpi_table_header *table; | ||
164 | 138 | ||
165 | ACPI_FUNCTION_TRACE(ex_load_table_op); | 139 | ACPI_FUNCTION_TRACE(ex_load_table_op); |
166 | 140 | ||
@@ -182,7 +156,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
182 | 156 | ||
183 | status = acpi_tb_find_table(operand[0]->string.pointer, | 157 | status = acpi_tb_find_table(operand[0]->string.pointer, |
184 | operand[1]->string.pointer, | 158 | operand[1]->string.pointer, |
185 | operand[2]->string.pointer, &table); | 159 | operand[2]->string.pointer, &table_index); |
186 | if (ACPI_FAILURE(status)) { | 160 | if (ACPI_FAILURE(status)) { |
187 | if (status != AE_NOT_FOUND) { | 161 | if (status != AE_NOT_FOUND) { |
188 | return_ACPI_STATUS(status); | 162 | return_ACPI_STATUS(status); |
@@ -245,7 +219,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
245 | 219 | ||
246 | /* Load the table into the namespace */ | 220 | /* Load the table into the namespace */ |
247 | 221 | ||
248 | status = acpi_ex_add_table(table, parent_node, &ddb_handle); | 222 | status = acpi_ex_add_table(table_index, parent_node, &ddb_handle); |
249 | if (ACPI_FAILURE(status)) { | 223 | if (ACPI_FAILURE(status)) { |
250 | return_ACPI_STATUS(status); | 224 | return_ACPI_STATUS(status); |
251 | } | 225 | } |
@@ -266,9 +240,13 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
266 | } | 240 | } |
267 | } | 241 | } |
268 | 242 | ||
269 | ACPI_INFO((AE_INFO, | 243 | status = acpi_get_table_by_index(table_index, &table); |
270 | "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", | 244 | if (ACPI_SUCCESS(status)) { |
271 | table->signature, table->oem_id, table->oem_table_id)); | 245 | ACPI_INFO((AE_INFO, |
246 | "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", | ||
247 | table->signature, table->oem_id, | ||
248 | table->oem_table_id)); | ||
249 | } | ||
272 | 250 | ||
273 | *return_desc = ddb_handle; | 251 | *return_desc = ddb_handle; |
274 | return_ACPI_STATUS(status); | 252 | return_ACPI_STATUS(status); |
@@ -298,6 +276,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
298 | union acpi_operand_object *ddb_handle; | 276 | union acpi_operand_object *ddb_handle; |
299 | union acpi_operand_object *buffer_desc = NULL; | 277 | union acpi_operand_object *buffer_desc = NULL; |
300 | struct acpi_table_header *table_ptr = NULL; | 278 | struct acpi_table_header *table_ptr = NULL; |
279 | acpi_native_uint table_index; | ||
301 | acpi_physical_address address; | 280 | acpi_physical_address address; |
302 | struct acpi_table_header table_header; | 281 | struct acpi_table_header table_header; |
303 | acpi_integer temp; | 282 | acpi_integer temp; |
@@ -420,8 +399,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
420 | 399 | ||
421 | /* The table must be either an SSDT or a PSDT */ | 400 | /* The table must be either an SSDT or a PSDT */ |
422 | 401 | ||
423 | if ((!ACPI_COMPARE_NAME(table_ptr->signature, PSDT_SIG)) && | 402 | if ((!ACPI_COMPARE_NAME(table_ptr->signature, ACPI_SIG_PSDT)) && |
424 | (!ACPI_COMPARE_NAME(table_ptr->signature, SSDT_SIG))) { | 403 | (!ACPI_COMPARE_NAME(table_ptr->signature, ACPI_SIG_SSDT))) { |
425 | ACPI_ERROR((AE_INFO, | 404 | ACPI_ERROR((AE_INFO, |
426 | "Table has invalid signature [%4.4s], must be SSDT or PSDT", | 405 | "Table has invalid signature [%4.4s], must be SSDT or PSDT", |
427 | table_ptr->signature)); | 406 | table_ptr->signature)); |
@@ -429,9 +408,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
429 | goto cleanup; | 408 | goto cleanup; |
430 | } | 409 | } |
431 | 410 | ||
432 | /* Install the new table into the local data structures */ | 411 | /* |
412 | * Install the new table into the local data structures | ||
413 | */ | ||
414 | status = acpi_tb_add_table(table_ptr, &table_index); | ||
415 | if (ACPI_FAILURE(status)) { | ||
416 | return_ACPI_STATUS(status); | ||
417 | } | ||
433 | 418 | ||
434 | status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle); | 419 | status = |
420 | acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); | ||
435 | if (ACPI_FAILURE(status)) { | 421 | if (ACPI_FAILURE(status)) { |
436 | 422 | ||
437 | /* On error, table_ptr was deallocated above */ | 423 | /* On error, table_ptr was deallocated above */ |
@@ -477,7 +463,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
477 | { | 463 | { |
478 | acpi_status status = AE_OK; | 464 | acpi_status status = AE_OK; |
479 | union acpi_operand_object *table_desc = ddb_handle; | 465 | union acpi_operand_object *table_desc = ddb_handle; |
480 | struct acpi_table_desc *table_info; | 466 | acpi_native_uint table_index; |
481 | 467 | ||
482 | ACPI_FUNCTION_TRACE(ex_unload_table); | 468 | ACPI_FUNCTION_TRACE(ex_unload_table); |
483 | 469 | ||
@@ -493,19 +479,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
493 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 479 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
494 | } | 480 | } |
495 | 481 | ||
496 | /* Get the actual table descriptor from the ddb_handle */ | 482 | /* Get the table index from the ddb_handle */ |
497 | 483 | ||
498 | table_info = (struct acpi_table_desc *)table_desc->reference.object; | 484 | table_index = (acpi_native_uint) table_desc->reference.object; |
499 | 485 | ||
500 | /* | 486 | /* |
501 | * Delete the entire namespace under this table Node | 487 | * Delete the entire namespace under this table Node |
502 | * (Offset contains the table_id) | 488 | * (Offset contains the table_id) |
503 | */ | 489 | */ |
504 | acpi_ns_delete_namespace_by_owner(table_info->owner_id); | 490 | acpi_tb_delete_namespace_by_owner(table_index); |
505 | 491 | acpi_tb_release_owner_id(table_index); | |
506 | /* Delete the table itself */ | ||
507 | 492 | ||
508 | (void)acpi_tb_uninstall_table(table_info->installed_desc); | 493 | acpi_tb_set_table_loaded_flag(table_index, FALSE); |
509 | 494 | ||
510 | /* Delete the table descriptor (ddb_handle) */ | 495 | /* Delete the table descriptor (ddb_handle) */ |
511 | 496 | ||
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c index 34eec82c1b1e..a4d29b2d086f 100644 --- a/drivers/acpi/executer/excreate.c +++ b/drivers/acpi/executer/excreate.c | |||
@@ -359,8 +359,9 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) | |||
359 | union acpi_operand_object **operand = &walk_state->operands[0]; | 359 | union acpi_operand_object **operand = &walk_state->operands[0]; |
360 | union acpi_operand_object *obj_desc; | 360 | union acpi_operand_object *obj_desc; |
361 | struct acpi_namespace_node *node; | 361 | struct acpi_namespace_node *node; |
362 | struct acpi_table_header *table; | ||
363 | union acpi_operand_object *region_obj2; | 362 | union acpi_operand_object *region_obj2; |
363 | acpi_native_uint table_index; | ||
364 | struct acpi_table_header *table; | ||
364 | 365 | ||
365 | ACPI_FUNCTION_TRACE(ex_create_table_region); | 366 | ACPI_FUNCTION_TRACE(ex_create_table_region); |
366 | 367 | ||
@@ -380,7 +381,7 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) | |||
380 | 381 | ||
381 | status = acpi_tb_find_table(operand[1]->string.pointer, | 382 | status = acpi_tb_find_table(operand[1]->string.pointer, |
382 | operand[2]->string.pointer, | 383 | operand[2]->string.pointer, |
383 | operand[3]->string.pointer, &table); | 384 | operand[3]->string.pointer, &table_index); |
384 | if (ACPI_FAILURE(status)) { | 385 | if (ACPI_FAILURE(status)) { |
385 | return_ACPI_STATUS(status); | 386 | return_ACPI_STATUS(status); |
386 | } | 387 | } |
@@ -395,6 +396,11 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state) | |||
395 | region_obj2 = obj_desc->common.next_object; | 396 | region_obj2 = obj_desc->common.next_object; |
396 | region_obj2->extra.region_context = NULL; | 397 | region_obj2->extra.region_context = NULL; |
397 | 398 | ||
399 | status = acpi_get_table_by_index(table_index, &table); | ||
400 | if (ACPI_FAILURE(status)) { | ||
401 | return_ACPI_STATUS(status); | ||
402 | } | ||
403 | |||
398 | /* Init the region from the operands */ | 404 | /* Init the region from the operands */ |
399 | 405 | ||
400 | obj_desc->region.space_id = REGION_DATA_TABLE; | 406 | obj_desc->region.space_id = REGION_DATA_TABLE; |
@@ -553,7 +559,8 @@ acpi_ex_create_method(u8 * aml_start, | |||
553 | 559 | ||
554 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); | 560 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); |
555 | if (!obj_desc) { | 561 | if (!obj_desc) { |
556 | return_ACPI_STATUS(AE_NO_MEMORY); | 562 | status = AE_NO_MEMORY; |
563 | goto exit; | ||
557 | } | 564 | } |
558 | 565 | ||
559 | /* Save the method's AML pointer and length */ | 566 | /* Save the method's AML pointer and length */ |
@@ -597,6 +604,7 @@ acpi_ex_create_method(u8 * aml_start, | |||
597 | 604 | ||
598 | acpi_ut_remove_reference(obj_desc); | 605 | acpi_ut_remove_reference(obj_desc); |
599 | 606 | ||
607 | exit: | ||
600 | /* Remove a reference to the operand */ | 608 | /* Remove a reference to the operand */ |
601 | 609 | ||
602 | acpi_ut_remove_reference(operand[1]); | 610 | acpi_ut_remove_reference(operand[1]); |
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index 40f0bee6faa5..b3f30d83d50a 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c | |||
@@ -257,14 +257,13 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
257 | } | 257 | } |
258 | 258 | ||
259 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, | 259 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, |
260 | " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n", | 260 | " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n", |
261 | acpi_ut_get_region_name(rgn_desc->region. | 261 | acpi_ut_get_region_name(rgn_desc->region. |
262 | space_id), | 262 | space_id), |
263 | rgn_desc->region.space_id, | 263 | rgn_desc->region.space_id, |
264 | obj_desc->common_field.access_byte_width, | 264 | obj_desc->common_field.access_byte_width, |
265 | obj_desc->common_field.base_byte_offset, | 265 | obj_desc->common_field.base_byte_offset, |
266 | field_datum_byte_offset, | 266 | field_datum_byte_offset, (void *)address)); |
267 | ACPI_FORMAT_UINT64(address))); | ||
268 | 267 | ||
269 | /* Invoke the appropriate address_space/op_region handler */ | 268 | /* Invoke the appropriate address_space/op_region handler */ |
270 | 269 | ||
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c index 3cc97ba48b36..496744774859 100644 --- a/drivers/acpi/executer/exregion.c +++ b/drivers/acpi/executer/exregion.c | |||
@@ -155,16 +155,15 @@ acpi_ex_system_memory_space_handler(u32 function, | |||
155 | 155 | ||
156 | /* Create a new mapping starting at the address given */ | 156 | /* Create a new mapping starting at the address given */ |
157 | 157 | ||
158 | status = acpi_os_map_memory(address, window_size, | 158 | mem_info->mapped_logical_address = |
159 | (void **)&mem_info-> | 159 | acpi_os_map_memory((acpi_native_uint) address, window_size); |
160 | mapped_logical_address); | 160 | if (!mem_info->mapped_logical_address) { |
161 | if (ACPI_FAILURE(status)) { | ||
162 | ACPI_ERROR((AE_INFO, | 161 | ACPI_ERROR((AE_INFO, |
163 | "Could not map memory at %8.8X%8.8X, size %X", | 162 | "Could not map memory at %8.8X%8.8X, size %X", |
164 | ACPI_FORMAT_UINT64(address), | 163 | ACPI_FORMAT_UINT64(address), |
165 | (u32) window_size)); | 164 | (u32) window_size)); |
166 | mem_info->mapped_length = 0; | 165 | mem_info->mapped_length = 0; |
167 | return_ACPI_STATUS(status); | 166 | return_ACPI_STATUS(AE_NO_MEMORY); |
168 | } | 167 | } |
169 | 168 | ||
170 | /* Save the physical address and mapping size */ | 169 | /* Save the physical address and mapping size */ |
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c index de50fab2a910..14e8111769a3 100644 --- a/drivers/acpi/hardware/hwacpi.c +++ b/drivers/acpi/hardware/hwacpi.c | |||
@@ -65,13 +65,6 @@ acpi_status acpi_hw_initialize(void) | |||
65 | 65 | ||
66 | ACPI_FUNCTION_TRACE(hw_initialize); | 66 | ACPI_FUNCTION_TRACE(hw_initialize); |
67 | 67 | ||
68 | /* We must have the ACPI tables by the time we get here */ | ||
69 | |||
70 | if (!acpi_gbl_FADT) { | ||
71 | ACPI_ERROR((AE_INFO, "No FADT is present")); | ||
72 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
73 | } | ||
74 | |||
75 | /* Sanity check the FADT for valid values */ | 68 | /* Sanity check the FADT for valid values */ |
76 | 69 | ||
77 | status = acpi_ut_validate_fadt(); | 70 | status = acpi_ut_validate_fadt(); |
@@ -106,7 +99,7 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
106 | * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, | 99 | * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, |
107 | * system does not support mode transition. | 100 | * system does not support mode transition. |
108 | */ | 101 | */ |
109 | if (!acpi_gbl_FADT->smi_cmd) { | 102 | if (!acpi_gbl_FADT.smi_command) { |
110 | ACPI_ERROR((AE_INFO, | 103 | ACPI_ERROR((AE_INFO, |
111 | "No SMI_CMD in FADT, mode transition failed")); | 104 | "No SMI_CMD in FADT, mode transition failed")); |
112 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); | 105 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); |
@@ -119,7 +112,7 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
119 | * we make sure both the numbers are zero to determine these | 112 | * we make sure both the numbers are zero to determine these |
120 | * transitions are not supported. | 113 | * transitions are not supported. |
121 | */ | 114 | */ |
122 | if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) { | 115 | if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) { |
123 | ACPI_ERROR((AE_INFO, | 116 | ACPI_ERROR((AE_INFO, |
124 | "No ACPI mode transition supported in this system (enable/disable both zero)")); | 117 | "No ACPI mode transition supported in this system (enable/disable both zero)")); |
125 | return_ACPI_STATUS(AE_OK); | 118 | return_ACPI_STATUS(AE_OK); |
@@ -130,9 +123,8 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
130 | 123 | ||
131 | /* BIOS should have disabled ALL fixed and GP events */ | 124 | /* BIOS should have disabled ALL fixed and GP events */ |
132 | 125 | ||
133 | status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, | 126 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, |
134 | (u32) acpi_gbl_FADT->acpi_enable, | 127 | (u32) acpi_gbl_FADT.acpi_enable, 8); |
135 | 8); | ||
136 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 128 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
137 | "Attempting to enable ACPI mode\n")); | 129 | "Attempting to enable ACPI mode\n")); |
138 | break; | 130 | break; |
@@ -143,8 +135,8 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
143 | * BIOS should clear all fixed status bits and restore fixed event | 135 | * BIOS should clear all fixed status bits and restore fixed event |
144 | * enable bits to default | 136 | * enable bits to default |
145 | */ | 137 | */ |
146 | status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, | 138 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, |
147 | (u32) acpi_gbl_FADT->acpi_disable, | 139 | (u32) acpi_gbl_FADT.acpi_disable, |
148 | 8); | 140 | 8); |
149 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 141 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
150 | "Attempting to enable Legacy (non-ACPI) mode\n")); | 142 | "Attempting to enable Legacy (non-ACPI) mode\n")); |
@@ -204,7 +196,7 @@ u32 acpi_hw_get_mode(void) | |||
204 | * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, | 196 | * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, |
205 | * system does not support mode transition. | 197 | * system does not support mode transition. |
206 | */ | 198 | */ |
207 | if (!acpi_gbl_FADT->smi_cmd) { | 199 | if (!acpi_gbl_FADT.smi_command) { |
208 | return_UINT32(ACPI_SYS_MODE_ACPI); | 200 | return_UINT32(ACPI_SYS_MODE_ACPI); |
209 | } | 201 | } |
210 | 202 | ||
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c index fa58c1edce1e..9fe7adf21f8b 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/hardware/hwregs.c | |||
@@ -73,7 +73,7 @@ acpi_status acpi_hw_clear_acpi_status(u32 flags) | |||
73 | 73 | ||
74 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", | 74 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", |
75 | ACPI_BITMASK_ALL_FIXED_STATUS, | 75 | ACPI_BITMASK_ALL_FIXED_STATUS, |
76 | (u16) acpi_gbl_FADT->xpm1a_evt_blk.address)); | 76 | (u16) acpi_gbl_FADT.xpm1a_event_block.address)); |
77 | 77 | ||
78 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 78 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); |
79 | 79 | ||
@@ -86,10 +86,10 @@ acpi_status acpi_hw_clear_acpi_status(u32 flags) | |||
86 | 86 | ||
87 | /* Clear the fixed events */ | 87 | /* Clear the fixed events */ |
88 | 88 | ||
89 | if (acpi_gbl_FADT->xpm1b_evt_blk.address) { | 89 | if (acpi_gbl_FADT.xpm1b_event_block.address) { |
90 | status = | 90 | status = |
91 | acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, | 91 | acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS, |
92 | &acpi_gbl_FADT->xpm1b_evt_blk); | 92 | &acpi_gbl_FADT.xpm1b_event_block); |
93 | if (ACPI_FAILURE(status)) { | 93 | if (ACPI_FAILURE(status)) { |
94 | goto unlock_and_exit; | 94 | goto unlock_and_exit; |
95 | } | 95 | } |
@@ -422,8 +422,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) | |||
422 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 422 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
423 | "PM2 control: Read %X from %8.8X%8.8X\n", | 423 | "PM2 control: Read %X from %8.8X%8.8X\n", |
424 | register_value, | 424 | register_value, |
425 | ACPI_FORMAT_UINT64(acpi_gbl_FADT-> | 425 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. |
426 | xpm2_cnt_blk.address))); | 426 | xpm2_control_block. |
427 | address))); | ||
427 | 428 | ||
428 | ACPI_REGISTER_INSERT_VALUE(register_value, | 429 | ACPI_REGISTER_INSERT_VALUE(register_value, |
429 | bit_reg_info->bit_position, | 430 | bit_reg_info->bit_position, |
@@ -433,8 +434,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags) | |||
433 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 434 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
434 | "About to write %4.4X to %8.8X%8.8X\n", | 435 | "About to write %4.4X to %8.8X%8.8X\n", |
435 | register_value, | 436 | register_value, |
436 | ACPI_FORMAT_UINT64(acpi_gbl_FADT-> | 437 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. |
437 | xpm2_cnt_blk.address))); | 438 | xpm2_control_block. |
439 | address))); | ||
438 | 440 | ||
439 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, | 441 | status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, |
440 | ACPI_REGISTER_PM2_CONTROL, | 442 | ACPI_REGISTER_PM2_CONTROL, |
@@ -495,7 +497,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) | |||
495 | 497 | ||
496 | status = | 498 | status = |
497 | acpi_hw_low_level_read(16, &value1, | 499 | acpi_hw_low_level_read(16, &value1, |
498 | &acpi_gbl_FADT->xpm1a_evt_blk); | 500 | &acpi_gbl_FADT.xpm1a_event_block); |
499 | if (ACPI_FAILURE(status)) { | 501 | if (ACPI_FAILURE(status)) { |
500 | goto unlock_and_exit; | 502 | goto unlock_and_exit; |
501 | } | 503 | } |
@@ -504,7 +506,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) | |||
504 | 506 | ||
505 | status = | 507 | status = |
506 | acpi_hw_low_level_read(16, &value2, | 508 | acpi_hw_low_level_read(16, &value2, |
507 | &acpi_gbl_FADT->xpm1b_evt_blk); | 509 | &acpi_gbl_FADT.xpm1b_event_block); |
508 | value1 |= value2; | 510 | value1 |= value2; |
509 | break; | 511 | break; |
510 | 512 | ||
@@ -527,14 +529,14 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) | |||
527 | 529 | ||
528 | status = | 530 | status = |
529 | acpi_hw_low_level_read(16, &value1, | 531 | acpi_hw_low_level_read(16, &value1, |
530 | &acpi_gbl_FADT->xpm1a_cnt_blk); | 532 | &acpi_gbl_FADT.xpm1a_control_block); |
531 | if (ACPI_FAILURE(status)) { | 533 | if (ACPI_FAILURE(status)) { |
532 | goto unlock_and_exit; | 534 | goto unlock_and_exit; |
533 | } | 535 | } |
534 | 536 | ||
535 | status = | 537 | status = |
536 | acpi_hw_low_level_read(16, &value2, | 538 | acpi_hw_low_level_read(16, &value2, |
537 | &acpi_gbl_FADT->xpm1b_cnt_blk); | 539 | &acpi_gbl_FADT.xpm1b_control_block); |
538 | value1 |= value2; | 540 | value1 |= value2; |
539 | break; | 541 | break; |
540 | 542 | ||
@@ -542,19 +544,20 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) | |||
542 | 544 | ||
543 | status = | 545 | status = |
544 | acpi_hw_low_level_read(8, &value1, | 546 | acpi_hw_low_level_read(8, &value1, |
545 | &acpi_gbl_FADT->xpm2_cnt_blk); | 547 | &acpi_gbl_FADT.xpm2_control_block); |
546 | break; | 548 | break; |
547 | 549 | ||
548 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 550 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
549 | 551 | ||
550 | status = | 552 | status = |
551 | acpi_hw_low_level_read(32, &value1, | 553 | acpi_hw_low_level_read(32, &value1, |
552 | &acpi_gbl_FADT->xpm_tmr_blk); | 554 | &acpi_gbl_FADT.xpm_timer_block); |
553 | break; | 555 | break; |
554 | 556 | ||
555 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 557 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
556 | 558 | ||
557 | status = acpi_os_read_port(acpi_gbl_FADT->smi_cmd, &value1, 8); | 559 | status = |
560 | acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8); | ||
558 | break; | 561 | break; |
559 | 562 | ||
560 | default: | 563 | default: |
@@ -635,7 +638,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) | |||
635 | 638 | ||
636 | status = | 639 | status = |
637 | acpi_hw_low_level_write(16, value, | 640 | acpi_hw_low_level_write(16, value, |
638 | &acpi_gbl_FADT->xpm1a_evt_blk); | 641 | &acpi_gbl_FADT.xpm1a_event_block); |
639 | if (ACPI_FAILURE(status)) { | 642 | if (ACPI_FAILURE(status)) { |
640 | goto unlock_and_exit; | 643 | goto unlock_and_exit; |
641 | } | 644 | } |
@@ -644,7 +647,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) | |||
644 | 647 | ||
645 | status = | 648 | status = |
646 | acpi_hw_low_level_write(16, value, | 649 | acpi_hw_low_level_write(16, value, |
647 | &acpi_gbl_FADT->xpm1b_evt_blk); | 650 | &acpi_gbl_FADT.xpm1b_event_block); |
648 | break; | 651 | break; |
649 | 652 | ||
650 | case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ | 653 | case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ |
@@ -682,49 +685,50 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) | |||
682 | 685 | ||
683 | status = | 686 | status = |
684 | acpi_hw_low_level_write(16, value, | 687 | acpi_hw_low_level_write(16, value, |
685 | &acpi_gbl_FADT->xpm1a_cnt_blk); | 688 | &acpi_gbl_FADT.xpm1a_control_block); |
686 | if (ACPI_FAILURE(status)) { | 689 | if (ACPI_FAILURE(status)) { |
687 | goto unlock_and_exit; | 690 | goto unlock_and_exit; |
688 | } | 691 | } |
689 | 692 | ||
690 | status = | 693 | status = |
691 | acpi_hw_low_level_write(16, value, | 694 | acpi_hw_low_level_write(16, value, |
692 | &acpi_gbl_FADT->xpm1b_cnt_blk); | 695 | &acpi_gbl_FADT.xpm1b_control_block); |
693 | break; | 696 | break; |
694 | 697 | ||
695 | case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ | 698 | case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ |
696 | 699 | ||
697 | status = | 700 | status = |
698 | acpi_hw_low_level_write(16, value, | 701 | acpi_hw_low_level_write(16, value, |
699 | &acpi_gbl_FADT->xpm1a_cnt_blk); | 702 | &acpi_gbl_FADT.xpm1a_control_block); |
700 | break; | 703 | break; |
701 | 704 | ||
702 | case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ | 705 | case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ |
703 | 706 | ||
704 | status = | 707 | status = |
705 | acpi_hw_low_level_write(16, value, | 708 | acpi_hw_low_level_write(16, value, |
706 | &acpi_gbl_FADT->xpm1b_cnt_blk); | 709 | &acpi_gbl_FADT.xpm1b_control_block); |
707 | break; | 710 | break; |
708 | 711 | ||
709 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ | 712 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ |
710 | 713 | ||
711 | status = | 714 | status = |
712 | acpi_hw_low_level_write(8, value, | 715 | acpi_hw_low_level_write(8, value, |
713 | &acpi_gbl_FADT->xpm2_cnt_blk); | 716 | &acpi_gbl_FADT.xpm2_control_block); |
714 | break; | 717 | break; |
715 | 718 | ||
716 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 719 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
717 | 720 | ||
718 | status = | 721 | status = |
719 | acpi_hw_low_level_write(32, value, | 722 | acpi_hw_low_level_write(32, value, |
720 | &acpi_gbl_FADT->xpm_tmr_blk); | 723 | &acpi_gbl_FADT.xpm_timer_block); |
721 | break; | 724 | break; |
722 | 725 | ||
723 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 726 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
724 | 727 | ||
725 | /* SMI_CMD is currently always in IO space */ | 728 | /* SMI_CMD is currently always in IO space */ |
726 | 729 | ||
727 | status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, value, 8); | 730 | status = |
731 | acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8); | ||
728 | break; | 732 | break; |
729 | 733 | ||
730 | default: | 734 | default: |
@@ -783,7 +787,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) | |||
783 | * Two address spaces supported: Memory or IO. | 787 | * Two address spaces supported: Memory or IO. |
784 | * PCI_Config is not supported here because the GAS struct is insufficient | 788 | * PCI_Config is not supported here because the GAS struct is insufficient |
785 | */ | 789 | */ |
786 | switch (reg->address_space_id) { | 790 | switch (reg->space_id) { |
787 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 791 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
788 | 792 | ||
789 | status = acpi_os_read_memory((acpi_physical_address) address, | 793 | status = acpi_os_read_memory((acpi_physical_address) address, |
@@ -798,8 +802,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) | |||
798 | 802 | ||
799 | default: | 803 | default: |
800 | ACPI_ERROR((AE_INFO, | 804 | ACPI_ERROR((AE_INFO, |
801 | "Unsupported address space: %X", | 805 | "Unsupported address space: %X", reg->space_id)); |
802 | reg->address_space_id)); | ||
803 | return (AE_BAD_PARAMETER); | 806 | return (AE_BAD_PARAMETER); |
804 | } | 807 | } |
805 | 808 | ||
@@ -807,7 +810,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg) | |||
807 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", | 810 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", |
808 | *value, width, | 811 | *value, width, |
809 | ACPI_FORMAT_UINT64(address), | 812 | ACPI_FORMAT_UINT64(address), |
810 | acpi_ut_get_region_name(reg->address_space_id))); | 813 | acpi_ut_get_region_name(reg->space_id))); |
811 | 814 | ||
812 | return (status); | 815 | return (status); |
813 | } | 816 | } |
@@ -854,7 +857,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) | |||
854 | * Two address spaces supported: Memory or IO. | 857 | * Two address spaces supported: Memory or IO. |
855 | * PCI_Config is not supported here because the GAS struct is insufficient | 858 | * PCI_Config is not supported here because the GAS struct is insufficient |
856 | */ | 859 | */ |
857 | switch (reg->address_space_id) { | 860 | switch (reg->space_id) { |
858 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 861 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
859 | 862 | ||
860 | status = acpi_os_write_memory((acpi_physical_address) address, | 863 | status = acpi_os_write_memory((acpi_physical_address) address, |
@@ -869,8 +872,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) | |||
869 | 872 | ||
870 | default: | 873 | default: |
871 | ACPI_ERROR((AE_INFO, | 874 | ACPI_ERROR((AE_INFO, |
872 | "Unsupported address space: %X", | 875 | "Unsupported address space: %X", reg->space_id)); |
873 | reg->address_space_id)); | ||
874 | return (AE_BAD_PARAMETER); | 876 | return (AE_BAD_PARAMETER); |
875 | } | 877 | } |
876 | 878 | ||
@@ -878,7 +880,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg) | |||
878 | "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", | 880 | "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", |
879 | value, width, | 881 | value, width, |
880 | ACPI_FORMAT_UINT64(address), | 882 | ACPI_FORMAT_UINT64(address), |
881 | acpi_ut_get_region_name(reg->address_space_id))); | 883 | acpi_ut_get_region_name(reg->space_id))); |
882 | 884 | ||
883 | return (status); | 885 | return (status); |
884 | } | 886 | } |
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 8bb43cae60c2..6faa76bdc3d5 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c | |||
@@ -43,6 +43,7 @@ | |||
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
46 | #include <acpi/actables.h> | ||
46 | 47 | ||
47 | #define _COMPONENT ACPI_HARDWARE | 48 | #define _COMPONENT ACPI_HARDWARE |
48 | ACPI_MODULE_NAME("hwsleep") | 49 | ACPI_MODULE_NAME("hwsleep") |
@@ -62,17 +63,32 @@ ACPI_MODULE_NAME("hwsleep") | |||
62 | acpi_status | 63 | acpi_status |
63 | acpi_set_firmware_waking_vector(acpi_physical_address physical_address) | 64 | acpi_set_firmware_waking_vector(acpi_physical_address physical_address) |
64 | { | 65 | { |
66 | struct acpi_table_facs *facs; | ||
67 | acpi_status status; | ||
65 | 68 | ||
66 | ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); | 69 | ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); |
67 | 70 | ||
71 | /* Get the FACS */ | ||
72 | |||
73 | status = | ||
74 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, | ||
75 | (struct acpi_table_header **)&facs); | ||
76 | if (ACPI_FAILURE(status)) { | ||
77 | return_ACPI_STATUS(status); | ||
78 | } | ||
79 | |||
68 | /* Set the vector */ | 80 | /* Set the vector */ |
69 | 81 | ||
70 | if (acpi_gbl_common_fACS.vector_width == 32) { | 82 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { |
71 | *(ACPI_CAST_PTR | 83 | /* |
72 | (u32, acpi_gbl_common_fACS.firmware_waking_vector)) | 84 | * ACPI 1.0 FACS or short table or optional X_ field is zero |
73 | = (u32) physical_address; | 85 | */ |
86 | facs->firmware_waking_vector = (u32) physical_address; | ||
74 | } else { | 87 | } else { |
75 | *acpi_gbl_common_fACS.firmware_waking_vector = physical_address; | 88 | /* |
89 | * ACPI 2.0 FACS with valid X_ field | ||
90 | */ | ||
91 | facs->xfirmware_waking_vector = physical_address; | ||
76 | } | 92 | } |
77 | 93 | ||
78 | return_ACPI_STATUS(AE_OK); | 94 | return_ACPI_STATUS(AE_OK); |
@@ -97,6 +113,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) | |||
97 | acpi_status | 113 | acpi_status |
98 | acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) | 114 | acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) |
99 | { | 115 | { |
116 | struct acpi_table_facs *facs; | ||
117 | acpi_status status; | ||
100 | 118 | ||
101 | ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector); | 119 | ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector); |
102 | 120 | ||
@@ -104,16 +122,29 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) | |||
104 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 122 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
105 | } | 123 | } |
106 | 124 | ||
125 | /* Get the FACS */ | ||
126 | |||
127 | status = | ||
128 | acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, | ||
129 | (struct acpi_table_header **)&facs); | ||
130 | if (ACPI_FAILURE(status)) { | ||
131 | return_ACPI_STATUS(status); | ||
132 | } | ||
133 | |||
107 | /* Get the vector */ | 134 | /* Get the vector */ |
108 | 135 | ||
109 | if (acpi_gbl_common_fACS.vector_width == 32) { | 136 | if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) { |
110 | *physical_address = (acpi_physical_address) | 137 | /* |
111 | * | 138 | * ACPI 1.0 FACS or short table or optional X_ field is zero |
112 | (ACPI_CAST_PTR | 139 | */ |
113 | (u32, acpi_gbl_common_fACS.firmware_waking_vector)); | 140 | *physical_address = |
141 | (acpi_physical_address) facs->firmware_waking_vector; | ||
114 | } else { | 142 | } else { |
143 | /* | ||
144 | * ACPI 2.0 FACS with valid X_ field | ||
145 | */ | ||
115 | *physical_address = | 146 | *physical_address = |
116 | *acpi_gbl_common_fACS.firmware_waking_vector; | 147 | (acpi_physical_address) facs->xfirmware_waking_vector; |
117 | } | 148 | } |
118 | 149 | ||
119 | return_ACPI_STATUS(AE_OK); | 150 | return_ACPI_STATUS(AE_OK); |
@@ -429,8 +460,8 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) | |||
429 | 460 | ||
430 | ACPI_FLUSH_CPU_CACHE(); | 461 | ACPI_FLUSH_CPU_CACHE(); |
431 | 462 | ||
432 | status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, | 463 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, |
433 | (u32) acpi_gbl_FADT->S4bios_req, 8); | 464 | (u32) acpi_gbl_FADT.S4bios_request, 8); |
434 | 465 | ||
435 | do { | 466 | do { |
436 | acpi_os_stall(1000); | 467 | acpi_os_stall(1000); |
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c index c4ec47c939fd..abd86e8d6287 100644 --- a/drivers/acpi/hardware/hwtimer.c +++ b/drivers/acpi/hardware/hwtimer.c | |||
@@ -66,7 +66,7 @@ acpi_status acpi_get_timer_resolution(u32 * resolution) | |||
66 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 66 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
67 | } | 67 | } |
68 | 68 | ||
69 | if (acpi_gbl_FADT->tmr_val_ext == 0) { | 69 | if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) { |
70 | *resolution = 24; | 70 | *resolution = 24; |
71 | } else { | 71 | } else { |
72 | *resolution = 32; | 72 | *resolution = 32; |
@@ -98,7 +98,8 @@ acpi_status acpi_get_timer(u32 * ticks) | |||
98 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 98 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
99 | } | 99 | } |
100 | 100 | ||
101 | status = acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT->xpm_tmr_blk); | 101 | status = |
102 | acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT.xpm_timer_block); | ||
102 | 103 | ||
103 | return_ACPI_STATUS(status); | 104 | return_ACPI_STATUS(status); |
104 | } | 105 | } |
@@ -153,7 +154,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) | |||
153 | if (start_ticks < end_ticks) { | 154 | if (start_ticks < end_ticks) { |
154 | delta_ticks = end_ticks - start_ticks; | 155 | delta_ticks = end_ticks - start_ticks; |
155 | } else if (start_ticks > end_ticks) { | 156 | } else if (start_ticks > end_ticks) { |
156 | if (acpi_gbl_FADT->tmr_val_ext == 0) { | 157 | if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) { |
157 | 158 | ||
158 | /* 24-bit Timer */ | 159 | /* 24-bit Timer */ |
159 | 160 | ||
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index fe75d888e183..5d555f8c167b 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c | |||
@@ -44,13 +44,12 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
46 | #include <acpi/acdispat.h> | 46 | #include <acpi/acdispat.h> |
47 | #include <acpi/actables.h> | ||
47 | 48 | ||
48 | #define _COMPONENT ACPI_NAMESPACE | 49 | #define _COMPONENT ACPI_NAMESPACE |
49 | ACPI_MODULE_NAME("nsload") | 50 | ACPI_MODULE_NAME("nsload") |
50 | 51 | ||
51 | /* Local prototypes */ | 52 | /* Local prototypes */ |
52 | static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type); | ||
53 | |||
54 | #ifdef ACPI_FUTURE_IMPLEMENTATION | 53 | #ifdef ACPI_FUTURE_IMPLEMENTATION |
55 | acpi_status acpi_ns_unload_namespace(acpi_handle handle); | 54 | acpi_status acpi_ns_unload_namespace(acpi_handle handle); |
56 | 55 | ||
@@ -62,7 +61,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); | |||
62 | * | 61 | * |
63 | * FUNCTION: acpi_ns_load_table | 62 | * FUNCTION: acpi_ns_load_table |
64 | * | 63 | * |
65 | * PARAMETERS: table_desc - Descriptor for table to be loaded | 64 | * PARAMETERS: table_index - Index for table to be loaded |
66 | * Node - Owning NS node | 65 | * Node - Owning NS node |
67 | * | 66 | * |
68 | * RETURN: Status | 67 | * RETURN: Status |
@@ -72,42 +71,13 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); | |||
72 | ******************************************************************************/ | 71 | ******************************************************************************/ |
73 | 72 | ||
74 | acpi_status | 73 | acpi_status |
75 | acpi_ns_load_table(struct acpi_table_desc *table_desc, | 74 | acpi_ns_load_table(acpi_native_uint table_index, |
76 | struct acpi_namespace_node *node) | 75 | struct acpi_namespace_node *node) |
77 | { | 76 | { |
78 | acpi_status status; | 77 | acpi_status status; |
79 | 78 | ||
80 | ACPI_FUNCTION_TRACE(ns_load_table); | 79 | ACPI_FUNCTION_TRACE(ns_load_table); |
81 | 80 | ||
82 | /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */ | ||
83 | |||
84 | if (! | ||
85 | (acpi_gbl_table_data[table_desc->type]. | ||
86 | flags & ACPI_TABLE_EXECUTABLE)) { | ||
87 | |||
88 | /* Just ignore this table */ | ||
89 | |||
90 | return_ACPI_STATUS(AE_OK); | ||
91 | } | ||
92 | |||
93 | /* Check validity of the AML start and length */ | ||
94 | |||
95 | if (!table_desc->aml_start) { | ||
96 | ACPI_ERROR((AE_INFO, "Null AML pointer")); | ||
97 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
98 | } | ||
99 | |||
100 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AML block at %p\n", | ||
101 | table_desc->aml_start)); | ||
102 | |||
103 | /* Ignore table if there is no AML contained within */ | ||
104 | |||
105 | if (!table_desc->aml_length) { | ||
106 | ACPI_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]", | ||
107 | table_desc->pointer->signature)); | ||
108 | return_ACPI_STATUS(AE_OK); | ||
109 | } | ||
110 | |||
111 | /* | 81 | /* |
112 | * Parse the table and load the namespace with all named | 82 | * Parse the table and load the namespace with all named |
113 | * objects found within. Control methods are NOT parsed | 83 | * objects found within. Control methods are NOT parsed |
@@ -117,15 +87,34 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, | |||
117 | * to another control method, we can't continue parsing | 87 | * to another control method, we can't continue parsing |
118 | * because we don't know how many arguments to parse next! | 88 | * because we don't know how many arguments to parse next! |
119 | */ | 89 | */ |
90 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
91 | if (ACPI_FAILURE(status)) { | ||
92 | return_ACPI_STATUS(status); | ||
93 | } | ||
94 | |||
95 | /* If table already loaded into namespace, just return */ | ||
96 | |||
97 | if (acpi_tb_is_table_loaded(table_index)) { | ||
98 | status = AE_ALREADY_EXISTS; | ||
99 | goto unlock; | ||
100 | } | ||
101 | |||
120 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 102 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
121 | "**** Loading table into namespace ****\n")); | 103 | "**** Loading table into namespace ****\n")); |
122 | 104 | ||
123 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 105 | status = acpi_tb_allocate_owner_id(table_index); |
124 | if (ACPI_FAILURE(status)) { | 106 | if (ACPI_FAILURE(status)) { |
125 | return_ACPI_STATUS(status); | 107 | goto unlock; |
108 | } | ||
109 | |||
110 | status = acpi_ns_parse_table(table_index, node->child); | ||
111 | if (ACPI_SUCCESS(status)) { | ||
112 | acpi_tb_set_table_loaded_flag(table_index, TRUE); | ||
113 | } else { | ||
114 | acpi_tb_release_owner_id(table_index); | ||
126 | } | 115 | } |
127 | 116 | ||
128 | status = acpi_ns_parse_table(table_desc, node->child); | 117 | unlock: |
129 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 118 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
130 | 119 | ||
131 | if (ACPI_FAILURE(status)) { | 120 | if (ACPI_FAILURE(status)) { |
@@ -141,7 +130,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, | |||
141 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 130 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
142 | "**** Begin Table Method Parsing and Object Initialization ****\n")); | 131 | "**** Begin Table Method Parsing and Object Initialization ****\n")); |
143 | 132 | ||
144 | status = acpi_ds_initialize_objects(table_desc, node); | 133 | status = acpi_ds_initialize_objects(table_index, node); |
145 | 134 | ||
146 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 135 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
147 | "**** Completed Table Method Parsing and Object Initialization ****\n")); | 136 | "**** Completed Table Method Parsing and Object Initialization ****\n")); |
@@ -149,99 +138,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc, | |||
149 | return_ACPI_STATUS(status); | 138 | return_ACPI_STATUS(status); |
150 | } | 139 | } |
151 | 140 | ||
152 | /******************************************************************************* | 141 | #ifdef ACPI_OBSOLETE_FUNCTIONS |
153 | * | ||
154 | * FUNCTION: acpi_ns_load_table_by_type | ||
155 | * | ||
156 | * PARAMETERS: table_type - Id of the table type to load | ||
157 | * | ||
158 | * RETURN: Status | ||
159 | * | ||
160 | * DESCRIPTION: Load an ACPI table or tables into the namespace. All tables | ||
161 | * of the given type are loaded. The mechanism allows this | ||
162 | * routine to be called repeatedly. | ||
163 | * | ||
164 | ******************************************************************************/ | ||
165 | |||
166 | static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type) | ||
167 | { | ||
168 | u32 i; | ||
169 | acpi_status status; | ||
170 | struct acpi_table_desc *table_desc; | ||
171 | |||
172 | ACPI_FUNCTION_TRACE(ns_load_table_by_type); | ||
173 | |||
174 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
175 | if (ACPI_FAILURE(status)) { | ||
176 | return_ACPI_STATUS(status); | ||
177 | } | ||
178 | |||
179 | /* | ||
180 | * Table types supported are: | ||
181 | * DSDT (one), SSDT/PSDT (multiple) | ||
182 | */ | ||
183 | switch (table_type) { | ||
184 | case ACPI_TABLE_ID_DSDT: | ||
185 | |||
186 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n")); | ||
187 | |||
188 | table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_DSDT].next; | ||
189 | |||
190 | /* If table already loaded into namespace, just return */ | ||
191 | |||
192 | if (table_desc->loaded_into_namespace) { | ||
193 | goto unlock_and_exit; | ||
194 | } | ||
195 | |||
196 | /* Now load the single DSDT */ | ||
197 | |||
198 | status = acpi_ns_load_table(table_desc, acpi_gbl_root_node); | ||
199 | if (ACPI_SUCCESS(status)) { | ||
200 | table_desc->loaded_into_namespace = TRUE; | ||
201 | } | ||
202 | break; | ||
203 | |||
204 | case ACPI_TABLE_ID_SSDT: | ||
205 | case ACPI_TABLE_ID_PSDT: | ||
206 | |||
207 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
208 | "Namespace load: %d SSDT or PSDTs\n", | ||
209 | acpi_gbl_table_lists[table_type].count)); | ||
210 | |||
211 | /* | ||
212 | * Traverse list of SSDT or PSDT tables | ||
213 | */ | ||
214 | table_desc = acpi_gbl_table_lists[table_type].next; | ||
215 | for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) { | ||
216 | /* | ||
217 | * Only attempt to load table into namespace if it is not | ||
218 | * already loaded! | ||
219 | */ | ||
220 | if (!table_desc->loaded_into_namespace) { | ||
221 | status = | ||
222 | acpi_ns_load_table(table_desc, | ||
223 | acpi_gbl_root_node); | ||
224 | if (ACPI_FAILURE(status)) { | ||
225 | break; | ||
226 | } | ||
227 | |||
228 | table_desc->loaded_into_namespace = TRUE; | ||
229 | } | ||
230 | |||
231 | table_desc = table_desc->next; | ||
232 | } | ||
233 | break; | ||
234 | |||
235 | default: | ||
236 | status = AE_SUPPORT; | ||
237 | break; | ||
238 | } | ||
239 | |||
240 | unlock_and_exit: | ||
241 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
242 | return_ACPI_STATUS(status); | ||
243 | } | ||
244 | |||
245 | /******************************************************************************* | 142 | /******************************************************************************* |
246 | * | 143 | * |
247 | * FUNCTION: acpi_load_namespace | 144 | * FUNCTION: acpi_load_namespace |
@@ -288,6 +185,7 @@ acpi_status acpi_ns_load_namespace(void) | |||
288 | 185 | ||
289 | return_ACPI_STATUS(status); | 186 | return_ACPI_STATUS(status); |
290 | } | 187 | } |
188 | #endif | ||
291 | 189 | ||
292 | #ifdef ACPI_FUTURE_IMPLEMENTATION | 190 | #ifdef ACPI_FUTURE_IMPLEMENTATION |
293 | /******************************************************************************* | 191 | /******************************************************************************* |
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c index 155505a4ef69..2e224796d56f 100644 --- a/drivers/acpi/namespace/nsparse.c +++ b/drivers/acpi/namespace/nsparse.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
46 | #include <acpi/acparser.h> | 46 | #include <acpi/acparser.h> |
47 | #include <acpi/acdispat.h> | 47 | #include <acpi/acdispat.h> |
48 | #include <acpi/actables.h> | ||
48 | 49 | ||
49 | #define _COMPONENT ACPI_NAMESPACE | 50 | #define _COMPONENT ACPI_NAMESPACE |
50 | ACPI_MODULE_NAME("nsparse") | 51 | ACPI_MODULE_NAME("nsparse") |
@@ -62,14 +63,24 @@ ACPI_MODULE_NAME("nsparse") | |||
62 | * | 63 | * |
63 | ******************************************************************************/ | 64 | ******************************************************************************/ |
64 | acpi_status | 65 | acpi_status |
65 | acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) | 66 | acpi_ns_one_complete_parse(acpi_native_uint pass_number, |
67 | acpi_native_uint table_index) | ||
66 | { | 68 | { |
67 | union acpi_parse_object *parse_root; | 69 | union acpi_parse_object *parse_root; |
68 | acpi_status status; | 70 | acpi_status status; |
71 | acpi_native_uint aml_length; | ||
72 | u8 *aml_start; | ||
69 | struct acpi_walk_state *walk_state; | 73 | struct acpi_walk_state *walk_state; |
74 | struct acpi_table_header *table; | ||
75 | acpi_owner_id owner_id; | ||
70 | 76 | ||
71 | ACPI_FUNCTION_TRACE(ns_one_complete_parse); | 77 | ACPI_FUNCTION_TRACE(ns_one_complete_parse); |
72 | 78 | ||
79 | status = acpi_tb_get_owner_id(table_index, &owner_id); | ||
80 | if (ACPI_FAILURE(status)) { | ||
81 | return_ACPI_STATUS(status); | ||
82 | } | ||
83 | |||
73 | /* Create and init a Root Node */ | 84 | /* Create and init a Root Node */ |
74 | 85 | ||
75 | parse_root = acpi_ps_create_scope_op(); | 86 | parse_root = acpi_ps_create_scope_op(); |
@@ -79,19 +90,34 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) | |||
79 | 90 | ||
80 | /* Create and initialize a new walk state */ | 91 | /* Create and initialize a new walk state */ |
81 | 92 | ||
82 | walk_state = acpi_ds_create_walk_state(table_desc->owner_id, | 93 | walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL); |
83 | NULL, NULL, NULL); | ||
84 | if (!walk_state) { | 94 | if (!walk_state) { |
85 | acpi_ps_free_op(parse_root); | 95 | acpi_ps_free_op(parse_root); |
86 | return_ACPI_STATUS(AE_NO_MEMORY); | 96 | return_ACPI_STATUS(AE_NO_MEMORY); |
87 | } | 97 | } |
88 | 98 | ||
89 | status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, | 99 | status = acpi_get_table_by_index(table_index, &table); |
90 | table_desc->aml_start, | 100 | if (ACPI_FAILURE(status)) { |
91 | table_desc->aml_length, NULL, | 101 | acpi_ds_delete_walk_state(walk_state); |
92 | pass_number); | 102 | acpi_ps_free_op(parse_root); |
103 | return_ACPI_STATUS(status); | ||
104 | } | ||
105 | |||
106 | /* Table must consist of at least a complete header */ | ||
107 | |||
108 | if (table->length < sizeof(struct acpi_table_header)) { | ||
109 | status = AE_BAD_HEADER; | ||
110 | } else { | ||
111 | aml_start = (u8 *) table + sizeof(struct acpi_table_header); | ||
112 | aml_length = table->length - sizeof(struct acpi_table_header); | ||
113 | status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, | ||
114 | aml_start, aml_length, NULL, | ||
115 | (u8) pass_number); | ||
116 | } | ||
117 | |||
93 | if (ACPI_FAILURE(status)) { | 118 | if (ACPI_FAILURE(status)) { |
94 | acpi_ds_delete_walk_state(walk_state); | 119 | acpi_ds_delete_walk_state(walk_state); |
120 | acpi_ps_delete_parse_tree(parse_root); | ||
95 | return_ACPI_STATUS(status); | 121 | return_ACPI_STATUS(status); |
96 | } | 122 | } |
97 | 123 | ||
@@ -119,7 +145,7 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc) | |||
119 | ******************************************************************************/ | 145 | ******************************************************************************/ |
120 | 146 | ||
121 | acpi_status | 147 | acpi_status |
122 | acpi_ns_parse_table(struct acpi_table_desc *table_desc, | 148 | acpi_ns_parse_table(acpi_native_uint table_index, |
123 | struct acpi_namespace_node *start_node) | 149 | struct acpi_namespace_node *start_node) |
124 | { | 150 | { |
125 | acpi_status status; | 151 | acpi_status status; |
@@ -137,7 +163,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc, | |||
137 | * performs another complete parse of the AML.. | 163 | * performs another complete parse of the AML.. |
138 | */ | 164 | */ |
139 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); | 165 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); |
140 | status = acpi_ns_one_complete_parse(1, table_desc); | 166 | status = acpi_ns_one_complete_parse(1, table_index); |
141 | if (ACPI_FAILURE(status)) { | 167 | if (ACPI_FAILURE(status)) { |
142 | return_ACPI_STATUS(status); | 168 | return_ACPI_STATUS(status); |
143 | } | 169 | } |
@@ -152,7 +178,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc, | |||
152 | * parse objects are all cached. | 178 | * parse objects are all cached. |
153 | */ | 179 | */ |
154 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); | 180 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); |
155 | status = acpi_ns_one_complete_parse(2, table_desc); | 181 | status = acpi_ns_one_complete_parse(2, table_index); |
156 | if (ACPI_FAILURE(status)) { | 182 | if (ACPI_FAILURE(status)) { |
157 | return_ACPI_STATUS(status); | 183 | return_ACPI_STATUS(status); |
158 | } | 184 | } |
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index aa4e799d9a8c..4eb155cc406f 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c | |||
@@ -770,13 +770,6 @@ void acpi_ns_terminate(void) | |||
770 | } | 770 | } |
771 | 771 | ||
772 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); | 772 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); |
773 | |||
774 | /* | ||
775 | * 2) Now we can delete the ACPI tables | ||
776 | */ | ||
777 | acpi_tb_delete_all_tables(); | ||
778 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); | ||
779 | |||
780 | return_VOID; | 773 | return_VOID; |
781 | } | 774 | } |
782 | 775 | ||
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c deleted file mode 100644 index d697fcb35d52..000000000000 --- a/drivers/acpi/tables/tbconvrt.c +++ /dev/null | |||
@@ -1,622 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbconvrt - ACPI Table conversion utilities | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbconvrt") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | static void | ||
52 | acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, | ||
53 | u8 register_bit_width, | ||
54 | acpi_physical_address address); | ||
55 | |||
56 | static void | ||
57 | acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, | ||
58 | struct fadt_descriptor_rev1 *original_fadt); | ||
59 | |||
60 | static void | ||
61 | acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, | ||
62 | struct fadt_descriptor *original_fadt); | ||
63 | |||
64 | u8 acpi_fadt_is_v1; | ||
65 | ACPI_EXPORT_SYMBOL(acpi_fadt_is_v1) | ||
66 | |||
67 | /******************************************************************************* | ||
68 | * | ||
69 | * FUNCTION: acpi_tb_get_table_count | ||
70 | * | ||
71 | * PARAMETERS: RSDP - Pointer to the RSDP | ||
72 | * RSDT - Pointer to the RSDT/XSDT | ||
73 | * | ||
74 | * RETURN: The number of tables pointed to by the RSDT or XSDT. | ||
75 | * | ||
76 | * DESCRIPTION: Calculate the number of tables. Automatically handles either | ||
77 | * an RSDT or XSDT. | ||
78 | * | ||
79 | ******************************************************************************/ | ||
80 | |||
81 | u32 | ||
82 | acpi_tb_get_table_count(struct rsdp_descriptor *RSDP, | ||
83 | struct acpi_table_header *RSDT) | ||
84 | { | ||
85 | u32 pointer_size; | ||
86 | |||
87 | ACPI_FUNCTION_ENTRY(); | ||
88 | |||
89 | /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ | ||
90 | |||
91 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
92 | pointer_size = sizeof(u32); | ||
93 | } else { | ||
94 | pointer_size = sizeof(u64); | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Determine the number of tables pointed to by the RSDT/XSDT. | ||
99 | * This is defined by the ACPI Specification to be the number of | ||
100 | * pointers contained within the RSDT/XSDT. The size of the pointers | ||
101 | * is architecture-dependent. | ||
102 | */ | ||
103 | return ((RSDT->length - | ||
104 | sizeof(struct acpi_table_header)) / pointer_size); | ||
105 | } | ||
106 | |||
107 | /******************************************************************************* | ||
108 | * | ||
109 | * FUNCTION: acpi_tb_convert_to_xsdt | ||
110 | * | ||
111 | * PARAMETERS: table_info - Info about the RSDT | ||
112 | * | ||
113 | * RETURN: Status | ||
114 | * | ||
115 | * DESCRIPTION: Convert an RSDT to an XSDT (internal common format) | ||
116 | * | ||
117 | ******************************************************************************/ | ||
118 | |||
119 | acpi_status acpi_tb_convert_to_xsdt(struct acpi_table_desc *table_info) | ||
120 | { | ||
121 | acpi_size table_size; | ||
122 | u32 i; | ||
123 | struct xsdt_descriptor *new_table; | ||
124 | |||
125 | ACPI_FUNCTION_ENTRY(); | ||
126 | |||
127 | /* Compute size of the converted XSDT */ | ||
128 | |||
129 | table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof(u64)) + | ||
130 | sizeof(struct acpi_table_header); | ||
131 | |||
132 | /* Allocate an XSDT */ | ||
133 | |||
134 | new_table = ACPI_ALLOCATE_ZEROED(table_size); | ||
135 | if (!new_table) { | ||
136 | return (AE_NO_MEMORY); | ||
137 | } | ||
138 | |||
139 | /* Copy the header and set the length */ | ||
140 | |||
141 | ACPI_MEMCPY(new_table, table_info->pointer, | ||
142 | sizeof(struct acpi_table_header)); | ||
143 | new_table->length = (u32) table_size; | ||
144 | |||
145 | /* Copy the table pointers */ | ||
146 | |||
147 | for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { | ||
148 | |||
149 | /* RSDT pointers are 32 bits, XSDT pointers are 64 bits */ | ||
150 | |||
151 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
152 | ACPI_STORE_ADDRESS(new_table->table_offset_entry[i], | ||
153 | (ACPI_CAST_PTR | ||
154 | (struct rsdt_descriptor, | ||
155 | table_info->pointer))-> | ||
156 | table_offset_entry[i]); | ||
157 | } else { | ||
158 | new_table->table_offset_entry[i] = | ||
159 | (ACPI_CAST_PTR(struct xsdt_descriptor, | ||
160 | table_info->pointer))-> | ||
161 | table_offset_entry[i]; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | /* Delete the original table (either mapped or in a buffer) */ | ||
166 | |||
167 | acpi_tb_delete_single_table(table_info); | ||
168 | |||
169 | /* Point the table descriptor to the new table */ | ||
170 | |||
171 | table_info->pointer = | ||
172 | ACPI_CAST_PTR(struct acpi_table_header, new_table); | ||
173 | table_info->length = table_size; | ||
174 | table_info->allocation = ACPI_MEM_ALLOCATED; | ||
175 | |||
176 | return (AE_OK); | ||
177 | } | ||
178 | |||
179 | /******************************************************************************* | ||
180 | * | ||
181 | * FUNCTION: acpi_tb_init_generic_address | ||
182 | * | ||
183 | * PARAMETERS: new_gas_struct - GAS struct to be initialized | ||
184 | * register_bit_width - Width of this register | ||
185 | * Address - Address of the register | ||
186 | * | ||
187 | * RETURN: None | ||
188 | * | ||
189 | * DESCRIPTION: Initialize a GAS structure. | ||
190 | * | ||
191 | ******************************************************************************/ | ||
192 | |||
193 | static void | ||
194 | acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, | ||
195 | u8 register_bit_width, | ||
196 | acpi_physical_address address) | ||
197 | { | ||
198 | |||
199 | ACPI_STORE_ADDRESS(new_gas_struct->address, address); | ||
200 | |||
201 | new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; | ||
202 | new_gas_struct->register_bit_width = register_bit_width; | ||
203 | new_gas_struct->register_bit_offset = 0; | ||
204 | new_gas_struct->access_width = 0; | ||
205 | } | ||
206 | |||
207 | /******************************************************************************* | ||
208 | * | ||
209 | * FUNCTION: acpi_tb_convert_fadt1 | ||
210 | * | ||
211 | * PARAMETERS: local_fadt - Pointer to new FADT | ||
212 | * original_fadt - Pointer to old FADT | ||
213 | * | ||
214 | * RETURN: None, populates local_fadt | ||
215 | * | ||
216 | * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format | ||
217 | * | ||
218 | ******************************************************************************/ | ||
219 | |||
220 | static void | ||
221 | acpi_tb_convert_fadt1(struct fadt_descriptor *local_fadt, | ||
222 | struct fadt_descriptor_rev1 *original_fadt) | ||
223 | { | ||
224 | |||
225 | /* ACPI 1.0 FACS */ | ||
226 | /* The BIOS stored FADT should agree with Revision 1.0 */ | ||
227 | acpi_fadt_is_v1 = 1; | ||
228 | |||
229 | /* | ||
230 | * Copy the table header and the common part of the tables. | ||
231 | * | ||
232 | * The 2.0 table is an extension of the 1.0 table, so the entire 1.0 | ||
233 | * table can be copied first, then expand some fields to 64 bits. | ||
234 | */ | ||
235 | ACPI_MEMCPY(local_fadt, original_fadt, | ||
236 | sizeof(struct fadt_descriptor_rev1)); | ||
237 | |||
238 | /* Convert table pointers to 64-bit fields */ | ||
239 | |||
240 | ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl, | ||
241 | local_fadt->V1_firmware_ctrl); | ||
242 | ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt); | ||
243 | |||
244 | /* | ||
245 | * System Interrupt Model isn't used in ACPI 2.0 | ||
246 | * (local_fadt->Reserved1 = 0;) | ||
247 | */ | ||
248 | |||
249 | /* | ||
250 | * This field is set by the OEM to convey the preferred power management | ||
251 | * profile to OSPM. It doesn't have any 1.0 equivalence. Since we don't | ||
252 | * know what kind of 32-bit system this is, we will use "unspecified". | ||
253 | */ | ||
254 | local_fadt->prefer_PM_profile = PM_UNSPECIFIED; | ||
255 | |||
256 | /* | ||
257 | * Processor Performance State Control. This is the value OSPM writes to | ||
258 | * the SMI_CMD register to assume processor performance state control | ||
259 | * responsibility. There isn't any equivalence in 1.0, but as many 1.x | ||
260 | * ACPI tables contain _PCT and _PSS we also keep this value, unless | ||
261 | * acpi_strict is set. | ||
262 | */ | ||
263 | if (acpi_strict) | ||
264 | local_fadt->pstate_cnt = 0; | ||
265 | |||
266 | /* | ||
267 | * Support for the _CST object and C States change notification. | ||
268 | * This data item hasn't any 1.0 equivalence so leave it zero. | ||
269 | */ | ||
270 | local_fadt->cst_cnt = 0; | ||
271 | |||
272 | /* | ||
273 | * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0. | ||
274 | * It primarily adds the FADT reset mechanism. | ||
275 | */ | ||
276 | if ((original_fadt->revision == 2) && | ||
277 | (original_fadt->length == | ||
278 | sizeof(struct fadt_descriptor_rev2_minus))) { | ||
279 | /* | ||
280 | * Grab the entire generic address struct, plus the 1-byte reset value | ||
281 | * that immediately follows. | ||
282 | */ | ||
283 | ACPI_MEMCPY(&local_fadt->reset_register, | ||
284 | &(ACPI_CAST_PTR(struct fadt_descriptor_rev2_minus, | ||
285 | original_fadt))->reset_register, | ||
286 | sizeof(struct acpi_generic_address) + 1); | ||
287 | } else { | ||
288 | /* | ||
289 | * Since there isn't any equivalence in 1.0 and since it is highly | ||
290 | * likely that a 1.0 system has legacy support. | ||
291 | */ | ||
292 | local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES; | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * Convert the V1.0 block addresses to V2.0 GAS structures | ||
297 | */ | ||
298 | acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk, | ||
299 | local_fadt->pm1_evt_len, | ||
300 | (acpi_physical_address) local_fadt-> | ||
301 | V1_pm1a_evt_blk); | ||
302 | acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk, | ||
303 | local_fadt->pm1_evt_len, | ||
304 | (acpi_physical_address) local_fadt-> | ||
305 | V1_pm1b_evt_blk); | ||
306 | acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk, | ||
307 | local_fadt->pm1_cnt_len, | ||
308 | (acpi_physical_address) local_fadt-> | ||
309 | V1_pm1a_cnt_blk); | ||
310 | acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk, | ||
311 | local_fadt->pm1_cnt_len, | ||
312 | (acpi_physical_address) local_fadt-> | ||
313 | V1_pm1b_cnt_blk); | ||
314 | acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk, | ||
315 | local_fadt->pm2_cnt_len, | ||
316 | (acpi_physical_address) local_fadt-> | ||
317 | V1_pm2_cnt_blk); | ||
318 | acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk, | ||
319 | local_fadt->pm_tm_len, | ||
320 | (acpi_physical_address) local_fadt-> | ||
321 | V1_pm_tmr_blk); | ||
322 | acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, 0, | ||
323 | (acpi_physical_address) local_fadt-> | ||
324 | V1_gpe0_blk); | ||
325 | acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, 0, | ||
326 | (acpi_physical_address) local_fadt-> | ||
327 | V1_gpe1_blk); | ||
328 | |||
329 | /* Create separate GAS structs for the PM1 Enable registers */ | ||
330 | |||
331 | acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, | ||
332 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
333 | pm1_evt_len), | ||
334 | (acpi_physical_address) | ||
335 | (local_fadt->xpm1a_evt_blk.address + | ||
336 | ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len))); | ||
337 | |||
338 | /* PM1B is optional; leave null if not present */ | ||
339 | |||
340 | if (local_fadt->xpm1b_evt_blk.address) { | ||
341 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, | ||
342 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
343 | pm1_evt_len), | ||
344 | (acpi_physical_address) | ||
345 | (local_fadt->xpm1b_evt_blk. | ||
346 | address + | ||
347 | ACPI_DIV_2(acpi_gbl_FADT-> | ||
348 | pm1_evt_len))); | ||
349 | } | ||
350 | } | ||
351 | |||
352 | /******************************************************************************* | ||
353 | * | ||
354 | * FUNCTION: acpi_tb_convert_fadt2 | ||
355 | * | ||
356 | * PARAMETERS: local_fadt - Pointer to new FADT | ||
357 | * original_fadt - Pointer to old FADT | ||
358 | * | ||
359 | * RETURN: None, populates local_fadt | ||
360 | * | ||
361 | * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format. | ||
362 | * Handles optional "X" fields. | ||
363 | * | ||
364 | ******************************************************************************/ | ||
365 | |||
366 | static void | ||
367 | acpi_tb_convert_fadt2(struct fadt_descriptor *local_fadt, | ||
368 | struct fadt_descriptor *original_fadt) | ||
369 | { | ||
370 | |||
371 | /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ | ||
372 | |||
373 | ACPI_MEMCPY(local_fadt, original_fadt, sizeof(struct fadt_descriptor)); | ||
374 | |||
375 | /* | ||
376 | * "X" fields are optional extensions to the original V1.0 fields, so | ||
377 | * we must selectively expand V1.0 fields if the corresponding X field | ||
378 | * is zero. | ||
379 | */ | ||
380 | if (!(local_fadt->xfirmware_ctrl)) { | ||
381 | ACPI_STORE_ADDRESS(local_fadt->xfirmware_ctrl, | ||
382 | local_fadt->V1_firmware_ctrl); | ||
383 | } | ||
384 | |||
385 | if (!(local_fadt->Xdsdt)) { | ||
386 | ACPI_STORE_ADDRESS(local_fadt->Xdsdt, local_fadt->V1_dsdt); | ||
387 | } | ||
388 | |||
389 | if (!(local_fadt->xpm1a_evt_blk.address)) { | ||
390 | acpi_tb_init_generic_address(&local_fadt->xpm1a_evt_blk, | ||
391 | local_fadt->pm1_evt_len, | ||
392 | (acpi_physical_address) | ||
393 | local_fadt->V1_pm1a_evt_blk); | ||
394 | } | ||
395 | |||
396 | if (!(local_fadt->xpm1b_evt_blk.address)) { | ||
397 | acpi_tb_init_generic_address(&local_fadt->xpm1b_evt_blk, | ||
398 | local_fadt->pm1_evt_len, | ||
399 | (acpi_physical_address) | ||
400 | local_fadt->V1_pm1b_evt_blk); | ||
401 | } | ||
402 | |||
403 | if (!(local_fadt->xpm1a_cnt_blk.address)) { | ||
404 | acpi_tb_init_generic_address(&local_fadt->xpm1a_cnt_blk, | ||
405 | local_fadt->pm1_cnt_len, | ||
406 | (acpi_physical_address) | ||
407 | local_fadt->V1_pm1a_cnt_blk); | ||
408 | } | ||
409 | |||
410 | if (!(local_fadt->xpm1b_cnt_blk.address)) { | ||
411 | acpi_tb_init_generic_address(&local_fadt->xpm1b_cnt_blk, | ||
412 | local_fadt->pm1_cnt_len, | ||
413 | (acpi_physical_address) | ||
414 | local_fadt->V1_pm1b_cnt_blk); | ||
415 | } | ||
416 | |||
417 | if (!(local_fadt->xpm2_cnt_blk.address)) { | ||
418 | acpi_tb_init_generic_address(&local_fadt->xpm2_cnt_blk, | ||
419 | local_fadt->pm2_cnt_len, | ||
420 | (acpi_physical_address) | ||
421 | local_fadt->V1_pm2_cnt_blk); | ||
422 | } | ||
423 | |||
424 | if (!(local_fadt->xpm_tmr_blk.address)) { | ||
425 | acpi_tb_init_generic_address(&local_fadt->xpm_tmr_blk, | ||
426 | local_fadt->pm_tm_len, | ||
427 | (acpi_physical_address) | ||
428 | local_fadt->V1_pm_tmr_blk); | ||
429 | } | ||
430 | |||
431 | if (!(local_fadt->xgpe0_blk.address)) { | ||
432 | acpi_tb_init_generic_address(&local_fadt->xgpe0_blk, | ||
433 | 0, | ||
434 | (acpi_physical_address) | ||
435 | local_fadt->V1_gpe0_blk); | ||
436 | } | ||
437 | |||
438 | if (!(local_fadt->xgpe1_blk.address)) { | ||
439 | acpi_tb_init_generic_address(&local_fadt->xgpe1_blk, | ||
440 | 0, | ||
441 | (acpi_physical_address) | ||
442 | local_fadt->V1_gpe1_blk); | ||
443 | } | ||
444 | |||
445 | /* Create separate GAS structs for the PM1 Enable registers */ | ||
446 | |||
447 | acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, | ||
448 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
449 | pm1_evt_len), | ||
450 | (acpi_physical_address) | ||
451 | (local_fadt->xpm1a_evt_blk.address + | ||
452 | ACPI_DIV_2(acpi_gbl_FADT->pm1_evt_len))); | ||
453 | |||
454 | acpi_gbl_xpm1a_enable.address_space_id = | ||
455 | local_fadt->xpm1a_evt_blk.address_space_id; | ||
456 | |||
457 | /* PM1B is optional; leave null if not present */ | ||
458 | |||
459 | if (local_fadt->xpm1b_evt_blk.address) { | ||
460 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, | ||
461 | (u8) ACPI_DIV_2(acpi_gbl_FADT-> | ||
462 | pm1_evt_len), | ||
463 | (acpi_physical_address) | ||
464 | (local_fadt->xpm1b_evt_blk. | ||
465 | address + | ||
466 | ACPI_DIV_2(acpi_gbl_FADT-> | ||
467 | pm1_evt_len))); | ||
468 | |||
469 | acpi_gbl_xpm1b_enable.address_space_id = | ||
470 | local_fadt->xpm1b_evt_blk.address_space_id; | ||
471 | } | ||
472 | } | ||
473 | |||
474 | /******************************************************************************* | ||
475 | * | ||
476 | * FUNCTION: acpi_tb_convert_table_fadt | ||
477 | * | ||
478 | * PARAMETERS: None | ||
479 | * | ||
480 | * RETURN: Status | ||
481 | * | ||
482 | * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local | ||
483 | * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply | ||
484 | * copied to the local FADT. The ACPI CA software uses this | ||
485 | * local FADT. Thus a significant amount of special #ifdef | ||
486 | * type codeing is saved. | ||
487 | * | ||
488 | ******************************************************************************/ | ||
489 | |||
490 | acpi_status acpi_tb_convert_table_fadt(void) | ||
491 | { | ||
492 | struct fadt_descriptor *local_fadt; | ||
493 | struct acpi_table_desc *table_desc; | ||
494 | |||
495 | ACPI_FUNCTION_TRACE(tb_convert_table_fadt); | ||
496 | |||
497 | /* | ||
498 | * acpi_gbl_FADT is valid. Validate the FADT length. The table must be | ||
499 | * at least as long as the version 1.0 FADT | ||
500 | */ | ||
501 | if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor_rev1)) { | ||
502 | ACPI_ERROR((AE_INFO, "FADT is invalid, too short: 0x%X", | ||
503 | acpi_gbl_FADT->length)); | ||
504 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
505 | } | ||
506 | |||
507 | /* Allocate buffer for the ACPI 2.0(+) FADT */ | ||
508 | |||
509 | local_fadt = ACPI_ALLOCATE_ZEROED(sizeof(struct fadt_descriptor)); | ||
510 | if (!local_fadt) { | ||
511 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
512 | } | ||
513 | |||
514 | if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) { | ||
515 | if (acpi_gbl_FADT->length < sizeof(struct fadt_descriptor)) { | ||
516 | |||
517 | /* Length is too short to be a V2.0 table */ | ||
518 | |||
519 | ACPI_WARNING((AE_INFO, | ||
520 | "Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table", | ||
521 | acpi_gbl_FADT->length, | ||
522 | acpi_gbl_FADT->revision)); | ||
523 | |||
524 | acpi_tb_convert_fadt1(local_fadt, | ||
525 | (void *)acpi_gbl_FADT); | ||
526 | } else { | ||
527 | /* Valid V2.0 table */ | ||
528 | |||
529 | acpi_tb_convert_fadt2(local_fadt, acpi_gbl_FADT); | ||
530 | } | ||
531 | } else { | ||
532 | /* Valid V1.0 table */ | ||
533 | |||
534 | acpi_tb_convert_fadt1(local_fadt, (void *)acpi_gbl_FADT); | ||
535 | } | ||
536 | |||
537 | /* Global FADT pointer will point to the new common V2.0 FADT */ | ||
538 | |||
539 | acpi_gbl_FADT = local_fadt; | ||
540 | acpi_gbl_FADT->length = sizeof(struct fadt_descriptor); | ||
541 | |||
542 | /* Free the original table */ | ||
543 | |||
544 | table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_FADT].next; | ||
545 | acpi_tb_delete_single_table(table_desc); | ||
546 | |||
547 | /* Install the new table */ | ||
548 | |||
549 | table_desc->pointer = | ||
550 | ACPI_CAST_PTR(struct acpi_table_header, acpi_gbl_FADT); | ||
551 | table_desc->allocation = ACPI_MEM_ALLOCATED; | ||
552 | table_desc->length = sizeof(struct fadt_descriptor); | ||
553 | |||
554 | /* Dump the entire FADT */ | ||
555 | |||
556 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
557 | "Hex dump of common internal FADT, size %d (%X)\n", | ||
558 | acpi_gbl_FADT->length, acpi_gbl_FADT->length)); | ||
559 | |||
560 | ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_FADT), | ||
561 | acpi_gbl_FADT->length); | ||
562 | |||
563 | return_ACPI_STATUS(AE_OK); | ||
564 | } | ||
565 | |||
566 | /******************************************************************************* | ||
567 | * | ||
568 | * FUNCTION: acpi_tb_build_common_facs | ||
569 | * | ||
570 | * PARAMETERS: table_info - Info for currently installed FACS | ||
571 | * | ||
572 | * RETURN: Status | ||
573 | * | ||
574 | * DESCRIPTION: Convert ACPI 1.0 and ACPI 2.0 FACS to a common internal | ||
575 | * table format. | ||
576 | * | ||
577 | ******************************************************************************/ | ||
578 | |||
579 | acpi_status acpi_tb_build_common_facs(struct acpi_table_desc *table_info) | ||
580 | { | ||
581 | |||
582 | ACPI_FUNCTION_TRACE(tb_build_common_facs); | ||
583 | |||
584 | /* Absolute minimum length is 24, but the ACPI spec says 64 */ | ||
585 | |||
586 | if (acpi_gbl_FACS->length < 24) { | ||
587 | ACPI_ERROR((AE_INFO, "Invalid FACS table length: 0x%X", | ||
588 | acpi_gbl_FACS->length)); | ||
589 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
590 | } | ||
591 | |||
592 | if (acpi_gbl_FACS->length < 64) { | ||
593 | ACPI_WARNING((AE_INFO, | ||
594 | "FACS is shorter than the ACPI specification allows: 0x%X, using anyway", | ||
595 | acpi_gbl_FACS->length)); | ||
596 | } | ||
597 | |||
598 | /* Copy fields to the new FACS */ | ||
599 | |||
600 | acpi_gbl_common_fACS.global_lock = &(acpi_gbl_FACS->global_lock); | ||
601 | |||
602 | if ((acpi_gbl_RSDP->revision < 2) || | ||
603 | (acpi_gbl_FACS->length < 32) || | ||
604 | (!(acpi_gbl_FACS->xfirmware_waking_vector))) { | ||
605 | |||
606 | /* ACPI 1.0 FACS or short table or optional X_ field is zero */ | ||
607 | |||
608 | acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR(u64, | ||
609 | & | ||
610 | (acpi_gbl_FACS-> | ||
611 | firmware_waking_vector)); | ||
612 | acpi_gbl_common_fACS.vector_width = 32; | ||
613 | } else { | ||
614 | /* ACPI 2.0 FACS with valid X_ field */ | ||
615 | |||
616 | acpi_gbl_common_fACS.firmware_waking_vector = | ||
617 | &acpi_gbl_FACS->xfirmware_waking_vector; | ||
618 | acpi_gbl_common_fACS.vector_width = 64; | ||
619 | } | ||
620 | |||
621 | return_ACPI_STATUS(AE_OK); | ||
622 | } | ||
diff --git a/drivers/acpi/tables/tbfind.c b/drivers/acpi/tables/tbfind.c new file mode 100644 index 000000000000..769213c74c16 --- /dev/null +++ b/drivers/acpi/tables/tbfind.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbfind - find table | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbfind") | ||
49 | |||
50 | /******************************************************************************* | ||
51 | * | ||
52 | * FUNCTION: acpi_tb_find_table | ||
53 | * | ||
54 | * PARAMETERS: Signature - String with ACPI table signature | ||
55 | * oem_id - String with the table OEM ID | ||
56 | * oem_table_id - String with the OEM Table ID | ||
57 | * table_index - Where the table index is returned | ||
58 | * | ||
59 | * RETURN: Status and table index | ||
60 | * | ||
61 | * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the | ||
62 | * Signature, OEM ID and OEM Table ID. Returns an index that can | ||
63 | * be used to get the table header or entire table. | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | acpi_status | ||
67 | acpi_tb_find_table(char *signature, | ||
68 | char *oem_id, | ||
69 | char *oem_table_id, acpi_native_uint * table_index) | ||
70 | { | ||
71 | acpi_native_uint i; | ||
72 | acpi_status status; | ||
73 | |||
74 | ACPI_FUNCTION_TRACE(tb_find_table); | ||
75 | |||
76 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { | ||
77 | if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature), | ||
78 | signature, ACPI_NAME_SIZE)) { | ||
79 | |||
80 | /* Not the requested table */ | ||
81 | |||
82 | continue; | ||
83 | } | ||
84 | |||
85 | /* Table with matching signature has been found */ | ||
86 | |||
87 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | ||
88 | |||
89 | /* Table is not currently mapped, map it */ | ||
90 | |||
91 | status = | ||
92 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
93 | tables[i]); | ||
94 | if (ACPI_FAILURE(status)) { | ||
95 | return_ACPI_STATUS(status); | ||
96 | } | ||
97 | |||
98 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | ||
99 | continue; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /* Check for table match on all IDs */ | ||
104 | |||
105 | if (!ACPI_MEMCMP | ||
106 | (acpi_gbl_root_table_list.tables[i].pointer->signature, | ||
107 | signature, ACPI_NAME_SIZE) && (!oem_id[0] | ||
108 | || | ||
109 | !ACPI_MEMCMP | ||
110 | (acpi_gbl_root_table_list. | ||
111 | tables[i].pointer->oem_id, | ||
112 | oem_id, ACPI_OEM_ID_SIZE)) | ||
113 | && (!oem_table_id[0] | ||
114 | || !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i]. | ||
115 | pointer->oem_table_id, oem_table_id, | ||
116 | ACPI_OEM_TABLE_ID_SIZE))) { | ||
117 | *table_index = i; | ||
118 | |||
119 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
120 | "Found table [%4.4s]\n", signature)); | ||
121 | return_ACPI_STATUS(AE_OK); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
126 | } | ||
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c deleted file mode 100644 index 11e2d4454e05..000000000000 --- a/drivers/acpi/tables/tbget.c +++ /dev/null | |||
@@ -1,471 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbget - ACPI Table get* routines | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbget") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | static acpi_status | ||
52 | acpi_tb_get_this_table(struct acpi_pointer *address, | ||
53 | struct acpi_table_header *header, | ||
54 | struct acpi_table_desc *table_info); | ||
55 | |||
56 | static acpi_status | ||
57 | acpi_tb_table_override(struct acpi_table_header *header, | ||
58 | struct acpi_table_desc *table_info); | ||
59 | |||
60 | /******************************************************************************* | ||
61 | * | ||
62 | * FUNCTION: acpi_tb_get_table | ||
63 | * | ||
64 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
65 | * Logical or Physical | ||
66 | * table_info - Where table info is returned | ||
67 | * | ||
68 | * RETURN: None | ||
69 | * | ||
70 | * DESCRIPTION: Get entire table of unknown size. | ||
71 | * | ||
72 | ******************************************************************************/ | ||
73 | |||
74 | acpi_status | ||
75 | acpi_tb_get_table(struct acpi_pointer *address, | ||
76 | struct acpi_table_desc *table_info) | ||
77 | { | ||
78 | acpi_status status; | ||
79 | struct acpi_table_header header; | ||
80 | |||
81 | ACPI_FUNCTION_TRACE(tb_get_table); | ||
82 | |||
83 | /* Get the header in order to get signature and table size */ | ||
84 | |||
85 | status = acpi_tb_get_table_header(address, &header); | ||
86 | if (ACPI_FAILURE(status)) { | ||
87 | return_ACPI_STATUS(status); | ||
88 | } | ||
89 | |||
90 | /* Get the entire table */ | ||
91 | |||
92 | status = acpi_tb_get_table_body(address, &header, table_info); | ||
93 | if (ACPI_FAILURE(status)) { | ||
94 | ACPI_EXCEPTION((AE_INFO, status, | ||
95 | "Could not get ACPI table (size %X)", | ||
96 | header.length)); | ||
97 | return_ACPI_STATUS(status); | ||
98 | } | ||
99 | |||
100 | return_ACPI_STATUS(AE_OK); | ||
101 | } | ||
102 | |||
103 | /******************************************************************************* | ||
104 | * | ||
105 | * FUNCTION: acpi_tb_get_table_header | ||
106 | * | ||
107 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
108 | * Logical or Physical | ||
109 | * return_header - Where the table header is returned | ||
110 | * | ||
111 | * RETURN: Status | ||
112 | * | ||
113 | * DESCRIPTION: Get an ACPI table header. Works in both physical or virtual | ||
114 | * addressing mode. Works with both physical or logical pointers. | ||
115 | * Table is either copied or mapped, depending on the pointer | ||
116 | * type and mode of the processor. | ||
117 | * | ||
118 | ******************************************************************************/ | ||
119 | |||
120 | acpi_status | ||
121 | acpi_tb_get_table_header(struct acpi_pointer *address, | ||
122 | struct acpi_table_header *return_header) | ||
123 | { | ||
124 | acpi_status status = AE_OK; | ||
125 | struct acpi_table_header *header = NULL; | ||
126 | |||
127 | ACPI_FUNCTION_TRACE(tb_get_table_header); | ||
128 | |||
129 | /* | ||
130 | * Flags contains the current processor mode (Virtual or Physical | ||
131 | * addressing) The pointer_type is either Logical or Physical | ||
132 | */ | ||
133 | switch (address->pointer_type) { | ||
134 | case ACPI_PHYSMODE_PHYSPTR: | ||
135 | case ACPI_LOGMODE_LOGPTR: | ||
136 | |||
137 | /* Pointer matches processor mode, copy the header */ | ||
138 | |||
139 | ACPI_MEMCPY(return_header, address->pointer.logical, | ||
140 | sizeof(struct acpi_table_header)); | ||
141 | break; | ||
142 | |||
143 | case ACPI_LOGMODE_PHYSPTR: | ||
144 | |||
145 | /* Create a logical address for the physical pointer */ | ||
146 | |||
147 | status = acpi_os_map_memory(address->pointer.physical, | ||
148 | sizeof(struct acpi_table_header), | ||
149 | (void *)&header); | ||
150 | if (ACPI_FAILURE(status)) { | ||
151 | ACPI_ERROR((AE_INFO, | ||
152 | "Could not map memory at %8.8X%8.8X for table header", | ||
153 | ACPI_FORMAT_UINT64(address->pointer. | ||
154 | physical))); | ||
155 | return_ACPI_STATUS(status); | ||
156 | } | ||
157 | |||
158 | /* Copy header and delete mapping */ | ||
159 | |||
160 | ACPI_MEMCPY(return_header, header, | ||
161 | sizeof(struct acpi_table_header)); | ||
162 | acpi_os_unmap_memory(header, sizeof(struct acpi_table_header)); | ||
163 | break; | ||
164 | |||
165 | default: | ||
166 | |||
167 | ACPI_ERROR((AE_INFO, "Invalid address flags %X", | ||
168 | address->pointer_type)); | ||
169 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
170 | } | ||
171 | |||
172 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n", | ||
173 | return_header->signature)); | ||
174 | |||
175 | return_ACPI_STATUS(AE_OK); | ||
176 | } | ||
177 | |||
178 | /******************************************************************************* | ||
179 | * | ||
180 | * FUNCTION: acpi_tb_get_table_body | ||
181 | * | ||
182 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
183 | * Logical or Physical | ||
184 | * Header - Header of the table to retrieve | ||
185 | * table_info - Where the table info is returned | ||
186 | * | ||
187 | * RETURN: Status | ||
188 | * | ||
189 | * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to | ||
190 | * replace the table with a newer version (table override.) | ||
191 | * Works in both physical or virtual | ||
192 | * addressing mode. Works with both physical or logical pointers. | ||
193 | * Table is either copied or mapped, depending on the pointer | ||
194 | * type and mode of the processor. | ||
195 | * | ||
196 | ******************************************************************************/ | ||
197 | |||
198 | acpi_status | ||
199 | acpi_tb_get_table_body(struct acpi_pointer *address, | ||
200 | struct acpi_table_header *header, | ||
201 | struct acpi_table_desc *table_info) | ||
202 | { | ||
203 | acpi_status status; | ||
204 | |||
205 | ACPI_FUNCTION_TRACE(tb_get_table_body); | ||
206 | |||
207 | if (!table_info || !address) { | ||
208 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
209 | } | ||
210 | |||
211 | /* Attempt table override. */ | ||
212 | |||
213 | status = acpi_tb_table_override(header, table_info); | ||
214 | if (ACPI_SUCCESS(status)) { | ||
215 | |||
216 | /* Table was overridden by the host OS */ | ||
217 | |||
218 | return_ACPI_STATUS(status); | ||
219 | } | ||
220 | |||
221 | /* No override, get the original table */ | ||
222 | |||
223 | status = acpi_tb_get_this_table(address, header, table_info); | ||
224 | return_ACPI_STATUS(status); | ||
225 | } | ||
226 | |||
227 | /******************************************************************************* | ||
228 | * | ||
229 | * FUNCTION: acpi_tb_table_override | ||
230 | * | ||
231 | * PARAMETERS: Header - Pointer to table header | ||
232 | * table_info - Return info if table is overridden | ||
233 | * | ||
234 | * RETURN: None | ||
235 | * | ||
236 | * DESCRIPTION: Attempts override of current table with a new one if provided | ||
237 | * by the host OS. | ||
238 | * | ||
239 | ******************************************************************************/ | ||
240 | |||
241 | static acpi_status | ||
242 | acpi_tb_table_override(struct acpi_table_header *header, | ||
243 | struct acpi_table_desc *table_info) | ||
244 | { | ||
245 | struct acpi_table_header *new_table; | ||
246 | acpi_status status; | ||
247 | struct acpi_pointer address; | ||
248 | |||
249 | ACPI_FUNCTION_TRACE(tb_table_override); | ||
250 | |||
251 | /* | ||
252 | * The OSL will examine the header and decide whether to override this | ||
253 | * table. If it decides to override, a table will be returned in new_table, | ||
254 | * which we will then copy. | ||
255 | */ | ||
256 | status = acpi_os_table_override(header, &new_table); | ||
257 | if (ACPI_FAILURE(status)) { | ||
258 | |||
259 | /* Some severe error from the OSL, but we basically ignore it */ | ||
260 | |||
261 | ACPI_EXCEPTION((AE_INFO, status, | ||
262 | "Could not override ACPI table")); | ||
263 | return_ACPI_STATUS(status); | ||
264 | } | ||
265 | |||
266 | if (!new_table) { | ||
267 | |||
268 | /* No table override */ | ||
269 | |||
270 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * We have a new table to override the old one. Get a copy of | ||
275 | * the new one. We know that the new table has a logical pointer. | ||
276 | */ | ||
277 | address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; | ||
278 | address.pointer.logical = new_table; | ||
279 | |||
280 | status = acpi_tb_get_this_table(&address, new_table, table_info); | ||
281 | if (ACPI_FAILURE(status)) { | ||
282 | ACPI_EXCEPTION((AE_INFO, status, "Could not copy ACPI table")); | ||
283 | return_ACPI_STATUS(status); | ||
284 | } | ||
285 | |||
286 | /* Copy the table info */ | ||
287 | |||
288 | ACPI_INFO((AE_INFO, "Table [%4.4s] replaced by host OS", | ||
289 | table_info->pointer->signature)); | ||
290 | |||
291 | return_ACPI_STATUS(AE_OK); | ||
292 | } | ||
293 | |||
294 | /******************************************************************************* | ||
295 | * | ||
296 | * FUNCTION: acpi_tb_get_this_table | ||
297 | * | ||
298 | * PARAMETERS: Address - Address of table to retrieve. Can be | ||
299 | * Logical or Physical | ||
300 | * Header - Header of the table to retrieve | ||
301 | * table_info - Where the table info is returned | ||
302 | * | ||
303 | * RETURN: Status | ||
304 | * | ||
305 | * DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual | ||
306 | * addressing mode. Works with both physical or logical pointers. | ||
307 | * Table is either copied or mapped, depending on the pointer | ||
308 | * type and mode of the processor. | ||
309 | * | ||
310 | ******************************************************************************/ | ||
311 | |||
312 | static acpi_status | ||
313 | acpi_tb_get_this_table(struct acpi_pointer *address, | ||
314 | struct acpi_table_header *header, | ||
315 | struct acpi_table_desc *table_info) | ||
316 | { | ||
317 | struct acpi_table_header *full_table = NULL; | ||
318 | u8 allocation; | ||
319 | acpi_status status = AE_OK; | ||
320 | |||
321 | ACPI_FUNCTION_TRACE(tb_get_this_table); | ||
322 | |||
323 | /* Validate minimum length */ | ||
324 | |||
325 | if (header->length < sizeof(struct acpi_table_header)) { | ||
326 | ACPI_ERROR((AE_INFO, | ||
327 | "Table length (%X) is smaller than minimum (%zX)", | ||
328 | header->length, sizeof(struct acpi_table_header))); | ||
329 | |||
330 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * Flags contains the current processor mode (Virtual or Physical | ||
335 | * addressing) The pointer_type is either Logical or Physical | ||
336 | */ | ||
337 | switch (address->pointer_type) { | ||
338 | case ACPI_PHYSMODE_PHYSPTR: | ||
339 | case ACPI_LOGMODE_LOGPTR: | ||
340 | |||
341 | /* Pointer matches processor mode, copy the table to a new buffer */ | ||
342 | |||
343 | full_table = ACPI_ALLOCATE(header->length); | ||
344 | if (!full_table) { | ||
345 | ACPI_ERROR((AE_INFO, | ||
346 | "Could not allocate table memory for [%4.4s] length %X", | ||
347 | header->signature, header->length)); | ||
348 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
349 | } | ||
350 | |||
351 | /* Copy the entire table (including header) to the local buffer */ | ||
352 | |||
353 | ACPI_MEMCPY(full_table, address->pointer.logical, | ||
354 | header->length); | ||
355 | |||
356 | /* Save allocation type */ | ||
357 | |||
358 | allocation = ACPI_MEM_ALLOCATED; | ||
359 | break; | ||
360 | |||
361 | case ACPI_LOGMODE_PHYSPTR: | ||
362 | |||
363 | /* | ||
364 | * Just map the table's physical memory | ||
365 | * into our address space. | ||
366 | */ | ||
367 | status = acpi_os_map_memory(address->pointer.physical, | ||
368 | (acpi_size) header->length, | ||
369 | ACPI_CAST_PTR(void, &full_table)); | ||
370 | if (ACPI_FAILURE(status)) { | ||
371 | ACPI_ERROR((AE_INFO, | ||
372 | "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X", | ||
373 | header->signature, | ||
374 | ACPI_FORMAT_UINT64(address->pointer. | ||
375 | physical), | ||
376 | header->length)); | ||
377 | return (status); | ||
378 | } | ||
379 | |||
380 | /* Save allocation type */ | ||
381 | |||
382 | allocation = ACPI_MEM_MAPPED; | ||
383 | break; | ||
384 | |||
385 | default: | ||
386 | |||
387 | ACPI_ERROR((AE_INFO, "Invalid address flags %X", | ||
388 | address->pointer_type)); | ||
389 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
390 | } | ||
391 | |||
392 | /* | ||
393 | * Validate checksum for _most_ tables, | ||
394 | * even the ones whose signature we don't recognize | ||
395 | */ | ||
396 | if (table_info->type != ACPI_TABLE_ID_FACS) { | ||
397 | status = acpi_tb_verify_table_checksum(full_table); | ||
398 | |||
399 | #if (!ACPI_CHECKSUM_ABORT) | ||
400 | if (ACPI_FAILURE(status)) { | ||
401 | |||
402 | /* Ignore the error if configuration says so */ | ||
403 | |||
404 | status = AE_OK; | ||
405 | } | ||
406 | #endif | ||
407 | } | ||
408 | |||
409 | /* Return values */ | ||
410 | |||
411 | table_info->pointer = full_table; | ||
412 | table_info->length = (acpi_size) header->length; | ||
413 | table_info->allocation = allocation; | ||
414 | |||
415 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
416 | "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n", | ||
417 | full_table->signature, | ||
418 | ACPI_FORMAT_UINT64(address->pointer.physical), | ||
419 | full_table)); | ||
420 | |||
421 | return_ACPI_STATUS(status); | ||
422 | } | ||
423 | |||
424 | /******************************************************************************* | ||
425 | * | ||
426 | * FUNCTION: acpi_tb_get_table_ptr | ||
427 | * | ||
428 | * PARAMETERS: table_type - one of the defined table types | ||
429 | * Instance - Which table of this type | ||
430 | * return_table - pointer to location to place the pointer for | ||
431 | * return | ||
432 | * | ||
433 | * RETURN: Status | ||
434 | * | ||
435 | * DESCRIPTION: This function is called to get the pointer to an ACPI table. | ||
436 | * | ||
437 | ******************************************************************************/ | ||
438 | |||
439 | acpi_status | ||
440 | acpi_tb_get_table_ptr(acpi_table_type table_type, | ||
441 | u32 instance, struct acpi_table_header **return_table) | ||
442 | { | ||
443 | struct acpi_table_desc *table_desc; | ||
444 | u32 i; | ||
445 | |||
446 | ACPI_FUNCTION_TRACE(tb_get_table_ptr); | ||
447 | |||
448 | if (table_type > ACPI_TABLE_ID_MAX) { | ||
449 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
450 | } | ||
451 | |||
452 | /* Check for instance out of range of the current table count */ | ||
453 | |||
454 | if (instance > acpi_gbl_table_lists[table_type].count) { | ||
455 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
456 | } | ||
457 | |||
458 | /* | ||
459 | * Walk the list to get the desired table | ||
460 | * Note: Instance is one-based | ||
461 | */ | ||
462 | table_desc = acpi_gbl_table_lists[table_type].next; | ||
463 | for (i = 1; i < instance; i++) { | ||
464 | table_desc = table_desc->next; | ||
465 | } | ||
466 | |||
467 | /* We are now pointing to the requested table's descriptor */ | ||
468 | |||
469 | *return_table = table_desc->pointer; | ||
470 | return_ACPI_STATUS(AE_OK); | ||
471 | } | ||
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c deleted file mode 100644 index ad982112e4c6..000000000000 --- a/drivers/acpi/tables/tbgetall.c +++ /dev/null | |||
@@ -1,311 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbgetall - Get all required ACPI tables | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbgetall") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | static acpi_status | ||
52 | acpi_tb_get_primary_table(struct acpi_pointer *address, | ||
53 | struct acpi_table_desc *table_info); | ||
54 | |||
55 | static acpi_status | ||
56 | acpi_tb_get_secondary_table(struct acpi_pointer *address, | ||
57 | acpi_string signature, | ||
58 | struct acpi_table_desc *table_info); | ||
59 | |||
60 | /******************************************************************************* | ||
61 | * | ||
62 | * FUNCTION: acpi_tb_get_primary_table | ||
63 | * | ||
64 | * PARAMETERS: Address - Physical address of table to retrieve | ||
65 | * *table_info - Where the table info is returned | ||
66 | * | ||
67 | * RETURN: Status | ||
68 | * | ||
69 | * DESCRIPTION: Maps the physical address of table into a logical address | ||
70 | * | ||
71 | ******************************************************************************/ | ||
72 | |||
73 | static acpi_status | ||
74 | acpi_tb_get_primary_table(struct acpi_pointer *address, | ||
75 | struct acpi_table_desc *table_info) | ||
76 | { | ||
77 | acpi_status status; | ||
78 | struct acpi_table_header header; | ||
79 | |||
80 | ACPI_FUNCTION_TRACE(tb_get_primary_table); | ||
81 | |||
82 | /* Ignore a NULL address in the RSDT */ | ||
83 | |||
84 | if (!address->pointer.value) { | ||
85 | return_ACPI_STATUS(AE_OK); | ||
86 | } | ||
87 | |||
88 | /* Get the header in order to get signature and table size */ | ||
89 | |||
90 | status = acpi_tb_get_table_header(address, &header); | ||
91 | if (ACPI_FAILURE(status)) { | ||
92 | return_ACPI_STATUS(status); | ||
93 | } | ||
94 | |||
95 | /* Clear the table_info */ | ||
96 | |||
97 | ACPI_MEMSET(table_info, 0, sizeof(struct acpi_table_desc)); | ||
98 | |||
99 | /* | ||
100 | * Check the table signature and make sure it is recognized. | ||
101 | * Also checks the header checksum | ||
102 | */ | ||
103 | table_info->pointer = &header; | ||
104 | status = acpi_tb_recognize_table(table_info, ACPI_TABLE_PRIMARY); | ||
105 | if (ACPI_FAILURE(status)) { | ||
106 | return_ACPI_STATUS(status); | ||
107 | } | ||
108 | |||
109 | /* Get the entire table */ | ||
110 | |||
111 | status = acpi_tb_get_table_body(address, &header, table_info); | ||
112 | if (ACPI_FAILURE(status)) { | ||
113 | return_ACPI_STATUS(status); | ||
114 | } | ||
115 | |||
116 | /* Install the table */ | ||
117 | |||
118 | status = acpi_tb_install_table(table_info); | ||
119 | return_ACPI_STATUS(status); | ||
120 | } | ||
121 | |||
122 | /******************************************************************************* | ||
123 | * | ||
124 | * FUNCTION: acpi_tb_get_secondary_table | ||
125 | * | ||
126 | * PARAMETERS: Address - Physical address of table to retrieve | ||
127 | * *table_info - Where the table info is returned | ||
128 | * | ||
129 | * RETURN: Status | ||
130 | * | ||
131 | * DESCRIPTION: Maps the physical address of table into a logical address | ||
132 | * | ||
133 | ******************************************************************************/ | ||
134 | |||
135 | static acpi_status | ||
136 | acpi_tb_get_secondary_table(struct acpi_pointer *address, | ||
137 | acpi_string signature, | ||
138 | struct acpi_table_desc *table_info) | ||
139 | { | ||
140 | acpi_status status; | ||
141 | struct acpi_table_header header; | ||
142 | |||
143 | ACPI_FUNCTION_TRACE_STR(tb_get_secondary_table, signature); | ||
144 | |||
145 | /* Get the header in order to match the signature */ | ||
146 | |||
147 | status = acpi_tb_get_table_header(address, &header); | ||
148 | if (ACPI_FAILURE(status)) { | ||
149 | return_ACPI_STATUS(status); | ||
150 | } | ||
151 | |||
152 | /* Signature must match request */ | ||
153 | |||
154 | if (!ACPI_COMPARE_NAME(header.signature, signature)) { | ||
155 | ACPI_ERROR((AE_INFO, | ||
156 | "Incorrect table signature - wanted [%s] found [%4.4s]", | ||
157 | signature, header.signature)); | ||
158 | return_ACPI_STATUS(AE_BAD_SIGNATURE); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * Check the table signature and make sure it is recognized. | ||
163 | * Also checks the header checksum | ||
164 | */ | ||
165 | table_info->pointer = &header; | ||
166 | status = acpi_tb_recognize_table(table_info, ACPI_TABLE_SECONDARY); | ||
167 | if (ACPI_FAILURE(status)) { | ||
168 | return_ACPI_STATUS(status); | ||
169 | } | ||
170 | |||
171 | /* Get the entire table */ | ||
172 | |||
173 | status = acpi_tb_get_table_body(address, &header, table_info); | ||
174 | if (ACPI_FAILURE(status)) { | ||
175 | return_ACPI_STATUS(status); | ||
176 | } | ||
177 | |||
178 | /* Install the table */ | ||
179 | |||
180 | status = acpi_tb_install_table(table_info); | ||
181 | return_ACPI_STATUS(status); | ||
182 | } | ||
183 | |||
184 | /******************************************************************************* | ||
185 | * | ||
186 | * FUNCTION: acpi_tb_get_required_tables | ||
187 | * | ||
188 | * PARAMETERS: None | ||
189 | * | ||
190 | * RETURN: Status | ||
191 | * | ||
192 | * DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must | ||
193 | * already be loaded and validated. | ||
194 | * | ||
195 | * Get the minimum set of ACPI tables, namely: | ||
196 | * | ||
197 | * 1) FADT (via RSDT in loop below) | ||
198 | * 2) FACS (via FADT) | ||
199 | * 3) DSDT (via FADT) | ||
200 | * | ||
201 | ******************************************************************************/ | ||
202 | |||
203 | acpi_status acpi_tb_get_required_tables(void) | ||
204 | { | ||
205 | acpi_status status = AE_OK; | ||
206 | u32 i; | ||
207 | struct acpi_table_desc table_info; | ||
208 | struct acpi_pointer address; | ||
209 | |||
210 | ACPI_FUNCTION_TRACE(tb_get_required_tables); | ||
211 | |||
212 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%d ACPI tables in RSDT\n", | ||
213 | acpi_gbl_rsdt_table_count)); | ||
214 | |||
215 | address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; | ||
216 | |||
217 | /* | ||
218 | * Loop through all table pointers found in RSDT. | ||
219 | * This will NOT include the FACS and DSDT - we must get | ||
220 | * them after the loop. | ||
221 | * | ||
222 | * The only tables we are interested in getting here is the FADT and | ||
223 | * any SSDTs. | ||
224 | */ | ||
225 | for (i = 0; i < acpi_gbl_rsdt_table_count; i++) { | ||
226 | |||
227 | /* Get the table address from the common internal XSDT */ | ||
228 | |||
229 | address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i]; | ||
230 | |||
231 | /* | ||
232 | * Get the tables needed by this subsystem (FADT and any SSDTs). | ||
233 | * NOTE: All other tables are completely ignored at this time. | ||
234 | */ | ||
235 | status = acpi_tb_get_primary_table(&address, &table_info); | ||
236 | if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) { | ||
237 | ACPI_WARNING((AE_INFO, | ||
238 | "%s, while getting table at %8.8X%8.8X", | ||
239 | acpi_format_exception(status), | ||
240 | ACPI_FORMAT_UINT64(address.pointer. | ||
241 | value))); | ||
242 | } | ||
243 | } | ||
244 | |||
245 | /* We must have a FADT to continue */ | ||
246 | |||
247 | if (!acpi_gbl_FADT) { | ||
248 | ACPI_ERROR((AE_INFO, "No FADT present in RSDT/XSDT")); | ||
249 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * Convert the FADT to a common format. This allows earlier revisions of | ||
254 | * the table to coexist with newer versions, using common access code. | ||
255 | */ | ||
256 | status = acpi_tb_convert_table_fadt(); | ||
257 | if (ACPI_FAILURE(status)) { | ||
258 | ACPI_ERROR((AE_INFO, | ||
259 | "Could not convert FADT to internal common format")); | ||
260 | return_ACPI_STATUS(status); | ||
261 | } | ||
262 | |||
263 | /* Get the FACS (Pointed to by the FADT) */ | ||
264 | |||
265 | address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl; | ||
266 | |||
267 | status = acpi_tb_get_secondary_table(&address, FACS_SIG, &table_info); | ||
268 | if (ACPI_FAILURE(status)) { | ||
269 | ACPI_EXCEPTION((AE_INFO, status, | ||
270 | "Could not get/install the FACS")); | ||
271 | return_ACPI_STATUS(status); | ||
272 | } | ||
273 | |||
274 | /* | ||
275 | * Create the common FACS pointer table | ||
276 | * (Contains pointers to the original table) | ||
277 | */ | ||
278 | status = acpi_tb_build_common_facs(&table_info); | ||
279 | if (ACPI_FAILURE(status)) { | ||
280 | return_ACPI_STATUS(status); | ||
281 | } | ||
282 | |||
283 | /* Get/install the DSDT (Pointed to by the FADT) */ | ||
284 | |||
285 | address.pointer.value = acpi_gbl_FADT->Xdsdt; | ||
286 | |||
287 | status = acpi_tb_get_secondary_table(&address, DSDT_SIG, &table_info); | ||
288 | if (ACPI_FAILURE(status)) { | ||
289 | ACPI_ERROR((AE_INFO, "Could not get/install the DSDT")); | ||
290 | return_ACPI_STATUS(status); | ||
291 | } | ||
292 | |||
293 | /* Set Integer Width (32/64) based upon DSDT revision */ | ||
294 | |||
295 | acpi_ut_set_integer_width(acpi_gbl_DSDT->revision); | ||
296 | |||
297 | /* Dump the entire DSDT */ | ||
298 | |||
299 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
300 | "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n", | ||
301 | acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, | ||
302 | acpi_gbl_integer_bit_width)); | ||
303 | |||
304 | ACPI_DUMP_BUFFER(ACPI_CAST_PTR(u8, acpi_gbl_DSDT), | ||
305 | acpi_gbl_DSDT->length); | ||
306 | |||
307 | /* Always delete the RSDP mapping, we are done with it */ | ||
308 | |||
309 | acpi_tb_delete_tables_by_type(ACPI_TABLE_ID_RSDP); | ||
310 | return_ACPI_STATUS(status); | ||
311 | } | ||
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 1668a232fb67..9076ca0913b7 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -42,510 +42,494 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | ||
45 | #include <acpi/actables.h> | 46 | #include <acpi/actables.h> |
46 | 47 | ||
47 | #define _COMPONENT ACPI_TABLES | 48 | #define _COMPONENT ACPI_TABLES |
48 | ACPI_MODULE_NAME("tbinstal") | 49 | ACPI_MODULE_NAME("tbinstal") |
49 | 50 | ||
50 | /* Local prototypes */ | 51 | /****************************************************************************** |
51 | static acpi_status | ||
52 | acpi_tb_match_signature(char *signature, | ||
53 | struct acpi_table_desc *table_info, u8 search_type); | ||
54 | |||
55 | /******************************************************************************* | ||
56 | * | 52 | * |
57 | * FUNCTION: acpi_tb_match_signature | 53 | * FUNCTION: acpi_tb_verify_table |
58 | * | 54 | * |
59 | * PARAMETERS: Signature - Table signature to match | 55 | * PARAMETERS: table_desc - table |
60 | * table_info - Return data | ||
61 | * search_type - Table type to match (primary/secondary) | ||
62 | * | 56 | * |
63 | * RETURN: Status | 57 | * RETURN: Status |
64 | * | 58 | * |
65 | * DESCRIPTION: Compare signature against the list of "ACPI-subsystem-owned" | 59 | * DESCRIPTION: this function is called to verify and map table |
66 | * tables (DSDT/FADT/SSDT, etc.) Returns the table_type_iD on match. | ||
67 | * | 60 | * |
68 | ******************************************************************************/ | 61 | *****************************************************************************/ |
69 | 62 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | |
70 | static acpi_status | ||
71 | acpi_tb_match_signature(char *signature, | ||
72 | struct acpi_table_desc *table_info, u8 search_type) | ||
73 | { | 63 | { |
74 | acpi_native_uint i; | 64 | u8 checksum; |
75 | 65 | ||
76 | ACPI_FUNCTION_TRACE(tb_match_signature); | 66 | ACPI_FUNCTION_TRACE(tb_verify_table); |
77 | 67 | ||
78 | /* Search for a signature match among the known table types */ | 68 | /* Map the table if necessary */ |
79 | 69 | ||
80 | for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { | 70 | if (!table_desc->pointer) { |
81 | if (!(acpi_gbl_table_data[i].flags & search_type)) { | 71 | table_desc->pointer = |
82 | continue; | 72 | acpi_tb_map(table_desc->address, table_desc->length, |
73 | table_desc->flags & ACPI_TABLE_ORIGIN_MASK); | ||
74 | if (!table_desc->pointer) { | ||
75 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
83 | } | 76 | } |
77 | } | ||
84 | 78 | ||
85 | if (!ACPI_STRNCMP(signature, acpi_gbl_table_data[i].signature, | 79 | /* FACS is the odd table, has no standard ACPI header and no checksum */ |
86 | acpi_gbl_table_data[i].sig_length)) { | ||
87 | 80 | ||
88 | /* Found a signature match, return index if requested */ | 81 | if (ACPI_COMPARE_NAME(&(table_desc->signature), ACPI_SIG_FACS)) { |
82 | return_ACPI_STATUS(AE_OK); | ||
83 | } | ||
89 | 84 | ||
90 | if (table_info) { | 85 | /* Always calculate checksum, ignore bad checksum if requested */ |
91 | table_info->type = (u8) i; | ||
92 | } | ||
93 | 86 | ||
94 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 87 | checksum = acpi_tb_checksum(ACPI_CAST_PTR(void, table_desc->pointer), |
95 | "Table [%4.4s] is an ACPI table consumed by the core subsystem\n", | 88 | table_desc->length); |
96 | (char *)acpi_gbl_table_data[i]. | ||
97 | signature)); | ||
98 | 89 | ||
99 | return_ACPI_STATUS(AE_OK); | 90 | #if (ACPI_CHECKSUM_ABORT) |
100 | } | ||
101 | } | ||
102 | 91 | ||
103 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 92 | if (checksum) { |
104 | "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n", | 93 | return_ACPI_STATUS(AE_BAD_CHECKSUM); |
105 | (char *)signature)); | 94 | } |
95 | #endif | ||
106 | 96 | ||
107 | return_ACPI_STATUS(AE_TABLE_NOT_SUPPORTED); | 97 | return_ACPI_STATUS(AE_OK); |
108 | } | 98 | } |
109 | 99 | ||
110 | /******************************************************************************* | 100 | /******************************************************************************* |
111 | * | 101 | * |
112 | * FUNCTION: acpi_tb_install_table | 102 | * FUNCTION: acpi_tb_add_table |
113 | * | 103 | * |
114 | * PARAMETERS: table_info - Return value from acpi_tb_get_table_body | 104 | * PARAMETERS: Table - Pointer to the table header |
105 | * table_index - Where the table index is returned | ||
115 | * | 106 | * |
116 | * RETURN: Status | 107 | * RETURN: Status |
117 | * | 108 | * |
118 | * DESCRIPTION: Install the table into the global data structures. | 109 | * DESCRIPTION: This function is called to add the ACPI table |
119 | * | 110 | * |
120 | ******************************************************************************/ | 111 | ******************************************************************************/ |
121 | 112 | ||
122 | acpi_status acpi_tb_install_table(struct acpi_table_desc *table_info) | 113 | acpi_status |
114 | acpi_tb_add_table(struct acpi_table_header *table, | ||
115 | acpi_native_uint * table_index) | ||
123 | { | 116 | { |
124 | acpi_status status; | 117 | acpi_native_uint i; |
118 | acpi_native_uint length; | ||
119 | acpi_status status = AE_OK; | ||
125 | 120 | ||
126 | ACPI_FUNCTION_TRACE(tb_install_table); | 121 | ACPI_FUNCTION_TRACE(tb_add_table); |
127 | 122 | ||
128 | /* Lock tables while installing */ | 123 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
129 | 124 | ||
130 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 125 | /* Check if table is already registered */ |
131 | if (ACPI_FAILURE(status)) { | 126 | |
132 | ACPI_EXCEPTION((AE_INFO, status, | 127 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { |
133 | "Could not acquire table mutex")); | 128 | if (!acpi_gbl_root_table_list.tables[i].pointer) { |
134 | return_ACPI_STATUS(status); | 129 | status = |
130 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
131 | tables[i]); | ||
132 | if (ACPI_FAILURE(status) | ||
133 | || !acpi_gbl_root_table_list.tables[i].pointer) { | ||
134 | continue; | ||
135 | } | ||
136 | } | ||
137 | |||
138 | length = ACPI_MIN(table->length, | ||
139 | acpi_gbl_root_table_list.tables[i].pointer-> | ||
140 | length); | ||
141 | if (ACPI_MEMCMP | ||
142 | (table, acpi_gbl_root_table_list.tables[i].pointer, | ||
143 | length)) { | ||
144 | continue; | ||
145 | } | ||
146 | |||
147 | /* Table is already registered */ | ||
148 | |||
149 | ACPI_FREE(table); | ||
150 | *table_index = i; | ||
151 | goto release; | ||
135 | } | 152 | } |
136 | 153 | ||
137 | /* | 154 | /* |
138 | * Ignore a table that is already installed. For example, some BIOS | 155 | * Add the table to the global table list |
139 | * ASL code will repeatedly attempt to load the same SSDT. | ||
140 | */ | 156 | */ |
141 | status = acpi_tb_is_table_installed(table_info); | 157 | status = acpi_tb_store_table(ACPI_TO_INTEGER(table), |
158 | table, table->length, | ||
159 | ACPI_TABLE_ORIGIN_ALLOCATED, table_index); | ||
142 | if (ACPI_FAILURE(status)) { | 160 | if (ACPI_FAILURE(status)) { |
143 | goto unlock_and_exit; | 161 | goto release; |
144 | } | 162 | } |
145 | 163 | ||
146 | /* Install the table into the global data structure */ | 164 | acpi_tb_print_table_header(0, table); |
147 | 165 | ||
148 | status = acpi_tb_init_table_descriptor(table_info->type, table_info); | 166 | release: |
149 | if (ACPI_FAILURE(status)) { | ||
150 | ACPI_EXCEPTION((AE_INFO, status, | ||
151 | "Could not install table [%4.4s]", | ||
152 | table_info->pointer->signature)); | ||
153 | } | ||
154 | |||
155 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s located at %p\n", | ||
156 | acpi_gbl_table_data[table_info->type].name, | ||
157 | table_info->pointer)); | ||
158 | |||
159 | unlock_and_exit: | ||
160 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 167 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
161 | return_ACPI_STATUS(status); | 168 | return_ACPI_STATUS(status); |
162 | } | 169 | } |
163 | 170 | ||
164 | /******************************************************************************* | 171 | /******************************************************************************* |
165 | * | 172 | * |
166 | * FUNCTION: acpi_tb_recognize_table | 173 | * FUNCTION: acpi_tb_resize_root_table_list |
167 | * | 174 | * |
168 | * PARAMETERS: table_info - Return value from acpi_tb_get_table_body | 175 | * PARAMETERS: None |
169 | * search_type - Table type to match (primary/secondary) | ||
170 | * | 176 | * |
171 | * RETURN: Status | 177 | * RETURN: Status |
172 | * | 178 | * |
173 | * DESCRIPTION: Check a table signature for a match against known table types | 179 | * DESCRIPTION: Expand the size of global table array |
174 | * | ||
175 | * NOTE: All table pointers are validated as follows: | ||
176 | * 1) Table pointer must point to valid physical memory | ||
177 | * 2) Signature must be 4 ASCII chars, even if we don't recognize the | ||
178 | * name | ||
179 | * 3) Table must be readable for length specified in the header | ||
180 | * 4) Table checksum must be valid (with the exception of the FACS | ||
181 | * which has no checksum for some odd reason) | ||
182 | * | 180 | * |
183 | ******************************************************************************/ | 181 | ******************************************************************************/ |
184 | 182 | ||
185 | acpi_status | 183 | acpi_status acpi_tb_resize_root_table_list(void) |
186 | acpi_tb_recognize_table(struct acpi_table_desc *table_info, u8 search_type) | ||
187 | { | 184 | { |
188 | struct acpi_table_header *table_header; | 185 | struct acpi_table_desc *tables; |
189 | acpi_status status; | ||
190 | 186 | ||
191 | ACPI_FUNCTION_TRACE(tb_recognize_table); | 187 | ACPI_FUNCTION_TRACE(tb_resize_root_table_list); |
192 | 188 | ||
193 | /* Ensure that we have a valid table pointer */ | 189 | /* allow_resize flag is a parameter to acpi_initialize_tables */ |
194 | 190 | ||
195 | table_header = (struct acpi_table_header *)table_info->pointer; | 191 | if (!(acpi_gbl_root_table_list.flags & ACPI_TABLE_FLAGS_ALLOW_RESIZE)) { |
196 | if (!table_header) { | 192 | ACPI_ERROR((AE_INFO, |
197 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 193 | "Resize of Root Table Array is not allowed")); |
194 | return_ACPI_STATUS(AE_SUPPORT); | ||
198 | } | 195 | } |
199 | 196 | ||
200 | /* | 197 | /* Increase the Table Array size */ |
201 | * We only "recognize" a limited number of ACPI tables -- namely, the | 198 | |
202 | * ones that are used by the subsystem (DSDT, FADT, etc.) | 199 | tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size + |
203 | * | 200 | ACPI_ROOT_TABLE_SIZE_INCREMENT) |
204 | * An AE_TABLE_NOT_SUPPORTED means that the table was not recognized. | 201 | * sizeof(struct acpi_table_desc)); |
205 | * This can be any one of many valid ACPI tables, it just isn't one of | 202 | if (!tables) { |
206 | * the tables that is consumed by the core subsystem | 203 | ACPI_ERROR((AE_INFO, |
207 | */ | 204 | "Could not allocate new root table array")); |
208 | status = acpi_tb_match_signature(table_header->signature, | 205 | return_ACPI_STATUS(AE_NO_MEMORY); |
209 | table_info, search_type); | ||
210 | if (ACPI_FAILURE(status)) { | ||
211 | return_ACPI_STATUS(status); | ||
212 | } | 206 | } |
213 | 207 | ||
214 | status = acpi_tb_validate_table_header(table_header); | 208 | /* Copy and free the previous table array */ |
215 | if (ACPI_FAILURE(status)) { | 209 | |
216 | return_ACPI_STATUS(status); | 210 | if (acpi_gbl_root_table_list.tables) { |
211 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, | ||
212 | acpi_gbl_root_table_list.size * | ||
213 | sizeof(struct acpi_table_desc)); | ||
214 | |||
215 | if (acpi_gbl_root_table_list.flags & ACPI_TABLE_ORIGIN_MASK == | ||
216 | ACPI_TABLE_ORIGIN_ALLOCATED) { | ||
217 | ACPI_FREE(acpi_gbl_root_table_list.tables); | ||
218 | } | ||
217 | } | 219 | } |
218 | 220 | ||
219 | /* Return the table type and length via the info struct */ | 221 | acpi_gbl_root_table_list.tables = tables; |
222 | acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT; | ||
223 | acpi_gbl_root_table_list.flags = (u8) (ACPI_TABLE_ORIGIN_ALLOCATED | | ||
224 | (acpi_gbl_root_table_list. | ||
225 | flags & | ||
226 | ~ACPI_TABLE_ORIGIN_MASK)); | ||
220 | 227 | ||
221 | table_info->length = (acpi_size) table_header->length; | 228 | return_ACPI_STATUS(AE_OK); |
222 | return_ACPI_STATUS(status); | ||
223 | } | 229 | } |
224 | 230 | ||
225 | /******************************************************************************* | 231 | /******************************************************************************* |
226 | * | 232 | * |
227 | * FUNCTION: acpi_tb_init_table_descriptor | 233 | * FUNCTION: acpi_tb_store_table |
228 | * | 234 | * |
229 | * PARAMETERS: table_type - The type of the table | 235 | * PARAMETERS: Address - Table address |
230 | * table_info - A table info struct | 236 | * Table - Table header |
237 | * Length - Table length | ||
238 | * Flags - flags | ||
231 | * | 239 | * |
232 | * RETURN: None. | 240 | * RETURN: Status and table index. |
233 | * | 241 | * |
234 | * DESCRIPTION: Install a table into the global data structs. | 242 | * DESCRIPTION: Add an ACPI table to the global table list |
235 | * | 243 | * |
236 | ******************************************************************************/ | 244 | ******************************************************************************/ |
237 | 245 | ||
238 | acpi_status | 246 | acpi_status |
239 | acpi_tb_init_table_descriptor(acpi_table_type table_type, | 247 | acpi_tb_store_table(acpi_physical_address address, |
240 | struct acpi_table_desc *table_info) | 248 | struct acpi_table_header *table, |
249 | u32 length, u8 flags, acpi_native_uint * table_index) | ||
241 | { | 250 | { |
242 | struct acpi_table_list *list_head; | 251 | acpi_status status = AE_OK; |
243 | struct acpi_table_desc *table_desc; | ||
244 | acpi_status status; | ||
245 | |||
246 | ACPI_FUNCTION_TRACE_U32(tb_init_table_descriptor, table_type); | ||
247 | |||
248 | /* Allocate a descriptor for this table */ | ||
249 | 252 | ||
250 | table_desc = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); | 253 | /* Ensure that there is room for the table in the Root Table List */ |
251 | if (!table_desc) { | ||
252 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
253 | } | ||
254 | |||
255 | /* Get a new owner ID for the table */ | ||
256 | 254 | ||
257 | status = acpi_ut_allocate_owner_id(&table_desc->owner_id); | 255 | if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) { |
258 | if (ACPI_FAILURE(status)) { | 256 | status = acpi_tb_resize_root_table_list(); |
259 | goto error_exit1; | 257 | if (ACPI_FAILURE(status)) { |
258 | return (status); | ||
259 | } | ||
260 | } | 260 | } |
261 | 261 | ||
262 | /* Install the table into the global data structure */ | 262 | /* Initialize added table */ |
263 | 263 | ||
264 | list_head = &acpi_gbl_table_lists[table_type]; | 264 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. |
265 | address = address; | ||
266 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. | ||
267 | pointer = table; | ||
268 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length = | ||
269 | length; | ||
270 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. | ||
271 | owner_id = 0; | ||
272 | acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags = | ||
273 | flags; | ||
274 | |||
275 | ACPI_MOVE_32_TO_32(& | ||
276 | (acpi_gbl_root_table_list. | ||
277 | tables[acpi_gbl_root_table_list.count].signature), | ||
278 | table->signature); | ||
279 | |||
280 | *table_index = acpi_gbl_root_table_list.count; | ||
281 | acpi_gbl_root_table_list.count++; | ||
282 | return (status); | ||
283 | } | ||
265 | 284 | ||
266 | /* | 285 | /******************************************************************************* |
267 | * Two major types of tables: 1) Only one instance is allowed. This | 286 | * |
268 | * includes most ACPI tables such as the DSDT. 2) Multiple instances of | 287 | * FUNCTION: acpi_tb_delete_table |
269 | * the table are allowed. This includes SSDT and PSDTs. | 288 | * |
270 | */ | 289 | * PARAMETERS: table_index - Table index |
271 | if (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags)) { | 290 | * |
272 | /* | 291 | * RETURN: None |
273 | * Only one table allowed, and a table has alread been installed | 292 | * |
274 | * at this location, so return an error. | 293 | * DESCRIPTION: Delete one internal ACPI table |
275 | */ | 294 | * |
276 | if (list_head->next) { | 295 | ******************************************************************************/ |
277 | status = AE_ALREADY_EXISTS; | ||
278 | goto error_exit2; | ||
279 | } | ||
280 | 296 | ||
281 | table_desc->next = list_head->next; | 297 | void acpi_tb_delete_table(acpi_native_uint table_index) |
282 | list_head->next = table_desc; | 298 | { |
299 | struct acpi_table_desc *table_desc; | ||
283 | 300 | ||
284 | if (table_desc->next) { | 301 | /* table_index assumed valid */ |
285 | table_desc->next->prev = table_desc; | ||
286 | } | ||
287 | 302 | ||
288 | list_head->count++; | 303 | table_desc = &acpi_gbl_root_table_list.tables[table_index]; |
289 | } else { | ||
290 | /* | ||
291 | * Link the new table in to the list of tables of this type. | ||
292 | * Insert at the end of the list, order IS IMPORTANT. | ||
293 | * | ||
294 | * table_desc->Prev & Next are already NULL from calloc() | ||
295 | */ | ||
296 | list_head->count++; | ||
297 | |||
298 | if (!list_head->next) { | ||
299 | list_head->next = table_desc; | ||
300 | } else { | ||
301 | table_desc->next = list_head->next; | ||
302 | 304 | ||
303 | while (table_desc->next->next) { | 305 | /* Table must be mapped or allocated */ |
304 | table_desc->next = table_desc->next->next; | ||
305 | } | ||
306 | 306 | ||
307 | table_desc->next->next = table_desc; | 307 | if (!table_desc->pointer) { |
308 | table_desc->prev = table_desc->next; | 308 | return; |
309 | table_desc->next = NULL; | ||
310 | } | ||
311 | } | 309 | } |
312 | 310 | ||
313 | /* Finish initialization of the table descriptor */ | 311 | if (table_desc->flags & ACPI_TABLE_ORIGIN_MAPPED) { |
314 | 312 | acpi_tb_unmap(table_desc->pointer, table_desc->length, | |
315 | table_desc->loaded_into_namespace = FALSE; | 313 | table_desc->flags & ACPI_TABLE_ORIGIN_MASK); |
316 | table_desc->type = (u8) table_type; | 314 | } else if (table_desc->flags & ACPI_TABLE_ORIGIN_ALLOCATED) { |
317 | table_desc->pointer = table_info->pointer; | 315 | ACPI_FREE(table_desc->pointer); |
318 | table_desc->length = table_info->length; | ||
319 | table_desc->allocation = table_info->allocation; | ||
320 | table_desc->aml_start = (u8 *) (table_desc->pointer + 1), | ||
321 | table_desc->aml_length = (u32) | ||
322 | (table_desc->length - (u32) sizeof(struct acpi_table_header)); | ||
323 | |||
324 | /* | ||
325 | * Set the appropriate global pointer (if there is one) to point to the | ||
326 | * newly installed table | ||
327 | */ | ||
328 | if (acpi_gbl_table_data[table_type].global_ptr) { | ||
329 | *(acpi_gbl_table_data[table_type].global_ptr) = | ||
330 | table_info->pointer; | ||
331 | } | 316 | } |
332 | 317 | ||
333 | /* Return Data */ | 318 | table_desc->pointer = NULL; |
334 | |||
335 | table_info->owner_id = table_desc->owner_id; | ||
336 | table_info->installed_desc = table_desc; | ||
337 | return_ACPI_STATUS(AE_OK); | ||
338 | |||
339 | /* Error exit with cleanup */ | ||
340 | |||
341 | error_exit2: | ||
342 | |||
343 | acpi_ut_release_owner_id(&table_desc->owner_id); | ||
344 | |||
345 | error_exit1: | ||
346 | |||
347 | ACPI_FREE(table_desc); | ||
348 | return_ACPI_STATUS(status); | ||
349 | } | 319 | } |
350 | 320 | ||
351 | /******************************************************************************* | 321 | /******************************************************************************* |
352 | * | 322 | * |
353 | * FUNCTION: acpi_tb_delete_all_tables | 323 | * FUNCTION: acpi_tb_terminate |
354 | * | 324 | * |
355 | * PARAMETERS: None. | 325 | * PARAMETERS: None |
356 | * | 326 | * |
357 | * RETURN: None. | 327 | * RETURN: None |
358 | * | 328 | * |
359 | * DESCRIPTION: Delete all internal ACPI tables | 329 | * DESCRIPTION: Delete all internal ACPI tables |
360 | * | 330 | * |
361 | ******************************************************************************/ | 331 | ******************************************************************************/ |
362 | 332 | ||
363 | void acpi_tb_delete_all_tables(void) | 333 | void acpi_tb_terminate(void) |
364 | { | 334 | { |
365 | acpi_table_type type; | 335 | acpi_native_uint i; |
336 | |||
337 | ACPI_FUNCTION_TRACE(tb_terminate); | ||
338 | |||
339 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
340 | |||
341 | /* Delete the individual tables */ | ||
342 | |||
343 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { | ||
344 | acpi_tb_delete_table(i); | ||
345 | } | ||
366 | 346 | ||
367 | /* | 347 | /* |
368 | * Free memory allocated for ACPI tables | 348 | * Delete the root table array if allocated locally. Array cannot be |
369 | * Memory can either be mapped or allocated | 349 | * mapped, so we don't need to check for that flag. |
370 | */ | 350 | */ |
371 | for (type = 0; type < (ACPI_TABLE_ID_MAX + 1); type++) { | 351 | if ((acpi_gbl_root_table_list.flags & ACPI_TABLE_ORIGIN_MASK) == |
372 | acpi_tb_delete_tables_by_type(type); | 352 | ACPI_TABLE_ORIGIN_ALLOCATED) { |
353 | ACPI_FREE(acpi_gbl_root_table_list.tables); | ||
373 | } | 354 | } |
355 | |||
356 | acpi_gbl_root_table_list.tables = NULL; | ||
357 | acpi_gbl_root_table_list.flags = 0; | ||
358 | acpi_gbl_root_table_list.count = 0; | ||
359 | |||
360 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); | ||
361 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
374 | } | 362 | } |
375 | 363 | ||
376 | /******************************************************************************* | 364 | /******************************************************************************* |
377 | * | 365 | * |
378 | * FUNCTION: acpi_tb_delete_tables_by_type | 366 | * FUNCTION: acpi_tb_delete_namespace_by_owner |
379 | * | 367 | * |
380 | * PARAMETERS: Type - The table type to be deleted | 368 | * PARAMETERS: table_index - Table index |
381 | * | 369 | * |
382 | * RETURN: None. | 370 | * RETURN: None |
383 | * | 371 | * |
384 | * DESCRIPTION: Delete an internal ACPI table | 372 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. |
385 | * Locks the ACPI table mutex | ||
386 | * | 373 | * |
387 | ******************************************************************************/ | 374 | ******************************************************************************/ |
388 | 375 | ||
389 | void acpi_tb_delete_tables_by_type(acpi_table_type type) | 376 | void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index) |
390 | { | 377 | { |
391 | struct acpi_table_desc *table_desc; | 378 | acpi_owner_id owner_id; |
392 | u32 count; | ||
393 | u32 i; | ||
394 | |||
395 | ACPI_FUNCTION_TRACE_U32(tb_delete_tables_by_type, type); | ||
396 | |||
397 | if (type > ACPI_TABLE_ID_MAX) { | ||
398 | return_VOID; | ||
399 | } | ||
400 | 379 | ||
401 | if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_TABLES))) { | 380 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
381 | if (table_index < acpi_gbl_root_table_list.count) { | ||
382 | owner_id = | ||
383 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
384 | } else { | ||
385 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
402 | return; | 386 | return; |
403 | } | 387 | } |
404 | 388 | ||
405 | /* Clear the appropriate "typed" global table pointer */ | 389 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
406 | 390 | acpi_ns_delete_namespace_by_owner(owner_id); | |
407 | switch (type) { | 391 | } |
408 | case ACPI_TABLE_ID_RSDP: | ||
409 | acpi_gbl_RSDP = NULL; | ||
410 | break; | ||
411 | |||
412 | case ACPI_TABLE_ID_DSDT: | ||
413 | acpi_gbl_DSDT = NULL; | ||
414 | break; | ||
415 | |||
416 | case ACPI_TABLE_ID_FADT: | ||
417 | acpi_gbl_FADT = NULL; | ||
418 | break; | ||
419 | |||
420 | case ACPI_TABLE_ID_FACS: | ||
421 | acpi_gbl_FACS = NULL; | ||
422 | break; | ||
423 | 392 | ||
424 | case ACPI_TABLE_ID_XSDT: | 393 | /******************************************************************************* |
425 | acpi_gbl_XSDT = NULL; | 394 | * |
426 | break; | 395 | * FUNCTION: acpi_tb_allocate_owner_id |
396 | * | ||
397 | * PARAMETERS: table_index - Table index | ||
398 | * | ||
399 | * RETURN: Status | ||
400 | * | ||
401 | * DESCRIPTION: Allocates owner_id in table_desc | ||
402 | * | ||
403 | ******************************************************************************/ | ||
427 | 404 | ||
428 | case ACPI_TABLE_ID_SSDT: | 405 | acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index) |
429 | case ACPI_TABLE_ID_PSDT: | 406 | { |
430 | default: | 407 | acpi_status status = AE_BAD_PARAMETER; |
431 | break; | ||
432 | } | ||
433 | 408 | ||
434 | /* | 409 | ACPI_FUNCTION_TRACE(tb_allocate_owner_id); |
435 | * Free the table | ||
436 | * 1) Get the head of the list | ||
437 | */ | ||
438 | table_desc = acpi_gbl_table_lists[type].next; | ||
439 | count = acpi_gbl_table_lists[type].count; | ||
440 | 410 | ||
441 | /* | 411 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
442 | * 2) Walk the entire list, deleting both the allocated tables | 412 | if (table_index < acpi_gbl_root_table_list.count) { |
443 | * and the table descriptors | 413 | status = acpi_ut_allocate_owner_id |
444 | */ | 414 | (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); |
445 | for (i = 0; i < count; i++) { | ||
446 | table_desc = acpi_tb_uninstall_table(table_desc); | ||
447 | } | 415 | } |
448 | 416 | ||
449 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 417 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
450 | return_VOID; | 418 | return_ACPI_STATUS(status); |
451 | } | 419 | } |
452 | 420 | ||
453 | /******************************************************************************* | 421 | /******************************************************************************* |
454 | * | 422 | * |
455 | * FUNCTION: acpi_tb_delete_single_table | 423 | * FUNCTION: acpi_tb_release_owner_id |
456 | * | 424 | * |
457 | * PARAMETERS: table_info - A table info struct | 425 | * PARAMETERS: table_index - Table index |
458 | * | 426 | * |
459 | * RETURN: None. | 427 | * RETURN: Status |
460 | * | 428 | * |
461 | * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where | 429 | * DESCRIPTION: Releases owner_id in table_desc |
462 | * the table was allocated a buffer or was mapped. | ||
463 | * | 430 | * |
464 | ******************************************************************************/ | 431 | ******************************************************************************/ |
465 | 432 | ||
466 | void acpi_tb_delete_single_table(struct acpi_table_desc *table_desc) | 433 | acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index) |
467 | { | 434 | { |
435 | acpi_status status = AE_BAD_PARAMETER; | ||
468 | 436 | ||
469 | /* Must have a valid table descriptor and pointer */ | 437 | ACPI_FUNCTION_TRACE(tb_release_owner_id); |
470 | 438 | ||
471 | if ((!table_desc) || (!table_desc->pointer)) { | 439 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
472 | return; | 440 | if (table_index < acpi_gbl_root_table_list.count) { |
441 | acpi_ut_release_owner_id(& | ||
442 | (acpi_gbl_root_table_list. | ||
443 | tables[table_index].owner_id)); | ||
444 | status = AE_OK; | ||
473 | } | 445 | } |
474 | 446 | ||
475 | /* Valid table, determine type of memory allocation */ | 447 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
476 | 448 | return_ACPI_STATUS(status); | |
477 | switch (table_desc->allocation) { | ||
478 | case ACPI_MEM_NOT_ALLOCATED: | ||
479 | break; | ||
480 | |||
481 | case ACPI_MEM_ALLOCATED: | ||
482 | |||
483 | ACPI_FREE(table_desc->pointer); | ||
484 | break; | ||
485 | |||
486 | case ACPI_MEM_MAPPED: | ||
487 | |||
488 | acpi_os_unmap_memory(table_desc->pointer, table_desc->length); | ||
489 | break; | ||
490 | |||
491 | default: | ||
492 | break; | ||
493 | } | ||
494 | } | 449 | } |
495 | 450 | ||
496 | /******************************************************************************* | 451 | /******************************************************************************* |
497 | * | 452 | * |
498 | * FUNCTION: acpi_tb_uninstall_table | 453 | * FUNCTION: acpi_tb_get_owner_id |
499 | * | 454 | * |
500 | * PARAMETERS: table_info - A table info struct | 455 | * PARAMETERS: table_index - Table index |
456 | * owner_id - Where the table owner_id is returned | ||
501 | * | 457 | * |
502 | * RETURN: Pointer to the next table in the list (of same type) | 458 | * RETURN: Status |
503 | * | 459 | * |
504 | * DESCRIPTION: Free the memory associated with an internal ACPI table that | 460 | * DESCRIPTION: returns owner_id for the ACPI table |
505 | * is either installed or has never been installed. | ||
506 | * Table mutex should be locked. | ||
507 | * | 461 | * |
508 | ******************************************************************************/ | 462 | ******************************************************************************/ |
509 | 463 | ||
510 | struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc | 464 | acpi_status |
511 | *table_desc) | 465 | acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id) |
512 | { | 466 | { |
513 | struct acpi_table_desc *next_desc; | 467 | acpi_status status = AE_BAD_PARAMETER; |
514 | 468 | ||
515 | ACPI_FUNCTION_TRACE_PTR(tb_uninstall_table, table_desc); | 469 | ACPI_FUNCTION_TRACE(tb_get_owner_id); |
516 | 470 | ||
517 | if (!table_desc) { | 471 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
518 | return_PTR(NULL); | 472 | if (table_index < acpi_gbl_root_table_list.count) { |
473 | *owner_id = | ||
474 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
475 | status = AE_OK; | ||
519 | } | 476 | } |
520 | 477 | ||
521 | /* Unlink the descriptor from the doubly linked list */ | 478 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
479 | return_ACPI_STATUS(status); | ||
480 | } | ||
522 | 481 | ||
523 | if (table_desc->prev) { | 482 | /******************************************************************************* |
524 | table_desc->prev->next = table_desc->next; | 483 | * |
525 | } else { | 484 | * FUNCTION: acpi_tb_is_table_loaded |
526 | /* Is first on list, update list head */ | 485 | * |
486 | * PARAMETERS: table_index - Table index | ||
487 | * | ||
488 | * RETURN: Table Loaded Flag | ||
489 | * | ||
490 | ******************************************************************************/ | ||
527 | 491 | ||
528 | acpi_gbl_table_lists[table_desc->type].next = table_desc->next; | 492 | u8 acpi_tb_is_table_loaded(acpi_native_uint table_index) |
529 | } | 493 | { |
494 | u8 is_loaded = FALSE; | ||
530 | 495 | ||
531 | if (table_desc->next) { | 496 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
532 | table_desc->next->prev = table_desc->prev; | 497 | if (table_index < acpi_gbl_root_table_list.count) { |
498 | is_loaded = (u8) | ||
499 | (acpi_gbl_root_table_list.tables[table_index]. | ||
500 | flags & ACPI_TABLE_FLAGS_LOADED); | ||
533 | } | 501 | } |
534 | 502 | ||
535 | /* Free the memory allocated for the table itself */ | 503 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
536 | 504 | return (is_loaded); | |
537 | acpi_tb_delete_single_table(table_desc); | 505 | } |
538 | |||
539 | /* Free the owner ID associated with this table */ | ||
540 | |||
541 | acpi_ut_release_owner_id(&table_desc->owner_id); | ||
542 | 506 | ||
543 | /* Free the table descriptor */ | 507 | /******************************************************************************* |
508 | * | ||
509 | * FUNCTION: acpi_tb_set_table_loaded_flag | ||
510 | * | ||
511 | * PARAMETERS: table_index - Table index | ||
512 | * is_loaded - TRUE if table is loaded, FALSE otherwise | ||
513 | * | ||
514 | * RETURN: None | ||
515 | * | ||
516 | * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. | ||
517 | * | ||
518 | ******************************************************************************/ | ||
544 | 519 | ||
545 | next_desc = table_desc->next; | 520 | void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded) |
546 | ACPI_FREE(table_desc); | 521 | { |
547 | 522 | ||
548 | /* Return pointer to the next descriptor */ | 523 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
524 | if (table_index < acpi_gbl_root_table_list.count) { | ||
525 | if (is_loaded) { | ||
526 | acpi_gbl_root_table_list.tables[table_index].flags |= | ||
527 | ACPI_TABLE_FLAGS_LOADED; | ||
528 | } else { | ||
529 | acpi_gbl_root_table_list.tables[table_index].flags &= | ||
530 | ~ACPI_TABLE_FLAGS_LOADED; | ||
531 | } | ||
532 | } | ||
549 | 533 | ||
550 | return_PTR(next_desc); | 534 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
551 | } | 535 | } |
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c deleted file mode 100644 index 86a5fca9b739..000000000000 --- a/drivers/acpi/tables/tbrsdt.c +++ /dev/null | |||
@@ -1,307 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: tbrsdt - ACPI RSDT table utilities | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2006, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include <acpi/actables.h> | ||
46 | |||
47 | #define _COMPONENT ACPI_TABLES | ||
48 | ACPI_MODULE_NAME("tbrsdt") | ||
49 | |||
50 | /******************************************************************************* | ||
51 | * | ||
52 | * FUNCTION: acpi_tb_verify_rsdp | ||
53 | * | ||
54 | * PARAMETERS: Address - RSDP (Pointer to RSDT) | ||
55 | * | ||
56 | * RETURN: Status | ||
57 | * | ||
58 | * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) | ||
59 | * | ||
60 | ******************************************************************************/ | ||
61 | acpi_status acpi_tb_verify_rsdp(struct acpi_pointer *address) | ||
62 | { | ||
63 | struct acpi_table_desc table_info; | ||
64 | acpi_status status; | ||
65 | struct rsdp_descriptor *rsdp; | ||
66 | |||
67 | ACPI_FUNCTION_TRACE(tb_verify_rsdp); | ||
68 | |||
69 | switch (address->pointer_type) { | ||
70 | case ACPI_LOGICAL_POINTER: | ||
71 | |||
72 | rsdp = address->pointer.logical; | ||
73 | break; | ||
74 | |||
75 | case ACPI_PHYSICAL_POINTER: | ||
76 | /* | ||
77 | * Obtain access to the RSDP structure | ||
78 | */ | ||
79 | status = acpi_os_map_memory(address->pointer.physical, | ||
80 | sizeof(struct rsdp_descriptor), | ||
81 | ACPI_CAST_PTR(void, &rsdp)); | ||
82 | if (ACPI_FAILURE(status)) { | ||
83 | return_ACPI_STATUS(status); | ||
84 | } | ||
85 | break; | ||
86 | |||
87 | default: | ||
88 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
89 | } | ||
90 | |||
91 | /* Verify RSDP signature and checksum */ | ||
92 | |||
93 | status = acpi_tb_validate_rsdp(rsdp); | ||
94 | if (ACPI_FAILURE(status)) { | ||
95 | goto cleanup; | ||
96 | } | ||
97 | |||
98 | /* RSDP is ok. Init the table info */ | ||
99 | |||
100 | table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp); | ||
101 | table_info.length = sizeof(struct rsdp_descriptor); | ||
102 | |||
103 | if (address->pointer_type == ACPI_PHYSICAL_POINTER) { | ||
104 | table_info.allocation = ACPI_MEM_MAPPED; | ||
105 | } else { | ||
106 | table_info.allocation = ACPI_MEM_NOT_ALLOCATED; | ||
107 | } | ||
108 | |||
109 | /* Save the table pointers and allocation info */ | ||
110 | |||
111 | status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_RSDP, &table_info); | ||
112 | if (ACPI_FAILURE(status)) { | ||
113 | goto cleanup; | ||
114 | } | ||
115 | |||
116 | /* Save the RSDP in a global for easy access */ | ||
117 | |||
118 | acpi_gbl_RSDP = | ||
119 | ACPI_CAST_PTR(struct rsdp_descriptor, table_info.pointer); | ||
120 | return_ACPI_STATUS(status); | ||
121 | |||
122 | /* Error exit */ | ||
123 | cleanup: | ||
124 | |||
125 | if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) { | ||
126 | acpi_os_unmap_memory(rsdp, sizeof(struct rsdp_descriptor)); | ||
127 | } | ||
128 | return_ACPI_STATUS(status); | ||
129 | } | ||
130 | |||
131 | /******************************************************************************* | ||
132 | * | ||
133 | * FUNCTION: acpi_tb_get_rsdt_address | ||
134 | * | ||
135 | * PARAMETERS: out_address - Where the address is returned | ||
136 | * | ||
137 | * RETURN: None, Address | ||
138 | * | ||
139 | * DESCRIPTION: Extract the address of either the RSDT or XSDT, depending on the | ||
140 | * version of the RSDP and whether the XSDT pointer is valid | ||
141 | * | ||
142 | ******************************************************************************/ | ||
143 | |||
144 | void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address) | ||
145 | { | ||
146 | |||
147 | ACPI_FUNCTION_ENTRY(); | ||
148 | |||
149 | out_address->pointer_type = | ||
150 | acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING; | ||
151 | |||
152 | /* Use XSDT if it is present */ | ||
153 | |||
154 | if ((acpi_gbl_RSDP->revision >= 2) && | ||
155 | acpi_gbl_RSDP->xsdt_physical_address) { | ||
156 | out_address->pointer.value = | ||
157 | acpi_gbl_RSDP->xsdt_physical_address; | ||
158 | acpi_gbl_root_table_type = ACPI_TABLE_TYPE_XSDT; | ||
159 | } else { | ||
160 | /* No XSDT, use the RSDT */ | ||
161 | |||
162 | out_address->pointer.value = | ||
163 | acpi_gbl_RSDP->rsdt_physical_address; | ||
164 | acpi_gbl_root_table_type = ACPI_TABLE_TYPE_RSDT; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | /******************************************************************************* | ||
169 | * | ||
170 | * FUNCTION: acpi_tb_validate_rsdt | ||
171 | * | ||
172 | * PARAMETERS: table_ptr - Addressable pointer to the RSDT. | ||
173 | * | ||
174 | * RETURN: Status | ||
175 | * | ||
176 | * DESCRIPTION: Validate signature for the RSDT or XSDT | ||
177 | * | ||
178 | ******************************************************************************/ | ||
179 | |||
180 | acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) | ||
181 | { | ||
182 | char *signature; | ||
183 | |||
184 | ACPI_FUNCTION_ENTRY(); | ||
185 | |||
186 | /* Validate minimum length */ | ||
187 | |||
188 | if (table_ptr->length < sizeof(struct acpi_table_header)) { | ||
189 | ACPI_ERROR((AE_INFO, | ||
190 | "RSDT/XSDT length (%X) is smaller than minimum (%zX)", | ||
191 | table_ptr->length, | ||
192 | sizeof(struct acpi_table_header))); | ||
193 | |||
194 | return (AE_INVALID_TABLE_LENGTH); | ||
195 | } | ||
196 | |||
197 | /* Search for appropriate signature, RSDT or XSDT */ | ||
198 | |||
199 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
200 | signature = RSDT_SIG; | ||
201 | } else { | ||
202 | signature = XSDT_SIG; | ||
203 | } | ||
204 | |||
205 | if (!ACPI_COMPARE_NAME(table_ptr->signature, signature)) { | ||
206 | |||
207 | /* Invalid RSDT or XSDT signature */ | ||
208 | |||
209 | ACPI_ERROR((AE_INFO, | ||
210 | "Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:")); | ||
211 | |||
212 | ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20); | ||
213 | |||
214 | ACPI_ERROR((AE_INFO, | ||
215 | "RSDT/XSDT signature at %X is invalid", | ||
216 | acpi_gbl_RSDP->rsdt_physical_address)); | ||
217 | |||
218 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | ||
219 | ACPI_ERROR((AE_INFO, "Looking for RSDT")); | ||
220 | } else { | ||
221 | ACPI_ERROR((AE_INFO, "Looking for XSDT")); | ||
222 | } | ||
223 | |||
224 | ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48); | ||
225 | return (AE_BAD_SIGNATURE); | ||
226 | } | ||
227 | |||
228 | return (AE_OK); | ||
229 | } | ||
230 | |||
231 | /******************************************************************************* | ||
232 | * | ||
233 | * FUNCTION: acpi_tb_get_table_rsdt | ||
234 | * | ||
235 | * PARAMETERS: None | ||
236 | * | ||
237 | * RETURN: Status | ||
238 | * | ||
239 | * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) | ||
240 | * | ||
241 | ******************************************************************************/ | ||
242 | |||
243 | acpi_status acpi_tb_get_table_rsdt(void) | ||
244 | { | ||
245 | struct acpi_table_desc table_info; | ||
246 | acpi_status status; | ||
247 | struct acpi_pointer address; | ||
248 | |||
249 | ACPI_FUNCTION_TRACE(tb_get_table_rsdt); | ||
250 | |||
251 | /* Get the RSDT/XSDT via the RSDP */ | ||
252 | |||
253 | acpi_tb_get_rsdt_address(&address); | ||
254 | |||
255 | table_info.type = ACPI_TABLE_ID_XSDT; | ||
256 | status = acpi_tb_get_table(&address, &table_info); | ||
257 | if (ACPI_FAILURE(status)) { | ||
258 | ACPI_EXCEPTION((AE_INFO, status, | ||
259 | "Could not get the RSDT/XSDT")); | ||
260 | return_ACPI_STATUS(status); | ||
261 | } | ||
262 | |||
263 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
264 | "RSDP located at %p, points to RSDT physical=%8.8X%8.8X\n", | ||
265 | acpi_gbl_RSDP, | ||
266 | ACPI_FORMAT_UINT64(address.pointer.value))); | ||
267 | |||
268 | /* Check the RSDT or XSDT signature */ | ||
269 | |||
270 | status = acpi_tb_validate_rsdt(table_info.pointer); | ||
271 | if (ACPI_FAILURE(status)) { | ||
272 | goto error_cleanup; | ||
273 | } | ||
274 | |||
275 | /* Get the number of tables defined in the RSDT or XSDT */ | ||
276 | |||
277 | acpi_gbl_rsdt_table_count = acpi_tb_get_table_count(acpi_gbl_RSDP, | ||
278 | table_info.pointer); | ||
279 | |||
280 | /* Convert and/or copy to an XSDT structure */ | ||
281 | |||
282 | status = acpi_tb_convert_to_xsdt(&table_info); | ||
283 | if (ACPI_FAILURE(status)) { | ||
284 | goto error_cleanup; | ||
285 | } | ||
286 | |||
287 | /* Save the table pointers and allocation info */ | ||
288 | |||
289 | status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info); | ||
290 | if (ACPI_FAILURE(status)) { | ||
291 | goto error_cleanup; | ||
292 | } | ||
293 | |||
294 | acpi_gbl_XSDT = | ||
295 | ACPI_CAST_PTR(struct xsdt_descriptor, table_info.pointer); | ||
296 | |||
297 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); | ||
298 | return_ACPI_STATUS(status); | ||
299 | |||
300 | error_cleanup: | ||
301 | |||
302 | /* Free table allocated by acpi_tb_get_table */ | ||
303 | |||
304 | acpi_tb_delete_single_table(&table_info); | ||
305 | |||
306 | return_ACPI_STATUS(status); | ||
307 | } | ||
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 209a401801e3..3620ac5f8681 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Module Name: tbutils - Table manipulation utilities | 3 | * Module Name: tbutils - table utilities |
4 | * | 4 | * |
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
@@ -48,295 +48,507 @@ | |||
48 | ACPI_MODULE_NAME("tbutils") | 48 | ACPI_MODULE_NAME("tbutils") |
49 | 49 | ||
50 | /* Local prototypes */ | 50 | /* Local prototypes */ |
51 | #ifdef ACPI_OBSOLETE_FUNCTIONS | 51 | static void acpi_tb_parse_fadt(struct acpi_table_fadt *fadt, u8 flags); |
52 | acpi_status | 52 | |
53 | acpi_tb_handle_to_object(u16 table_id, struct acpi_table_desc **table_desc); | 53 | static void inline |
54 | #endif | 54 | acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, |
55 | u8 bit_width, acpi_physical_address address); | ||
55 | 56 | ||
56 | /******************************************************************************* | 57 | /******************************************************************************* |
57 | * | 58 | * |
58 | * FUNCTION: acpi_tb_is_table_installed | 59 | * FUNCTION: acpi_tb_print_table_header |
59 | * | 60 | * |
60 | * PARAMETERS: new_table_desc - Descriptor for new table being installed | 61 | * PARAMETERS: Address - Table physical address |
62 | * Header - Table header | ||
61 | * | 63 | * |
62 | * RETURN: Status - AE_ALREADY_EXISTS if the table is already installed | 64 | * RETURN: None |
63 | * | 65 | * |
64 | * DESCRIPTION: Determine if an ACPI table is already installed | 66 | * DESCRIPTION: Print an ACPI table header |
65 | * | ||
66 | * MUTEX: Table data structures should be locked | ||
67 | * | 67 | * |
68 | ******************************************************************************/ | 68 | ******************************************************************************/ |
69 | 69 | ||
70 | acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) | 70 | void |
71 | acpi_tb_print_table_header(acpi_physical_address address, | ||
72 | struct acpi_table_header *header) | ||
71 | { | 73 | { |
72 | struct acpi_table_desc *table_desc; | ||
73 | |||
74 | ACPI_FUNCTION_TRACE(tb_is_table_installed); | ||
75 | |||
76 | /* Get the list descriptor and first table descriptor */ | ||
77 | |||
78 | table_desc = acpi_gbl_table_lists[new_table_desc->type].next; | ||
79 | |||
80 | /* Examine all installed tables of this type */ | ||
81 | |||
82 | while (table_desc) { | ||
83 | /* | ||
84 | * If the table lengths match, perform a full bytewise compare. This | ||
85 | * means that we will allow tables with duplicate oem_table_id(s), as | ||
86 | * long as the tables are different in some way. | ||
87 | * | ||
88 | * Checking if the table has been loaded into the namespace means that | ||
89 | * we don't check for duplicate tables during the initial installation | ||
90 | * of tables within the RSDT/XSDT. | ||
91 | */ | ||
92 | if ((table_desc->loaded_into_namespace) && | ||
93 | (table_desc->pointer->length == | ||
94 | new_table_desc->pointer->length) | ||
95 | && | ||
96 | (!ACPI_MEMCMP | ||
97 | (table_desc->pointer, new_table_desc->pointer, | ||
98 | new_table_desc->pointer->length))) { | ||
99 | |||
100 | /* Match: this table is already installed */ | ||
101 | |||
102 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | ||
103 | "Table [%4.4s] already installed: Rev %X OemTableId [%8.8s]\n", | ||
104 | new_table_desc->pointer->signature, | ||
105 | new_table_desc->pointer->revision, | ||
106 | new_table_desc->pointer-> | ||
107 | oem_table_id)); | ||
108 | |||
109 | new_table_desc->owner_id = table_desc->owner_id; | ||
110 | new_table_desc->installed_desc = table_desc; | ||
111 | |||
112 | return_ACPI_STATUS(AE_ALREADY_EXISTS); | ||
113 | } | ||
114 | |||
115 | /* Get next table on the list */ | ||
116 | 74 | ||
117 | table_desc = table_desc->next; | 75 | ACPI_INFO((AE_INFO, |
118 | } | 76 | "%4.4s @ 0x%p Length 0x%04X (v%3.3d %6.6s %8.8s 0x%08X %4.4s 0x%08X)", |
119 | 77 | header->signature, ACPI_CAST_PTR(void, address), | |
120 | return_ACPI_STATUS(AE_OK); | 78 | header->length, header->revision, header->oem_id, |
79 | header->oem_table_id, header->oem_revision, | ||
80 | header->asl_compiler_id, header->asl_compiler_revision)); | ||
121 | } | 81 | } |
122 | 82 | ||
123 | /******************************************************************************* | 83 | /******************************************************************************* |
124 | * | 84 | * |
125 | * FUNCTION: acpi_tb_validate_table_header | 85 | * FUNCTION: acpi_tb_init_generic_address |
126 | * | ||
127 | * PARAMETERS: table_header - Logical pointer to the table | ||
128 | * | 86 | * |
129 | * RETURN: Status | 87 | * PARAMETERS: new_gas_struct - GAS struct to be initialized |
88 | * bit_width - Width of this register | ||
89 | * Address - Address of the register | ||
130 | * | 90 | * |
131 | * DESCRIPTION: Check an ACPI table header for validity | 91 | * RETURN: None |
132 | * | 92 | * |
133 | * NOTE: Table pointers are validated as follows: | 93 | * DESCRIPTION: Initialize a GAS structure. |
134 | * 1) Table pointer must point to valid physical memory | ||
135 | * 2) Signature must be 4 ASCII chars, even if we don't recognize the | ||
136 | * name | ||
137 | * 3) Table must be readable for length specified in the header | ||
138 | * 4) Table checksum must be valid (with the exception of the FACS | ||
139 | * which has no checksum because it contains variable fields) | ||
140 | * | 94 | * |
141 | ******************************************************************************/ | 95 | ******************************************************************************/ |
142 | 96 | ||
143 | acpi_status | 97 | static void inline |
144 | acpi_tb_validate_table_header(struct acpi_table_header *table_header) | 98 | acpi_tb_init_generic_address(struct acpi_generic_address *new_gas_struct, |
99 | u8 bit_width, acpi_physical_address address) | ||
145 | { | 100 | { |
146 | acpi_name signature; | ||
147 | |||
148 | ACPI_FUNCTION_ENTRY(); | ||
149 | |||
150 | /* Verify that this is a valid address */ | ||
151 | |||
152 | if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) { | ||
153 | ACPI_ERROR((AE_INFO, | ||
154 | "Cannot read table header at %p", table_header)); | ||
155 | |||
156 | return (AE_BAD_ADDRESS); | ||
157 | } | ||
158 | |||
159 | /* Ensure that the signature is 4 ASCII characters */ | ||
160 | |||
161 | ACPI_MOVE_32_TO_32(&signature, table_header->signature); | ||
162 | if (!acpi_ut_valid_acpi_name(signature)) { | ||
163 | ACPI_ERROR((AE_INFO, "Invalid table signature 0x%8.8X", | ||
164 | signature)); | ||
165 | 101 | ||
166 | ACPI_DUMP_BUFFER(table_header, | 102 | ACPI_STORE_ADDRESS(new_gas_struct->address, address); |
167 | sizeof(struct acpi_table_header)); | 103 | new_gas_struct->space_id = ACPI_ADR_SPACE_SYSTEM_IO; |
168 | return (AE_BAD_SIGNATURE); | 104 | new_gas_struct->bit_width = bit_width; |
169 | } | 105 | new_gas_struct->bit_offset = 0; |
170 | 106 | new_gas_struct->access_width = 0; | |
171 | /* Validate the table length */ | ||
172 | |||
173 | if (table_header->length < sizeof(struct acpi_table_header)) { | ||
174 | ACPI_ERROR((AE_INFO, | ||
175 | "Invalid length 0x%X in table with signature %4.4s", | ||
176 | (u32) table_header->length, | ||
177 | ACPI_CAST_PTR(char, &signature))); | ||
178 | |||
179 | ACPI_DUMP_BUFFER(table_header, | ||
180 | sizeof(struct acpi_table_header)); | ||
181 | return (AE_BAD_HEADER); | ||
182 | } | ||
183 | |||
184 | return (AE_OK); | ||
185 | } | 107 | } |
186 | 108 | ||
187 | /******************************************************************************* | 109 | /******************************************************************************* |
188 | * | 110 | * |
189 | * FUNCTION: acpi_tb_sum_table | 111 | * FUNCTION: acpi_tb_checksum |
190 | * | 112 | * |
191 | * PARAMETERS: Buffer - Buffer to sum | 113 | * PARAMETERS: Buffer - Pointer to memory region to be checked |
192 | * Length - Size of the buffer | 114 | * Length - Length of this memory region |
193 | * | 115 | * |
194 | * RETURN: 8 bit sum of buffer | 116 | * RETURN: Checksum (u8) |
195 | * | 117 | * |
196 | * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it. | 118 | * DESCRIPTION: Calculates circular checksum of memory region. |
197 | * | 119 | * |
198 | ******************************************************************************/ | 120 | ******************************************************************************/ |
199 | 121 | ||
200 | u8 acpi_tb_sum_table(void *buffer, u32 length) | 122 | u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length) |
201 | { | 123 | { |
202 | acpi_native_uint i; | ||
203 | u8 sum = 0; | 124 | u8 sum = 0; |
125 | u8 *end = buffer + length; | ||
204 | 126 | ||
205 | if (!buffer || !length) { | 127 | while (buffer < end) { |
206 | return (0); | 128 | sum = (u8) (sum + *(buffer++)); |
207 | } | 129 | } |
208 | 130 | ||
209 | for (i = 0; i < length; i++) { | 131 | return sum; |
210 | sum = (u8) (sum + ((u8 *) buffer)[i]); | ||
211 | } | ||
212 | return (sum); | ||
213 | } | 132 | } |
214 | 133 | ||
215 | /******************************************************************************* | 134 | /******************************************************************************* |
216 | * | 135 | * |
217 | * FUNCTION: acpi_tb_generate_checksum | 136 | * FUNCTION: acpi_tb_convert_fadt |
218 | * | 137 | * |
219 | * PARAMETERS: Table - Pointer to a valid ACPI table (with a | 138 | * PARAMETERS: Fadt - FADT table to be converted |
220 | * standard ACPI header) | ||
221 | * | 139 | * |
222 | * RETURN: 8 bit checksum of buffer | 140 | * RETURN: None |
223 | * | 141 | * |
224 | * DESCRIPTION: Computes an 8 bit checksum of the table. | 142 | * DESCRIPTION: Converts a BIOS supplied ACPI 1.0 FADT to a local |
143 | * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply | ||
144 | * copied to the local FADT. The ACPI CA software uses this | ||
145 | * local FADT. Thus a significant amount of special #ifdef | ||
146 | * type codeing is saved. | ||
225 | * | 147 | * |
226 | ******************************************************************************/ | 148 | ******************************************************************************/ |
227 | 149 | ||
228 | u8 acpi_tb_generate_checksum(struct acpi_table_header * table) | 150 | void acpi_tb_convert_fadt(struct acpi_table_fadt *fadt) |
229 | { | 151 | { |
230 | u8 checksum; | ||
231 | |||
232 | /* Sum the entire table as-is */ | ||
233 | 152 | ||
234 | checksum = acpi_tb_sum_table(table, table->length); | 153 | /* |
154 | * Convert table pointers to 64-bit fields | ||
155 | */ | ||
156 | if (!acpi_gbl_FADT.Xfacs) { | ||
157 | acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; | ||
158 | } | ||
235 | 159 | ||
236 | /* Subtract off the existing checksum value in the table */ | 160 | if (!acpi_gbl_FADT.Xdsdt) { |
161 | acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; | ||
162 | } | ||
237 | 163 | ||
238 | checksum = (u8) (checksum - table->checksum); | 164 | /* |
165 | * Convert the V1.0 block addresses to V2.0 GAS structures | ||
166 | */ | ||
167 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1a_event_block, | ||
168 | acpi_gbl_FADT.pm1_event_length, | ||
169 | (acpi_physical_address) acpi_gbl_FADT. | ||
170 | pm1a_event_block); | ||
171 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1b_event_block, | ||
172 | acpi_gbl_FADT.pm1_event_length, | ||
173 | (acpi_physical_address) acpi_gbl_FADT. | ||
174 | pm1b_event_block); | ||
175 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1a_control_block, | ||
176 | acpi_gbl_FADT.pm1_control_length, | ||
177 | (acpi_physical_address) acpi_gbl_FADT. | ||
178 | pm1a_control_block); | ||
179 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm1b_control_block, | ||
180 | acpi_gbl_FADT.pm1_control_length, | ||
181 | (acpi_physical_address) acpi_gbl_FADT. | ||
182 | pm1b_control_block); | ||
183 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm2_control_block, | ||
184 | acpi_gbl_FADT.pm2_control_length, | ||
185 | (acpi_physical_address) acpi_gbl_FADT. | ||
186 | pm2_control_block); | ||
187 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xpm_timer_block, | ||
188 | acpi_gbl_FADT.pm_timer_length, | ||
189 | (acpi_physical_address) acpi_gbl_FADT. | ||
190 | pm_timer_block); | ||
191 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xgpe0_block, 0, | ||
192 | (acpi_physical_address) acpi_gbl_FADT. | ||
193 | gpe0_block); | ||
194 | acpi_tb_init_generic_address(&acpi_gbl_FADT.xgpe1_block, 0, | ||
195 | (acpi_physical_address) acpi_gbl_FADT. | ||
196 | gpe1_block); | ||
197 | |||
198 | /* | ||
199 | * Create separate GAS structs for the PM1 Enable registers | ||
200 | */ | ||
201 | acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, | ||
202 | (u8) ACPI_DIV_2(acpi_gbl_FADT. | ||
203 | pm1_event_length), | ||
204 | (acpi_physical_address) | ||
205 | (acpi_gbl_FADT.xpm1a_event_block.address + | ||
206 | ACPI_DIV_2(acpi_gbl_FADT. | ||
207 | pm1_event_length))); | ||
208 | |||
209 | /* | ||
210 | * PM1B is optional; leave null if not present | ||
211 | */ | ||
212 | if (acpi_gbl_FADT.xpm1b_event_block.address) { | ||
213 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, | ||
214 | (u8) ACPI_DIV_2(acpi_gbl_FADT. | ||
215 | pm1_event_length), | ||
216 | (acpi_physical_address) | ||
217 | (acpi_gbl_FADT.xpm1b_event_block. | ||
218 | address + | ||
219 | ACPI_DIV_2(acpi_gbl_FADT. | ||
220 | pm1_event_length))); | ||
221 | } | ||
239 | 222 | ||
240 | /* Compute the final checksum */ | 223 | /* Global FADT is the new common V2.0 FADT */ |
241 | 224 | ||
242 | checksum = (u8) (0 - checksum); | 225 | acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); |
243 | return (checksum); | ||
244 | } | 226 | } |
245 | 227 | ||
246 | /******************************************************************************* | 228 | /******************************************************************************* |
247 | * | 229 | * |
248 | * FUNCTION: acpi_tb_set_checksum | 230 | * FUNCTION: acpi_tb_parse_fadt |
249 | * | 231 | * |
250 | * PARAMETERS: Table - Pointer to a valid ACPI table (with a | 232 | * PARAMETERS: Fadt - Pointer to FADT table |
251 | * standard ACPI header) | 233 | * Flags - Flags |
252 | * | 234 | * |
253 | * RETURN: None. Sets the table checksum field | 235 | * RETURN: none |
254 | * | 236 | * |
255 | * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the | 237 | * DESCRIPTION: This function is called to initialise the FADT, DSDT and FACS |
256 | * checksum into the table header. | 238 | * tables (FADT contains the addresses of the DSDT and FACS) |
257 | * | 239 | * |
258 | ******************************************************************************/ | 240 | ******************************************************************************/ |
259 | 241 | ||
260 | void acpi_tb_set_checksum(struct acpi_table_header *table) | 242 | static void acpi_tb_parse_fadt(struct acpi_table_fadt *fadt, u8 flags) |
261 | { | 243 | { |
244 | acpi_physical_address dsdt_address = | ||
245 | (acpi_physical_address) fadt->Xdsdt; | ||
246 | acpi_physical_address facs_address = | ||
247 | (acpi_physical_address) fadt->Xfacs; | ||
248 | struct acpi_table_header *table; | ||
249 | |||
250 | if (!dsdt_address) { | ||
251 | goto no_dsdt; | ||
252 | } | ||
253 | |||
254 | table = | ||
255 | acpi_os_map_memory(dsdt_address, sizeof(struct acpi_table_header)); | ||
256 | if (!table) { | ||
257 | goto no_dsdt; | ||
258 | } | ||
259 | |||
260 | /* Initialize the DSDT table */ | ||
261 | |||
262 | ACPI_MOVE_32_TO_32(& | ||
263 | (acpi_gbl_root_table_list. | ||
264 | tables[ACPI_TABLE_INDEX_DSDT].signature), | ||
265 | ACPI_SIG_DSDT); | ||
266 | |||
267 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].address = | ||
268 | dsdt_address; | ||
269 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length = | ||
270 | table->length; | ||
271 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = flags; | ||
272 | |||
273 | acpi_tb_print_table_header(dsdt_address, table); | ||
274 | |||
275 | /* Global integer width is based upon revision of the DSDT */ | ||
276 | |||
277 | acpi_ut_set_integer_width(table->revision); | ||
278 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
279 | |||
280 | no_dsdt: | ||
281 | if (!facs_address) { | ||
282 | return; | ||
283 | } | ||
262 | 284 | ||
263 | table->checksum = acpi_tb_generate_checksum(table); | 285 | table = |
286 | acpi_os_map_memory(facs_address, sizeof(struct acpi_table_header)); | ||
287 | if (!table) { | ||
288 | return; | ||
289 | } | ||
290 | |||
291 | /* Initialize the FACS table */ | ||
292 | |||
293 | ACPI_MOVE_32_TO_32(& | ||
294 | (acpi_gbl_root_table_list. | ||
295 | tables[ACPI_TABLE_INDEX_FACS].signature), | ||
296 | ACPI_SIG_FACS); | ||
297 | |||
298 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_FACS].address = | ||
299 | facs_address; | ||
300 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_FACS].length = | ||
301 | table->length; | ||
302 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_FACS].flags = flags; | ||
303 | |||
304 | ACPI_INFO((AE_INFO, "%4.4s @ 0x%p", | ||
305 | table->signature, ACPI_CAST_PTR(void, facs_address))); | ||
306 | |||
307 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
264 | } | 308 | } |
265 | 309 | ||
266 | /******************************************************************************* | 310 | /******************************************************************************* |
267 | * | 311 | * |
268 | * FUNCTION: acpi_tb_verify_table_checksum | 312 | * FUNCTION: acpi_tb_parse_root_table |
269 | * | 313 | * |
270 | * PARAMETERS: *table_header - ACPI table to verify | 314 | * PARAMETERS: Rsdp - Pointer to the RSDP |
315 | * Flags - Flags | ||
316 | * | ||
317 | * RETURN: Status | ||
271 | * | 318 | * |
272 | * RETURN: 8 bit checksum of table | 319 | * DESCRIPTION: This function is called to parse the Root System Description |
320 | * Table (RSDT or XSDT) | ||
273 | * | 321 | * |
274 | * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares | 322 | * NOTE: Tables are mapped (not copied) for efficiency. The FACS must |
275 | * it to the existing checksum value. | 323 | * be mapped and cannot be copied because it contains the actual |
324 | * memory location of the ACPI Global Lock. | ||
276 | * | 325 | * |
277 | ******************************************************************************/ | 326 | ******************************************************************************/ |
278 | 327 | ||
279 | acpi_status | 328 | acpi_status acpi_tb_parse_root_table(struct acpi_table_rsdp *rsdp, u8 flags) |
280 | acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) | ||
281 | { | 329 | { |
330 | struct acpi_table_header *table; | ||
331 | acpi_physical_address address; | ||
332 | u32 length; | ||
333 | u8 *table_entry; | ||
334 | acpi_native_uint i; | ||
335 | acpi_native_uint pointer_size; | ||
336 | u32 table_count; | ||
282 | u8 checksum; | 337 | u8 checksum; |
338 | acpi_status status; | ||
339 | |||
340 | ACPI_FUNCTION_TRACE(tb_parse_root_table); | ||
341 | |||
342 | /* Differentiate between RSDT and XSDT root tables */ | ||
343 | |||
344 | if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { | ||
345 | /* | ||
346 | * Root table is an XSDT (64-bit physical addresses). We must use the | ||
347 | * XSDT if the revision is > 1 and the XSDT pointer is present, as per | ||
348 | * the ACPI specification. | ||
349 | */ | ||
350 | address = (acpi_native_uint) rsdp->xsdt_physical_address; | ||
351 | pointer_size = sizeof(u64); | ||
352 | } else { | ||
353 | /* Root table is an RSDT (32-bit physical addresses) */ | ||
354 | |||
355 | address = (acpi_native_uint) rsdp->rsdt_physical_address; | ||
356 | pointer_size = sizeof(u32); | ||
357 | } | ||
283 | 358 | ||
284 | ACPI_FUNCTION_TRACE(tb_verify_table_checksum); | 359 | /* Map the table header to get the full table length */ |
285 | 360 | ||
286 | /* Compute the checksum on the table */ | 361 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); |
362 | if (!table) { | ||
363 | return (AE_NO_MEMORY); | ||
364 | } | ||
365 | |||
366 | /* Get the length of the full table, verify length and map entire table */ | ||
367 | |||
368 | length = table->length; | ||
369 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | ||
370 | |||
371 | if (length < sizeof(struct acpi_table_header)) { | ||
372 | ACPI_ERROR((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", | ||
373 | length)); | ||
374 | return (AE_INVALID_TABLE_LENGTH); | ||
375 | } | ||
376 | |||
377 | table = acpi_os_map_memory(address, length); | ||
378 | if (!table) { | ||
379 | return (AE_NO_MEMORY); | ||
380 | } | ||
381 | |||
382 | /* Validate the root table checksum */ | ||
383 | |||
384 | checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); | ||
385 | #if (ACPI_CHECKSUM_ABORT) | ||
386 | |||
387 | if (checksum) { | ||
388 | acpi_os_unmap_memory(table, length); | ||
389 | return (AE_BAD_CHECKSUM); | ||
390 | } | ||
391 | #endif | ||
392 | |||
393 | acpi_tb_print_table_header(address, table); | ||
394 | |||
395 | /* Calculate the number of tables described in the root table */ | ||
396 | |||
397 | table_count = | ||
398 | (table->length - sizeof(struct acpi_table_header)) / pointer_size; | ||
399 | |||
400 | /* Setup loop */ | ||
287 | 401 | ||
288 | checksum = acpi_tb_generate_checksum(table_header); | 402 | table_entry = |
403 | ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); | ||
404 | acpi_gbl_root_table_list.count = 2; | ||
289 | 405 | ||
290 | /* Checksum ok? */ | 406 | /* |
407 | * Initialize the ACPI table entries | ||
408 | * First two entries in the table array are reserved for the DSDT and FACS | ||
409 | */ | ||
410 | for (i = 0; i < table_count; ++i, table_entry += pointer_size) { | ||
291 | 411 | ||
292 | if (checksum == table_header->checksum) { | 412 | /* Ensure there is room for another table entry */ |
293 | return_ACPI_STATUS(AE_OK); | 413 | |
414 | if (acpi_gbl_root_table_list.count >= | ||
415 | acpi_gbl_root_table_list.size) { | ||
416 | status = acpi_tb_resize_root_table_list(); | ||
417 | if (ACPI_FAILURE(status)) { | ||
418 | ACPI_WARNING((AE_INFO, | ||
419 | "Truncating %u table entries!", | ||
420 | (unsigned) | ||
421 | (acpi_gbl_root_table_list.size - | ||
422 | acpi_gbl_root_table_list. | ||
423 | count))); | ||
424 | break; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | /* Get the physical address (32-bit for RSDT, 64-bit for XSDT) */ | ||
429 | |||
430 | if (pointer_size == sizeof(u32)) { | ||
431 | acpi_gbl_root_table_list. | ||
432 | tables[acpi_gbl_root_table_list.count].address = | ||
433 | (acpi_physical_address) (*ACPI_CAST_PTR | ||
434 | (u32, table_entry)); | ||
435 | } else { | ||
436 | acpi_gbl_root_table_list. | ||
437 | tables[acpi_gbl_root_table_list.count].address = | ||
438 | (acpi_physical_address) (*ACPI_CAST_PTR | ||
439 | (u64, table_entry)); | ||
440 | } | ||
441 | |||
442 | acpi_gbl_root_table_list.count++; | ||
294 | } | 443 | } |
295 | 444 | ||
296 | ACPI_WARNING((AE_INFO, | 445 | /* |
297 | "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X", | 446 | * It is not possible to map more than one entry in some environments, |
298 | table_header->signature, table_header->checksum, | 447 | * so unmap the root table here before mapping other tables |
299 | checksum)); | 448 | */ |
449 | acpi_os_unmap_memory(table, length); | ||
450 | |||
451 | /* Initialize all tables other than the DSDT and FACS */ | ||
452 | |||
453 | for (i = 2; i < acpi_gbl_root_table_list.count; i++) { | ||
454 | address = acpi_gbl_root_table_list.tables[i].address; | ||
455 | length = sizeof(struct acpi_table_header); | ||
456 | |||
457 | table = acpi_os_map_memory(address, length); | ||
458 | if (!table) { | ||
459 | continue; | ||
460 | } | ||
461 | |||
462 | acpi_gbl_root_table_list.tables[i].length = table->length; | ||
463 | acpi_gbl_root_table_list.tables[i].flags = flags; | ||
464 | |||
465 | ACPI_MOVE_32_TO_32(& | ||
466 | (acpi_gbl_root_table_list.tables[i]. | ||
467 | signature), table->signature); | ||
468 | |||
469 | acpi_tb_print_table_header(address, table); | ||
470 | |||
471 | /* | ||
472 | * Special case for the FADT because of multiple versions - | ||
473 | * get a local copy and convert to common format | ||
474 | */ | ||
475 | if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_FADT)) { | ||
476 | acpi_os_unmap_memory(table, length); | ||
477 | length = table->length; | ||
478 | |||
479 | table = acpi_os_map_memory(address, length); | ||
480 | if (!table) { | ||
481 | continue; | ||
482 | } | ||
483 | |||
484 | /* Copy the entire FADT locally */ | ||
485 | |||
486 | ACPI_MEMCPY(&acpi_gbl_FADT, table, | ||
487 | ACPI_MIN(table->length, | ||
488 | sizeof(struct acpi_table_fadt))); | ||
489 | |||
490 | /* Small table means old revision, convert to new */ | ||
491 | |||
492 | if (table->length < sizeof(struct acpi_table_fadt)) { | ||
493 | acpi_tb_convert_fadt(ACPI_CAST_PTR | ||
494 | (struct acpi_table_fadt, | ||
495 | table)); | ||
496 | } | ||
497 | |||
498 | /* Unmap original FADT */ | ||
300 | 499 | ||
301 | return_ACPI_STATUS(AE_BAD_CHECKSUM); | 500 | acpi_os_unmap_memory(table, length); |
501 | acpi_tb_parse_fadt(&acpi_gbl_FADT, flags); | ||
502 | } else { | ||
503 | acpi_os_unmap_memory(table, length); | ||
504 | } | ||
505 | } | ||
506 | |||
507 | return_ACPI_STATUS(AE_OK); | ||
302 | } | 508 | } |
303 | 509 | ||
304 | #ifdef ACPI_OBSOLETE_FUNCTIONS | 510 | /****************************************************************************** |
305 | /******************************************************************************* | ||
306 | * | 511 | * |
307 | * FUNCTION: acpi_tb_handle_to_object | 512 | * FUNCTION: acpi_tb_map |
308 | * | 513 | * |
309 | * PARAMETERS: table_id - Id for which the function is searching | 514 | * PARAMETERS: Address - Address to be mapped |
310 | * table_desc - Pointer to return the matching table | 515 | * Length - Length to be mapped |
311 | * descriptor. | 516 | * Flags - Logical or physical addressing mode |
312 | * | 517 | * |
313 | * RETURN: Search the tables to find one with a matching table_id and | 518 | * RETURN: Pointer to mapped region |
314 | * return a pointer to that table descriptor. | ||
315 | * | 519 | * |
316 | ******************************************************************************/ | 520 | * DESCRIPTION: Maps memory according to flag |
521 | * | ||
522 | *****************************************************************************/ | ||
317 | 523 | ||
318 | acpi_status | 524 | void *acpi_tb_map(acpi_physical_address address, u32 length, u32 flags) |
319 | acpi_tb_handle_to_object(u16 table_id, | ||
320 | struct acpi_table_desc **return_table_desc) | ||
321 | { | 525 | { |
322 | u32 i; | ||
323 | struct acpi_table_desc *table_desc; | ||
324 | 526 | ||
325 | ACPI_FUNCTION_NAME(tb_handle_to_object); | 527 | if (flags == ACPI_TABLE_ORIGIN_MAPPED) { |
528 | return (acpi_os_map_memory(address, length)); | ||
529 | } else { | ||
530 | return (ACPI_CAST_PTR(void, address)); | ||
531 | } | ||
532 | } | ||
326 | 533 | ||
327 | for (i = 0; i < ACPI_TABLE_MAX; i++) { | 534 | /****************************************************************************** |
328 | table_desc = acpi_gbl_table_lists[i].next; | 535 | * |
329 | while (table_desc) { | 536 | * FUNCTION: acpi_tb_unmap |
330 | if (table_desc->table_id == table_id) { | 537 | * |
331 | *return_table_desc = table_desc; | 538 | * PARAMETERS: Pointer - To mapped region |
332 | return (AE_OK); | 539 | * Length - Length to be unmapped |
333 | } | 540 | * Flags - Logical or physical addressing mode |
541 | * | ||
542 | * RETURN: None | ||
543 | * | ||
544 | * DESCRIPTION: Unmaps memory according to flag | ||
545 | * | ||
546 | *****************************************************************************/ | ||
334 | 547 | ||
335 | table_desc = table_desc->next; | 548 | void acpi_tb_unmap(void *pointer, u32 length, u32 flags) |
336 | } | 549 | { |
337 | } | ||
338 | 550 | ||
339 | ACPI_ERROR((AE_INFO, "TableId=%X does not exist", table_id)); | 551 | if (flags == ACPI_TABLE_ORIGIN_MAPPED) { |
340 | return (AE_BAD_PARAMETER); | 552 | acpi_os_unmap_memory(pointer, length); |
553 | } | ||
341 | } | 554 | } |
342 | #endif | ||
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 5ba9303293ad..77439fc36c32 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c | |||
@@ -49,80 +49,146 @@ | |||
49 | #define _COMPONENT ACPI_TABLES | 49 | #define _COMPONENT ACPI_TABLES |
50 | ACPI_MODULE_NAME("tbxface") | 50 | ACPI_MODULE_NAME("tbxface") |
51 | 51 | ||
52 | /* Local prototypes */ | ||
53 | static acpi_status acpi_tb_load_namespace(void); | ||
54 | |||
52 | /******************************************************************************* | 55 | /******************************************************************************* |
53 | * | 56 | * |
54 | * FUNCTION: acpi_load_tables | 57 | * FUNCTION: acpi_initialize_tables |
55 | * | 58 | * |
56 | * PARAMETERS: None | 59 | * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated |
60 | * struct acpi_table_desc structures. If NULL, the | ||
61 | * array is dynamically allocated. | ||
62 | * initial_table_count - Size of initial_table_array, in number of | ||
63 | * struct acpi_table_desc structures | ||
64 | * allow_realloc - Flag to tell Table Manager if resize of | ||
65 | * pre-allocated array is allowed. Ignored | ||
66 | * if initial_table_array is NULL. | ||
57 | * | 67 | * |
58 | * RETURN: Status | 68 | * RETURN: Status |
59 | * | 69 | * |
60 | * DESCRIPTION: This function is called to load the ACPI tables from the | 70 | * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT. |
61 | * provided RSDT | 71 | * |
72 | * NOTE: Allows static allocation of the initial table array in order | ||
73 | * to avoid the use of dynamic memory in confined environments | ||
74 | * such as the kernel boot sequence where it may not be available. | ||
75 | * | ||
76 | * If the host OS memory managers are initialized, use NULL for | ||
77 | * initial_table_array, and the table will be dynamically allocated. | ||
62 | * | 78 | * |
63 | ******************************************************************************/ | 79 | ******************************************************************************/ |
64 | acpi_status acpi_load_tables(void) | 80 | |
81 | acpi_status | ||
82 | acpi_initialize_tables(struct acpi_table_desc *initial_table_array, | ||
83 | u32 initial_table_count, u8 allow_resize) | ||
65 | { | 84 | { |
66 | struct acpi_pointer rsdp_address; | 85 | acpi_physical_address address; |
67 | acpi_status status; | 86 | acpi_status status; |
87 | struct acpi_table_rsdp *rsdp; | ||
68 | 88 | ||
69 | ACPI_FUNCTION_TRACE(acpi_load_tables); | 89 | ACPI_FUNCTION_TRACE(acpi_initialize_tables); |
70 | 90 | ||
71 | /* Get the RSDP */ | 91 | /* |
92 | * Set up the Root Table Array | ||
93 | * Allocate the table array if requested | ||
94 | */ | ||
95 | if (!initial_table_array) { | ||
96 | acpi_gbl_root_table_list.size = initial_table_count; | ||
97 | acpi_gbl_root_table_list.flags = ACPI_TABLE_FLAGS_ALLOW_RESIZE; | ||
72 | 98 | ||
73 | status = acpi_os_get_root_pointer(ACPI_LOGICAL_ADDRESSING, | 99 | status = acpi_tb_resize_root_table_list(); |
74 | &rsdp_address); | 100 | if (ACPI_FAILURE(status)) { |
75 | if (ACPI_FAILURE(status)) { | 101 | return_ACPI_STATUS(status); |
76 | ACPI_EXCEPTION((AE_INFO, status, "Could not get the RSDP")); | 102 | } |
77 | goto error_exit; | 103 | } else { |
104 | /* Root Table Array has been statically allocated by the host */ | ||
105 | |||
106 | acpi_gbl_root_table_list.tables = initial_table_array; | ||
107 | acpi_gbl_root_table_list.size = initial_table_count; | ||
108 | acpi_gbl_root_table_list.flags = ACPI_TABLE_ORIGIN_UNKNOWN; | ||
109 | if (allow_resize) { | ||
110 | acpi_gbl_root_table_list.flags = | ||
111 | ACPI_TABLE_FLAGS_ALLOW_RESIZE; | ||
112 | } | ||
78 | } | 113 | } |
79 | 114 | ||
80 | /* Map and validate the RSDP */ | 115 | /* Get the RSDP and map it */ |
81 | 116 | ||
82 | acpi_gbl_table_flags = rsdp_address.pointer_type; | 117 | address = acpi_os_get_root_pointer(); |
118 | if (!address) { | ||
119 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
120 | } | ||
83 | 121 | ||
84 | status = acpi_tb_verify_rsdp(&rsdp_address); | 122 | rsdp = acpi_os_map_memory(address, sizeof(struct acpi_table_rsdp)); |
85 | if (ACPI_FAILURE(status)) { | 123 | if (!rsdp) { |
86 | ACPI_EXCEPTION((AE_INFO, status, "During RSDP validation")); | 124 | return_ACPI_STATUS(AE_NO_MEMORY); |
87 | goto error_exit; | ||
88 | } | 125 | } |
89 | 126 | ||
90 | /* Get the RSDT via the RSDP */ | 127 | ACPI_INFO((AE_INFO, "%.8s @ 0x%p", |
128 | rsdp->signature, ACPI_CAST_PTR(void, address))); | ||
91 | 129 | ||
92 | status = acpi_tb_get_table_rsdt(); | 130 | /* |
93 | if (ACPI_FAILURE(status)) { | 131 | * Get the root table (RSDT or XSDT) and extract all entries to the local |
94 | ACPI_EXCEPTION((AE_INFO, status, "Could not load RSDT")); | 132 | * Root Table Array. This array contains the information of the RSDT/XSDT |
95 | goto error_exit; | 133 | * in a common, more useable format. |
96 | } | 134 | */ |
135 | status = acpi_tb_parse_root_table(rsdp, ACPI_TABLE_ORIGIN_MAPPED); | ||
136 | acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); | ||
137 | return_ACPI_STATUS(status); | ||
138 | } | ||
97 | 139 | ||
98 | /* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */ | 140 | ACPI_EXPORT_SYMBOL(acpi_initialize_tables) |
99 | 141 | ||
100 | status = acpi_tb_get_required_tables(); | 142 | /******************************************************************************* |
101 | if (ACPI_FAILURE(status)) { | 143 | * |
102 | ACPI_EXCEPTION((AE_INFO, status, | 144 | * FUNCTION: acpi_reallocate_root_table |
103 | "Could not get all required tables (DSDT/FADT/FACS)")); | 145 | * |
104 | goto error_exit; | 146 | * PARAMETERS: None |
147 | * | ||
148 | * RETURN: Status | ||
149 | * | ||
150 | * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the | ||
151 | * root list from the previously provided scratch area. Should | ||
152 | * be called once dynamic memory allocation is available in the | ||
153 | * kernel | ||
154 | * | ||
155 | ******************************************************************************/ | ||
156 | acpi_status acpi_reallocate_root_table(void) | ||
157 | { | ||
158 | struct acpi_table_desc *tables; | ||
159 | acpi_size new_size; | ||
160 | |||
161 | ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); | ||
162 | |||
163 | /* | ||
164 | * Only reallocate the root table if the host provided a static buffer | ||
165 | * for the table array in the call to acpi_initialize_tables. | ||
166 | */ | ||
167 | if ((acpi_gbl_root_table_list.flags & ACPI_TABLE_ORIGIN_MASK) != | ||
168 | ACPI_TABLE_ORIGIN_UNKNOWN) { | ||
169 | return_ACPI_STATUS(AE_SUPPORT); | ||
105 | } | 170 | } |
106 | 171 | ||
107 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); | 172 | new_size = |
173 | (acpi_gbl_root_table_list.count + | ||
174 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc); | ||
108 | 175 | ||
109 | /* Load the namespace from the tables */ | 176 | /* Create new array and copy the old array */ |
110 | 177 | ||
111 | status = acpi_ns_load_namespace(); | 178 | tables = ACPI_ALLOCATE_ZEROED(new_size); |
112 | if (ACPI_FAILURE(status)) { | 179 | if (!tables) { |
113 | ACPI_EXCEPTION((AE_INFO, status, "Could not load namespace")); | 180 | return_ACPI_STATUS(AE_NO_MEMORY); |
114 | goto error_exit; | ||
115 | } | 181 | } |
116 | 182 | ||
117 | return_ACPI_STATUS(AE_OK); | 183 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size); |
118 | 184 | ||
119 | error_exit: | 185 | acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count; |
120 | ACPI_EXCEPTION((AE_INFO, status, "Could not load tables")); | 186 | acpi_gbl_root_table_list.tables = tables; |
121 | return_ACPI_STATUS(status); | 187 | acpi_gbl_root_table_list.flags = |
122 | } | 188 | ACPI_TABLE_ORIGIN_ALLOCATED | ACPI_TABLE_FLAGS_ALLOW_RESIZE; |
123 | |||
124 | ACPI_EXPORT_SYMBOL(acpi_load_tables) | ||
125 | 189 | ||
190 | return_ACPI_STATUS(AE_OK); | ||
191 | } | ||
126 | /******************************************************************************* | 192 | /******************************************************************************* |
127 | * | 193 | * |
128 | * FUNCTION: acpi_load_table | 194 | * FUNCTION: acpi_load_table |
@@ -141,342 +207,358 @@ ACPI_EXPORT_SYMBOL(acpi_load_tables) | |||
141 | acpi_status acpi_load_table(struct acpi_table_header *table_ptr) | 207 | acpi_status acpi_load_table(struct acpi_table_header *table_ptr) |
142 | { | 208 | { |
143 | acpi_status status; | 209 | acpi_status status; |
144 | struct acpi_table_desc table_info; | 210 | acpi_native_uint table_index; |
145 | struct acpi_pointer address; | ||
146 | |||
147 | ACPI_FUNCTION_TRACE(acpi_load_table); | ||
148 | |||
149 | if (!table_ptr) { | ||
150 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
151 | } | ||
152 | 211 | ||
153 | /* Copy the table to a local buffer */ | 212 | /* |
154 | 213 | * Install the new table into the local data structures | |
155 | address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; | 214 | */ |
156 | address.pointer.logical = table_ptr; | 215 | status = acpi_tb_add_table(table_ptr, &table_index); |
157 | |||
158 | status = acpi_tb_get_table_body(&address, table_ptr, &table_info); | ||
159 | if (ACPI_FAILURE(status)) { | ||
160 | return_ACPI_STATUS(status); | ||
161 | } | ||
162 | |||
163 | /* Check signature for a valid table type */ | ||
164 | |||
165 | status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL); | ||
166 | if (ACPI_FAILURE(status)) { | 216 | if (ACPI_FAILURE(status)) { |
167 | return_ACPI_STATUS(status); | 217 | return_ACPI_STATUS(status); |
168 | } | 218 | } |
219 | status = acpi_ns_load_table(table_index, acpi_gbl_root_node); | ||
220 | return_ACPI_STATUS(status); | ||
221 | } | ||
169 | 222 | ||
170 | /* Install the new table into the local data structures */ | 223 | ACPI_EXPORT_SYMBOL(acpi_load_table) |
171 | |||
172 | status = acpi_tb_install_table(&table_info); | ||
173 | if (ACPI_FAILURE(status)) { | ||
174 | if (status == AE_ALREADY_EXISTS) { | ||
175 | 224 | ||
176 | /* Table already exists, no error */ | 225 | /****************************************************************************** |
226 | * | ||
227 | * FUNCTION: acpi_get_table_header | ||
228 | * | ||
229 | * PARAMETERS: Signature - ACPI signature of needed table | ||
230 | * Instance - Which instance (for SSDTs) | ||
231 | * out_table_header - Where the pointer to the table header | ||
232 | * is returned | ||
233 | * | ||
234 | * RETURN: Status and pointer to mapped table header | ||
235 | * | ||
236 | * DESCRIPTION: Finds an ACPI table header. | ||
237 | * | ||
238 | * NOTE: Caller is responsible in unmapping the header with | ||
239 | * acpi_os_unmap_memory | ||
240 | * | ||
241 | *****************************************************************************/ | ||
242 | acpi_status | ||
243 | acpi_get_table_header(char *signature, | ||
244 | acpi_native_uint instance, | ||
245 | struct acpi_table_header **out_table_header) | ||
246 | { | ||
247 | acpi_native_uint i; | ||
248 | acpi_native_uint j; | ||
177 | 249 | ||
178 | status = AE_OK; | 250 | /* |
251 | * Walk the root table list | ||
252 | */ | ||
253 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { | ||
254 | if (!ACPI_COMPARE_NAME | ||
255 | (&(acpi_gbl_root_table_list.tables[i].signature), | ||
256 | signature)) { | ||
257 | continue; | ||
179 | } | 258 | } |
180 | 259 | ||
181 | /* Free table allocated by acpi_tb_get_table_body */ | 260 | if (++j < instance) { |
182 | 261 | continue; | |
183 | acpi_tb_delete_single_table(&table_info); | 262 | } |
184 | return_ACPI_STATUS(status); | ||
185 | } | ||
186 | |||
187 | /* Convert the table to common format if necessary */ | ||
188 | |||
189 | switch (table_info.type) { | ||
190 | case ACPI_TABLE_ID_FADT: | ||
191 | |||
192 | status = acpi_tb_convert_table_fadt(); | ||
193 | break; | ||
194 | |||
195 | case ACPI_TABLE_ID_FACS: | ||
196 | |||
197 | status = acpi_tb_build_common_facs(&table_info); | ||
198 | break; | ||
199 | |||
200 | default: | ||
201 | /* Load table into namespace if it contains executable AML */ | ||
202 | |||
203 | status = | ||
204 | acpi_ns_load_table(table_info.installed_desc, | ||
205 | acpi_gbl_root_node); | ||
206 | break; | ||
207 | } | ||
208 | 263 | ||
209 | if (ACPI_FAILURE(status)) { | 264 | *out_table_header = |
265 | acpi_tb_map(acpi_gbl_root_table_list.tables[i].address, | ||
266 | (u32) sizeof(struct acpi_table_header), | ||
267 | acpi_gbl_root_table_list.tables[i]. | ||
268 | flags & ACPI_TABLE_ORIGIN_MASK); | ||
210 | 269 | ||
211 | /* Uninstall table and free the buffer */ | 270 | if (!out_table_header) { |
271 | return (AE_NO_MEMORY); | ||
272 | } | ||
212 | 273 | ||
213 | (void)acpi_tb_uninstall_table(table_info.installed_desc); | 274 | return (AE_OK); |
214 | } | 275 | } |
215 | 276 | ||
216 | return_ACPI_STATUS(status); | 277 | return (AE_NOT_FOUND); |
217 | } | 278 | } |
218 | 279 | ||
219 | ACPI_EXPORT_SYMBOL(acpi_load_table) | 280 | ACPI_EXPORT_SYMBOL(acpi_get_table_header) |
220 | 281 | ||
221 | /******************************************************************************* | 282 | |
283 | /****************************************************************************** | ||
222 | * | 284 | * |
223 | * FUNCTION: acpi_unload_table_id | 285 | * FUNCTION: acpi_unload_table_id |
224 | * | 286 | * |
225 | * PARAMETERS: table_type - Type of table to be unloaded | 287 | * PARAMETERS: id - Owner ID of the table to be removed. |
226 | * id - Owner ID of the table to be removed. | ||
227 | * | 288 | * |
228 | * RETURN: Status | 289 | * RETURN: Status |
229 | * | 290 | * |
230 | * DESCRIPTION: This routine is used to force the unload of a table (by id) | 291 | * DESCRIPTION: This routine is used to force the unload of a table (by id) |
231 | * | 292 | * |
232 | ******************************************************************************/ | 293 | ******************************************************************************/ |
233 | acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id) | 294 | acpi_status acpi_unload_table_id(acpi_owner_id id) |
234 | { | 295 | { |
235 | struct acpi_table_desc *table_desc; | 296 | int i; |
236 | acpi_status status; | 297 | acpi_status status = AE_NOT_EXIST; |
237 | 298 | ||
238 | ACPI_FUNCTION_TRACE(acpi_unload_table); | 299 | ACPI_FUNCTION_TRACE(acpi_unload_table); |
239 | 300 | ||
240 | /* Parameter validation */ | ||
241 | if (table_type > ACPI_TABLE_ID_MAX) | ||
242 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
243 | |||
244 | /* Find table from the requested type list */ | 301 | /* Find table from the requested type list */ |
245 | table_desc = acpi_gbl_table_lists[table_type].next; | 302 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { |
246 | while (table_desc && table_desc->owner_id != id) | 303 | if (id != acpi_gbl_root_table_list.tables[i].owner_id) { |
247 | table_desc = table_desc->next; | 304 | continue; |
248 | 305 | } | |
249 | if (!table_desc) | 306 | /* |
250 | return_ACPI_STATUS(AE_NOT_EXIST); | 307 | * Delete all namespace objects owned by this table. Note that these |
251 | 308 | * objects can appear anywhere in the namespace by virtue of the AML | |
252 | /* | 309 | * "Scope" operator. Thus, we need to track ownership by an ID, not |
253 | * Delete all namespace objects owned by this table. Note that these | 310 | * simply a position within the hierarchy |
254 | * objects can appear anywhere in the namespace by virtue of the AML | 311 | */ |
255 | * "Scope" operator. Thus, we need to track ownership by an ID, not | 312 | acpi_tb_delete_namespace_by_owner(i); |
256 | * simply a position within the hierarchy | 313 | acpi_tb_release_owner_id(i); |
257 | */ | 314 | acpi_tb_set_table_loaded_flag(i, FALSE); |
258 | acpi_ns_delete_namespace_by_owner(table_desc->owner_id); | 315 | } |
259 | 316 | return_ACPI_STATUS(status); | |
260 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
261 | if (ACPI_FAILURE(status)) | ||
262 | return_ACPI_STATUS(status); | ||
263 | |||
264 | (void)acpi_tb_uninstall_table(table_desc); | ||
265 | |||
266 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
267 | |||
268 | return_ACPI_STATUS(AE_OK); | ||
269 | } | 317 | } |
270 | 318 | ||
271 | ACPI_EXPORT_SYMBOL(acpi_unload_table_id) | 319 | ACPI_EXPORT_SYMBOL(acpi_unload_table_id) |
272 | 320 | ||
273 | #ifdef ACPI_FUTURE_USAGE | ||
274 | /******************************************************************************* | 321 | /******************************************************************************* |
275 | * | 322 | * |
276 | * FUNCTION: acpi_unload_table | 323 | * FUNCTION: acpi_get_table |
277 | * | 324 | * |
278 | * PARAMETERS: table_type - Type of table to be unloaded | 325 | * PARAMETERS: Signature - ACPI signature of needed table |
326 | * Instance - Which instance (for SSDTs) | ||
327 | * out_table - Where the pointer to the table is returned | ||
279 | * | 328 | * |
280 | * RETURN: Status | 329 | * RETURN: Status and pointer to table |
281 | * | 330 | * |
282 | * DESCRIPTION: This routine is used to force the unload of a table | 331 | * DESCRIPTION: Finds and verifies an ACPI table. |
283 | * | 332 | * |
284 | ******************************************************************************/ | 333 | *****************************************************************************/ |
285 | acpi_status acpi_unload_table(acpi_table_type table_type) | 334 | acpi_status |
335 | acpi_get_table(char *signature, | ||
336 | acpi_native_uint instance, struct acpi_table_header ** out_table) | ||
286 | { | 337 | { |
287 | struct acpi_table_desc *table_desc; | 338 | acpi_native_uint i; |
288 | 339 | acpi_native_uint j; | |
289 | ACPI_FUNCTION_TRACE(acpi_unload_table); | 340 | acpi_status status; |
290 | |||
291 | /* Parameter validation */ | ||
292 | 341 | ||
293 | if (table_type > ACPI_TABLE_ID_MAX) { | 342 | /* |
294 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 343 | * Walk the root table list |
295 | } | 344 | */ |
345 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { | ||
346 | if (!ACPI_COMPARE_NAME | ||
347 | (&(acpi_gbl_root_table_list.tables[i].signature), | ||
348 | signature)) { | ||
349 | continue; | ||
350 | } | ||
296 | 351 | ||
297 | /* Find all tables of the requested type */ | 352 | if (++j < instance) { |
353 | continue; | ||
354 | } | ||
298 | 355 | ||
299 | table_desc = acpi_gbl_table_lists[table_type].next; | 356 | status = |
300 | if (!table_desc) { | 357 | acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); |
301 | return_ACPI_STATUS(AE_NOT_EXIST); | 358 | if (ACPI_SUCCESS(status)) { |
302 | } | 359 | *out_table = acpi_gbl_root_table_list.tables[i].pointer; |
360 | } | ||
303 | 361 | ||
304 | while (table_desc) { | 362 | return (status); |
305 | /* | ||
306 | * Delete all namespace objects owned by this table. Note that these | ||
307 | * objects can appear anywhere in the namespace by virtue of the AML | ||
308 | * "Scope" operator. Thus, we need to track ownership by an ID, not | ||
309 | * simply a position within the hierarchy | ||
310 | */ | ||
311 | acpi_ns_delete_namespace_by_owner(table_desc->owner_id); | ||
312 | table_desc = table_desc->next; | ||
313 | } | 363 | } |
314 | 364 | ||
315 | /* Delete (or unmap) all tables of this type */ | 365 | return (AE_NOT_FOUND); |
316 | |||
317 | acpi_tb_delete_tables_by_type(table_type); | ||
318 | return_ACPI_STATUS(AE_OK); | ||
319 | } | 366 | } |
320 | 367 | ||
321 | ACPI_EXPORT_SYMBOL(acpi_unload_table) | 368 | ACPI_EXPORT_SYMBOL(acpi_get_table) |
322 | 369 | ||
323 | /******************************************************************************* | 370 | /******************************************************************************* |
324 | * | 371 | * |
325 | * FUNCTION: acpi_get_table_header | 372 | * FUNCTION: acpi_get_table_by_index |
326 | * | 373 | * |
327 | * PARAMETERS: table_type - one of the defined table types | 374 | * PARAMETERS: table_index - Table index |
328 | * Instance - the non zero instance of the table, allows | 375 | * Table - Where the pointer to the table is returned |
329 | * support for multiple tables of the same type | ||
330 | * see acpi_gbl_acpi_table_flag | ||
331 | * out_table_header - pointer to the struct acpi_table_header if successful | ||
332 | * | 376 | * |
333 | * DESCRIPTION: This function is called to get an ACPI table header. The caller | 377 | * RETURN: Status and pointer to the table |
334 | * supplies an pointer to a data area sufficient to contain an ACPI | ||
335 | * struct acpi_table_header structure. | ||
336 | * | 378 | * |
337 | * The header contains a length field that can be used to determine | 379 | * DESCRIPTION: Obtain a table by an index into the global table list. |
338 | * the size of the buffer needed to contain the entire table. This | ||
339 | * function is not valid for the RSD PTR table since it does not | ||
340 | * have a standard header and is fixed length. | ||
341 | * | 380 | * |
342 | ******************************************************************************/ | 381 | ******************************************************************************/ |
343 | acpi_status | 382 | acpi_status |
344 | acpi_get_table_header(acpi_table_type table_type, | 383 | acpi_get_table_by_index(acpi_native_uint table_index, |
345 | u32 instance, struct acpi_table_header *out_table_header) | 384 | struct acpi_table_header ** table) |
346 | { | 385 | { |
347 | struct acpi_table_header *tbl_ptr; | ||
348 | acpi_status status; | 386 | acpi_status status; |
349 | 387 | ||
350 | ACPI_FUNCTION_TRACE(acpi_get_table_header); | 388 | ACPI_FUNCTION_TRACE(acpi_get_table_by_index); |
351 | 389 | ||
352 | if ((instance == 0) || | 390 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
353 | (table_type == ACPI_TABLE_ID_RSDP) || (!out_table_header)) { | ||
354 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
355 | } | ||
356 | 391 | ||
357 | /* Check the table type and instance */ | 392 | /* Validate index */ |
358 | 393 | ||
359 | if ((table_type > ACPI_TABLE_ID_MAX) || | 394 | if (table_index >= acpi_gbl_root_table_list.count) { |
360 | (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && | 395 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
361 | instance > 1)) { | ||
362 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 396 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
363 | } | 397 | } |
364 | 398 | ||
365 | /* Get a pointer to the entire table */ | 399 | if (!acpi_gbl_root_table_list.tables[table_index].pointer) { |
366 | 400 | ||
367 | status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); | 401 | /* Table is not mapped, map it */ |
368 | if (ACPI_FAILURE(status)) { | ||
369 | return_ACPI_STATUS(status); | ||
370 | } | ||
371 | 402 | ||
372 | /* The function will return a NULL pointer if the table is not loaded */ | 403 | status = |
373 | 404 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | |
374 | if (tbl_ptr == NULL) { | 405 | tables[table_index]); |
375 | return_ACPI_STATUS(AE_NOT_EXIST); | 406 | if (ACPI_FAILURE(status)) { |
407 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
408 | return_ACPI_STATUS(status); | ||
409 | } | ||
376 | } | 410 | } |
377 | 411 | ||
378 | /* Copy the header to the caller's buffer */ | 412 | *table = acpi_gbl_root_table_list.tables[table_index].pointer; |
379 | 413 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | |
380 | ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header), | 414 | return_ACPI_STATUS(AE_OK); |
381 | ACPI_CAST_PTR(void, tbl_ptr), | ||
382 | sizeof(struct acpi_table_header)); | ||
383 | |||
384 | return_ACPI_STATUS(status); | ||
385 | } | 415 | } |
386 | 416 | ||
387 | ACPI_EXPORT_SYMBOL(acpi_get_table_header) | 417 | ACPI_EXPORT_SYMBOL(acpi_get_table_by_index) |
388 | #endif /* ACPI_FUTURE_USAGE */ | ||
389 | 418 | ||
390 | /******************************************************************************* | 419 | /******************************************************************************* |
391 | * | 420 | * |
392 | * FUNCTION: acpi_get_table | 421 | * FUNCTION: acpi_tb_load_namespace |
393 | * | 422 | * |
394 | * PARAMETERS: table_type - one of the defined table types | 423 | * PARAMETERS: None |
395 | * Instance - the non zero instance of the table, allows | ||
396 | * support for multiple tables of the same type | ||
397 | * see acpi_gbl_acpi_table_flag | ||
398 | * ret_buffer - pointer to a structure containing a buffer to | ||
399 | * receive the table | ||
400 | * | 424 | * |
401 | * RETURN: Status | 425 | * RETURN: Status |
402 | * | 426 | * |
403 | * DESCRIPTION: This function is called to get an ACPI table. The caller | 427 | * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in |
404 | * supplies an out_buffer large enough to contain the entire ACPI | 428 | * the RSDT/XSDT. |
405 | * table. The caller should call the acpi_get_table_header function | ||
406 | * first to determine the buffer size needed. Upon completion | ||
407 | * the out_buffer->Length field will indicate the number of bytes | ||
408 | * copied into the out_buffer->buf_ptr buffer. This table will be | ||
409 | * a complete table including the header. | ||
410 | * | 429 | * |
411 | ******************************************************************************/ | 430 | ******************************************************************************/ |
412 | acpi_status | 431 | static acpi_status acpi_tb_load_namespace(void) |
413 | acpi_get_table(acpi_table_type table_type, | ||
414 | u32 instance, struct acpi_buffer *ret_buffer) | ||
415 | { | 432 | { |
416 | struct acpi_table_header *tbl_ptr; | ||
417 | acpi_status status; | 433 | acpi_status status; |
418 | acpi_size table_length; | 434 | struct acpi_table_header *table; |
435 | acpi_native_uint i; | ||
419 | 436 | ||
420 | ACPI_FUNCTION_TRACE(acpi_get_table); | 437 | ACPI_FUNCTION_TRACE(tb_load_namespace); |
421 | 438 | ||
422 | /* Parameter validation */ | 439 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
423 | 440 | ||
424 | if (instance == 0) { | 441 | /* |
425 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 442 | * Load the namespace. The DSDT is required, but any SSDT and PSDT tables |
443 | * are optional. | ||
444 | */ | ||
445 | if (!acpi_gbl_root_table_list.count || | ||
446 | !ACPI_COMPARE_NAME(& | ||
447 | (acpi_gbl_root_table_list. | ||
448 | tables[ACPI_TABLE_INDEX_DSDT].signature), | ||
449 | ACPI_SIG_DSDT) | ||
450 | || | ||
451 | ACPI_FAILURE(acpi_tb_verify_table | ||
452 | (&acpi_gbl_root_table_list. | ||
453 | tables[ACPI_TABLE_INDEX_DSDT]))) { | ||
454 | status = AE_NO_ACPI_TABLES; | ||
455 | goto unlock_and_exit; | ||
426 | } | 456 | } |
427 | 457 | ||
428 | status = acpi_ut_validate_buffer(ret_buffer); | 458 | /* |
429 | if (ACPI_FAILURE(status)) { | 459 | * Find DSDT table |
430 | return_ACPI_STATUS(status); | 460 | */ |
461 | status = | ||
462 | acpi_os_table_override(acpi_gbl_root_table_list. | ||
463 | tables[ACPI_TABLE_INDEX_DSDT].pointer, | ||
464 | &table); | ||
465 | if (ACPI_SUCCESS(status) && table) { | ||
466 | /* | ||
467 | * DSDT table has been found | ||
468 | */ | ||
469 | acpi_tb_delete_table(ACPI_TABLE_INDEX_DSDT); | ||
470 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer = | ||
471 | table; | ||
472 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length = | ||
473 | table->length; | ||
474 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = | ||
475 | ACPI_TABLE_ORIGIN_UNKNOWN; | ||
476 | |||
477 | ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS")); | ||
478 | acpi_tb_print_table_header(0, table); | ||
431 | } | 479 | } |
432 | 480 | ||
433 | /* Check the table type and instance */ | 481 | status = |
482 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | ||
483 | tables[ACPI_TABLE_INDEX_DSDT]); | ||
484 | if (ACPI_FAILURE(status)) { | ||
485 | |||
486 | /* A valid DSDT is required */ | ||
434 | 487 | ||
435 | if ((table_type > ACPI_TABLE_ID_MAX) || | 488 | status = AE_NO_ACPI_TABLES; |
436 | (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) && | 489 | goto unlock_and_exit; |
437 | instance > 1)) { | ||
438 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
439 | } | 490 | } |
440 | 491 | ||
441 | /* Get a pointer to the entire table */ | 492 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
442 | 493 | ||
443 | status = acpi_tb_get_table_ptr(table_type, instance, &tbl_ptr); | 494 | /* |
495 | * Load and parse tables. | ||
496 | */ | ||
497 | status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); | ||
444 | if (ACPI_FAILURE(status)) { | 498 | if (ACPI_FAILURE(status)) { |
445 | return_ACPI_STATUS(status); | 499 | return_ACPI_STATUS(status); |
446 | } | 500 | } |
447 | 501 | ||
448 | /* | 502 | /* |
449 | * acpi_tb_get_table_ptr will return a NULL pointer if the | 503 | * Load any SSDT or PSDT tables. Note: Loop leaves tables locked |
450 | * table is not loaded. | ||
451 | */ | 504 | */ |
452 | if (tbl_ptr == NULL) { | 505 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
453 | return_ACPI_STATUS(AE_NOT_EXIST); | 506 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { |
507 | if ((!ACPI_COMPARE_NAME | ||
508 | (&(acpi_gbl_root_table_list.tables[i].signature), | ||
509 | ACPI_SIG_SSDT) | ||
510 | && | ||
511 | !ACPI_COMPARE_NAME(& | ||
512 | (acpi_gbl_root_table_list.tables[i]. | ||
513 | signature), ACPI_SIG_PSDT)) | ||
514 | || | ||
515 | ACPI_FAILURE(acpi_tb_verify_table | ||
516 | (&acpi_gbl_root_table_list.tables[i]))) { | ||
517 | continue; | ||
518 | } | ||
519 | |||
520 | /* Ignore errors while loading tables, get as many as possible */ | ||
521 | |||
522 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
523 | (void)acpi_ns_load_table(i, acpi_gbl_root_node); | ||
524 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
454 | } | 525 | } |
455 | 526 | ||
456 | /* Get the table length */ | 527 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); |
457 | 528 | ||
458 | if (table_type == ACPI_TABLE_ID_RSDP) { | 529 | unlock_and_exit: |
530 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | ||
531 | return_ACPI_STATUS(status); | ||
532 | } | ||
459 | 533 | ||
460 | /* RSD PTR is the only "table" without a header */ | 534 | /******************************************************************************* |
535 | * | ||
536 | * FUNCTION: acpi_load_tables | ||
537 | * | ||
538 | * PARAMETERS: None | ||
539 | * | ||
540 | * RETURN: Status | ||
541 | * | ||
542 | * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT | ||
543 | * | ||
544 | ******************************************************************************/ | ||
461 | 545 | ||
462 | table_length = sizeof(struct rsdp_descriptor); | 546 | acpi_status acpi_load_tables(void) |
463 | } else { | 547 | { |
464 | table_length = (acpi_size) tbl_ptr->length; | 548 | acpi_status status; |
465 | } | ||
466 | 549 | ||
467 | /* Validate/Allocate/Clear caller buffer */ | 550 | ACPI_FUNCTION_TRACE(acpi_load_tables); |
468 | 551 | ||
469 | status = acpi_ut_initialize_buffer(ret_buffer, table_length); | 552 | /* |
553 | * Load the namespace from the tables | ||
554 | */ | ||
555 | status = acpi_tb_load_namespace(); | ||
470 | if (ACPI_FAILURE(status)) { | 556 | if (ACPI_FAILURE(status)) { |
471 | return_ACPI_STATUS(status); | 557 | ACPI_EXCEPTION((AE_INFO, status, |
558 | "While loading namespace from ACPI tables")); | ||
472 | } | 559 | } |
473 | 560 | ||
474 | /* Copy the table to the buffer */ | 561 | return_ACPI_STATUS(status); |
475 | |||
476 | ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer), | ||
477 | ACPI_CAST_PTR(void, tbl_ptr), table_length); | ||
478 | |||
479 | return_ACPI_STATUS(AE_OK); | ||
480 | } | 562 | } |
481 | 563 | ||
482 | ACPI_EXPORT_SYMBOL(acpi_get_table) | 564 | ACPI_EXPORT_SYMBOL(acpi_load_tables) |
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index da2648bbdbc0..5c6e88251c1a 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c | |||
@@ -48,16 +48,15 @@ | |||
48 | ACPI_MODULE_NAME("tbxfroot") | 48 | ACPI_MODULE_NAME("tbxfroot") |
49 | 49 | ||
50 | /* Local prototypes */ | 50 | /* Local prototypes */ |
51 | static acpi_status | ||
52 | acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags); | ||
53 | |||
54 | static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); | 51 | static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); |
55 | 52 | ||
53 | static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); | ||
54 | |||
56 | /******************************************************************************* | 55 | /******************************************************************************* |
57 | * | 56 | * |
58 | * FUNCTION: acpi_tb_validate_rsdp | 57 | * FUNCTION: acpi_tb_validate_rsdp |
59 | * | 58 | * |
60 | * PARAMETERS: Rsdp - Pointer to unvalidated RSDP | 59 | * PARAMETERS: Rsdp - Pointer to unvalidated RSDP |
61 | * | 60 | * |
62 | * RETURN: Status | 61 | * RETURN: Status |
63 | * | 62 | * |
@@ -65,14 +64,18 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length); | |||
65 | * | 64 | * |
66 | ******************************************************************************/ | 65 | ******************************************************************************/ |
67 | 66 | ||
68 | acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) | 67 | static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) |
69 | { | 68 | { |
70 | ACPI_FUNCTION_ENTRY(); | 69 | ACPI_FUNCTION_ENTRY(); |
71 | 70 | ||
72 | /* | 71 | /* |
73 | * The signature and checksum must both be correct | 72 | * The signature and checksum must both be correct |
73 | * | ||
74 | * Note: Sometimes there exists more than one RSDP in memory; the valid | ||
75 | * RSDP has a valid checksum, all others have an invalid checksum. | ||
74 | */ | 76 | */ |
75 | if (ACPI_STRNCMP((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) { | 77 | if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1) |
78 | != 0) { | ||
76 | 79 | ||
77 | /* Nope, BAD Signature */ | 80 | /* Nope, BAD Signature */ |
78 | 81 | ||
@@ -81,330 +84,141 @@ acpi_status acpi_tb_validate_rsdp(struct rsdp_descriptor *rsdp) | |||
81 | 84 | ||
82 | /* Check the standard checksum */ | 85 | /* Check the standard checksum */ |
83 | 86 | ||
84 | if (acpi_tb_sum_table(rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { | 87 | if (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { |
85 | return (AE_BAD_CHECKSUM); | 88 | return (AE_BAD_CHECKSUM); |
86 | } | 89 | } |
87 | 90 | ||
88 | /* Check extended checksum if table version >= 2 */ | 91 | /* Check extended checksum if table version >= 2 */ |
89 | 92 | ||
90 | if ((rsdp->revision >= 2) && | 93 | if ((rsdp->revision >= 2) && |
91 | (acpi_tb_sum_table(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { | 94 | (acpi_tb_checksum((u8 *) rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { |
92 | return (AE_BAD_CHECKSUM); | 95 | return (AE_BAD_CHECKSUM); |
93 | } | 96 | } |
94 | 97 | ||
95 | return (AE_OK); | 98 | return (AE_OK); |
96 | } | 99 | } |
97 | 100 | ||
101 | #if ACPI_MACHINE_WIDTH != 16 | ||
102 | |||
98 | /******************************************************************************* | 103 | /******************************************************************************* |
99 | * | 104 | * |
100 | * FUNCTION: acpi_tb_find_table | 105 | * FUNCTION: acpi_tb_find_rsdp |
101 | * | ||
102 | * PARAMETERS: Signature - String with ACPI table signature | ||
103 | * oem_id - String with the table OEM ID | ||
104 | * oem_table_id - String with the OEM Table ID | ||
105 | * table_ptr - Where the table pointer is returned | ||
106 | * | ||
107 | * RETURN: Status | ||
108 | * | 106 | * |
109 | * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the | 107 | * PARAMETERS: table_address - Where the table pointer is returned |
110 | * Signature, OEM ID and OEM Table ID. | ||
111 | * | 108 | * |
112 | ******************************************************************************/ | 109 | * RETURN: Status, RSDP physical address |
113 | |||
114 | acpi_status | ||
115 | acpi_tb_find_table(char *signature, | ||
116 | char *oem_id, | ||
117 | char *oem_table_id, struct acpi_table_header ** table_ptr) | ||
118 | { | ||
119 | acpi_status status; | ||
120 | struct acpi_table_header *table; | ||
121 | |||
122 | ACPI_FUNCTION_TRACE(tb_find_table); | ||
123 | |||
124 | /* Validate string lengths */ | ||
125 | |||
126 | if ((ACPI_STRLEN(signature) > ACPI_NAME_SIZE) || | ||
127 | (ACPI_STRLEN(oem_id) > sizeof(table->oem_id)) || | ||
128 | (ACPI_STRLEN(oem_table_id) > sizeof(table->oem_table_id))) { | ||
129 | return_ACPI_STATUS(AE_AML_STRING_LIMIT); | ||
130 | } | ||
131 | |||
132 | if (ACPI_COMPARE_NAME(signature, DSDT_SIG)) { | ||
133 | /* | ||
134 | * The DSDT pointer is contained in the FADT, not the RSDT. | ||
135 | * This code should suffice, because the only code that would perform | ||
136 | * a "find" on the DSDT is the data_table_region() AML opcode -- in | ||
137 | * which case, the DSDT is guaranteed to be already loaded. | ||
138 | * If this becomes insufficient, the FADT will have to be found first. | ||
139 | */ | ||
140 | if (!acpi_gbl_DSDT) { | ||
141 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
142 | } | ||
143 | table = acpi_gbl_DSDT; | ||
144 | } else { | ||
145 | /* Find the table */ | ||
146 | |||
147 | status = acpi_get_firmware_table(signature, 1, | ||
148 | ACPI_LOGICAL_ADDRESSING, | ||
149 | &table); | ||
150 | if (ACPI_FAILURE(status)) { | ||
151 | return_ACPI_STATUS(status); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /* Check oem_id and oem_table_id */ | ||
156 | |||
157 | if ((oem_id[0] && | ||
158 | ACPI_STRNCMP(oem_id, table->oem_id, | ||
159 | sizeof(table->oem_id))) || | ||
160 | (oem_table_id[0] && | ||
161 | ACPI_STRNCMP(oem_table_id, table->oem_table_id, | ||
162 | sizeof(table->oem_table_id)))) { | ||
163 | return_ACPI_STATUS(AE_AML_NAME_NOT_FOUND); | ||
164 | } | ||
165 | |||
166 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Found table [%4.4s]\n", | ||
167 | table->signature)); | ||
168 | |||
169 | *table_ptr = table; | ||
170 | return_ACPI_STATUS(AE_OK); | ||
171 | } | ||
172 | |||
173 | /******************************************************************************* | ||
174 | * | ||
175 | * FUNCTION: acpi_get_firmware_table | ||
176 | * | 110 | * |
177 | * PARAMETERS: Signature - Any ACPI table signature | 111 | * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor |
178 | * Instance - the non zero instance of the table, allows | 112 | * pointer structure. If it is found, set *RSDP to point to it. |
179 | * support for multiple tables of the same type | ||
180 | * Flags - Physical/Virtual support | ||
181 | * table_pointer - Where a buffer containing the table is | ||
182 | * returned | ||
183 | * | 113 | * |
184 | * RETURN: Status | 114 | * NOTE1: The RSDP must be either in the first 1_k of the Extended |
115 | * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) | ||
116 | * Only a 32-bit physical address is necessary. | ||
185 | * | 117 | * |
186 | * DESCRIPTION: This function is called to get an ACPI table. A buffer is | 118 | * NOTE2: This function is always available, regardless of the |
187 | * allocated for the table and returned in table_pointer. | 119 | * initialization state of the rest of ACPI. |
188 | * This table will be a complete table including the header. | ||
189 | * | 120 | * |
190 | ******************************************************************************/ | 121 | ******************************************************************************/ |
191 | 122 | ||
192 | acpi_status | 123 | acpi_status acpi_find_root_pointer(acpi_native_uint * table_address) |
193 | acpi_get_firmware_table(acpi_string signature, | ||
194 | u32 instance, | ||
195 | u32 flags, struct acpi_table_header **table_pointer) | ||
196 | { | 124 | { |
197 | acpi_status status; | 125 | u8 *table_ptr; |
198 | struct acpi_pointer address; | 126 | u8 *mem_rover; |
199 | struct acpi_table_header *header = NULL; | 127 | u32 physical_address; |
200 | struct acpi_table_desc *table_info = NULL; | ||
201 | struct acpi_table_desc *rsdt_info; | ||
202 | u32 table_count; | ||
203 | u32 i; | ||
204 | u32 j; | ||
205 | |||
206 | ACPI_FUNCTION_TRACE(acpi_get_firmware_table); | ||
207 | |||
208 | /* | ||
209 | * Ensure that at least the table manager is initialized. We don't | ||
210 | * require that the entire ACPI subsystem is up for this interface. | ||
211 | * If we have a buffer, we must have a length too | ||
212 | */ | ||
213 | if ((instance == 0) || (!signature) || (!table_pointer)) { | ||
214 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
215 | } | ||
216 | |||
217 | /* Ensure that we have a RSDP */ | ||
218 | |||
219 | if (!acpi_gbl_RSDP) { | ||
220 | |||
221 | /* Get the RSDP */ | ||
222 | |||
223 | status = acpi_os_get_root_pointer(flags, &address); | ||
224 | if (ACPI_FAILURE(status)) { | ||
225 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "RSDP not found\n")); | ||
226 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
227 | } | ||
228 | |||
229 | /* Map and validate the RSDP */ | ||
230 | |||
231 | if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { | ||
232 | status = acpi_os_map_memory(address.pointer.physical, | ||
233 | sizeof(struct | ||
234 | rsdp_descriptor), | ||
235 | (void *)&acpi_gbl_RSDP); | ||
236 | if (ACPI_FAILURE(status)) { | ||
237 | return_ACPI_STATUS(status); | ||
238 | } | ||
239 | } else { | ||
240 | acpi_gbl_RSDP = address.pointer.logical; | ||
241 | } | ||
242 | |||
243 | /* The RDSP signature and checksum must both be correct */ | ||
244 | |||
245 | status = acpi_tb_validate_rsdp(acpi_gbl_RSDP); | ||
246 | if (ACPI_FAILURE(status)) { | ||
247 | return_ACPI_STATUS(status); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | /* Get the RSDT address via the RSDP */ | ||
252 | |||
253 | acpi_tb_get_rsdt_address(&address); | ||
254 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
255 | "RSDP located at %p, RSDT physical=%8.8X%8.8X\n", | ||
256 | acpi_gbl_RSDP, | ||
257 | ACPI_FORMAT_UINT64(address.pointer.value))); | ||
258 | 128 | ||
259 | /* Insert processor_mode flags */ | 129 | ACPI_FUNCTION_TRACE(acpi_find_root_pointer); |
260 | 130 | ||
261 | address.pointer_type |= flags; | 131 | /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ |
262 | 132 | ||
263 | /* Get and validate the RSDT */ | 133 | table_ptr = acpi_os_map_memory((acpi_physical_address) |
134 | ACPI_EBDA_PTR_LOCATION, | ||
135 | ACPI_EBDA_PTR_LENGTH); | ||
136 | if (!table_ptr) { | ||
137 | ACPI_ERROR((AE_INFO, | ||
138 | "Could not map memory at %8.8X for length %X", | ||
139 | ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); | ||
264 | 140 | ||
265 | rsdt_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); | ||
266 | if (!rsdt_info) { | ||
267 | return_ACPI_STATUS(AE_NO_MEMORY); | 141 | return_ACPI_STATUS(AE_NO_MEMORY); |
268 | } | 142 | } |
269 | 143 | ||
270 | status = acpi_tb_get_table(&address, rsdt_info); | 144 | ACPI_MOVE_16_TO_32(&physical_address, table_ptr); |
271 | if (ACPI_FAILURE(status)) { | ||
272 | goto cleanup; | ||
273 | } | ||
274 | |||
275 | status = acpi_tb_validate_rsdt(rsdt_info->pointer); | ||
276 | if (ACPI_FAILURE(status)) { | ||
277 | goto cleanup; | ||
278 | } | ||
279 | |||
280 | /* Allocate a scratch table header and table descriptor */ | ||
281 | |||
282 | header = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); | ||
283 | if (!header) { | ||
284 | status = AE_NO_MEMORY; | ||
285 | goto cleanup; | ||
286 | } | ||
287 | 145 | ||
288 | table_info = ACPI_ALLOCATE(sizeof(struct acpi_table_desc)); | 146 | /* Convert segment part to physical address */ |
289 | if (!table_info) { | ||
290 | status = AE_NO_MEMORY; | ||
291 | goto cleanup; | ||
292 | } | ||
293 | 147 | ||
294 | /* Get the number of table pointers within the RSDT */ | 148 | physical_address <<= 4; |
149 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); | ||
295 | 150 | ||
296 | table_count = | 151 | /* EBDA present? */ |
297 | acpi_tb_get_table_count(acpi_gbl_RSDP, rsdt_info->pointer); | ||
298 | address.pointer_type = acpi_gbl_table_flags | flags; | ||
299 | 152 | ||
300 | /* | 153 | if (physical_address > 0x400) { |
301 | * Search the RSDT/XSDT for the correct instance of the | ||
302 | * requested table | ||
303 | */ | ||
304 | for (i = 0, j = 0; i < table_count; i++) { | ||
305 | /* | 154 | /* |
306 | * Get the next table pointer, handle RSDT vs. XSDT | 155 | * 1b) Search EBDA paragraphs (EBDA is required to be a |
307 | * RSDT pointers are 32 bits, XSDT pointers are 64 bits | 156 | * minimum of 1_k length) |
308 | */ | 157 | */ |
309 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | 158 | table_ptr = acpi_os_map_memory((acpi_native_uint) |
310 | address.pointer.value = | 159 | physical_address, |
311 | (ACPI_CAST_PTR | 160 | ACPI_EBDA_WINDOW_SIZE); |
312 | (struct rsdt_descriptor, | 161 | if (!table_ptr) { |
313 | rsdt_info->pointer))->table_offset_entry[i]; | 162 | ACPI_ERROR((AE_INFO, |
314 | } else { | 163 | "Could not map memory at %8.8X for length %X", |
315 | address.pointer.value = | 164 | physical_address, ACPI_EBDA_WINDOW_SIZE)); |
316 | (ACPI_CAST_PTR | ||
317 | (struct xsdt_descriptor, | ||
318 | rsdt_info->pointer))->table_offset_entry[i]; | ||
319 | } | ||
320 | |||
321 | /* Get the table header */ | ||
322 | 165 | ||
323 | status = acpi_tb_get_table_header(&address, header); | 166 | return_ACPI_STATUS(AE_NO_MEMORY); |
324 | if (ACPI_FAILURE(status)) { | ||
325 | goto cleanup; | ||
326 | } | 167 | } |
327 | 168 | ||
328 | /* Compare table signatures and table instance */ | 169 | mem_rover = |
329 | 170 | acpi_tb_scan_memory_for_rsdp(table_ptr, | |
330 | if (ACPI_COMPARE_NAME(header->signature, signature)) { | 171 | ACPI_EBDA_WINDOW_SIZE); |
331 | 172 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); | |
332 | /* An instance of the table was found */ | ||
333 | 173 | ||
334 | j++; | 174 | if (mem_rover) { |
335 | if (j >= instance) { | ||
336 | 175 | ||
337 | /* Found the correct instance, get the entire table */ | 176 | /* Return the physical address */ |
338 | 177 | ||
339 | status = | 178 | physical_address += |
340 | acpi_tb_get_table_body(&address, header, | 179 | (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); |
341 | table_info); | ||
342 | if (ACPI_FAILURE(status)) { | ||
343 | goto cleanup; | ||
344 | } | ||
345 | 180 | ||
346 | *table_pointer = table_info->pointer; | 181 | *table_address = physical_address; |
347 | goto cleanup; | 182 | return_ACPI_STATUS(AE_OK); |
348 | } | ||
349 | } | 183 | } |
350 | } | 184 | } |
351 | 185 | ||
352 | /* Did not find the table */ | 186 | /* |
187 | * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh | ||
188 | */ | ||
189 | table_ptr = acpi_os_map_memory((acpi_physical_address) | ||
190 | ACPI_HI_RSDP_WINDOW_BASE, | ||
191 | ACPI_HI_RSDP_WINDOW_SIZE); | ||
353 | 192 | ||
354 | status = AE_NOT_EXIST; | 193 | if (!table_ptr) { |
194 | ACPI_ERROR((AE_INFO, | ||
195 | "Could not map memory at %8.8X for length %X", | ||
196 | ACPI_HI_RSDP_WINDOW_BASE, | ||
197 | ACPI_HI_RSDP_WINDOW_SIZE)); | ||
355 | 198 | ||
356 | cleanup: | 199 | return_ACPI_STATUS(AE_NO_MEMORY); |
357 | if (rsdt_info->pointer) { | ||
358 | acpi_os_unmap_memory(rsdt_info->pointer, | ||
359 | (acpi_size) rsdt_info->pointer->length); | ||
360 | } | 200 | } |
361 | ACPI_FREE(rsdt_info); | ||
362 | 201 | ||
363 | if (header) { | 202 | mem_rover = |
364 | ACPI_FREE(header); | 203 | acpi_tb_scan_memory_for_rsdp(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); |
365 | } | 204 | acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); |
366 | if (table_info) { | ||
367 | ACPI_FREE(table_info); | ||
368 | } | ||
369 | return_ACPI_STATUS(status); | ||
370 | } | ||
371 | 205 | ||
372 | ACPI_EXPORT_SYMBOL(acpi_get_firmware_table) | 206 | if (mem_rover) { |
373 | 207 | ||
374 | /* TBD: Move to a new file */ | 208 | /* Return the physical address */ |
375 | #if ACPI_MACHINE_WIDTH != 16 | ||
376 | /******************************************************************************* | ||
377 | * | ||
378 | * FUNCTION: acpi_find_root_pointer | ||
379 | * | ||
380 | * PARAMETERS: Flags - Logical/Physical addressing | ||
381 | * rsdp_address - Where to place the RSDP address | ||
382 | * | ||
383 | * RETURN: Status, Physical address of the RSDP | ||
384 | * | ||
385 | * DESCRIPTION: Find the RSDP | ||
386 | * | ||
387 | ******************************************************************************/ | ||
388 | acpi_status acpi_find_root_pointer(u32 flags, struct acpi_pointer *rsdp_address) | ||
389 | { | ||
390 | struct acpi_table_desc table_info; | ||
391 | acpi_status status; | ||
392 | |||
393 | ACPI_FUNCTION_TRACE(acpi_find_root_pointer); | ||
394 | 209 | ||
395 | /* Get the RSDP */ | 210 | physical_address = (u32) |
211 | (ACPI_HI_RSDP_WINDOW_BASE + | ||
212 | ACPI_PTR_DIFF(mem_rover, table_ptr)); | ||
396 | 213 | ||
397 | status = acpi_tb_find_rsdp(&table_info, flags); | 214 | *table_address = physical_address; |
398 | if (ACPI_FAILURE(status)) { | 215 | return_ACPI_STATUS(AE_OK); |
399 | ACPI_EXCEPTION((AE_INFO, status, | ||
400 | "RSDP structure not found - Flags=%X", flags)); | ||
401 | |||
402 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
403 | } | 216 | } |
404 | 217 | ||
405 | rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER; | 218 | /* A valid RSDP was not found */ |
406 | rsdp_address->pointer.physical = table_info.physical_address; | 219 | |
407 | return_ACPI_STATUS(AE_OK); | 220 | ACPI_ERROR((AE_INFO, "A valid RSDP was not found")); |
221 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
408 | } | 222 | } |
409 | 223 | ||
410 | ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) | 224 | ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) |
@@ -440,7 +254,7 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) | |||
440 | 254 | ||
441 | status = | 255 | status = |
442 | acpi_tb_validate_rsdp(ACPI_CAST_PTR | 256 | acpi_tb_validate_rsdp(ACPI_CAST_PTR |
443 | (struct rsdp_descriptor, mem_rover)); | 257 | (struct acpi_table_rsdp, mem_rover)); |
444 | if (ACPI_SUCCESS(status)) { | 258 | if (ACPI_SUCCESS(status)) { |
445 | 259 | ||
446 | /* Sig and checksum valid, we have found a real RSDP */ | 260 | /* Sig and checksum valid, we have found a real RSDP */ |
@@ -462,188 +276,4 @@ static u8 *acpi_tb_scan_memory_for_rsdp(u8 * start_address, u32 length) | |||
462 | return_PTR(NULL); | 276 | return_PTR(NULL); |
463 | } | 277 | } |
464 | 278 | ||
465 | /******************************************************************************* | ||
466 | * | ||
467 | * FUNCTION: acpi_tb_find_rsdp | ||
468 | * | ||
469 | * PARAMETERS: table_info - Where the table info is returned | ||
470 | * Flags - Current memory mode (logical vs. | ||
471 | * physical addressing) | ||
472 | * | ||
473 | * RETURN: Status, RSDP physical address | ||
474 | * | ||
475 | * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor | ||
476 | * pointer structure. If it is found, set *RSDP to point to it. | ||
477 | * | ||
478 | * NOTE1: The RSDP must be either in the first 1_k of the Extended | ||
479 | * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) | ||
480 | * Only a 32-bit physical address is necessary. | ||
481 | * | ||
482 | * NOTE2: This function is always available, regardless of the | ||
483 | * initialization state of the rest of ACPI. | ||
484 | * | ||
485 | ******************************************************************************/ | ||
486 | |||
487 | static acpi_status | ||
488 | acpi_tb_find_rsdp(struct acpi_table_desc *table_info, u32 flags) | ||
489 | { | ||
490 | u8 *table_ptr; | ||
491 | u8 *mem_rover; | ||
492 | u32 physical_address; | ||
493 | acpi_status status; | ||
494 | |||
495 | ACPI_FUNCTION_TRACE(tb_find_rsdp); | ||
496 | |||
497 | /* | ||
498 | * Scan supports either logical addressing or physical addressing | ||
499 | */ | ||
500 | if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) { | ||
501 | |||
502 | /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ | ||
503 | |||
504 | status = acpi_os_map_memory((acpi_physical_address) | ||
505 | ACPI_EBDA_PTR_LOCATION, | ||
506 | ACPI_EBDA_PTR_LENGTH, | ||
507 | (void *)&table_ptr); | ||
508 | if (ACPI_FAILURE(status)) { | ||
509 | ACPI_ERROR((AE_INFO, | ||
510 | "Could not map memory at %8.8X for length %X", | ||
511 | ACPI_EBDA_PTR_LOCATION, | ||
512 | ACPI_EBDA_PTR_LENGTH)); | ||
513 | |||
514 | return_ACPI_STATUS(status); | ||
515 | } | ||
516 | |||
517 | ACPI_MOVE_16_TO_32(&physical_address, table_ptr); | ||
518 | |||
519 | /* Convert segment part to physical address */ | ||
520 | |||
521 | physical_address <<= 4; | ||
522 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_PTR_LENGTH); | ||
523 | |||
524 | /* EBDA present? */ | ||
525 | |||
526 | if (physical_address > 0x400) { | ||
527 | /* | ||
528 | * 1b) Search EBDA paragraphs (EBDA is required to be a | ||
529 | * minimum of 1_k length) | ||
530 | */ | ||
531 | status = acpi_os_map_memory((acpi_physical_address) | ||
532 | physical_address, | ||
533 | ACPI_EBDA_WINDOW_SIZE, | ||
534 | (void *)&table_ptr); | ||
535 | if (ACPI_FAILURE(status)) { | ||
536 | ACPI_ERROR((AE_INFO, | ||
537 | "Could not map memory at %8.8X for length %X", | ||
538 | physical_address, | ||
539 | ACPI_EBDA_WINDOW_SIZE)); | ||
540 | |||
541 | return_ACPI_STATUS(status); | ||
542 | } | ||
543 | |||
544 | mem_rover = acpi_tb_scan_memory_for_rsdp(table_ptr, | ||
545 | ACPI_EBDA_WINDOW_SIZE); | ||
546 | acpi_os_unmap_memory(table_ptr, ACPI_EBDA_WINDOW_SIZE); | ||
547 | |||
548 | if (mem_rover) { | ||
549 | |||
550 | /* Return the physical address */ | ||
551 | |||
552 | physical_address += | ||
553 | (u32) ACPI_PTR_DIFF(mem_rover, table_ptr); | ||
554 | |||
555 | table_info->physical_address = | ||
556 | (acpi_physical_address) physical_address; | ||
557 | return_ACPI_STATUS(AE_OK); | ||
558 | } | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh | ||
563 | */ | ||
564 | status = acpi_os_map_memory((acpi_physical_address) | ||
565 | ACPI_HI_RSDP_WINDOW_BASE, | ||
566 | ACPI_HI_RSDP_WINDOW_SIZE, | ||
567 | (void *)&table_ptr); | ||
568 | |||
569 | if (ACPI_FAILURE(status)) { | ||
570 | ACPI_ERROR((AE_INFO, | ||
571 | "Could not map memory at %8.8X for length %X", | ||
572 | ACPI_HI_RSDP_WINDOW_BASE, | ||
573 | ACPI_HI_RSDP_WINDOW_SIZE)); | ||
574 | |||
575 | return_ACPI_STATUS(status); | ||
576 | } | ||
577 | |||
578 | mem_rover = | ||
579 | acpi_tb_scan_memory_for_rsdp(table_ptr, | ||
580 | ACPI_HI_RSDP_WINDOW_SIZE); | ||
581 | acpi_os_unmap_memory(table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); | ||
582 | |||
583 | if (mem_rover) { | ||
584 | |||
585 | /* Return the physical address */ | ||
586 | |||
587 | physical_address = (u32) | ||
588 | (ACPI_HI_RSDP_WINDOW_BASE + | ||
589 | ACPI_PTR_DIFF(mem_rover, table_ptr)); | ||
590 | |||
591 | table_info->physical_address = | ||
592 | (acpi_physical_address) physical_address; | ||
593 | return_ACPI_STATUS(AE_OK); | ||
594 | } | ||
595 | } | ||
596 | |||
597 | /* | ||
598 | * Physical addressing | ||
599 | */ | ||
600 | else { | ||
601 | /* 1a) Get the location of the EBDA */ | ||
602 | |||
603 | ACPI_MOVE_16_TO_32(&physical_address, ACPI_EBDA_PTR_LOCATION); | ||
604 | physical_address <<= 4; /* Convert segment to physical address */ | ||
605 | |||
606 | /* EBDA present? */ | ||
607 | |||
608 | if (physical_address > 0x400) { | ||
609 | /* | ||
610 | * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of | ||
611 | * 1_k length) | ||
612 | */ | ||
613 | mem_rover = | ||
614 | acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR | ||
615 | (physical_address), | ||
616 | ACPI_EBDA_WINDOW_SIZE); | ||
617 | if (mem_rover) { | ||
618 | |||
619 | /* Return the physical address */ | ||
620 | |||
621 | table_info->physical_address = | ||
622 | ACPI_TO_INTEGER(mem_rover); | ||
623 | return_ACPI_STATUS(AE_OK); | ||
624 | } | ||
625 | } | ||
626 | |||
627 | /* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */ | ||
628 | |||
629 | mem_rover = | ||
630 | acpi_tb_scan_memory_for_rsdp(ACPI_PHYSADDR_TO_PTR | ||
631 | (ACPI_HI_RSDP_WINDOW_BASE), | ||
632 | ACPI_HI_RSDP_WINDOW_SIZE); | ||
633 | if (mem_rover) { | ||
634 | |||
635 | /* Found it, return the physical address */ | ||
636 | |||
637 | table_info->physical_address = | ||
638 | ACPI_TO_INTEGER(mem_rover); | ||
639 | return_ACPI_STATUS(AE_OK); | ||
640 | } | ||
641 | } | ||
642 | |||
643 | /* A valid RSDP was not found */ | ||
644 | |||
645 | ACPI_ERROR((AE_INFO, "No valid RSDP was found")); | ||
646 | return_ACPI_STATUS(AE_NOT_FOUND); | ||
647 | } | ||
648 | |||
649 | #endif | 279 | #endif |
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 103845213e22..8809306ba94c 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c | |||
@@ -46,8 +46,9 @@ | |||
46 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
47 | #include <acpi/acnamesp.h> | 47 | #include <acpi/acnamesp.h> |
48 | 48 | ||
49 | ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) | ||
49 | #define _COMPONENT ACPI_UTILITIES | 50 | #define _COMPONENT ACPI_UTILITIES |
50 | ACPI_MODULE_NAME("utglobal") | 51 | ACPI_MODULE_NAME("utglobal") |
51 | 52 | ||
52 | /******************************************************************************* | 53 | /******************************************************************************* |
53 | * | 54 | * |
@@ -280,53 +281,6 @@ char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position) | |||
280 | return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); | 281 | return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); |
281 | } | 282 | } |
282 | 283 | ||
283 | /******************************************************************************* | ||
284 | * | ||
285 | * Table name globals | ||
286 | * | ||
287 | * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes. | ||
288 | * it is NOT an exhaustive list of all possible ACPI tables. All ACPI tables | ||
289 | * that are not used by the subsystem are simply ignored. | ||
290 | * | ||
291 | * Do NOT add any table to this list that is not consumed directly by this | ||
292 | * subsystem (No MADT, ECDT, SBST, etc.) | ||
293 | * | ||
294 | ******************************************************************************/ | ||
295 | |||
296 | struct acpi_table_list acpi_gbl_table_lists[ACPI_TABLE_ID_MAX + 1]; | ||
297 | |||
298 | struct acpi_table_support acpi_gbl_table_data[ACPI_TABLE_ID_MAX + 1] = { | ||
299 | /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */ | ||
300 | |||
301 | /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof(RSDP_SIG) - 1, | ||
302 | ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE} | ||
303 | , | ||
304 | /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *)&acpi_gbl_DSDT, | ||
305 | sizeof(DSDT_SIG) - 1, | ||
306 | ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE | | ||
307 | ACPI_TABLE_EXECUTABLE} | ||
308 | , | ||
309 | /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *)&acpi_gbl_FADT, | ||
310 | sizeof(FADT_SIG) - 1, | ||
311 | ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE} | ||
312 | , | ||
313 | /* FACS 3 */ {FACS_SIG, FACS_SIG, (void *)&acpi_gbl_FACS, | ||
314 | sizeof(FACS_SIG) - 1, | ||
315 | ACPI_TABLE_SECONDARY | ACPI_TABLE_SINGLE} | ||
316 | , | ||
317 | /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof(PSDT_SIG) - 1, | ||
318 | ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | | ||
319 | ACPI_TABLE_EXECUTABLE} | ||
320 | , | ||
321 | /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof(SSDT_SIG) - 1, | ||
322 | ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | | ||
323 | ACPI_TABLE_EXECUTABLE} | ||
324 | , | ||
325 | /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof(RSDT_SIG) - 1, | ||
326 | ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE} | ||
327 | , | ||
328 | }; | ||
329 | |||
330 | /****************************************************************************** | 284 | /****************************************************************************** |
331 | * | 285 | * |
332 | * Event and Hardware globals | 286 | * Event and Hardware globals |
@@ -751,13 +705,6 @@ void acpi_ut_init_globals(void) | |||
751 | return; | 705 | return; |
752 | } | 706 | } |
753 | 707 | ||
754 | /* ACPI table structure */ | ||
755 | |||
756 | for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { | ||
757 | acpi_gbl_table_lists[i].next = NULL; | ||
758 | acpi_gbl_table_lists[i].count = 0; | ||
759 | } | ||
760 | |||
761 | /* Mutex locked flags */ | 708 | /* Mutex locked flags */ |
762 | 709 | ||
763 | for (i = 0; i < ACPI_NUM_MUTEX; i++) { | 710 | for (i = 0; i < ACPI_NUM_MUTEX; i++) { |
@@ -784,14 +731,6 @@ void acpi_ut_init_globals(void) | |||
784 | acpi_gbl_exception_handler = NULL; | 731 | acpi_gbl_exception_handler = NULL; |
785 | acpi_gbl_init_handler = NULL; | 732 | acpi_gbl_init_handler = NULL; |
786 | 733 | ||
787 | /* Global "typed" ACPI table pointers */ | ||
788 | |||
789 | acpi_gbl_RSDP = NULL; | ||
790 | acpi_gbl_XSDT = NULL; | ||
791 | acpi_gbl_FACS = NULL; | ||
792 | acpi_gbl_FADT = NULL; | ||
793 | acpi_gbl_DSDT = NULL; | ||
794 | |||
795 | /* Global Lock support */ | 734 | /* Global Lock support */ |
796 | 735 | ||
797 | acpi_gbl_global_lock_semaphore = NULL; | 736 | acpi_gbl_global_lock_semaphore = NULL; |
@@ -801,8 +740,6 @@ void acpi_ut_init_globals(void) | |||
801 | 740 | ||
802 | /* Miscellaneous variables */ | 741 | /* Miscellaneous variables */ |
803 | 742 | ||
804 | acpi_gbl_table_flags = ACPI_PHYSICAL_POINTER; | ||
805 | acpi_gbl_rsdp_original_location = 0; | ||
806 | acpi_gbl_cm_single_step = FALSE; | 743 | acpi_gbl_cm_single_step = FALSE; |
807 | acpi_gbl_db_terminate_threads = FALSE; | 744 | acpi_gbl_db_terminate_threads = FALSE; |
808 | acpi_gbl_shutdown = FALSE; | 745 | acpi_gbl_shutdown = FALSE; |
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c index ff76055eb7d6..2d2c4a3aeaae 100644 --- a/drivers/acpi/utilities/utinit.c +++ b/drivers/acpi/utilities/utinit.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include <acpi/acnamesp.h> | 45 | #include <acpi/acnamesp.h> |
46 | #include <acpi/acevents.h> | 46 | #include <acpi/acevents.h> |
47 | #include <acpi/actables.h> | ||
47 | 48 | ||
48 | #define _COMPONENT ACPI_UTILITIES | 49 | #define _COMPONENT ACPI_UTILITIES |
49 | ACPI_MODULE_NAME("utinit") | 50 | ACPI_MODULE_NAME("utinit") |
@@ -73,8 +74,8 @@ acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset) | |||
73 | { | 74 | { |
74 | 75 | ||
75 | ACPI_WARNING((AE_INFO, | 76 | ACPI_WARNING((AE_INFO, |
76 | "Invalid FADT value %s=%X at offset %X FADT=%p", | 77 | "Invalid FADT value %s=%X at offset %X in FADT=%p", |
77 | register_name, value, offset, acpi_gbl_FADT)); | 78 | register_name, value, offset, &acpi_gbl_FADT)); |
78 | } | 79 | } |
79 | 80 | ||
80 | /****************************************************************************** | 81 | /****************************************************************************** |
@@ -96,62 +97,70 @@ acpi_status acpi_ut_validate_fadt(void) | |||
96 | * Verify Fixed ACPI Description Table fields, | 97 | * Verify Fixed ACPI Description Table fields, |
97 | * but don't abort on any problems, just display error | 98 | * but don't abort on any problems, just display error |
98 | */ | 99 | */ |
99 | if (acpi_gbl_FADT->pm1_evt_len < 4) { | 100 | if (acpi_gbl_FADT.pm1_event_length < 4) { |
100 | acpi_ut_fadt_register_error("PM1_EVT_LEN", | 101 | acpi_ut_fadt_register_error("PM1_EVT_LEN", |
101 | (u32) acpi_gbl_FADT->pm1_evt_len, | 102 | (u32) acpi_gbl_FADT. |
102 | ACPI_FADT_OFFSET(pm1_evt_len)); | 103 | pm1_event_length, |
104 | ACPI_FADT_OFFSET(pm1_event_length)); | ||
103 | } | 105 | } |
104 | 106 | ||
105 | if (!acpi_gbl_FADT->pm1_cnt_len) { | 107 | if (!acpi_gbl_FADT.pm1_control_length) { |
106 | acpi_ut_fadt_register_error("PM1_CNT_LEN", 0, | 108 | acpi_ut_fadt_register_error("PM1_CNT_LEN", 0, |
107 | ACPI_FADT_OFFSET(pm1_cnt_len)); | 109 | ACPI_FADT_OFFSET |
110 | (pm1_control_length)); | ||
108 | } | 111 | } |
109 | 112 | ||
110 | if (!acpi_gbl_FADT->xpm1a_evt_blk.address) { | 113 | if (!acpi_gbl_FADT.xpm1a_event_block.address) { |
111 | acpi_ut_fadt_register_error("X_PM1a_EVT_BLK", 0, | 114 | acpi_ut_fadt_register_error("X_PM1a_EVT_BLK", 0, |
112 | ACPI_FADT_OFFSET(xpm1a_evt_blk. | 115 | ACPI_FADT_OFFSET(xpm1a_event_block. |
113 | address)); | 116 | address)); |
114 | } | 117 | } |
115 | 118 | ||
116 | if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) { | 119 | if (!acpi_gbl_FADT.xpm1a_control_block.address) { |
117 | acpi_ut_fadt_register_error("X_PM1a_CNT_BLK", 0, | 120 | acpi_ut_fadt_register_error("X_PM1a_CNT_BLK", 0, |
118 | ACPI_FADT_OFFSET(xpm1a_cnt_blk. | 121 | ACPI_FADT_OFFSET |
119 | address)); | 122 | (xpm1a_control_block.address)); |
120 | } | 123 | } |
121 | 124 | ||
122 | if (!acpi_gbl_FADT->xpm_tmr_blk.address) { | 125 | if (!acpi_gbl_FADT.xpm_timer_block.address) { |
123 | acpi_ut_fadt_register_error("X_PM_TMR_BLK", 0, | 126 | acpi_ut_fadt_register_error("X_PM_TMR_BLK", 0, |
124 | ACPI_FADT_OFFSET(xpm_tmr_blk. | 127 | ACPI_FADT_OFFSET(xpm_timer_block. |
125 | address)); | 128 | address)); |
126 | } | 129 | } |
127 | 130 | ||
128 | if ((acpi_gbl_FADT->xpm2_cnt_blk.address && | 131 | if ((acpi_gbl_FADT.xpm2_control_block.address && |
129 | !acpi_gbl_FADT->pm2_cnt_len)) { | 132 | !acpi_gbl_FADT.pm2_control_length)) { |
130 | acpi_ut_fadt_register_error("PM2_CNT_LEN", | 133 | acpi_ut_fadt_register_error("PM2_CNT_LEN", |
131 | (u32) acpi_gbl_FADT->pm2_cnt_len, | 134 | (u32) acpi_gbl_FADT. |
132 | ACPI_FADT_OFFSET(pm2_cnt_len)); | 135 | pm2_control_length, |
136 | ACPI_FADT_OFFSET | ||
137 | (pm2_control_length)); | ||
133 | } | 138 | } |
134 | 139 | ||
135 | if (acpi_gbl_FADT->pm_tm_len < 4) { | 140 | if (acpi_gbl_FADT.pm_timer_length < 4) { |
136 | acpi_ut_fadt_register_error("PM_TM_LEN", | 141 | acpi_ut_fadt_register_error("PM_TM_LEN", |
137 | (u32) acpi_gbl_FADT->pm_tm_len, | 142 | (u32) acpi_gbl_FADT.pm_timer_length, |
138 | ACPI_FADT_OFFSET(pm_tm_len)); | 143 | ACPI_FADT_OFFSET(pm_timer_length)); |
139 | } | 144 | } |
140 | 145 | ||
141 | /* Length of GPE blocks must be a multiple of 2 */ | 146 | /* Length of GPE blocks must be a multiple of 2 */ |
142 | 147 | ||
143 | if (acpi_gbl_FADT->xgpe0_blk.address && | 148 | if (acpi_gbl_FADT.xgpe0_block.address && |
144 | (acpi_gbl_FADT->gpe0_blk_len & 1)) { | 149 | (acpi_gbl_FADT.gpe0_block_length & 1)) { |
145 | acpi_ut_fadt_register_error("(x)GPE0_BLK_LEN", | 150 | acpi_ut_fadt_register_error("(x)GPE0_BLK_LEN", |
146 | (u32) acpi_gbl_FADT->gpe0_blk_len, | 151 | (u32) acpi_gbl_FADT. |
147 | ACPI_FADT_OFFSET(gpe0_blk_len)); | 152 | gpe0_block_length, |
153 | ACPI_FADT_OFFSET | ||
154 | (gpe0_block_length)); | ||
148 | } | 155 | } |
149 | 156 | ||
150 | if (acpi_gbl_FADT->xgpe1_blk.address && | 157 | if (acpi_gbl_FADT.xgpe1_block.address && |
151 | (acpi_gbl_FADT->gpe1_blk_len & 1)) { | 158 | (acpi_gbl_FADT.gpe1_block_length & 1)) { |
152 | acpi_ut_fadt_register_error("(x)GPE1_BLK_LEN", | 159 | acpi_ut_fadt_register_error("(x)GPE1_BLK_LEN", |
153 | (u32) acpi_gbl_FADT->gpe1_blk_len, | 160 | (u32) acpi_gbl_FADT. |
154 | ACPI_FADT_OFFSET(gpe1_blk_len)); | 161 | gpe1_block_length, |
162 | ACPI_FADT_OFFSET | ||
163 | (gpe1_block_length)); | ||
155 | } | 164 | } |
156 | 165 | ||
157 | return (AE_OK); | 166 | return (AE_OK); |
@@ -178,7 +187,6 @@ static void acpi_ut_terminate(void) | |||
178 | 187 | ||
179 | ACPI_FUNCTION_TRACE(ut_terminate); | 188 | ACPI_FUNCTION_TRACE(ut_terminate); |
180 | 189 | ||
181 | /* Free global tables, etc. */ | ||
182 | /* Free global GPE blocks and related info structures */ | 190 | /* Free global GPE blocks and related info structures */ |
183 | 191 | ||
184 | gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; | 192 | gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; |
@@ -239,6 +247,10 @@ void acpi_ut_subsystem_shutdown(void) | |||
239 | 247 | ||
240 | acpi_ns_terminate(); | 248 | acpi_ns_terminate(); |
241 | 249 | ||
250 | /* Delete the ACPI tables */ | ||
251 | |||
252 | acpi_tb_terminate(); | ||
253 | |||
242 | /* Close the globals */ | 254 | /* Close the globals */ |
243 | 255 | ||
244 | acpi_ut_terminate(); | 256 | acpi_ut_terminate(); |
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 6d8a8211be90..47dcf82a3b5e 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -67,9 +67,9 @@ u8 acpi_ut_is_aml_table(struct acpi_table_header *table) | |||
67 | 67 | ||
68 | /* These are the only tables that contain executable AML */ | 68 | /* These are the only tables that contain executable AML */ |
69 | 69 | ||
70 | if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) || | 70 | if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) || |
71 | ACPI_COMPARE_NAME(table->signature, PSDT_SIG) || | 71 | ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) || |
72 | ACPI_COMPARE_NAME(table->signature, SSDT_SIG)) { | 72 | ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) { |
73 | return (TRUE); | 73 | return (TRUE); |
74 | } | 74 | } |
75 | 75 | ||
@@ -418,7 +418,7 @@ u32 acpi_ut_dword_byte_swap(u32 value) | |||
418 | void acpi_ut_set_integer_width(u8 revision) | 418 | void acpi_ut_set_integer_width(u8 revision) |
419 | { | 419 | { |
420 | 420 | ||
421 | if (revision <= 1) { | 421 | if (revision < 2) { |
422 | 422 | ||
423 | /* 32-bit case */ | 423 | /* 32-bit case */ |
424 | 424 | ||
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index 3538f69c82a1..7ea2981d4382 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c | |||
@@ -398,7 +398,6 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) | |||
398 | { | 398 | { |
399 | struct acpi_system_info *info_ptr; | 399 | struct acpi_system_info *info_ptr; |
400 | acpi_status status; | 400 | acpi_status status; |
401 | u32 i; | ||
402 | 401 | ||
403 | ACPI_FUNCTION_TRACE(acpi_get_system_info); | 402 | ACPI_FUNCTION_TRACE(acpi_get_system_info); |
404 | 403 | ||
@@ -431,9 +430,7 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) | |||
431 | 430 | ||
432 | /* Timer resolution - 24 or 32 bits */ | 431 | /* Timer resolution - 24 or 32 bits */ |
433 | 432 | ||
434 | if (!acpi_gbl_FADT) { | 433 | if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) { |
435 | info_ptr->timer_resolution = 0; | ||
436 | } else if (acpi_gbl_FADT->tmr_val_ext == 0) { | ||
437 | info_ptr->timer_resolution = 24; | 434 | info_ptr->timer_resolution = 24; |
438 | } else { | 435 | } else { |
439 | info_ptr->timer_resolution = 32; | 436 | info_ptr->timer_resolution = 32; |
@@ -449,13 +446,6 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) | |||
449 | info_ptr->debug_layer = acpi_dbg_layer; | 446 | info_ptr->debug_layer = acpi_dbg_layer; |
450 | info_ptr->debug_level = acpi_dbg_level; | 447 | info_ptr->debug_level = acpi_dbg_level; |
451 | 448 | ||
452 | /* Current status of the ACPI tables, per table type */ | ||
453 | |||
454 | info_ptr->num_table_types = ACPI_TABLE_ID_MAX + 1; | ||
455 | for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) { | ||
456 | info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count; | ||
457 | } | ||
458 | |||
459 | return_ACPI_STATUS(AE_OK); | 449 | return_ACPI_STATUS(AE_OK); |
460 | } | 450 | } |
461 | 451 | ||