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