1 /****************************************************************************** 2 * 3 * Module Name: dsfield - Dispatcher field routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 53 ACPI_MODULE_NAME("dsfield") 54 55 /* Local prototypes */ 56 #ifdef ACPI_ASL_COMPILER 57 #include "acdisasm.h" 58 static acpi_status 59 acpi_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 66 static acpi_status 67 acpi_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 89 static acpi_status 90 acpi_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_to_external_list(op, path, ACPI_TYPE_REGION, 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 148 acpi_status 149 acpi_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 262 cleanup: 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 285 static acpi_status 286 acpi_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 364 /* 365 * A Connection() is either an actual resource descriptor (buffer) 366 * or a named reference to a resource template 367 */ 368 child = arg->common.value.arg; 369 if (child->common.aml_opcode == AML_INT_BYTELIST_OP) { 370 info->resource_buffer = child->named.data; 371 info->resource_length = 372 (u16)child->named.value.integer; 373 } else { 374 /* Lookup the Connection() namepath, it should already exist */ 375 376 status = acpi_ns_lookup(walk_state->scope_info, 377 child->common.value. 378 name, ACPI_TYPE_ANY, 379 ACPI_IMODE_EXECUTE, 380 ACPI_NS_DONT_OPEN_SCOPE, 381 walk_state, 382 &info->connection_node); 383 if (ACPI_FAILURE(status)) { 384 ACPI_ERROR_NAMESPACE(child->common. 385 value.name, 386 status); 387 return_ACPI_STATUS(status); 388 } 389 } 390 break; 391 392 case AML_INT_NAMEDFIELD_OP: 393 394 /* Lookup the name, it should already exist */ 395 396 status = acpi_ns_lookup(walk_state->scope_info, 397 (char *)&arg->named.name, 398 info->field_type, 399 ACPI_IMODE_EXECUTE, 400 ACPI_NS_DONT_OPEN_SCOPE, 401 walk_state, &info->field_node); 402 if (ACPI_FAILURE(status)) { 403 ACPI_ERROR_NAMESPACE((char *)&arg->named.name, 404 status); 405 return_ACPI_STATUS(status); 406 } else { 407 arg->common.node = info->field_node; 408 info->field_bit_length = arg->common.value.size; 409 410 /* 411 * If there is no object attached to the node, this node was 412 * just created and we need to create the field object. 413 * Otherwise, this was a lookup of an existing node and we 414 * don't want to create the field object again. 415 */ 416 if (!acpi_ns_get_attached_object 417 (info->field_node)) { 418 status = acpi_ex_prep_field_value(info); 419 if (ACPI_FAILURE(status)) { 420 return_ACPI_STATUS(status); 421 } 422 } 423 } 424 425 /* Keep track of bit position for the next field */ 426 427 position = (u64) info->field_bit_position 428 + (u64) arg->common.value.size; 429 430 if (position > ACPI_UINT32_MAX) { 431 ACPI_ERROR((AE_INFO, 432 "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)", 433 ACPI_CAST_PTR(char, 434 &info->field_node-> 435 name))); 436 return_ACPI_STATUS(AE_SUPPORT); 437 } 438 439 info->field_bit_position += info->field_bit_length; 440 break; 441 442 default: 443 444 ACPI_ERROR((AE_INFO, 445 "Invalid opcode in field list: 0x%X", 446 arg->common.aml_opcode)); 447 return_ACPI_STATUS(AE_AML_BAD_OPCODE); 448 } 449 450 arg = arg->common.next; 451 } 452 453 return_ACPI_STATUS(AE_OK); 454 } 455 456 /******************************************************************************* 457 * 458 * FUNCTION: acpi_ds_create_field 459 * 460 * PARAMETERS: op - Op containing the Field definition and args 461 * region_node - Object for the containing Operation Region 462 * ` walk_state - Current method state 463 * 464 * RETURN: Status 465 * 466 * DESCRIPTION: Create a new field in the specified operation region 467 * 468 ******************************************************************************/ 469 470 acpi_status 471 acpi_ds_create_field(union acpi_parse_object *op, 472 struct acpi_namespace_node *region_node, 473 struct acpi_walk_state *walk_state) 474 { 475 acpi_status status; 476 union acpi_parse_object *arg; 477 struct acpi_create_field_info info; 478 479 ACPI_FUNCTION_TRACE_PTR(ds_create_field, op); 480 481 /* First arg is the name of the parent op_region (must already exist) */ 482 483 arg = op->common.value.arg; 484 485 if (!region_node) { 486 status = 487 acpi_ns_lookup(walk_state->scope_info, 488 arg->common.value.name, ACPI_TYPE_REGION, 489 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 490 walk_state, ®ion_node); 491 #ifdef ACPI_ASL_COMPILER 492 status = acpi_ds_create_external_region(status, arg, 493 arg->common.value.name, 494 walk_state, 495 ®ion_node); 496 #endif 497 if (ACPI_FAILURE(status)) { 498 ACPI_ERROR_NAMESPACE(arg->common.value.name, status); 499 return_ACPI_STATUS(status); 500 } 501 } 502 503 ACPI_MEMSET(&info, 0, sizeof(struct acpi_create_field_info)); 504 505 /* Second arg is the field flags */ 506 507 arg = arg->common.next; 508 info.field_flags = (u8) arg->common.value.integer; 509 info.attribute = 0; 510 511 /* Each remaining arg is a Named Field */ 512 513 info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD; 514 info.region_node = region_node; 515 516 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 517 return_ACPI_STATUS(status); 518 } 519 520 /******************************************************************************* 521 * 522 * FUNCTION: acpi_ds_init_field_objects 523 * 524 * PARAMETERS: op - Op containing the Field definition and args 525 * ` walk_state - Current method state 526 * 527 * RETURN: Status 528 * 529 * DESCRIPTION: For each "Field Unit" name in the argument list that is 530 * part of the field declaration, enter the name into the 531 * namespace. 532 * 533 ******************************************************************************/ 534 535 acpi_status 536 acpi_ds_init_field_objects(union acpi_parse_object *op, 537 struct acpi_walk_state *walk_state) 538 { 539 acpi_status status; 540 union acpi_parse_object *arg = NULL; 541 struct acpi_namespace_node *node; 542 u8 type = 0; 543 u32 flags; 544 545 ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); 546 547 /* Execute flag should always be set when this function is entered */ 548 549 if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) { 550 if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) { 551 552 /* bank_field Op is deferred, just return OK */ 553 554 return_ACPI_STATUS(AE_OK); 555 } 556 557 return_ACPI_STATUS(AE_AML_INTERNAL); 558 } 559 560 /* 561 * Get the field_list argument for this opcode. This is the start of the 562 * list of field elements. 563 */ 564 switch (walk_state->opcode) { 565 case AML_FIELD_OP: 566 567 arg = acpi_ps_get_arg(op, 2); 568 type = ACPI_TYPE_LOCAL_REGION_FIELD; 569 break; 570 571 case AML_BANK_FIELD_OP: 572 573 arg = acpi_ps_get_arg(op, 4); 574 type = ACPI_TYPE_LOCAL_BANK_FIELD; 575 break; 576 577 case AML_INDEX_FIELD_OP: 578 579 arg = acpi_ps_get_arg(op, 3); 580 type = ACPI_TYPE_LOCAL_INDEX_FIELD; 581 break; 582 583 default: 584 585 return_ACPI_STATUS(AE_BAD_PARAMETER); 586 } 587 588 /* Creating new namespace node(s), should not already exist */ 589 590 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 591 ACPI_NS_ERROR_IF_FOUND; 592 593 /* 594 * Mark node(s) temporary if we are executing a normal control 595 * method. (Don't mark if this is a module-level code method) 596 */ 597 if (walk_state->method_node && 598 !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { 599 flags |= ACPI_NS_TEMPORARY; 600 } 601 602 /* 603 * Walk the list of entries in the field_list 604 * Note: field_list can be of zero length. In this case, Arg will be NULL. 605 */ 606 while (arg) { 607 /* 608 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested 609 * in the field names in order to enter them into the namespace. 610 */ 611 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { 612 status = acpi_ns_lookup(walk_state->scope_info, 613 (char *)&arg->named.name, type, 614 ACPI_IMODE_LOAD_PASS1, flags, 615 walk_state, &node); 616 if (ACPI_FAILURE(status)) { 617 ACPI_ERROR_NAMESPACE((char *)&arg->named.name, 618 status); 619 if (status != AE_ALREADY_EXISTS) { 620 return_ACPI_STATUS(status); 621 } 622 623 /* Name already exists, just ignore this error */ 624 625 status = AE_OK; 626 } 627 628 arg->common.node = node; 629 } 630 631 /* Get the next field element in the list */ 632 633 arg = arg->common.next; 634 } 635 636 return_ACPI_STATUS(AE_OK); 637 } 638 639 /******************************************************************************* 640 * 641 * FUNCTION: acpi_ds_create_bank_field 642 * 643 * PARAMETERS: op - Op containing the Field definition and args 644 * region_node - Object for the containing Operation Region 645 * walk_state - Current method state 646 * 647 * RETURN: Status 648 * 649 * DESCRIPTION: Create a new bank field in the specified operation region 650 * 651 ******************************************************************************/ 652 653 acpi_status 654 acpi_ds_create_bank_field(union acpi_parse_object *op, 655 struct acpi_namespace_node *region_node, 656 struct acpi_walk_state *walk_state) 657 { 658 acpi_status status; 659 union acpi_parse_object *arg; 660 struct acpi_create_field_info info; 661 662 ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op); 663 664 /* First arg is the name of the parent op_region (must already exist) */ 665 666 arg = op->common.value.arg; 667 if (!region_node) { 668 status = 669 acpi_ns_lookup(walk_state->scope_info, 670 arg->common.value.name, ACPI_TYPE_REGION, 671 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 672 walk_state, ®ion_node); 673 #ifdef ACPI_ASL_COMPILER 674 status = acpi_ds_create_external_region(status, arg, 675 arg->common.value.name, 676 walk_state, 677 ®ion_node); 678 #endif 679 if (ACPI_FAILURE(status)) { 680 ACPI_ERROR_NAMESPACE(arg->common.value.name, status); 681 return_ACPI_STATUS(status); 682 } 683 } 684 685 /* Second arg is the Bank Register (Field) (must already exist) */ 686 687 arg = arg->common.next; 688 status = 689 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string, 690 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 691 ACPI_NS_SEARCH_PARENT, walk_state, 692 &info.register_node); 693 if (ACPI_FAILURE(status)) { 694 ACPI_ERROR_NAMESPACE(arg->common.value.string, status); 695 return_ACPI_STATUS(status); 696 } 697 698 /* 699 * Third arg is the bank_value 700 * This arg is a term_arg, not a constant 701 * It will be evaluated later, by acpi_ds_eval_bank_field_operands 702 */ 703 arg = arg->common.next; 704 705 /* Fourth arg is the field flags */ 706 707 arg = arg->common.next; 708 info.field_flags = (u8) arg->common.value.integer; 709 710 /* Each remaining arg is a Named Field */ 711 712 info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; 713 info.region_node = region_node; 714 715 /* 716 * Use Info.data_register_node to store bank_field Op 717 * It's safe because data_register_node will never be used when create bank field 718 * We store aml_start and aml_length in the bank_field Op for late evaluation 719 * Used in acpi_ex_prep_field_value(Info) 720 * 721 * TBD: Or, should we add a field in struct acpi_create_field_info, like "void *ParentOp"? 722 */ 723 info.data_register_node = (struct acpi_namespace_node *)op; 724 725 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 726 return_ACPI_STATUS(status); 727 } 728 729 /******************************************************************************* 730 * 731 * FUNCTION: acpi_ds_create_index_field 732 * 733 * PARAMETERS: op - Op containing the Field definition and args 734 * region_node - Object for the containing Operation Region 735 * ` walk_state - Current method state 736 * 737 * RETURN: Status 738 * 739 * DESCRIPTION: Create a new index field in the specified operation region 740 * 741 ******************************************************************************/ 742 743 acpi_status 744 acpi_ds_create_index_field(union acpi_parse_object *op, 745 struct acpi_namespace_node *region_node, 746 struct acpi_walk_state *walk_state) 747 { 748 acpi_status status; 749 union acpi_parse_object *arg; 750 struct acpi_create_field_info info; 751 752 ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op); 753 754 /* First arg is the name of the Index register (must already exist) */ 755 756 arg = op->common.value.arg; 757 status = 758 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string, 759 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 760 ACPI_NS_SEARCH_PARENT, walk_state, 761 &info.register_node); 762 if (ACPI_FAILURE(status)) { 763 ACPI_ERROR_NAMESPACE(arg->common.value.string, status); 764 return_ACPI_STATUS(status); 765 } 766 767 /* Second arg is the data register (must already exist) */ 768 769 arg = arg->common.next; 770 status = 771 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string, 772 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 773 ACPI_NS_SEARCH_PARENT, walk_state, 774 &info.data_register_node); 775 if (ACPI_FAILURE(status)) { 776 ACPI_ERROR_NAMESPACE(arg->common.value.string, status); 777 return_ACPI_STATUS(status); 778 } 779 780 /* Next arg is the field flags */ 781 782 arg = arg->common.next; 783 info.field_flags = (u8) arg->common.value.integer; 784 785 /* Each remaining arg is a Named Field */ 786 787 info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD; 788 info.region_node = region_node; 789 790 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 791 return_ACPI_STATUS(status); 792 } 793