Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.17-rc4 476 lines 14 kB view raw
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 48ACPI_MODULE_NAME("tbget") 49 50/* Local prototypes */ 51static acpi_status 52acpi_tb_get_this_table(struct acpi_pointer *address, 53 struct acpi_table_header *header, 54 struct acpi_table_desc *table_info); 55 56static acpi_status 57acpi_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 74acpi_status 75acpi_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 120acpi_status 121acpi_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 return_ACPI_STATUS(status); 152 } 153 154 /* Copy header and delete mapping */ 155 156 ACPI_MEMCPY(return_header, header, 157 sizeof(struct acpi_table_header)); 158 acpi_os_unmap_memory(header, sizeof(struct acpi_table_header)); 159 break; 160 161 default: 162 163 ACPI_ERROR((AE_INFO, "Invalid address flags %X", 164 address->pointer_type)); 165 return_ACPI_STATUS(AE_BAD_PARAMETER); 166 } 167 168 ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n", 169 return_header->signature)); 170 171 return_ACPI_STATUS(AE_OK); 172} 173 174/******************************************************************************* 175 * 176 * FUNCTION: acpi_tb_get_table_body 177 * 178 * PARAMETERS: Address - Address of table to retrieve. Can be 179 * Logical or Physical 180 * Header - Header of the table to retrieve 181 * table_info - Where the table info is returned 182 * 183 * RETURN: Status 184 * 185 * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to 186 * replace the table with a newer version (table override.) 187 * Works in both physical or virtual 188 * addressing mode. Works with both physical or logical pointers. 189 * Table is either copied or mapped, depending on the pointer 190 * type and mode of the processor. 191 * 192 ******************************************************************************/ 193 194acpi_status 195acpi_tb_get_table_body(struct acpi_pointer *address, 196 struct acpi_table_header *header, 197 struct acpi_table_desc *table_info) 198{ 199 acpi_status status; 200 201 ACPI_FUNCTION_TRACE("tb_get_table_body"); 202 203 if (!table_info || !address) { 204 return_ACPI_STATUS(AE_BAD_PARAMETER); 205 } 206 207 /* Attempt table override. */ 208 209 status = acpi_tb_table_override(header, table_info); 210 if (ACPI_SUCCESS(status)) { 211 /* Table was overridden by the host OS */ 212 213 return_ACPI_STATUS(status); 214 } 215 216 /* No override, get the original table */ 217 218 status = acpi_tb_get_this_table(address, header, table_info); 219 return_ACPI_STATUS(status); 220} 221 222/******************************************************************************* 223 * 224 * FUNCTION: acpi_tb_table_override 225 * 226 * PARAMETERS: Header - Pointer to table header 227 * table_info - Return info if table is overridden 228 * 229 * RETURN: None 230 * 231 * DESCRIPTION: Attempts override of current table with a new one if provided 232 * by the host OS. 233 * 234 ******************************************************************************/ 235 236static acpi_status 237acpi_tb_table_override(struct acpi_table_header *header, 238 struct acpi_table_desc *table_info) 239{ 240 struct acpi_table_header *new_table; 241 acpi_status status; 242 struct acpi_pointer address; 243 244 ACPI_FUNCTION_TRACE("tb_table_override"); 245 246 /* 247 * The OSL will examine the header and decide whether to override this 248 * table. If it decides to override, a table will be returned in new_table, 249 * which we will then copy. 250 */ 251 status = acpi_os_table_override(header, &new_table); 252 if (ACPI_FAILURE(status)) { 253 /* Some severe error from the OSL, but we basically ignore it */ 254 255 ACPI_EXCEPTION((AE_INFO, status, 256 "Could not override ACPI table")); 257 return_ACPI_STATUS(status); 258 } 259 260 if (!new_table) { 261 /* No table override */ 262 263 return_ACPI_STATUS(AE_NO_ACPI_TABLES); 264 } 265 266 /* 267 * We have a new table to override the old one. Get a copy of 268 * the new one. We know that the new table has a logical pointer. 269 */ 270 address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; 271 address.pointer.logical = new_table; 272 273 status = acpi_tb_get_this_table(&address, new_table, table_info); 274 if (ACPI_FAILURE(status)) { 275 ACPI_EXCEPTION((AE_INFO, status, "Could not copy ACPI table")); 276 return_ACPI_STATUS(status); 277 } 278 279 /* Copy the table info */ 280 281 ACPI_INFO((AE_INFO, "Table [%4.4s] replaced by host OS", 282 table_info->pointer->signature)); 283 284 return_ACPI_STATUS(AE_OK); 285} 286 287/******************************************************************************* 288 * 289 * FUNCTION: acpi_tb_get_this_table 290 * 291 * PARAMETERS: Address - Address of table to retrieve. Can be 292 * Logical or Physical 293 * Header - Header of the table to retrieve 294 * table_info - Where the table info is returned 295 * 296 * RETURN: Status 297 * 298 * DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual 299 * addressing mode. Works with both physical or logical pointers. 300 * Table is either copied or mapped, depending on the pointer 301 * type and mode of the processor. 302 * 303 ******************************************************************************/ 304 305static acpi_status 306acpi_tb_get_this_table(struct acpi_pointer *address, 307 struct acpi_table_header *header, 308 struct acpi_table_desc *table_info) 309{ 310 struct acpi_table_header *full_table = NULL; 311 u8 allocation; 312 acpi_status status = AE_OK; 313 314 ACPI_FUNCTION_TRACE("tb_get_this_table"); 315 316 /* 317 * Flags contains the current processor mode (Virtual or Physical 318 * addressing) The pointer_type is either Logical or Physical 319 */ 320 switch (address->pointer_type) { 321 case ACPI_PHYSMODE_PHYSPTR: 322 case ACPI_LOGMODE_LOGPTR: 323 324 /* Pointer matches processor mode, copy the table to a new buffer */ 325 326 full_table = ACPI_MEM_ALLOCATE(header->length); 327 if (!full_table) { 328 ACPI_ERROR((AE_INFO, 329 "Could not allocate table memory for [%4.4s] length %X", 330 header->signature, header->length)); 331 return_ACPI_STATUS(AE_NO_MEMORY); 332 } 333 334 /* Copy the entire table (including header) to the local buffer */ 335 336 ACPI_MEMCPY(full_table, address->pointer.logical, 337 header->length); 338 339 /* Save allocation type */ 340 341 allocation = ACPI_MEM_ALLOCATED; 342 break; 343 344 case ACPI_LOGMODE_PHYSPTR: 345 346 /* 347 * Just map the table's physical memory 348 * into our address space. 349 */ 350 status = acpi_os_map_memory(address->pointer.physical, 351 (acpi_size) header->length, 352 (void *)&full_table); 353 if (ACPI_FAILURE(status)) { 354 ACPI_ERROR((AE_INFO, 355 "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X", 356 header->signature, 357 ACPI_FORMAT_UINT64(address->pointer. 358 physical), 359 header->length)); 360 return (status); 361 } 362 363 /* Save allocation type */ 364 365 allocation = ACPI_MEM_MAPPED; 366 break; 367 368 default: 369 370 ACPI_ERROR((AE_INFO, "Invalid address flags %X", 371 address->pointer_type)); 372 return_ACPI_STATUS(AE_BAD_PARAMETER); 373 } 374 375 /* 376 * Validate checksum for _most_ tables, 377 * even the ones whose signature we don't recognize 378 */ 379 if (table_info->type != ACPI_TABLE_FACS) { 380 status = acpi_tb_verify_table_checksum(full_table); 381 382#if (!ACPI_CHECKSUM_ABORT) 383 if (ACPI_FAILURE(status)) { 384 /* Ignore the error if configuration says so */ 385 386 status = AE_OK; 387 } 388#endif 389 } 390 391 /* Return values */ 392 393 table_info->pointer = full_table; 394 table_info->length = (acpi_size) header->length; 395 table_info->allocation = allocation; 396 397 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 398 "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n", 399 full_table->signature, 400 ACPI_FORMAT_UINT64(address->pointer.physical), 401 full_table)); 402 403 return_ACPI_STATUS(status); 404} 405 406/******************************************************************************* 407 * 408 * FUNCTION: acpi_tb_get_table_ptr 409 * 410 * PARAMETERS: table_type - one of the defined table types 411 * Instance - Which table of this type 412 * table_ptr_loc - pointer to location to place the pointer for 413 * return 414 * 415 * RETURN: Status 416 * 417 * DESCRIPTION: This function is called to get the pointer to an ACPI table. 418 * 419 ******************************************************************************/ 420 421acpi_status 422acpi_tb_get_table_ptr(acpi_table_type table_type, 423 u32 instance, struct acpi_table_header **table_ptr_loc) 424{ 425 struct acpi_table_desc *table_desc; 426 u32 i; 427 428 ACPI_FUNCTION_TRACE("tb_get_table_ptr"); 429 430 if (!acpi_gbl_DSDT) { 431 return_ACPI_STATUS(AE_NO_ACPI_TABLES); 432 } 433 434 if (table_type > ACPI_TABLE_MAX) { 435 return_ACPI_STATUS(AE_BAD_PARAMETER); 436 } 437 438 /* 439 * For all table types (Single/Multiple), the first 440 * instance is always in the list head. 441 */ 442 if (instance == 1) { 443 /* Get the first */ 444 445 *table_ptr_loc = NULL; 446 if (acpi_gbl_table_lists[table_type].next) { 447 *table_ptr_loc = 448 acpi_gbl_table_lists[table_type].next->pointer; 449 } 450 return_ACPI_STATUS(AE_OK); 451 } 452 453 /* Check for instance out of range */ 454 455 if (instance > acpi_gbl_table_lists[table_type].count) { 456 return_ACPI_STATUS(AE_NOT_EXIST); 457 } 458 459 /* Walk the list to get the desired table 460 * Since the if (Instance == 1) check above checked for the 461 * first table, setting table_desc equal to the .Next member 462 * is actually pointing to the second table. Therefore, we 463 * need to walk from the 2nd table until we reach the Instance 464 * that the user is looking for and return its table pointer. 465 */ 466 table_desc = acpi_gbl_table_lists[table_type].next; 467 for (i = 2; i < instance; i++) { 468 table_desc = table_desc->next; 469 } 470 471 /* We are now pointing to the requested table's descriptor */ 472 473 *table_ptr_loc = table_desc->pointer; 474 475 return_ACPI_STATUS(AE_OK); 476}