diff options
| -rw-r--r-- | drivers/acpi/dispatcher/dsfield.c | 121 | ||||
| -rw-r--r-- | drivers/acpi/dispatcher/dswload.c | 6 |
2 files changed, 79 insertions, 48 deletions
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c index e87f6bfbfa5c..0befcff19f5a 100644 --- a/drivers/acpi/dispatcher/dsfield.c +++ b/drivers/acpi/dispatcher/dsfield.c | |||
| @@ -89,12 +89,16 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
| 89 | 89 | ||
| 90 | ACPI_FUNCTION_TRACE(ds_create_buffer_field); | 90 | ACPI_FUNCTION_TRACE(ds_create_buffer_field); |
| 91 | 91 | ||
| 92 | /* Get the name_string argument */ | 92 | /* |
| 93 | 93 | * Get the name_string argument (name of the new buffer_field) | |
| 94 | */ | ||
| 94 | if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { | 95 | if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { |
| 96 | |||
| 97 | /* For create_field, name is the 4th argument */ | ||
| 98 | |||
| 95 | arg = acpi_ps_get_arg(op, 3); | 99 | arg = acpi_ps_get_arg(op, 3); |
| 96 | } else { | 100 | } else { |
| 97 | /* Create Bit/Byte/Word/Dword field */ | 101 | /* For all other create_xXXField operators, name is the 3rd argument */ |
| 98 | 102 | ||
| 99 | arg = acpi_ps_get_arg(op, 2); | 103 | arg = acpi_ps_get_arg(op, 2); |
| 100 | } | 104 | } |
| @@ -107,26 +111,30 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
| 107 | node = walk_state->deferred_node; | 111 | node = walk_state->deferred_node; |
| 108 | status = AE_OK; | 112 | status = AE_OK; |
| 109 | } else { | 113 | } else { |
| 110 | /* | 114 | /* Execute flag should always be set when this function is entered */ |
| 111 | * During the load phase, we want to enter the name of the field into | 115 | |
| 112 | * the namespace. During the execute phase (when we evaluate the size | 116 | if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) { |
| 113 | * operand), we want to lookup the name | 117 | return_ACPI_STATUS(AE_AML_INTERNAL); |
| 114 | */ | ||
| 115 | if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) { | ||
| 116 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE; | ||
| 117 | } else { | ||
| 118 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | ||
| 119 | ACPI_NS_ERROR_IF_FOUND; | ||
| 120 | } | 118 | } |
| 121 | 119 | ||
| 122 | /* | 120 | /* Creating new namespace node, should not already exist */ |
| 123 | * Enter the name_string into the namespace | 121 | |
| 124 | */ | 122 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | |
| 123 | ACPI_NS_ERROR_IF_FOUND; | ||
| 124 | |||
| 125 | /* Mark node temporary if we are executing a method */ | ||
| 126 | |||
| 127 | if (walk_state->method_node) { | ||
| 128 | flags |= ACPI_NS_TEMPORARY; | ||
| 129 | } | ||
| 130 | |||
| 131 | /* Enter the name_string into the namespace */ | ||
| 132 | |||
| 125 | status = | 133 | status = |
| 126 | acpi_ns_lookup(walk_state->scope_info, | 134 | acpi_ns_lookup(walk_state->scope_info, |
| 127 | arg->common.value.string, ACPI_TYPE_ANY, | 135 | arg->common.value.string, ACPI_TYPE_ANY, |
| 128 | ACPI_IMODE_LOAD_PASS1, flags, walk_state, | 136 | ACPI_IMODE_LOAD_PASS1, flags, walk_state, |
| 129 | &(node)); | 137 | &node); |
| 130 | if (ACPI_FAILURE(status)) { | 138 | if (ACPI_FAILURE(status)) { |
| 131 | ACPI_ERROR_NAMESPACE(arg->common.value.string, status); | 139 | ACPI_ERROR_NAMESPACE(arg->common.value.string, status); |
| 132 | return_ACPI_STATUS(status); | 140 | return_ACPI_STATUS(status); |
| @@ -136,13 +144,13 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
| 136 | /* | 144 | /* |
| 137 | * We could put the returned object (Node) on the object stack for later, | 145 | * We could put the returned object (Node) on the object stack for later, |
| 138 | * but for now, we will put it in the "op" object that the parser uses, | 146 | * but for now, we will put it in the "op" object that the parser uses, |
| 139 | * so we can get it again at the end of this scope | 147 | * so we can get it again at the end of this scope. |
| 140 | */ | 148 | */ |
| 141 | op->common.node = node; | 149 | op->common.node = node; |
| 142 | 150 | ||
| 143 | /* | 151 | /* |
| 144 | * If there is no object attached to the node, this node was just created | 152 | * If there is no object attached to the node, this node was just created |
| 145 | * and we need to create the field object. Otherwise, this was a lookup | 153 | * and we need to create the field object. Otherwise, this was a lookup |
| 146 | * of an existing node and we don't want to create the field object again. | 154 | * of an existing node and we don't want to create the field object again. |
| 147 | */ | 155 | */ |
| 148 | obj_desc = acpi_ns_get_attached_object(node); | 156 | obj_desc = acpi_ns_get_attached_object(node); |
| @@ -164,9 +172,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
| 164 | } | 172 | } |
| 165 | 173 | ||
| 166 | /* | 174 | /* |
| 167 | * Remember location in AML stream of the field unit | 175 | * Remember location in AML stream of the field unit opcode and operands -- |
| 168 | * opcode and operands -- since the buffer and index | 176 | * since the buffer and index operands must be evaluated. |
| 169 | * operands must be evaluated. | ||
| 170 | */ | 177 | */ |
| 171 | second_desc = obj_desc->common.next_object; | 178 | second_desc = obj_desc->common.next_object; |
| 172 | second_desc->extra.aml_start = op->named.data; | 179 | second_desc->extra.aml_start = op->named.data; |
| @@ -261,7 +268,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, | |||
| 261 | 268 | ||
| 262 | case AML_INT_NAMEDFIELD_OP: | 269 | case AML_INT_NAMEDFIELD_OP: |
| 263 | 270 | ||
| 264 | /* Lookup the name */ | 271 | /* Lookup the name, it should already exist */ |
| 265 | 272 | ||
| 266 | status = acpi_ns_lookup(walk_state->scope_info, | 273 | status = acpi_ns_lookup(walk_state->scope_info, |
| 267 | (char *)&arg->named.name, | 274 | (char *)&arg->named.name, |
| @@ -272,19 +279,16 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, | |||
| 272 | if (ACPI_FAILURE(status)) { | 279 | if (ACPI_FAILURE(status)) { |
| 273 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, | 280 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, |
| 274 | status); | 281 | status); |
| 275 | if (status != AE_ALREADY_EXISTS) { | 282 | return_ACPI_STATUS(status); |
| 276 | return_ACPI_STATUS(status); | ||
| 277 | } | ||
| 278 | |||
| 279 | /* Already exists, ignore error */ | ||
| 280 | } else { | 283 | } else { |
| 281 | arg->common.node = info->field_node; | 284 | arg->common.node = info->field_node; |
| 282 | info->field_bit_length = arg->common.value.size; | 285 | info->field_bit_length = arg->common.value.size; |
| 283 | 286 | ||
| 284 | /* | 287 | /* |
| 285 | * If there is no object attached to the node, this node was just created | 288 | * If there is no object attached to the node, this node was |
| 286 | * and we need to create the field object. Otherwise, this was a lookup | 289 | * just created and we need to create the field object. |
| 287 | * of an existing node and we don't want to create the field object again. | 290 | * Otherwise, this was a lookup of an existing node and we |
| 291 | * don't want to create the field object again. | ||
| 288 | */ | 292 | */ |
| 289 | if (!acpi_ns_get_attached_object | 293 | if (!acpi_ns_get_attached_object |
| 290 | (info->field_node)) { | 294 | (info->field_node)) { |
| @@ -409,18 +413,23 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
| 409 | 413 | ||
| 410 | ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); | 414 | ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); |
| 411 | 415 | ||
| 412 | /* | 416 | /* Execute flag should always be set when this function is entered */ |
| 413 | * During the load phase, we want to enter the name of the field into | 417 | |
| 414 | * the namespace. During the execute phase (when we evaluate the bank_value | 418 | if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) { |
| 415 | * operand), we want to lookup the name. | 419 | if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) { |
| 416 | */ | 420 | |
| 417 | if (walk_state->deferred_node) { | 421 | /* bank_field Op is deferred, just return OK */ |
| 418 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE; | 422 | |
| 419 | } else { | 423 | return_ACPI_STATUS(AE_OK); |
| 420 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | 424 | } |
| 421 | ACPI_NS_ERROR_IF_FOUND; | 425 | |
| 426 | return_ACPI_STATUS(AE_AML_INTERNAL); | ||
| 422 | } | 427 | } |
| 423 | 428 | ||
| 429 | /* | ||
| 430 | * Get the field_list argument for this opcode. This is the start of the | ||
| 431 | * list of field elements. | ||
| 432 | */ | ||
| 424 | switch (walk_state->opcode) { | 433 | switch (walk_state->opcode) { |
| 425 | case AML_FIELD_OP: | 434 | case AML_FIELD_OP: |
| 426 | arg = acpi_ps_get_arg(op, 2); | 435 | arg = acpi_ps_get_arg(op, 2); |
| @@ -441,18 +450,34 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
| 441 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 450 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
| 442 | } | 451 | } |
| 443 | 452 | ||
| 453 | if (!arg) { | ||
| 454 | return_ACPI_STATUS(AE_AML_NO_OPERAND); | ||
| 455 | } | ||
| 456 | |||
| 457 | /* Creating new namespace node(s), should not already exist */ | ||
| 458 | |||
| 459 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | ||
| 460 | ACPI_NS_ERROR_IF_FOUND; | ||
| 461 | |||
| 462 | /* Mark node(s) temporary if we are executing a method */ | ||
| 463 | |||
| 464 | if (walk_state->method_node) { | ||
| 465 | flags |= ACPI_NS_TEMPORARY; | ||
| 466 | } | ||
| 467 | |||
| 444 | /* | 468 | /* |
| 445 | * Walk the list of entries in the field_list | 469 | * Walk the list of entries in the field_list |
| 446 | */ | 470 | */ |
| 447 | while (arg) { | 471 | while (arg) { |
| 448 | 472 | /* | |
| 449 | /* Ignore OFFSET and ACCESSAS terms here */ | 473 | * Ignore OFFSET and ACCESSAS terms here; we are only interested in the |
| 450 | 474 | * field names in order to enter them into the namespace. | |
| 475 | */ | ||
| 451 | if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { | 476 | if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { |
| 452 | status = acpi_ns_lookup(walk_state->scope_info, | 477 | status = acpi_ns_lookup(walk_state->scope_info, |
| 453 | (char *)&arg->named.name, | 478 | (char *)&arg->named.name, type, |
| 454 | type, ACPI_IMODE_LOAD_PASS1, | 479 | ACPI_IMODE_LOAD_PASS1, flags, |
| 455 | flags, walk_state, &node); | 480 | walk_state, &node); |
| 456 | if (ACPI_FAILURE(status)) { | 481 | if (ACPI_FAILURE(status)) { |
| 457 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, | 482 | ACPI_ERROR_NAMESPACE((char *)&arg->named.name, |
| 458 | status); | 483 | status); |
| @@ -468,7 +493,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
| 468 | arg->common.node = node; | 493 | arg->common.node = node; |
| 469 | } | 494 | } |
| 470 | 495 | ||
| 471 | /* Move to next field in the list */ | 496 | /* Get the next field element in the list */ |
| 472 | 497 | ||
| 473 | arg = arg->common.next; | 498 | arg = arg->common.next; |
| 474 | } | 499 | } |
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index ec68c1df3932..775b18390c36 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c | |||
| @@ -776,6 +776,12 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | |||
| 776 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, | 776 | acpi_ns_lookup(walk_state->scope_info, buffer_ptr, |
| 777 | object_type, ACPI_IMODE_LOAD_PASS2, flags, | 777 | object_type, ACPI_IMODE_LOAD_PASS2, flags, |
| 778 | walk_state, &node); | 778 | walk_state, &node); |
| 779 | |||
| 780 | if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) { | ||
| 781 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
| 782 | "***New Node [%4.4s] %p is temporary\n", | ||
| 783 | acpi_ut_get_node_name(node), node)); | ||
| 784 | } | ||
| 779 | break; | 785 | break; |
| 780 | } | 786 | } |
| 781 | 787 | ||
