diff options
author | Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> | 2007-02-02 11:48:22 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-02-02 21:14:29 -0500 |
commit | 428f211297bc95fd41f23830eab4180339020dd0 (patch) | |
tree | 81537f25f9add9e727e9d764fdcb333a1af07528 /drivers/acpi/tables | |
parent | 77f6a9fca39f4f19d2d9d5fff1ff5c2ccf20629c (diff) |
ACPICA: Miscellaneous table manager updates and optimizations
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/tables')
-rw-r--r-- | drivers/acpi/tables/tbinstal.c | 91 | ||||
-rw-r--r-- | drivers/acpi/tables/tbutils.c | 46 | ||||
-rw-r--r-- | drivers/acpi/tables/tbxface.c | 54 |
3 files changed, 93 insertions, 98 deletions
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 9e0b3ce0d8e..b07d9c8330b 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -61,16 +61,19 @@ ACPI_MODULE_NAME("tbinstal") | |||
61 | *****************************************************************************/ | 61 | *****************************************************************************/ |
62 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | 62 | acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) |
63 | { | 63 | { |
64 | acpi_status status; | 64 | acpi_status status = AE_OK; |
65 | 65 | ||
66 | ACPI_FUNCTION_TRACE(tb_verify_table); | 66 | ACPI_FUNCTION_TRACE(tb_verify_table); |
67 | 67 | ||
68 | /* Map the table if necessary */ | 68 | /* Map the table if necessary */ |
69 | 69 | ||
70 | if (!table_desc->pointer) { | 70 | if (!table_desc->pointer) { |
71 | table_desc->pointer = | 71 | if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == |
72 | acpi_tb_map(table_desc->address, table_desc->length, | 72 | ACPI_TABLE_ORIGIN_MAPPED) { |
73 | table_desc->flags & ACPI_TABLE_ORIGIN_MASK); | 73 | table_desc->pointer = |
74 | acpi_os_map_memory(table_desc->address, | ||
75 | table_desc->length); | ||
76 | } | ||
74 | if (!table_desc->pointer) { | 77 | if (!table_desc->pointer) { |
75 | return_ACPI_STATUS(AE_NO_MEMORY); | 78 | return_ACPI_STATUS(AE_NO_MEMORY); |
76 | } | 79 | } |
@@ -78,14 +81,15 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | |||
78 | 81 | ||
79 | /* FACS is the odd table, has no standard ACPI header and no checksum */ | 82 | /* FACS is the odd table, has no standard ACPI header and no checksum */ |
80 | 83 | ||
81 | if (ACPI_COMPARE_NAME(&(table_desc->signature), ACPI_SIG_FACS)) { | 84 | if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) { |
82 | return_ACPI_STATUS(AE_OK); | ||
83 | } | ||
84 | 85 | ||
85 | /* Always calculate checksum, ignore bad checksum if requested */ | 86 | /* Always calculate checksum, ignore bad checksum if requested */ |
87 | |||
88 | status = | ||
89 | acpi_tb_verify_checksum(table_desc->pointer, | ||
90 | table_desc->length); | ||
91 | } | ||
86 | 92 | ||
87 | status = | ||
88 | acpi_tb_verify_checksum(table_desc->pointer, table_desc->length); | ||
89 | return_ACPI_STATUS(status); | 93 | return_ACPI_STATUS(status); |
90 | } | 94 | } |
91 | 95 | ||
@@ -93,7 +97,7 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | |||
93 | * | 97 | * |
94 | * FUNCTION: acpi_tb_add_table | 98 | * FUNCTION: acpi_tb_add_table |
95 | * | 99 | * |
96 | * PARAMETERS: Table - Pointer to the table header | 100 | * PARAMETERS: table_desc - Table descriptor |
97 | * table_index - Where the table index is returned | 101 | * table_index - Where the table index is returned |
98 | * | 102 | * |
99 | * RETURN: Status | 103 | * RETURN: Status |
@@ -103,7 +107,7 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | |||
103 | ******************************************************************************/ | 107 | ******************************************************************************/ |
104 | 108 | ||
105 | acpi_status | 109 | acpi_status |
106 | acpi_tb_add_table(struct acpi_table_header *table, | 110 | acpi_tb_add_table(struct acpi_table_desc *table_desc, |
107 | acpi_native_uint * table_index) | 111 | acpi_native_uint * table_index) |
108 | { | 112 | { |
109 | acpi_native_uint i; | 113 | acpi_native_uint i; |
@@ -112,6 +116,25 @@ acpi_tb_add_table(struct acpi_table_header *table, | |||
112 | 116 | ||
113 | ACPI_FUNCTION_TRACE(tb_add_table); | 117 | ACPI_FUNCTION_TRACE(tb_add_table); |
114 | 118 | ||
119 | if (!table_desc->pointer) { | ||
120 | status = acpi_tb_verify_table(table_desc); | ||
121 | if (ACPI_FAILURE(status) || !table_desc->pointer) { | ||
122 | return_ACPI_STATUS(status); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | /* The table must be either an SSDT or a PSDT */ | ||
127 | |||
128 | if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)) | ||
129 | && | ||
130 | (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))) | ||
131 | { | ||
132 | ACPI_ERROR((AE_INFO, | ||
133 | "Table has invalid signature [%4.4s], must be SSDT or PSDT", | ||
134 | table_desc->pointer->signature)); | ||
135 | return_ACPI_STATUS(AE_BAD_SIGNATURE); | ||
136 | } | ||
137 | |||
115 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 138 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
116 | 139 | ||
117 | /* Check if table is already registered */ | 140 | /* Check if table is already registered */ |
@@ -127,18 +150,17 @@ acpi_tb_add_table(struct acpi_table_header *table, | |||
127 | } | 150 | } |
128 | } | 151 | } |
129 | 152 | ||
130 | length = ACPI_MIN(table->length, | 153 | length = ACPI_MIN(table_desc->length, |
131 | acpi_gbl_root_table_list.tables[i].pointer-> | 154 | acpi_gbl_root_table_list.tables[i].length); |
132 | length); | 155 | if (ACPI_MEMCMP(table_desc->pointer, |
133 | if (ACPI_MEMCMP | 156 | acpi_gbl_root_table_list.tables[i].pointer, |
134 | (table, acpi_gbl_root_table_list.tables[i].pointer, | 157 | length)) { |
135 | length)) { | ||
136 | continue; | 158 | continue; |
137 | } | 159 | } |
138 | 160 | ||
139 | /* Table is already registered */ | 161 | /* Table is already registered */ |
140 | 162 | ||
141 | ACPI_FREE(table); | 163 | acpi_tb_delete_table(table_desc); |
142 | *table_index = i; | 164 | *table_index = i; |
143 | goto release; | 165 | goto release; |
144 | } | 166 | } |
@@ -146,14 +168,14 @@ acpi_tb_add_table(struct acpi_table_header *table, | |||
146 | /* | 168 | /* |
147 | * Add the table to the global table list | 169 | * Add the table to the global table list |
148 | */ | 170 | */ |
149 | status = acpi_tb_store_table(ACPI_TO_INTEGER(table), | 171 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, |
150 | table, table->length, | 172 | table_desc->length, table_desc->flags, |
151 | ACPI_TABLE_ORIGIN_ALLOCATED, table_index); | 173 | table_index); |
152 | if (ACPI_FAILURE(status)) { | 174 | if (ACPI_FAILURE(status)) { |
153 | goto release; | 175 | goto release; |
154 | } | 176 | } |
155 | 177 | ||
156 | acpi_tb_print_table_header(0, table); | 178 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); |
157 | 179 | ||
158 | release: | 180 | release: |
159 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 181 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
@@ -282,25 +304,20 @@ acpi_tb_store_table(acpi_physical_address address, | |||
282 | * | 304 | * |
283 | ******************************************************************************/ | 305 | ******************************************************************************/ |
284 | 306 | ||
285 | void acpi_tb_delete_table(acpi_native_uint table_index) | 307 | void acpi_tb_delete_table(struct acpi_table_desc *table_desc) |
286 | { | 308 | { |
287 | struct acpi_table_desc *table_desc; | ||
288 | |||
289 | /* table_index assumed valid */ | ||
290 | |||
291 | table_desc = &acpi_gbl_root_table_list.tables[table_index]; | ||
292 | |||
293 | /* Table must be mapped or allocated */ | 309 | /* Table must be mapped or allocated */ |
294 | |||
295 | if (!table_desc->pointer) { | 310 | if (!table_desc->pointer) { |
296 | return; | 311 | return; |
297 | } | 312 | } |
298 | 313 | switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { | |
299 | if (table_desc->flags & ACPI_TABLE_ORIGIN_MAPPED) { | 314 | case ACPI_TABLE_ORIGIN_MAPPED: |
300 | acpi_tb_unmap(table_desc->pointer, table_desc->length, | 315 | acpi_os_unmap_memory(table_desc->pointer, table_desc->length); |
301 | table_desc->flags & ACPI_TABLE_ORIGIN_MASK); | 316 | break; |
302 | } else if (table_desc->flags & ACPI_TABLE_ORIGIN_ALLOCATED) { | 317 | case ACPI_TABLE_ORIGIN_ALLOCATED: |
303 | ACPI_FREE(table_desc->pointer); | 318 | ACPI_FREE(table_desc->pointer); |
319 | break; | ||
320 | default:; | ||
304 | } | 321 | } |
305 | 322 | ||
306 | table_desc->pointer = NULL; | 323 | table_desc->pointer = NULL; |
@@ -329,7 +346,7 @@ void acpi_tb_terminate(void) | |||
329 | /* Delete the individual tables */ | 346 | /* Delete the individual tables */ |
330 | 347 | ||
331 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { | 348 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { |
332 | acpi_tb_delete_table(i); | 349 | acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); |
333 | } | 350 | } |
334 | 351 | ||
335 | /* | 352 | /* |
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 1033748e73e..0cb743962fa 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c | |||
@@ -462,49 +462,3 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) | |||
462 | 462 | ||
463 | return_ACPI_STATUS(AE_OK); | 463 | return_ACPI_STATUS(AE_OK); |
464 | } | 464 | } |
465 | |||
466 | /****************************************************************************** | ||
467 | * | ||
468 | * FUNCTION: acpi_tb_map | ||
469 | * | ||
470 | * PARAMETERS: Address - Address to be mapped | ||
471 | * Length - Length to be mapped | ||
472 | * Flags - Logical or physical addressing mode | ||
473 | * | ||
474 | * RETURN: Pointer to mapped region | ||
475 | * | ||
476 | * DESCRIPTION: Maps memory according to flag | ||
477 | * | ||
478 | *****************************************************************************/ | ||
479 | |||
480 | void *acpi_tb_map(acpi_physical_address address, u32 length, u32 flags) | ||
481 | { | ||
482 | |||
483 | if (flags == ACPI_TABLE_ORIGIN_MAPPED) { | ||
484 | return (acpi_os_map_memory(address, length)); | ||
485 | } else { | ||
486 | return (ACPI_CAST_PTR(void, address)); | ||
487 | } | ||
488 | } | ||
489 | |||
490 | /****************************************************************************** | ||
491 | * | ||
492 | * FUNCTION: acpi_tb_unmap | ||
493 | * | ||
494 | * PARAMETERS: Pointer - To mapped region | ||
495 | * Length - Length to be unmapped | ||
496 | * Flags - Logical or physical addressing mode | ||
497 | * | ||
498 | * RETURN: None | ||
499 | * | ||
500 | * DESCRIPTION: Unmaps memory according to flag | ||
501 | * | ||
502 | *****************************************************************************/ | ||
503 | |||
504 | void acpi_tb_unmap(void *pointer, u32 length, u32 flags) | ||
505 | { | ||
506 | |||
507 | if (flags == ACPI_TABLE_ORIGIN_MAPPED) { | ||
508 | acpi_os_unmap_memory(pointer, length); | ||
509 | } | ||
510 | } | ||
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 9d451e8a4e4..77224bd0667 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c | |||
@@ -220,16 +220,25 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr) | |||
220 | { | 220 | { |
221 | acpi_status status; | 221 | acpi_status status; |
222 | acpi_native_uint table_index; | 222 | acpi_native_uint table_index; |
223 | struct acpi_table_desc table_desc; | ||
224 | |||
225 | if (!table_ptr) | ||
226 | return AE_BAD_PARAMETER; | ||
227 | |||
228 | ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); | ||
229 | table_desc.pointer = table_ptr; | ||
230 | table_desc.length = table_ptr->length; | ||
231 | table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN; | ||
223 | 232 | ||
224 | /* | 233 | /* |
225 | * Install the new table into the local data structures | 234 | * Install the new table into the local data structures |
226 | */ | 235 | */ |
227 | status = acpi_tb_add_table(table_ptr, &table_index); | 236 | status = acpi_tb_add_table(&table_desc, &table_index); |
228 | if (ACPI_FAILURE(status)) { | 237 | if (ACPI_FAILURE(status)) { |
229 | return_ACPI_STATUS(status); | 238 | return status; |
230 | } | 239 | } |
231 | status = acpi_ns_load_table(table_index, acpi_gbl_root_node); | 240 | status = acpi_ns_load_table(table_index, acpi_gbl_root_node); |
232 | return_ACPI_STATUS(status); | 241 | return status; |
233 | } | 242 | } |
234 | 243 | ||
235 | ACPI_EXPORT_SYMBOL(acpi_load_table) | 244 | ACPI_EXPORT_SYMBOL(acpi_load_table) |
@@ -240,8 +249,7 @@ ACPI_EXPORT_SYMBOL(acpi_load_table) | |||
240 | * | 249 | * |
241 | * PARAMETERS: Signature - ACPI signature of needed table | 250 | * PARAMETERS: Signature - ACPI signature of needed table |
242 | * Instance - Which instance (for SSDTs) | 251 | * Instance - Which instance (for SSDTs) |
243 | * out_table_header - Where the pointer to the table header | 252 | * out_table_header - The pointer to the table header to fill |
244 | * is returned | ||
245 | * | 253 | * |
246 | * RETURN: Status and pointer to mapped table header | 254 | * RETURN: Status and pointer to mapped table header |
247 | * | 255 | * |
@@ -254,10 +262,11 @@ ACPI_EXPORT_SYMBOL(acpi_load_table) | |||
254 | acpi_status | 262 | acpi_status |
255 | acpi_get_table_header(char *signature, | 263 | acpi_get_table_header(char *signature, |
256 | acpi_native_uint instance, | 264 | acpi_native_uint instance, |
257 | struct acpi_table_header **out_table_header) | 265 | struct acpi_table_header *out_table_header) |
258 | { | 266 | { |
259 | acpi_native_uint i; | 267 | acpi_native_uint i; |
260 | acpi_native_uint j; | 268 | acpi_native_uint j; |
269 | struct acpi_table_header *header; | ||
261 | 270 | ||
262 | /* Parameter validation */ | 271 | /* Parameter validation */ |
263 | 272 | ||
@@ -279,16 +288,31 @@ acpi_get_table_header(char *signature, | |||
279 | continue; | 288 | continue; |
280 | } | 289 | } |
281 | 290 | ||
282 | *out_table_header = | 291 | if (!acpi_gbl_root_table_list.tables[i].pointer) { |
283 | acpi_tb_map(acpi_gbl_root_table_list.tables[i].address, | 292 | if ((acpi_gbl_root_table_list.tables[i]. |
284 | (u32) sizeof(struct acpi_table_header), | 293 | flags & ACPI_TABLE_ORIGIN_MASK) == |
285 | acpi_gbl_root_table_list.tables[i]. | 294 | ACPI_TABLE_ORIGIN_MAPPED) { |
286 | flags & ACPI_TABLE_ORIGIN_MASK); | 295 | header = |
287 | 296 | acpi_os_map_memory(acpi_gbl_root_table_list. | |
288 | if (!(*out_table_header)) { | 297 | tables[i].address, |
289 | return (AE_NO_MEMORY); | 298 | sizeof(struct |
299 | acpi_table_header)); | ||
300 | if (!header) { | ||
301 | return AE_NO_MEMORY; | ||
302 | } | ||
303 | ACPI_MEMCPY(out_table_header, header, | ||
304 | sizeof(struct acpi_table_header)); | ||
305 | acpi_os_unmap_memory(header, | ||
306 | sizeof(struct | ||
307 | acpi_table_header)); | ||
308 | } else { | ||
309 | return AE_NOT_FOUND; | ||
310 | } | ||
311 | } else { | ||
312 | ACPI_MEMCPY(out_table_header, | ||
313 | acpi_gbl_root_table_list.tables[i].pointer, | ||
314 | sizeof(struct acpi_table_header)); | ||
290 | } | 315 | } |
291 | |||
292 | return (AE_OK); | 316 | return (AE_OK); |
293 | } | 317 | } |
294 | 318 | ||