1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /****************************************************************************** 3 * 4 * Module Name: dsfield - Dispatcher field routines 5 * 6 * Copyright (C) 2000 - 2019, Intel Corp. 7 * 8 *****************************************************************************/ 9 10 #include <acpi/acpi.h> 11 #include "accommon.h" 12 #include "amlcode.h" 13 #include "acdispat.h" 14 #include "acinterp.h" 15 #include "acnamesp.h" 16 #include "acparser.h" 17 18 #ifdef ACPI_EXEC_APP 19 #include "aecommon.h" 20 #endif 21 22 #define _COMPONENT ACPI_DISPATCHER 23 ACPI_MODULE_NAME("dsfield") 24 25 /* Local prototypes */ 26 #ifdef ACPI_ASL_COMPILER 27 #include "acdisasm.h" 28 static acpi_status 29 acpi_ds_create_external_region(acpi_status lookup_status, 30 union acpi_parse_object *op, 31 char *path, 32 struct acpi_walk_state *walk_state, 33 struct acpi_namespace_node **node); 34 #endif 35 36 static acpi_status 37 acpi_ds_get_field_names(struct acpi_create_field_info *info, 38 struct acpi_walk_state *walk_state, 39 union acpi_parse_object *arg); 40 41 #ifdef ACPI_ASL_COMPILER 42 /******************************************************************************* 43 * 44 * FUNCTION: acpi_ds_create_external_region (iASL Disassembler only) 45 * 46 * PARAMETERS: lookup_status - Status from ns_lookup operation 47 * op - Op containing the Field definition and args 48 * path - Pathname of the region 49 * ` walk_state - Current method state 50 * node - Where the new region node is returned 51 * 52 * RETURN: Status 53 * 54 * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new 55 * region node/object. 56 * 57 ******************************************************************************/ 58 59 static acpi_status 60 acpi_ds_create_external_region(acpi_status lookup_status, 61 union acpi_parse_object *op, 62 char *path, 63 struct acpi_walk_state *walk_state, 64 struct acpi_namespace_node **node) 65 { 66 acpi_status status; 67 union acpi_operand_object *obj_desc; 68 69 if (lookup_status != AE_NOT_FOUND) { 70 return (lookup_status); 71 } 72 73 /* 74 * Table disassembly: 75 * operation_region not found. Generate an External for it, and 76 * insert the name into the namespace. 77 */ 78 acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0); 79 80 status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION, 81 ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, 82 walk_state, node); 83 if (ACPI_FAILURE(status)) { 84 return (status); 85 } 86 87 /* Must create and install a region object for the new node */ 88 89 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION); 90 if (!obj_desc) { 91 return (AE_NO_MEMORY); 92 } 93 94 obj_desc->region.node = *node; 95 status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION); 96 return (status); 97 } 98 #endif 99 100 /******************************************************************************* 101 * 102 * FUNCTION: acpi_ds_create_buffer_field 103 * 104 * PARAMETERS: op - Current parse op (create_XXField) 105 * walk_state - Current state 106 * 107 * RETURN: Status 108 * 109 * DESCRIPTION: Execute the create_field operators: 110 * create_bit_field_op, 111 * create_byte_field_op, 112 * create_word_field_op, 113 * create_dword_field_op, 114 * create_qword_field_op, 115 * create_field_op (all of which define a field in a buffer) 116 * 117 ******************************************************************************/ 118 119 acpi_status 120 acpi_ds_create_buffer_field(union acpi_parse_object *op, 121 struct acpi_walk_state *walk_state) 122 { 123 union acpi_parse_object *arg; 124 struct acpi_namespace_node *node; 125 acpi_status status; 126 union acpi_operand_object *obj_desc; 127 union acpi_operand_object *second_desc = NULL; 128 u32 flags; 129 130 ACPI_FUNCTION_TRACE(ds_create_buffer_field); 131 132 /* 133 * Get the name_string argument (name of the new buffer_field) 134 */ 135 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { 136 137 /* For create_field, name is the 4th argument */ 138 139 arg = acpi_ps_get_arg(op, 3); 140 } else { 141 /* For all other create_XXXField operators, name is the 3rd argument */ 142 143 arg = acpi_ps_get_arg(op, 2); 144 } 145 146 if (!arg) { 147 return_ACPI_STATUS(AE_AML_NO_OPERAND); 148 } 149 150 if (walk_state->deferred_node) { 151 node = walk_state->deferred_node; 152 status = AE_OK; 153 } else { 154 /* Execute flag should always be set when this function is entered */ 155 156 if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) { 157 ACPI_ERROR((AE_INFO, "Parse execute mode is not set")); 158 return_ACPI_STATUS(AE_AML_INTERNAL); 159 } 160 161 /* Creating new namespace node, should not already exist */ 162 163 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 164 ACPI_NS_ERROR_IF_FOUND; 165 166 /* 167 * Mark node temporary if we are executing a normal control 168 * method. (Don't mark if this is a module-level code method) 169 */ 170 if (walk_state->method_node && 171 !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { 172 flags |= ACPI_NS_TEMPORARY; 173 } 174 175 /* Enter the name_string into the namespace */ 176 177 status = acpi_ns_lookup(walk_state->scope_info, 178 arg->common.value.string, ACPI_TYPE_ANY, 179 ACPI_IMODE_LOAD_PASS1, flags, 180 walk_state, &node); 181 if (ACPI_FAILURE(status)) { 182 ACPI_ERROR_NAMESPACE(walk_state->scope_info, 183 arg->common.value.string, status); 184 return_ACPI_STATUS(status); 185 } 186 } 187 188 /* 189 * We could put the returned object (Node) on the object stack for later, 190 * but for now, we will put it in the "op" object that the parser uses, 191 * so we can get it again at the end of this scope. 192 */ 193 op->common.node = node; 194 195 /* 196 * If there is no object attached to the node, this node was just created 197 * and we need to create the field object. Otherwise, this was a lookup 198 * of an existing node and we don't want to create the field object again. 199 */ 200 obj_desc = acpi_ns_get_attached_object(node); 201 if (obj_desc) { 202 return_ACPI_STATUS(AE_OK); 203 } 204 205 /* 206 * The Field definition is not fully parsed at this time. 207 * (We must save the address of the AML for the buffer and index operands) 208 */ 209 210 /* Create the buffer field object */ 211 212 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD); 213 if (!obj_desc) { 214 status = AE_NO_MEMORY; 215 goto cleanup; 216 } 217 218 /* 219 * Remember location in AML stream of the field unit opcode and operands 220 * -- since the buffer and index operands must be evaluated. 221 */ 222 second_desc = obj_desc->common.next_object; 223 second_desc->extra.aml_start = op->named.data; 224 second_desc->extra.aml_length = op->named.length; 225 obj_desc->buffer_field.node = node; 226 227 /* Attach constructed field descriptors to parent node */ 228 229 status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD); 230 if (ACPI_FAILURE(status)) { 231 goto cleanup; 232 } 233 234 cleanup: 235 236 /* Remove local reference to the object */ 237 238 acpi_ut_remove_reference(obj_desc); 239 return_ACPI_STATUS(status); 240 } 241 242 /******************************************************************************* 243 * 244 * FUNCTION: acpi_ds_get_field_names 245 * 246 * PARAMETERS: info - create_field info structure 247 * ` walk_state - Current method state 248 * arg - First parser arg for the field name list 249 * 250 * RETURN: Status 251 * 252 * DESCRIPTION: Process all named fields in a field declaration. Names are 253 * entered into the namespace. 254 * 255 ******************************************************************************/ 256 257 static acpi_status 258 acpi_ds_get_field_names(struct acpi_create_field_info *info, 259 struct acpi_walk_state *walk_state, 260 union acpi_parse_object *arg) 261 { 262 acpi_status status; 263 u64 position; 264 union acpi_parse_object *child; 265 266 #ifdef ACPI_EXEC_APP 267 u64 value = 0; 268 union acpi_operand_object *result_desc; 269 union acpi_operand_object *obj_desc; 270 char *name_path; 271 #endif 272 273 ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info); 274 275 /* First field starts at bit zero */ 276 277 info->field_bit_position = 0; 278 279 /* Process all elements in the field list (of parse nodes) */ 280 281 while (arg) { 282 /* 283 * Four types of field elements are handled: 284 * 1) name - Enters a new named field into the namespace 285 * 2) offset - specifies a bit offset 286 * 3) access_as - changes the access mode/attributes 287 * 4) connection - Associate a resource template with the field 288 */ 289 switch (arg->common.aml_opcode) { 290 case AML_INT_RESERVEDFIELD_OP: 291 292 position = (u64)info->field_bit_position + 293 (u64)arg->common.value.size; 294 295 if (position > ACPI_UINT32_MAX) { 296 ACPI_ERROR((AE_INFO, 297 "Bit offset within field too large (> 0xFFFFFFFF)")); 298 return_ACPI_STATUS(AE_SUPPORT); 299 } 300 301 info->field_bit_position = (u32) position; 302 break; 303 304 case AML_INT_ACCESSFIELD_OP: 305 case AML_INT_EXTACCESSFIELD_OP: 306 /* 307 * Get new access_type, access_attribute, and access_length fields 308 * -- to be used for all field units that follow, until the 309 * end-of-field or another access_as keyword is encountered. 310 * NOTE. These three bytes are encoded in the integer value 311 * of the parseop for convenience. 312 * 313 * In field_flags, preserve the flag bits other than the 314 * ACCESS_TYPE bits. 315 */ 316 317 /* access_type (byte_acc, word_acc, etc.) */ 318 319 info->field_flags = (u8) 320 ((info-> 321 field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | 322 ((u8)((u32)(arg->common.value.integer & 0x07)))); 323 324 /* access_attribute (attrib_quick, attrib_byte, etc.) */ 325 326 info->attribute = (u8) 327 ((arg->common.value.integer >> 8) & 0xFF); 328 329 /* access_length (for serial/buffer protocols) */ 330 331 info->access_length = (u8) 332 ((arg->common.value.integer >> 16) & 0xFF); 333 break; 334 335 case AML_INT_CONNECTION_OP: 336 /* 337 * Clear any previous connection. New connection is used for all 338 * fields that follow, similar to access_as 339 */ 340 info->resource_buffer = NULL; 341 info->connection_node = NULL; 342 info->pin_number_index = 0; 343 344 /* 345 * A Connection() is either an actual resource descriptor (buffer) 346 * or a named reference to a resource template 347 */ 348 child = arg->common.value.arg; 349 if (child->common.aml_opcode == AML_INT_BYTELIST_OP) { 350 info->resource_buffer = child->named.data; 351 info->resource_length = 352 (u16)child->named.value.integer; 353 } else { 354 /* Lookup the Connection() namepath, it should already exist */ 355 356 status = acpi_ns_lookup(walk_state->scope_info, 357 child->common.value. 358 name, ACPI_TYPE_ANY, 359 ACPI_IMODE_EXECUTE, 360 ACPI_NS_DONT_OPEN_SCOPE, 361 walk_state, 362 &info->connection_node); 363 if (ACPI_FAILURE(status)) { 364 ACPI_ERROR_NAMESPACE(walk_state-> 365 scope_info, 366 child->common. 367 value.name, 368 status); 369 return_ACPI_STATUS(status); 370 } 371 } 372 break; 373 374 case AML_INT_NAMEDFIELD_OP: 375 376 /* Lookup the name, it should already exist */ 377 378 status = acpi_ns_lookup(walk_state->scope_info, 379 (char *)&arg->named.name, 380 info->field_type, 381 ACPI_IMODE_EXECUTE, 382 ACPI_NS_DONT_OPEN_SCOPE, 383 walk_state, &info->field_node); 384 if (ACPI_FAILURE(status)) { 385 ACPI_ERROR_NAMESPACE(walk_state->scope_info, 386 (char *)&arg->named.name, 387 status); 388 return_ACPI_STATUS(status); 389 } else { 390 arg->common.node = info->field_node; 391 info->field_bit_length = arg->common.value.size; 392 393 /* 394 * If there is no object attached to the node, this node was 395 * just created and we need to create the field object. 396 * Otherwise, this was a lookup of an existing node and we 397 * don't want to create the field object again. 398 */ 399 if (!acpi_ns_get_attached_object 400 (info->field_node)) { 401 status = acpi_ex_prep_field_value(info); 402 if (ACPI_FAILURE(status)) { 403 return_ACPI_STATUS(status); 404 } 405 #ifdef ACPI_EXEC_APP 406 name_path = 407 acpi_ns_get_external_pathname(info-> 408 field_node); 409 obj_desc = 410 acpi_ut_create_integer_object 411 (value); 412 if (ACPI_SUCCESS 413 (ae_lookup_init_file_entry 414 (name_path, &value))) { 415 acpi_ex_write_data_to_field 416 (obj_desc, 417 acpi_ns_get_attached_object 418 (info->field_node), 419 &result_desc); 420 } 421 acpi_ut_remove_reference(obj_desc); 422 ACPI_FREE(name_path); 423 #endif 424 } 425 } 426 427 /* Keep track of bit position for the next field */ 428 429 position = (u64)info->field_bit_position + 430 (u64)arg->common.value.size; 431 432 if (position > ACPI_UINT32_MAX) { 433 ACPI_ERROR((AE_INFO, 434 "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)", 435 ACPI_CAST_PTR(char, 436 &info->field_node-> 437 name))); 438 return_ACPI_STATUS(AE_SUPPORT); 439 } 440 441 info->field_bit_position += info->field_bit_length; 442 info->pin_number_index++; /* Index relative to previous Connection() */ 443 break; 444 445 default: 446 447 ACPI_ERROR((AE_INFO, 448 "Invalid opcode in field list: 0x%X", 449 arg->common.aml_opcode)); 450 return_ACPI_STATUS(AE_AML_BAD_OPCODE); 451 } 452 453 arg = arg->common.next; 454 } 455 456 return_ACPI_STATUS(AE_OK); 457 } 458 459 /******************************************************************************* 460 * 461 * FUNCTION: acpi_ds_create_field 462 * 463 * PARAMETERS: op - Op containing the Field definition and args 464 * region_node - Object for the containing Operation Region 465 * ` walk_state - Current method state 466 * 467 * RETURN: Status 468 * 469 * DESCRIPTION: Create a new field in the specified operation region 470 * 471 ******************************************************************************/ 472 473 acpi_status 474 acpi_ds_create_field(union acpi_parse_object *op, 475 struct acpi_namespace_node *region_node, 476 struct acpi_walk_state *walk_state) 477 { 478 acpi_status status; 479 union acpi_parse_object *arg; 480 struct acpi_create_field_info info; 481 482 ACPI_FUNCTION_TRACE_PTR(ds_create_field, op); 483 484 /* First arg is the name of the parent op_region (must already exist) */ 485 486 arg = op->common.value.arg; 487 488 if (!region_node) { 489 status = 490 acpi_ns_lookup(walk_state->scope_info, 491 arg->common.value.name, ACPI_TYPE_REGION, 492 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 493 walk_state, ®ion_node); 494 #ifdef ACPI_ASL_COMPILER 495 status = acpi_ds_create_external_region(status, arg, 496 arg->common.value.name, 497 walk_state, 498 ®ion_node); 499 #endif 500 if (ACPI_FAILURE(status)) { 501 ACPI_ERROR_NAMESPACE(walk_state->scope_info, 502 arg->common.value.name, status); 503 return_ACPI_STATUS(status); 504 } 505 } 506 507 memset(&info, 0, sizeof(struct acpi_create_field_info)); 508 509 /* Second arg is the field flags */ 510 511 arg = arg->common.next; 512 info.field_flags = (u8) arg->common.value.integer; 513 info.attribute = 0; 514 515 /* Each remaining arg is a Named Field */ 516 517 info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD; 518 info.region_node = region_node; 519 520 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 521 if (info.region_node->object->region.space_id == 522 ACPI_ADR_SPACE_PLATFORM_COMM 523 && !(region_node->object->field.internal_pcc_buffer = 524 ACPI_ALLOCATE_ZEROED(info.region_node->object->region. 525 length))) { 526 return_ACPI_STATUS(AE_NO_MEMORY); 527 } 528 return_ACPI_STATUS(status); 529 } 530 531 /******************************************************************************* 532 * 533 * FUNCTION: acpi_ds_init_field_objects 534 * 535 * PARAMETERS: op - Op containing the Field definition and args 536 * ` walk_state - Current method state 537 * 538 * RETURN: Status 539 * 540 * DESCRIPTION: For each "Field Unit" name in the argument list that is 541 * part of the field declaration, enter the name into the 542 * namespace. 543 * 544 ******************************************************************************/ 545 546 acpi_status 547 acpi_ds_init_field_objects(union acpi_parse_object *op, 548 struct acpi_walk_state *walk_state) 549 { 550 acpi_status status; 551 union acpi_parse_object *arg = NULL; 552 struct acpi_namespace_node *node; 553 u8 type = 0; 554 u32 flags; 555 556 ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); 557 558 /* Execute flag should always be set when this function is entered */ 559 560 if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) { 561 if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) { 562 563 /* bank_field Op is deferred, just return OK */ 564 565 return_ACPI_STATUS(AE_OK); 566 } 567 568 ACPI_ERROR((AE_INFO, "Parse deferred mode is not set")); 569 return_ACPI_STATUS(AE_AML_INTERNAL); 570 } 571 572 /* 573 * Get the field_list argument for this opcode. This is the start of the 574 * list of field elements. 575 */ 576 switch (walk_state->opcode) { 577 case AML_FIELD_OP: 578 579 arg = acpi_ps_get_arg(op, 2); 580 type = ACPI_TYPE_LOCAL_REGION_FIELD; 581 break; 582 583 case AML_BANK_FIELD_OP: 584 585 arg = acpi_ps_get_arg(op, 4); 586 type = ACPI_TYPE_LOCAL_BANK_FIELD; 587 break; 588 589 case AML_INDEX_FIELD_OP: 590 591 arg = acpi_ps_get_arg(op, 3); 592 type = ACPI_TYPE_LOCAL_INDEX_FIELD; 593 break; 594 595 default: 596 597 return_ACPI_STATUS(AE_BAD_PARAMETER); 598 } 599 600 /* Creating new namespace node(s), should not already exist */ 601 602 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 603 ACPI_NS_ERROR_IF_FOUND; 604 605 /* 606 * Mark node(s) temporary if we are executing a normal control 607 * method. (Don't mark if this is a module-level code method) 608 */ 609 if (walk_state->method_node && 610 !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { 611 flags |= ACPI_NS_TEMPORARY; 612 } 613 #ifdef ACPI_EXEC_APP 614 flags |= ACPI_NS_OVERRIDE_IF_FOUND; 615 #endif 616 /* 617 * Walk the list of entries in the field_list 618 * Note: field_list can be of zero length. In this case, Arg will be NULL. 619 */ 620 while (arg) { 621 /* 622 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested 623 * in the field names in order to enter them into the namespace. 624 */ 625 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { 626 status = acpi_ns_lookup(walk_state->scope_info, 627 (char *)&arg->named.name, type, 628 ACPI_IMODE_LOAD_PASS1, flags, 629 walk_state, &node); 630 if (ACPI_FAILURE(status)) { 631 ACPI_ERROR_NAMESPACE(walk_state->scope_info, 632 (char *)&arg->named.name, 633 status); 634 if (status != AE_ALREADY_EXISTS) { 635 return_ACPI_STATUS(status); 636 } 637 638 /* Name already exists, just ignore this error */ 639 640 status = AE_OK; 641 } 642 643 arg->common.node = node; 644 } 645 646 /* Get the next field element in the list */ 647 648 arg = arg->common.next; 649 } 650 651 return_ACPI_STATUS(AE_OK); 652 } 653 654 /******************************************************************************* 655 * 656 * FUNCTION: acpi_ds_create_bank_field 657 * 658 * PARAMETERS: op - Op containing the Field definition and args 659 * region_node - Object for the containing Operation Region 660 * walk_state - Current method state 661 * 662 * RETURN: Status 663 * 664 * DESCRIPTION: Create a new bank field in the specified operation region 665 * 666 ******************************************************************************/ 667 668 acpi_status 669 acpi_ds_create_bank_field(union acpi_parse_object *op, 670 struct acpi_namespace_node *region_node, 671 struct acpi_walk_state *walk_state) 672 { 673 acpi_status status; 674 union acpi_parse_object *arg; 675 struct acpi_create_field_info info; 676 677 ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op); 678 679 /* First arg is the name of the parent op_region (must already exist) */ 680 681 arg = op->common.value.arg; 682 if (!region_node) { 683 status = 684 acpi_ns_lookup(walk_state->scope_info, 685 arg->common.value.name, ACPI_TYPE_REGION, 686 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 687 walk_state, ®ion_node); 688 #ifdef ACPI_ASL_COMPILER 689 status = acpi_ds_create_external_region(status, arg, 690 arg->common.value.name, 691 walk_state, 692 ®ion_node); 693 #endif 694 if (ACPI_FAILURE(status)) { 695 ACPI_ERROR_NAMESPACE(walk_state->scope_info, 696 arg->common.value.name, status); 697 return_ACPI_STATUS(status); 698 } 699 } 700 701 /* Second arg is the Bank Register (Field) (must already exist) */ 702 703 arg = arg->common.next; 704 status = 705 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string, 706 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 707 ACPI_NS_SEARCH_PARENT, walk_state, 708 &info.register_node); 709 if (ACPI_FAILURE(status)) { 710 ACPI_ERROR_NAMESPACE(walk_state->scope_info, 711 arg->common.value.string, status); 712 return_ACPI_STATUS(status); 713 } 714 715 /* 716 * Third arg is the bank_value 717 * This arg is a term_arg, not a constant 718 * It will be evaluated later, by acpi_ds_eval_bank_field_operands 719 */ 720 arg = arg->common.next; 721 722 /* Fourth arg is the field flags */ 723 724 arg = arg->common.next; 725 info.field_flags = (u8) arg->common.value.integer; 726 727 /* Each remaining arg is a Named Field */ 728 729 info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; 730 info.region_node = region_node; 731 732 /* 733 * Use Info.data_register_node to store bank_field Op 734 * It's safe because data_register_node will never be used when create 735 * bank field \we store aml_start and aml_length in the bank_field Op for 736 * late evaluation. Used in acpi_ex_prep_field_value(Info) 737 * 738 * TBD: Or, should we add a field in struct acpi_create_field_info, like 739 * "void *ParentOp"? 740 */ 741 info.data_register_node = (struct acpi_namespace_node *)op; 742 743 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 744 return_ACPI_STATUS(status); 745 } 746 747 /******************************************************************************* 748 * 749 * FUNCTION: acpi_ds_create_index_field 750 * 751 * PARAMETERS: op - Op containing the Field definition and args 752 * region_node - Object for the containing Operation Region 753 * ` walk_state - Current method state 754 * 755 * RETURN: Status 756 * 757 * DESCRIPTION: Create a new index field in the specified operation region 758 * 759 ******************************************************************************/ 760 761 acpi_status 762 acpi_ds_create_index_field(union acpi_parse_object *op, 763 struct acpi_namespace_node *region_node, 764 struct acpi_walk_state *walk_state) 765 { 766 acpi_status status; 767 union acpi_parse_object *arg; 768 struct acpi_create_field_info info; 769 770 ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op); 771 772 /* First arg is the name of the Index register (must already exist) */ 773 774 arg = op->common.value.arg; 775 status = 776 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string, 777 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 778 ACPI_NS_SEARCH_PARENT, walk_state, 779 &info.register_node); 780 if (ACPI_FAILURE(status)) { 781 ACPI_ERROR_NAMESPACE(walk_state->scope_info, 782 arg->common.value.string, status); 783 return_ACPI_STATUS(status); 784 } 785 786 /* Second arg is the data register (must already exist) */ 787 788 arg = arg->common.next; 789 status = 790 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string, 791 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 792 ACPI_NS_SEARCH_PARENT, walk_state, 793 &info.data_register_node); 794 if (ACPI_FAILURE(status)) { 795 ACPI_ERROR_NAMESPACE(walk_state->scope_info, 796 arg->common.value.string, status); 797 return_ACPI_STATUS(status); 798 } 799 800 /* Next arg is the field flags */ 801 802 arg = arg->common.next; 803 info.field_flags = (u8) arg->common.value.integer; 804 805 /* Each remaining arg is a Named Field */ 806 807 info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD; 808 info.region_node = region_node; 809 810 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 811 return_ACPI_STATUS(status); 812 } 813