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