diff options
Diffstat (limited to 'drivers/acpi/executer/exfldio.c')
| -rw-r--r-- | drivers/acpi/executer/exfldio.c | 133 |
1 files changed, 87 insertions, 46 deletions
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index 9d0f9d2e9061..3c2f89e00f78 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c | |||
| @@ -52,12 +52,31 @@ | |||
| 52 | #define _COMPONENT ACPI_EXECUTER | 52 | #define _COMPONENT ACPI_EXECUTER |
| 53 | ACPI_MODULE_NAME ("exfldio") | 53 | ACPI_MODULE_NAME ("exfldio") |
| 54 | 54 | ||
| 55 | /* Local prototypes */ | ||
| 56 | |||
| 57 | static acpi_status | ||
| 58 | acpi_ex_field_datum_io ( | ||
| 59 | union acpi_operand_object *obj_desc, | ||
| 60 | u32 field_datum_byte_offset, | ||
| 61 | acpi_integer *value, | ||
| 62 | u32 read_write); | ||
| 63 | |||
| 64 | static u8 | ||
| 65 | acpi_ex_register_overflow ( | ||
| 66 | union acpi_operand_object *obj_desc, | ||
| 67 | acpi_integer value); | ||
| 68 | |||
| 69 | static acpi_status | ||
| 70 | acpi_ex_setup_region ( | ||
| 71 | union acpi_operand_object *obj_desc, | ||
| 72 | u32 field_datum_byte_offset); | ||
| 73 | |||
| 55 | 74 | ||
| 56 | /******************************************************************************* | 75 | /******************************************************************************* |
| 57 | * | 76 | * |
| 58 | * FUNCTION: acpi_ex_setup_region | 77 | * FUNCTION: acpi_ex_setup_region |
| 59 | * | 78 | * |
| 60 | * PARAMETERS: *obj_desc - Field to be read or written | 79 | * PARAMETERS: obj_desc - Field to be read or written |
| 61 | * field_datum_byte_offset - Byte offset of this datum within the | 80 | * field_datum_byte_offset - Byte offset of this datum within the |
| 62 | * parent field | 81 | * parent field |
| 63 | * | 82 | * |
| @@ -69,7 +88,7 @@ | |||
| 69 | * | 88 | * |
| 70 | ******************************************************************************/ | 89 | ******************************************************************************/ |
| 71 | 90 | ||
| 72 | acpi_status | 91 | static acpi_status |
| 73 | acpi_ex_setup_region ( | 92 | acpi_ex_setup_region ( |
| 74 | union acpi_operand_object *obj_desc, | 93 | union acpi_operand_object *obj_desc, |
| 75 | u32 field_datum_byte_offset) | 94 | u32 field_datum_byte_offset) |
| @@ -127,9 +146,9 @@ acpi_ex_setup_region ( | |||
| 127 | * length of one field datum (access width) must fit within the region. | 146 | * length of one field datum (access width) must fit within the region. |
| 128 | * (Region length is specified in bytes) | 147 | * (Region length is specified in bytes) |
| 129 | */ | 148 | */ |
| 130 | if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset | 149 | if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset + |
| 131 | + field_datum_byte_offset | 150 | field_datum_byte_offset + |
| 132 | + obj_desc->common_field.access_byte_width)) { | 151 | obj_desc->common_field.access_byte_width)) { |
| 133 | if (acpi_gbl_enable_interpreter_slack) { | 152 | if (acpi_gbl_enable_interpreter_slack) { |
| 134 | /* | 153 | /* |
| 135 | * Slack mode only: We will go ahead and allow access to this | 154 | * Slack mode only: We will go ahead and allow access to this |
| @@ -155,7 +174,8 @@ acpi_ex_setup_region ( | |||
| 155 | "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n", | 174 | "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n", |
| 156 | acpi_ut_get_node_name (obj_desc->common_field.node), | 175 | acpi_ut_get_node_name (obj_desc->common_field.node), |
| 157 | obj_desc->common_field.access_byte_width, | 176 | obj_desc->common_field.access_byte_width, |
| 158 | acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length)); | 177 | acpi_ut_get_node_name (rgn_desc->region.node), |
| 178 | rgn_desc->region.length)); | ||
| 159 | } | 179 | } |
| 160 | 180 | ||
| 161 | /* | 181 | /* |
| @@ -167,7 +187,8 @@ acpi_ex_setup_region ( | |||
| 167 | acpi_ut_get_node_name (obj_desc->common_field.node), | 187 | acpi_ut_get_node_name (obj_desc->common_field.node), |
| 168 | obj_desc->common_field.base_byte_offset, | 188 | obj_desc->common_field.base_byte_offset, |
| 169 | field_datum_byte_offset, obj_desc->common_field.access_byte_width, | 189 | field_datum_byte_offset, obj_desc->common_field.access_byte_width, |
| 170 | acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length)); | 190 | acpi_ut_get_node_name (rgn_desc->region.node), |
| 191 | rgn_desc->region.length)); | ||
| 171 | 192 | ||
| 172 | return_ACPI_STATUS (AE_AML_REGION_LIMIT); | 193 | return_ACPI_STATUS (AE_AML_REGION_LIMIT); |
| 173 | } | 194 | } |
| @@ -180,10 +201,10 @@ acpi_ex_setup_region ( | |||
| 180 | * | 201 | * |
| 181 | * FUNCTION: acpi_ex_access_region | 202 | * FUNCTION: acpi_ex_access_region |
| 182 | * | 203 | * |
| 183 | * PARAMETERS: *obj_desc - Field to be read | 204 | * PARAMETERS: obj_desc - Field to be read |
| 184 | * field_datum_byte_offset - Byte offset of this datum within the | 205 | * field_datum_byte_offset - Byte offset of this datum within the |
| 185 | * parent field | 206 | * parent field |
| 186 | * *Value - Where to store value (must at least | 207 | * Value - Where to store value (must at least |
| 187 | * the size of acpi_integer) | 208 | * the size of acpi_integer) |
| 188 | * Function - Read or Write flag plus other region- | 209 | * Function - Read or Write flag plus other region- |
| 189 | * dependent flags | 210 | * dependent flags |
| @@ -226,9 +247,9 @@ acpi_ex_access_region ( | |||
| 226 | * 3) The current offset into the field | 247 | * 3) The current offset into the field |
| 227 | */ | 248 | */ |
| 228 | rgn_desc = obj_desc->common_field.region_obj; | 249 | rgn_desc = obj_desc->common_field.region_obj; |
| 229 | address = rgn_desc->region.address | 250 | address = rgn_desc->region.address + |
| 230 | + obj_desc->common_field.base_byte_offset | 251 | obj_desc->common_field.base_byte_offset + |
| 231 | + field_datum_byte_offset; | 252 | field_datum_byte_offset; |
| 232 | 253 | ||
| 233 | if ((function & ACPI_IO_MASK) == ACPI_READ) { | 254 | if ((function & ACPI_IO_MASK) == ACPI_READ) { |
| 234 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]")); | 255 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]")); |
| @@ -249,7 +270,8 @@ acpi_ex_access_region ( | |||
| 249 | /* Invoke the appropriate address_space/op_region handler */ | 270 | /* Invoke the appropriate address_space/op_region handler */ |
| 250 | 271 | ||
| 251 | status = acpi_ev_address_space_dispatch (rgn_desc, function, | 272 | status = acpi_ev_address_space_dispatch (rgn_desc, function, |
| 252 | address, ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value); | 273 | address, |
| 274 | ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value); | ||
| 253 | 275 | ||
| 254 | if (ACPI_FAILURE (status)) { | 276 | if (ACPI_FAILURE (status)) { |
| 255 | if (status == AE_NOT_IMPLEMENTED) { | 277 | if (status == AE_NOT_IMPLEMENTED) { |
| @@ -274,7 +296,7 @@ acpi_ex_access_region ( | |||
| 274 | * | 296 | * |
| 275 | * FUNCTION: acpi_ex_register_overflow | 297 | * FUNCTION: acpi_ex_register_overflow |
| 276 | * | 298 | * |
| 277 | * PARAMETERS: *obj_desc - Register(Field) to be written | 299 | * PARAMETERS: obj_desc - Register(Field) to be written |
| 278 | * Value - Value to be stored | 300 | * Value - Value to be stored |
| 279 | * | 301 | * |
| 280 | * RETURN: TRUE if value overflows the field, FALSE otherwise | 302 | * RETURN: TRUE if value overflows the field, FALSE otherwise |
| @@ -287,7 +309,7 @@ acpi_ex_access_region ( | |||
| 287 | * | 309 | * |
| 288 | ******************************************************************************/ | 310 | ******************************************************************************/ |
| 289 | 311 | ||
| 290 | u8 | 312 | static u8 |
| 291 | acpi_ex_register_overflow ( | 313 | acpi_ex_register_overflow ( |
| 292 | union acpi_operand_object *obj_desc, | 314 | union acpi_operand_object *obj_desc, |
| 293 | acpi_integer value) | 315 | acpi_integer value) |
| @@ -319,10 +341,10 @@ acpi_ex_register_overflow ( | |||
| 319 | * | 341 | * |
| 320 | * FUNCTION: acpi_ex_field_datum_io | 342 | * FUNCTION: acpi_ex_field_datum_io |
| 321 | * | 343 | * |
| 322 | * PARAMETERS: *obj_desc - Field to be read | 344 | * PARAMETERS: obj_desc - Field to be read |
| 323 | * field_datum_byte_offset - Byte offset of this datum within the | 345 | * field_datum_byte_offset - Byte offset of this datum within the |
| 324 | * parent field | 346 | * parent field |
| 325 | * *Value - Where to store value (must be 64 bits) | 347 | * Value - Where to store value (must be 64 bits) |
| 326 | * read_write - Read or Write flag | 348 | * read_write - Read or Write flag |
| 327 | * | 349 | * |
| 328 | * RETURN: Status | 350 | * RETURN: Status |
| @@ -333,7 +355,7 @@ acpi_ex_register_overflow ( | |||
| 333 | * | 355 | * |
| 334 | ******************************************************************************/ | 356 | ******************************************************************************/ |
| 335 | 357 | ||
| 336 | acpi_status | 358 | static acpi_status |
| 337 | acpi_ex_field_datum_io ( | 359 | acpi_ex_field_datum_io ( |
| 338 | union acpi_operand_object *obj_desc, | 360 | union acpi_operand_object *obj_desc, |
| 339 | u32 field_datum_byte_offset, | 361 | u32 field_datum_byte_offset, |
| @@ -350,7 +372,9 @@ acpi_ex_field_datum_io ( | |||
| 350 | if (read_write == ACPI_READ) { | 372 | if (read_write == ACPI_READ) { |
| 351 | if (!value) { | 373 | if (!value) { |
| 352 | local_value = 0; | 374 | local_value = 0; |
| 353 | value = &local_value; /* To support reads without saving return value */ | 375 | |
| 376 | /* To support reads without saving return value */ | ||
| 377 | value = &local_value; | ||
| 354 | } | 378 | } |
| 355 | 379 | ||
| 356 | /* Clear the entire return buffer first, [Very Important!] */ | 380 | /* Clear the entire return buffer first, [Very Important!] */ |
| @@ -363,8 +387,10 @@ acpi_ex_field_datum_io ( | |||
| 363 | * | 387 | * |
| 364 | * buffer_field - Read/write from/to a Buffer | 388 | * buffer_field - Read/write from/to a Buffer |
| 365 | * region_field - Read/write from/to a Operation Region. | 389 | * region_field - Read/write from/to a Operation Region. |
| 366 | * bank_field - Write to a Bank Register, then read/write from/to an op_region | 390 | * bank_field - Write to a Bank Register, then read/write from/to an |
| 367 | * index_field - Write to an Index Register, then read/write from/to a Data Register | 391 | * operation_region |
| 392 | * index_field - Write to an Index Register, then read/write from/to a | ||
| 393 | * Data Register | ||
| 368 | */ | 394 | */ |
| 369 | switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { | 395 | switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { |
| 370 | case ACPI_TYPE_BUFFER_FIELD: | 396 | case ACPI_TYPE_BUFFER_FIELD: |
| @@ -384,19 +410,20 @@ acpi_ex_field_datum_io ( | |||
| 384 | * Copy the data from the source buffer. | 410 | * Copy the data from the source buffer. |
| 385 | * Length is the field width in bytes. | 411 | * Length is the field width in bytes. |
| 386 | */ | 412 | */ |
| 387 | ACPI_MEMCPY (value, (obj_desc->buffer_field.buffer_obj)->buffer.pointer | 413 | ACPI_MEMCPY (value, |
| 388 | + obj_desc->buffer_field.base_byte_offset | 414 | (obj_desc->buffer_field.buffer_obj)->buffer.pointer + |
| 389 | + field_datum_byte_offset, | 415 | obj_desc->buffer_field.base_byte_offset + |
| 390 | obj_desc->common_field.access_byte_width); | 416 | field_datum_byte_offset, |
| 417 | obj_desc->common_field.access_byte_width); | ||
| 391 | } | 418 | } |
| 392 | else { | 419 | else { |
| 393 | /* | 420 | /* |
| 394 | * Copy the data to the target buffer. | 421 | * Copy the data to the target buffer. |
| 395 | * Length is the field width in bytes. | 422 | * Length is the field width in bytes. |
| 396 | */ | 423 | */ |
| 397 | ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer | 424 | ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer + |
| 398 | + obj_desc->buffer_field.base_byte_offset | 425 | obj_desc->buffer_field.base_byte_offset + |
| 399 | + field_datum_byte_offset, | 426 | field_datum_byte_offset, |
| 400 | value, obj_desc->common_field.access_byte_width); | 427 | value, obj_desc->common_field.access_byte_width); |
| 401 | } | 428 | } |
| 402 | 429 | ||
| @@ -406,8 +433,10 @@ acpi_ex_field_datum_io ( | |||
| 406 | 433 | ||
| 407 | case ACPI_TYPE_LOCAL_BANK_FIELD: | 434 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
| 408 | 435 | ||
| 409 | /* Ensure that the bank_value is not beyond the capacity of the register */ | 436 | /* |
| 410 | 437 | * Ensure that the bank_value is not beyond the capacity of | |
| 438 | * the register | ||
| 439 | */ | ||
| 411 | if (acpi_ex_register_overflow (obj_desc->bank_field.bank_obj, | 440 | if (acpi_ex_register_overflow (obj_desc->bank_field.bank_obj, |
| 412 | (acpi_integer) obj_desc->bank_field.value)) { | 441 | (acpi_integer) obj_desc->bank_field.value)) { |
| 413 | return_ACPI_STATUS (AE_AML_REGISTER_LIMIT); | 442 | return_ACPI_STATUS (AE_AML_REGISTER_LIMIT); |
| @@ -445,8 +474,10 @@ acpi_ex_field_datum_io ( | |||
| 445 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | 474 | case ACPI_TYPE_LOCAL_INDEX_FIELD: |
| 446 | 475 | ||
| 447 | 476 | ||
| 448 | /* Ensure that the index_value is not beyond the capacity of the register */ | 477 | /* |
| 449 | 478 | * Ensure that the index_value is not beyond the capacity of | |
| 479 | * the register | ||
| 480 | */ | ||
| 450 | if (acpi_ex_register_overflow (obj_desc->index_field.index_obj, | 481 | if (acpi_ex_register_overflow (obj_desc->index_field.index_obj, |
| 451 | (acpi_integer) obj_desc->index_field.value)) { | 482 | (acpi_integer) obj_desc->index_field.value)) { |
| 452 | return_ACPI_STATUS (AE_AML_REGISTER_LIMIT); | 483 | return_ACPI_STATUS (AE_AML_REGISTER_LIMIT); |
| @@ -496,14 +527,16 @@ acpi_ex_field_datum_io ( | |||
| 496 | 527 | ||
| 497 | if (ACPI_SUCCESS (status)) { | 528 | if (ACPI_SUCCESS (status)) { |
| 498 | if (read_write == ACPI_READ) { | 529 | if (read_write == ACPI_READ) { |
| 499 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n", | 530 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
| 500 | ACPI_FORMAT_UINT64 (*value), | 531 | "Value Read %8.8X%8.8X, Width %d\n", |
| 501 | obj_desc->common_field.access_byte_width)); | 532 | ACPI_FORMAT_UINT64 (*value), |
| 533 | obj_desc->common_field.access_byte_width)); | ||
| 502 | } | 534 | } |
| 503 | else { | 535 | else { |
| 504 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n", | 536 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
| 505 | ACPI_FORMAT_UINT64 (*value), | 537 | "Value Written %8.8X%8.8X, Width %d\n", |
| 506 | obj_desc->common_field.access_byte_width)); | 538 | ACPI_FORMAT_UINT64 (*value), |
| 539 | obj_desc->common_field.access_byte_width)); | ||
| 507 | } | 540 | } |
| 508 | } | 541 | } |
| 509 | 542 | ||
| @@ -515,8 +548,10 @@ acpi_ex_field_datum_io ( | |||
| 515 | * | 548 | * |
| 516 | * FUNCTION: acpi_ex_write_with_update_rule | 549 | * FUNCTION: acpi_ex_write_with_update_rule |
| 517 | * | 550 | * |
| 518 | * PARAMETERS: *obj_desc - Field to be set | 551 | * PARAMETERS: obj_desc - Field to be written |
| 519 | * Value - Value to store | 552 | * Mask - bitmask within field datum |
| 553 | * field_value - Value to write | ||
| 554 | * field_datum_byte_offset - Offset of datum within field | ||
| 520 | * | 555 | * |
| 521 | * RETURN: Status | 556 | * RETURN: Status |
| 522 | * | 557 | * |
| @@ -689,7 +724,8 @@ acpi_ex_extract_from_field ( | |||
| 689 | /* Merge with previous datum if necessary */ | 724 | /* Merge with previous datum if necessary */ |
| 690 | 725 | ||
| 691 | merged_datum |= raw_datum << | 726 | merged_datum |= raw_datum << |
| 692 | (obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset); | 727 | (obj_desc->common_field.access_bit_width - |
| 728 | obj_desc->common_field.start_field_bit_offset); | ||
| 693 | 729 | ||
| 694 | if (i == datum_count) { | 730 | if (i == datum_count) { |
| 695 | break; | 731 | break; |
| @@ -707,7 +743,8 @@ acpi_ex_extract_from_field ( | |||
| 707 | 743 | ||
| 708 | /* Mask off any extra bits in the last datum */ | 744 | /* Mask off any extra bits in the last datum */ |
| 709 | 745 | ||
| 710 | buffer_tail_bits = obj_desc->common_field.bit_length % obj_desc->common_field.access_bit_width; | 746 | buffer_tail_bits = obj_desc->common_field.bit_length % |
| 747 | obj_desc->common_field.access_bit_width; | ||
| 711 | if (buffer_tail_bits) { | 748 | if (buffer_tail_bits) { |
| 712 | merged_datum &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits); | 749 | merged_datum &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits); |
| 713 | } | 750 | } |
| @@ -791,7 +828,8 @@ acpi_ex_insert_into_field ( | |||
| 791 | /* Write merged datum to the target field */ | 828 | /* Write merged datum to the target field */ |
| 792 | 829 | ||
| 793 | merged_datum &= mask; | 830 | merged_datum &= mask; |
| 794 | status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset); | 831 | status = acpi_ex_write_with_update_rule (obj_desc, mask, |
| 832 | merged_datum, field_offset); | ||
| 795 | if (ACPI_FAILURE (status)) { | 833 | if (ACPI_FAILURE (status)) { |
| 796 | return_ACPI_STATUS (status); | 834 | return_ACPI_STATUS (status); |
| 797 | } | 835 | } |
| @@ -800,7 +838,8 @@ acpi_ex_insert_into_field ( | |||
| 800 | 838 | ||
| 801 | field_offset += obj_desc->common_field.access_byte_width; | 839 | field_offset += obj_desc->common_field.access_byte_width; |
| 802 | merged_datum = raw_datum >> | 840 | merged_datum = raw_datum >> |
| 803 | (obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset); | 841 | (obj_desc->common_field.access_bit_width - |
| 842 | obj_desc->common_field.start_field_bit_offset); | ||
| 804 | mask = ACPI_INTEGER_MAX; | 843 | mask = ACPI_INTEGER_MAX; |
| 805 | 844 | ||
| 806 | if (i == datum_count) { | 845 | if (i == datum_count) { |
| @@ -819,7 +858,8 @@ acpi_ex_insert_into_field ( | |||
| 819 | /* Mask off any extra bits in the last datum */ | 858 | /* Mask off any extra bits in the last datum */ |
| 820 | 859 | ||
| 821 | buffer_tail_bits = (obj_desc->common_field.bit_length + | 860 | buffer_tail_bits = (obj_desc->common_field.bit_length + |
| 822 | obj_desc->common_field.start_field_bit_offset) % obj_desc->common_field.access_bit_width; | 861 | obj_desc->common_field.start_field_bit_offset) % |
| 862 | obj_desc->common_field.access_bit_width; | ||
| 823 | if (buffer_tail_bits) { | 863 | if (buffer_tail_bits) { |
| 824 | mask &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits); | 864 | mask &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits); |
| 825 | } | 865 | } |
| @@ -827,7 +867,8 @@ acpi_ex_insert_into_field ( | |||
| 827 | /* Write the last datum to the field */ | 867 | /* Write the last datum to the field */ |
| 828 | 868 | ||
| 829 | merged_datum &= mask; | 869 | merged_datum &= mask; |
| 830 | status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset); | 870 | status = acpi_ex_write_with_update_rule (obj_desc, |
| 871 | mask, merged_datum, field_offset); | ||
| 831 | 872 | ||
| 832 | return_ACPI_STATUS (status); | 873 | return_ACPI_STATUS (status); |
| 833 | } | 874 | } |
