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 554 lines 15 kB view raw
1/******************************************************************************* 2 * 3 * Module Name: utresrc - Resource managment 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/amlresrc.h> 46 47#define _COMPONENT ACPI_UTILITIES 48ACPI_MODULE_NAME("utmisc") 49 50#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) 51/* 52 * Strings used to decode resource descriptors. 53 * Used by both the disasssembler and the debugger resource dump routines 54 */ 55const char *acpi_gbl_BMdecode[2] = { 56 "not_bus_master", 57 "bus_master" 58}; 59 60const char *acpi_gbl_config_decode[4] = { 61 "0 - Good Configuration", 62 "1 - Acceptable Configuration", 63 "2 - Suboptimal Configuration", 64 "3 - ***Invalid Configuration***", 65}; 66 67const char *acpi_gbl_consume_decode[2] = { 68 "resource_producer", 69 "resource_consumer" 70}; 71 72const char *acpi_gbl_DECdecode[2] = { 73 "pos_decode", 74 "sub_decode" 75}; 76 77const char *acpi_gbl_HEdecode[2] = { 78 "Level", 79 "Edge" 80}; 81 82const char *acpi_gbl_io_decode[2] = { 83 "Decode10", 84 "Decode16" 85}; 86 87const char *acpi_gbl_LLdecode[2] = { 88 "active_high", 89 "active_low" 90}; 91 92const char *acpi_gbl_max_decode[2] = { 93 "max_not_fixed", 94 "max_fixed" 95}; 96 97const char *acpi_gbl_MEMdecode[4] = { 98 "non_cacheable", 99 "Cacheable", 100 "write_combining", 101 "Prefetchable" 102}; 103 104const char *acpi_gbl_min_decode[2] = { 105 "min_not_fixed", 106 "min_fixed" 107}; 108 109const char *acpi_gbl_MTPdecode[4] = { 110 "address_range_memory", 111 "address_range_reserved", 112 "address_range_aCPI", 113 "address_range_nVS" 114}; 115 116const char *acpi_gbl_RNGdecode[4] = { 117 "invalid_ranges", 118 "non_iSAonly_ranges", 119 "ISAonly_ranges", 120 "entire_range" 121}; 122 123const char *acpi_gbl_RWdecode[2] = { 124 "read_only", 125 "read_write" 126}; 127 128const char *acpi_gbl_SHRdecode[2] = { 129 "Exclusive", 130 "Shared" 131}; 132 133const char *acpi_gbl_SIZdecode[4] = { 134 "Transfer8", 135 "Transfer8_16", 136 "Transfer16", 137 "invalid_size" 138}; 139 140const char *acpi_gbl_TRSdecode[2] = { 141 "dense_translation", 142 "sparse_translation" 143}; 144 145const char *acpi_gbl_TTPdecode[2] = { 146 "type_static", 147 "type_translation" 148}; 149 150const char *acpi_gbl_TYPdecode[4] = { 151 "Compatibility", 152 "type_a", 153 "type_b", 154 "type_f" 155}; 156 157#endif 158 159/* 160 * Base sizes of the raw AML resource descriptors, indexed by resource type. 161 * Zero indicates a reserved (and therefore invalid) resource type. 162 */ 163const u8 acpi_gbl_resource_aml_sizes[] = { 164 /* Small descriptors */ 165 166 0, 167 0, 168 0, 169 0, 170 ACPI_AML_SIZE_SMALL(struct aml_resource_irq), 171 ACPI_AML_SIZE_SMALL(struct aml_resource_dma), 172 ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent), 173 ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent), 174 ACPI_AML_SIZE_SMALL(struct aml_resource_io), 175 ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io), 176 0, 177 0, 178 0, 179 0, 180 ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small), 181 ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag), 182 183 /* Large descriptors */ 184 185 0, 186 ACPI_AML_SIZE_LARGE(struct aml_resource_memory24), 187 ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register), 188 0, 189 ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large), 190 ACPI_AML_SIZE_LARGE(struct aml_resource_memory32), 191 ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32), 192 ACPI_AML_SIZE_LARGE(struct aml_resource_address32), 193 ACPI_AML_SIZE_LARGE(struct aml_resource_address16), 194 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq), 195 ACPI_AML_SIZE_LARGE(struct aml_resource_address64), 196 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64) 197}; 198 199/* 200 * Resource types, used to validate the resource length field. 201 * The length of fixed-length types must match exactly, variable 202 * lengths must meet the minimum required length, etc. 203 * Zero indicates a reserved (and therefore invalid) resource type. 204 */ 205static const u8 acpi_gbl_resource_types[] = { 206 /* Small descriptors */ 207 208 0, 209 0, 210 0, 211 0, 212 ACPI_SMALL_VARIABLE_LENGTH, 213 ACPI_FIXED_LENGTH, 214 ACPI_SMALL_VARIABLE_LENGTH, 215 ACPI_FIXED_LENGTH, 216 ACPI_FIXED_LENGTH, 217 ACPI_FIXED_LENGTH, 218 0, 219 0, 220 0, 221 0, 222 ACPI_VARIABLE_LENGTH, 223 ACPI_FIXED_LENGTH, 224 225 /* Large descriptors */ 226 227 0, 228 ACPI_FIXED_LENGTH, 229 ACPI_FIXED_LENGTH, 230 0, 231 ACPI_VARIABLE_LENGTH, 232 ACPI_FIXED_LENGTH, 233 ACPI_FIXED_LENGTH, 234 ACPI_VARIABLE_LENGTH, 235 ACPI_VARIABLE_LENGTH, 236 ACPI_VARIABLE_LENGTH, 237 ACPI_VARIABLE_LENGTH, 238 ACPI_FIXED_LENGTH 239}; 240 241/******************************************************************************* 242 * 243 * FUNCTION: acpi_ut_validate_resource 244 * 245 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 246 * return_index - Where the resource index is returned. NULL 247 * if the index is not required. 248 * 249 * RETURN: Status, and optionally the Index into the global resource tables 250 * 251 * DESCRIPTION: Validate an AML resource descriptor by checking the Resource 252 * Type and Resource Length. Returns an index into the global 253 * resource information/dispatch tables for later use. 254 * 255 ******************************************************************************/ 256 257acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index) 258{ 259 u8 resource_type; 260 u8 resource_index; 261 acpi_rs_length resource_length; 262 acpi_rs_length minimum_resource_length; 263 264 ACPI_FUNCTION_ENTRY(); 265 266 /* 267 * 1) Validate the resource_type field (Byte 0) 268 */ 269 resource_type = ACPI_GET8(aml); 270 271 /* 272 * Byte 0 contains the descriptor name (Resource Type) 273 * Examine the large/small bit in the resource header 274 */ 275 if (resource_type & ACPI_RESOURCE_NAME_LARGE) { 276 /* Verify the large resource type (name) against the max */ 277 278 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { 279 return (AE_AML_INVALID_RESOURCE_TYPE); 280 } 281 282 /* 283 * Large Resource Type -- bits 6:0 contain the name 284 * Translate range 0x80-0x8B to index range 0x10-0x1B 285 */ 286 resource_index = (u8) (resource_type - 0x70); 287 } else { 288 /* 289 * Small Resource Type -- bits 6:3 contain the name 290 * Shift range to index range 0x00-0x0F 291 */ 292 resource_index = (u8) 293 ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3); 294 } 295 296 /* Check validity of the resource type, zero indicates name is invalid */ 297 298 if (!acpi_gbl_resource_types[resource_index]) { 299 return (AE_AML_INVALID_RESOURCE_TYPE); 300 } 301 302 /* 303 * 2) Validate the resource_length field. This ensures that the length 304 * is at least reasonable, and guarantees that it is non-zero. 305 */ 306 resource_length = acpi_ut_get_resource_length(aml); 307 minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index]; 308 309 /* Validate based upon the type of resource - fixed length or variable */ 310 311 switch (acpi_gbl_resource_types[resource_index]) { 312 case ACPI_FIXED_LENGTH: 313 314 /* Fixed length resource, length must match exactly */ 315 316 if (resource_length != minimum_resource_length) { 317 return (AE_AML_BAD_RESOURCE_LENGTH); 318 } 319 break; 320 321 case ACPI_VARIABLE_LENGTH: 322 323 /* Variable length resource, length must be at least the minimum */ 324 325 if (resource_length < minimum_resource_length) { 326 return (AE_AML_BAD_RESOURCE_LENGTH); 327 } 328 break; 329 330 case ACPI_SMALL_VARIABLE_LENGTH: 331 332 /* Small variable length resource, length can be (Min) or (Min-1) */ 333 334 if ((resource_length > minimum_resource_length) || 335 (resource_length < (minimum_resource_length - 1))) { 336 return (AE_AML_BAD_RESOURCE_LENGTH); 337 } 338 break; 339 340 default: 341 342 /* Shouldn't happen (because of validation earlier), but be sure */ 343 344 return (AE_AML_INVALID_RESOURCE_TYPE); 345 } 346 347 /* Optionally return the resource table index */ 348 349 if (return_index) { 350 *return_index = resource_index; 351 } 352 353 return (AE_OK); 354} 355 356/******************************************************************************* 357 * 358 * FUNCTION: acpi_ut_get_resource_type 359 * 360 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 361 * 362 * RETURN: The Resource Type with no extraneous bits (except the 363 * Large/Small descriptor bit -- this is left alone) 364 * 365 * DESCRIPTION: Extract the Resource Type/Name from the first byte of 366 * a resource descriptor. 367 * 368 ******************************************************************************/ 369 370u8 acpi_ut_get_resource_type(void *aml) 371{ 372 ACPI_FUNCTION_ENTRY(); 373 374 /* 375 * Byte 0 contains the descriptor name (Resource Type) 376 * Examine the large/small bit in the resource header 377 */ 378 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { 379 /* Large Resource Type -- bits 6:0 contain the name */ 380 381 return (ACPI_GET8(aml)); 382 } else { 383 /* Small Resource Type -- bits 6:3 contain the name */ 384 385 return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK)); 386 } 387} 388 389/******************************************************************************* 390 * 391 * FUNCTION: acpi_ut_get_resource_length 392 * 393 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 394 * 395 * RETURN: Byte Length 396 * 397 * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By 398 * definition, this does not include the size of the descriptor 399 * header or the length field itself. 400 * 401 ******************************************************************************/ 402 403u16 acpi_ut_get_resource_length(void *aml) 404{ 405 acpi_rs_length resource_length; 406 407 ACPI_FUNCTION_ENTRY(); 408 409 /* 410 * Byte 0 contains the descriptor name (Resource Type) 411 * Examine the large/small bit in the resource header 412 */ 413 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { 414 /* Large Resource type -- bytes 1-2 contain the 16-bit length */ 415 416 ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1)); 417 418 } else { 419 /* Small Resource type -- bits 2:0 of byte 0 contain the length */ 420 421 resource_length = (u16) (ACPI_GET8(aml) & 422 ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); 423 } 424 425 return (resource_length); 426} 427 428/******************************************************************************* 429 * 430 * FUNCTION: acpi_ut_get_resource_header_length 431 * 432 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 433 * 434 * RETURN: Length of the AML header (depends on large/small descriptor) 435 * 436 * DESCRIPTION: Get the length of the header for this resource. 437 * 438 ******************************************************************************/ 439 440u8 acpi_ut_get_resource_header_length(void *aml) 441{ 442 ACPI_FUNCTION_ENTRY(); 443 444 /* Examine the large/small bit in the resource header */ 445 446 if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) { 447 return (sizeof(struct aml_resource_large_header)); 448 } else { 449 return (sizeof(struct aml_resource_small_header)); 450 } 451} 452 453/******************************************************************************* 454 * 455 * FUNCTION: acpi_ut_get_descriptor_length 456 * 457 * PARAMETERS: Aml - Pointer to the raw AML resource descriptor 458 * 459 * RETURN: Byte length 460 * 461 * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the 462 * length of the descriptor header and the length field itself. 463 * Used to walk descriptor lists. 464 * 465 ******************************************************************************/ 466 467u32 acpi_ut_get_descriptor_length(void *aml) 468{ 469 ACPI_FUNCTION_ENTRY(); 470 471 /* 472 * Get the Resource Length (does not include header length) and add 473 * the header length (depends on if this is a small or large resource) 474 */ 475 return (acpi_ut_get_resource_length(aml) + 476 acpi_ut_get_resource_header_length(aml)); 477} 478 479/******************************************************************************* 480 * 481 * FUNCTION: acpi_ut_get_resource_end_tag 482 * 483 * PARAMETERS: obj_desc - The resource template buffer object 484 * end_tag - Where the pointer to the end_tag is returned 485 * 486 * RETURN: Status, pointer to the end tag 487 * 488 * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template 489 * Note: allows a buffer length of zero. 490 * 491 ******************************************************************************/ 492 493acpi_status 494acpi_ut_get_resource_end_tag(union acpi_operand_object * obj_desc, 495 u8 ** end_tag) 496{ 497 acpi_status status; 498 u8 *aml; 499 u8 *end_aml; 500 501 ACPI_FUNCTION_TRACE("ut_get_resource_end_tag"); 502 503 /* Get start and end pointers */ 504 505 aml = obj_desc->buffer.pointer; 506 end_aml = aml + obj_desc->buffer.length; 507 508 /* Allow a buffer length of zero */ 509 510 if (!obj_desc->buffer.length) { 511 *end_tag = aml; 512 return_ACPI_STATUS(AE_OK); 513 } 514 515 /* Walk the resource template, one descriptor per iteration */ 516 517 while (aml < end_aml) { 518 /* Validate the Resource Type and Resource Length */ 519 520 status = acpi_ut_validate_resource(aml, NULL); 521 if (ACPI_FAILURE(status)) { 522 return_ACPI_STATUS(status); 523 } 524 525 /* end_tag resource indicates the end of the resource template */ 526 527 if (acpi_ut_get_resource_type(aml) == 528 ACPI_RESOURCE_NAME_END_TAG) { 529 /* 530 * There must be at least one more byte in the buffer for 531 * the 2nd byte of the end_tag 532 */ 533 if ((aml + 1) >= end_aml) { 534 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 535 } 536 537 /* Return the pointer to the end_tag */ 538 539 *end_tag = aml; 540 return_ACPI_STATUS(AE_OK); 541 } 542 543 /* 544 * Point to the next resource descriptor in the AML buffer. The 545 * descriptor length is guaranteed to be non-zero by resource 546 * validation above. 547 */ 548 aml += acpi_ut_get_descriptor_length(aml); 549 } 550 551 /* Did not find an end_tag resource descriptor */ 552 553 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 554}