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