diff options
Diffstat (limited to 'drivers/acpi/executer/exprep.c')
| -rw-r--r-- | drivers/acpi/executer/exprep.c | 104 |
1 files changed, 69 insertions, 35 deletions
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c index 264ef3bba31b..c9e3c68b5549 100644 --- a/drivers/acpi/executer/exprep.c +++ b/drivers/acpi/executer/exprep.c | |||
| @@ -52,8 +52,23 @@ | |||
| 52 | #define _COMPONENT ACPI_EXECUTER | 52 | #define _COMPONENT ACPI_EXECUTER |
| 53 | ACPI_MODULE_NAME ("exprep") | 53 | ACPI_MODULE_NAME ("exprep") |
| 54 | 54 | ||
| 55 | /* Local prototypes */ | ||
| 56 | |||
| 57 | static u32 | ||
| 58 | acpi_ex_decode_field_access ( | ||
| 59 | union acpi_operand_object *obj_desc, | ||
| 60 | u8 field_flags, | ||
| 61 | u32 *return_byte_alignment); | ||
| 62 | |||
| 55 | 63 | ||
| 56 | #ifdef ACPI_UNDER_DEVELOPMENT | 64 | #ifdef ACPI_UNDER_DEVELOPMENT |
| 65 | |||
| 66 | static u32 | ||
| 67 | acpi_ex_generate_access ( | ||
| 68 | u32 field_bit_offset, | ||
| 69 | u32 field_bit_length, | ||
| 70 | u32 region_length); | ||
| 71 | |||
| 57 | /******************************************************************************* | 72 | /******************************************************************************* |
| 58 | * | 73 | * |
| 59 | * FUNCTION: acpi_ex_generate_access | 74 | * FUNCTION: acpi_ex_generate_access |
| @@ -99,12 +114,14 @@ acpi_ex_generate_access ( | |||
| 99 | /* Round Field start offset and length to "minimal" byte boundaries */ | 114 | /* Round Field start offset and length to "minimal" byte boundaries */ |
| 100 | 115 | ||
| 101 | field_byte_offset = ACPI_DIV_8 (ACPI_ROUND_DOWN (field_bit_offset, 8)); | 116 | field_byte_offset = ACPI_DIV_8 (ACPI_ROUND_DOWN (field_bit_offset, 8)); |
| 102 | field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length + field_bit_offset, 8)); | 117 | field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length + |
| 118 | field_bit_offset, 8)); | ||
| 103 | field_byte_length = field_byte_end_offset - field_byte_offset; | 119 | field_byte_length = field_byte_end_offset - field_byte_offset; |
| 104 | 120 | ||
| 105 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, | 121 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
| 106 | "Bit length %d, Bit offset %d\n", | 122 | "Bit length %d, Bit offset %d\n", |
| 107 | field_bit_length, field_bit_offset)); | 123 | field_bit_length, field_bit_offset)); |
| 124 | |||
| 108 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, | 125 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
| 109 | "Byte Length %d, Byte Offset %d, End Offset %d\n", | 126 | "Byte Length %d, Byte Offset %d, End Offset %d\n", |
| 110 | field_byte_length, field_byte_offset, field_byte_end_offset)); | 127 | field_byte_length, field_byte_offset, field_byte_end_offset)); |
| @@ -117,20 +134,26 @@ acpi_ex_generate_access ( | |||
| 117 | */ | 134 | */ |
| 118 | for (access_byte_width = 1; access_byte_width <= 8; access_byte_width <<= 1) { | 135 | for (access_byte_width = 1; access_byte_width <= 8; access_byte_width <<= 1) { |
| 119 | /* | 136 | /* |
| 120 | * 1) Round end offset up to next access boundary and make sure that this | 137 | * 1) Round end offset up to next access boundary and make sure that |
| 121 | * does not go beyond the end of the parent region. | 138 | * this does not go beyond the end of the parent region. |
| 122 | * 2) When the Access width is greater than the field_byte_length, we are done. | 139 | * 2) When the Access width is greater than the field_byte_length, we |
| 123 | * (This does not optimize for the perfectly aligned case yet). | 140 | * are done. (This does not optimize for the perfectly aligned |
| 141 | * case yet). | ||
| 124 | */ | 142 | */ |
| 125 | if (ACPI_ROUND_UP (field_byte_end_offset, access_byte_width) <= region_length) { | 143 | if (ACPI_ROUND_UP (field_byte_end_offset, access_byte_width) <= region_length) { |
| 126 | field_start_offset = ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) / | 144 | field_start_offset = |
| 127 | access_byte_width; | 145 | ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) / |
| 128 | field_end_offset = ACPI_ROUND_UP ((field_byte_length + field_byte_offset), | 146 | access_byte_width; |
| 129 | access_byte_width) / access_byte_width; | 147 | |
| 130 | accesses = field_end_offset - field_start_offset; | 148 | field_end_offset = |
| 149 | ACPI_ROUND_UP ((field_byte_length + field_byte_offset), | ||
| 150 | access_byte_width) / access_byte_width; | ||
| 151 | |||
| 152 | accesses = field_end_offset - field_start_offset; | ||
| 131 | 153 | ||
| 132 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, | 154 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
| 133 | "access_width %d end is within region\n", access_byte_width)); | 155 | "access_width %d end is within region\n", access_byte_width)); |
| 156 | |||
| 134 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, | 157 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
| 135 | "Field Start %d, Field End %d -- requires %d accesses\n", | 158 | "Field Start %d, Field End %d -- requires %d accesses\n", |
| 136 | field_start_offset, field_end_offset, accesses)); | 159 | field_start_offset, field_end_offset, accesses)); |
| @@ -139,8 +162,8 @@ acpi_ex_generate_access ( | |||
| 139 | 162 | ||
| 140 | if (accesses <= 1) { | 163 | if (accesses <= 1) { |
| 141 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, | 164 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
| 142 | "Entire field can be accessed with one operation of size %d\n", | 165 | "Entire field can be accessed with one operation of size %d\n", |
| 143 | access_byte_width)); | 166 | access_byte_width)); |
| 144 | return_VALUE (access_byte_width); | 167 | return_VALUE (access_byte_width); |
| 145 | } | 168 | } |
| 146 | 169 | ||
| @@ -155,15 +178,20 @@ acpi_ex_generate_access ( | |||
| 155 | } | 178 | } |
| 156 | else { | 179 | else { |
| 157 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, | 180 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
| 158 | "access_width %d end is NOT within region\n", access_byte_width)); | 181 | "access_width %d end is NOT within region\n", access_byte_width)); |
| 159 | if (access_byte_width == 1) { | 182 | if (access_byte_width == 1) { |
| 160 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, | 183 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
| 161 | "Field goes beyond end-of-region!\n")); | 184 | "Field goes beyond end-of-region!\n")); |
| 162 | return_VALUE (0); /* Field does not fit in the region at all */ | ||
| 163 | } | ||
| 164 | 185 | ||
| 165 | /* This width goes beyond the end-of-region, back off to previous access */ | 186 | /* Field does not fit in the region at all */ |
| 166 | 187 | ||
| 188 | return_VALUE (0); | ||
| 189 | } | ||
| 190 | |||
| 191 | /* | ||
| 192 | * This width goes beyond the end-of-region, back off to | ||
| 193 | * previous access | ||
| 194 | */ | ||
| 167 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, | 195 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
| 168 | "Backing off to previous optimal access width of %d\n", | 196 | "Backing off to previous optimal access width of %d\n", |
| 169 | minimum_access_width)); | 197 | minimum_access_width)); |
| @@ -171,8 +199,10 @@ acpi_ex_generate_access ( | |||
| 171 | } | 199 | } |
| 172 | } | 200 | } |
| 173 | 201 | ||
| 174 | /* Could not read/write field with one operation, just use max access width */ | 202 | /* |
| 175 | 203 | * Could not read/write field with one operation, | |
| 204 | * just use max access width | ||
| 205 | */ | ||
| 176 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, | 206 | ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, |
| 177 | "Cannot access field in one operation, using width 8\n")); | 207 | "Cannot access field in one operation, using width 8\n")); |
| 178 | return_VALUE (8); | 208 | return_VALUE (8); |
| @@ -184,8 +214,9 @@ acpi_ex_generate_access ( | |||
| 184 | * | 214 | * |
| 185 | * FUNCTION: acpi_ex_decode_field_access | 215 | * FUNCTION: acpi_ex_decode_field_access |
| 186 | * | 216 | * |
| 187 | * PARAMETERS: Access - Encoded field access bits | 217 | * PARAMETERS: obj_desc - Field object |
| 188 | * Length - Field length. | 218 | * field_flags - Encoded fieldflags (contains access bits) |
| 219 | * return_byte_alignment - Where the byte alignment is returned | ||
| 189 | * | 220 | * |
| 190 | * RETURN: Field granularity (8, 16, 32 or 64) and | 221 | * RETURN: Field granularity (8, 16, 32 or 64) and |
| 191 | * byte_alignment (1, 2, 3, or 4) | 222 | * byte_alignment (1, 2, 3, or 4) |
| @@ -214,9 +245,10 @@ acpi_ex_decode_field_access ( | |||
| 214 | case AML_FIELD_ACCESS_ANY: | 245 | case AML_FIELD_ACCESS_ANY: |
| 215 | 246 | ||
| 216 | #ifdef ACPI_UNDER_DEVELOPMENT | 247 | #ifdef ACPI_UNDER_DEVELOPMENT |
| 217 | byte_alignment = acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset, | 248 | byte_alignment = |
| 218 | obj_desc->common_field.bit_length, | 249 | acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset, |
| 219 | 0xFFFFFFFF /* Temp until we pass region_length as param */); | 250 | obj_desc->common_field.bit_length, |
| 251 | 0xFFFFFFFF /* Temp until we pass region_length as parameter */); | ||
| 220 | bit_length = byte_alignment * 8; | 252 | bit_length = byte_alignment * 8; |
| 221 | #endif | 253 | #endif |
| 222 | 254 | ||
| @@ -276,6 +308,7 @@ acpi_ex_decode_field_access ( | |||
| 276 | * field_flags - Access, lock_rule, and update_rule. | 308 | * field_flags - Access, lock_rule, and update_rule. |
| 277 | * The format of a field_flag is described | 309 | * The format of a field_flag is described |
| 278 | * in the ACPI specification | 310 | * in the ACPI specification |
| 311 | * field_attribute - Special attributes (not used) | ||
| 279 | * field_bit_position - Field start position | 312 | * field_bit_position - Field start position |
| 280 | * field_bit_length - Field length in number of bits | 313 | * field_bit_length - Field length in number of bits |
| 281 | * | 314 | * |
| @@ -337,7 +370,7 @@ acpi_ex_prep_common_field_object ( | |||
| 337 | /* Setup width (access granularity) fields */ | 370 | /* Setup width (access granularity) fields */ |
| 338 | 371 | ||
| 339 | obj_desc->common_field.access_byte_width = (u8) | 372 | obj_desc->common_field.access_byte_width = (u8) |
| 340 | ACPI_DIV_8 (access_bit_width); /* 1, 2, 4, 8 */ | 373 | ACPI_DIV_8 (access_bit_width); /* 1, 2, 4, 8 */ |
| 341 | 374 | ||
| 342 | obj_desc->common_field.access_bit_width = (u8) access_bit_width; | 375 | obj_desc->common_field.access_bit_width = (u8) access_bit_width; |
| 343 | 376 | ||
| @@ -380,11 +413,7 @@ acpi_ex_prep_common_field_object ( | |||
| 380 | * | 413 | * |
| 381 | * FUNCTION: acpi_ex_prep_field_value | 414 | * FUNCTION: acpi_ex_prep_field_value |
| 382 | * | 415 | * |
| 383 | * PARAMETERS: Node - Owning Node | 416 | * PARAMETERS: Info - Contains all field creation info |
| 384 | * region_node - Region in which field is being defined | ||
| 385 | * field_flags - Access, lock_rule, and update_rule. | ||
| 386 | * field_bit_position - Field start position | ||
| 387 | * field_bit_length - Field length in number of bits | ||
| 388 | * | 417 | * |
| 389 | * RETURN: Status | 418 | * RETURN: Status |
| 390 | * | 419 | * |
| @@ -445,7 +474,7 @@ acpi_ex_prep_field_value ( | |||
| 445 | switch (info->field_type) { | 474 | switch (info->field_type) { |
| 446 | case ACPI_TYPE_LOCAL_REGION_FIELD: | 475 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
| 447 | 476 | ||
| 448 | obj_desc->field.region_obj = acpi_ns_get_attached_object (info->region_node); | 477 | obj_desc->field.region_obj = acpi_ns_get_attached_object (info->region_node); |
| 449 | 478 | ||
| 450 | /* An additional reference for the container */ | 479 | /* An additional reference for the container */ |
| 451 | 480 | ||
| @@ -461,8 +490,10 @@ acpi_ex_prep_field_value ( | |||
| 461 | case ACPI_TYPE_LOCAL_BANK_FIELD: | 490 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
| 462 | 491 | ||
| 463 | obj_desc->bank_field.value = info->bank_value; | 492 | obj_desc->bank_field.value = info->bank_value; |
| 464 | obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (info->region_node); | 493 | obj_desc->bank_field.region_obj = acpi_ns_get_attached_object ( |
| 465 | obj_desc->bank_field.bank_obj = acpi_ns_get_attached_object (info->register_node); | 494 | info->region_node); |
| 495 | obj_desc->bank_field.bank_obj = acpi_ns_get_attached_object ( | ||
| 496 | info->register_node); | ||
| 466 | 497 | ||
| 467 | /* An additional reference for the attached objects */ | 498 | /* An additional reference for the attached objects */ |
| 468 | 499 | ||
| @@ -481,10 +512,13 @@ acpi_ex_prep_field_value ( | |||
| 481 | 512 | ||
| 482 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | 513 | case ACPI_TYPE_LOCAL_INDEX_FIELD: |
| 483 | 514 | ||
| 484 | obj_desc->index_field.index_obj = acpi_ns_get_attached_object (info->register_node); | 515 | obj_desc->index_field.index_obj = acpi_ns_get_attached_object ( |
| 485 | obj_desc->index_field.data_obj = acpi_ns_get_attached_object (info->data_register_node); | 516 | info->register_node); |
| 517 | obj_desc->index_field.data_obj = acpi_ns_get_attached_object ( | ||
| 518 | info->data_register_node); | ||
| 486 | obj_desc->index_field.value = (u32) | 519 | obj_desc->index_field.value = (u32) |
| 487 | (info->field_bit_position / ACPI_MUL_8 (obj_desc->field.access_byte_width)); | 520 | (info->field_bit_position / ACPI_MUL_8 ( |
| 521 | obj_desc->field.access_byte_width)); | ||
| 488 | 522 | ||
| 489 | if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) { | 523 | if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) { |
| 490 | ACPI_REPORT_ERROR (("Null Index Object during field prep\n")); | 524 | ACPI_REPORT_ERROR (("Null Index Object during field prep\n")); |
