1 /****************************************************************************** 2 * 3 * Module Name: dsfield - Dispatcher field routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, 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 arg = acpi_ps_get_arg(op, 2); 567 type = ACPI_TYPE_LOCAL_REGION_FIELD; 568 break; 569 570 case AML_BANK_FIELD_OP: 571 arg = acpi_ps_get_arg(op, 4); 572 type = ACPI_TYPE_LOCAL_BANK_FIELD; 573 break; 574 575 case AML_INDEX_FIELD_OP: 576 arg = acpi_ps_get_arg(op, 3); 577 type = ACPI_TYPE_LOCAL_INDEX_FIELD; 578 break; 579 580 default: 581 return_ACPI_STATUS(AE_BAD_PARAMETER); 582 } 583 584 /* Creating new namespace node(s), should not already exist */ 585 586 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 587 ACPI_NS_ERROR_IF_FOUND; 588 589 /* 590 * Mark node(s) temporary if we are executing a normal control 591 * method. (Don't mark if this is a module-level code method) 592 */ 593 if (walk_state->method_node && 594 !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { 595 flags |= ACPI_NS_TEMPORARY; 596 } 597 598 /* 599 * Walk the list of entries in the field_list 600 * Note: field_list can be of zero length. In this case, Arg will be NULL. 601 */ 602 while (arg) { 603 /* 604 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested 605 * in the field names in order to enter them into the namespace. 606 */ 607 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { 608 status = acpi_ns_lookup(walk_state->scope_info, 609 (char *)&arg->named.name, type, 610 ACPI_IMODE_LOAD_PASS1, flags, 611 walk_state, &node); 612 if (ACPI_FAILURE(status)) { 613 ACPI_ERROR_NAMESPACE((char *)&arg->named.name, 614 status); 615 if (status != AE_ALREADY_EXISTS) { 616 return_ACPI_STATUS(status); 617 } 618 619 /* Name already exists, just ignore this error */ 620 621 status = AE_OK; 622 } 623 624 arg->common.node = node; 625 } 626 627 /* Get the next field element in the list */ 628 629 arg = arg->common.next; 630 } 631 632 return_ACPI_STATUS(AE_OK); 633 } 634 635 /******************************************************************************* 636 * 637 * FUNCTION: acpi_ds_create_bank_field 638 * 639 * PARAMETERS: op - Op containing the Field definition and args 640 * region_node - Object for the containing Operation Region 641 * walk_state - Current method state 642 * 643 * RETURN: Status 644 * 645 * DESCRIPTION: Create a new bank field in the specified operation region 646 * 647 ******************************************************************************/ 648 649 acpi_status 650 acpi_ds_create_bank_field(union acpi_parse_object *op, 651 struct acpi_namespace_node *region_node, 652 struct acpi_walk_state *walk_state) 653 { 654 acpi_status status; 655 union acpi_parse_object *arg; 656 struct acpi_create_field_info info; 657 658 ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op); 659 660 /* First arg is the name of the parent op_region (must already exist) */ 661 662 arg = op->common.value.arg; 663 if (!region_node) { 664 status = 665 acpi_ns_lookup(walk_state->scope_info, 666 arg->common.value.name, ACPI_TYPE_REGION, 667 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 668 walk_state, ®ion_node); 669 #ifdef ACPI_ASL_COMPILER 670 status = acpi_ds_create_external_region(status, arg, 671 arg->common.value.name, 672 walk_state, 673 ®ion_node); 674 #endif 675 if (ACPI_FAILURE(status)) { 676 ACPI_ERROR_NAMESPACE(arg->common.value.name, status); 677 return_ACPI_STATUS(status); 678 } 679 } 680 681 /* Second arg is the Bank Register (Field) (must already exist) */ 682 683 arg = arg->common.next; 684 status = 685 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string, 686 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 687 ACPI_NS_SEARCH_PARENT, walk_state, 688 &info.register_node); 689 if (ACPI_FAILURE(status)) { 690 ACPI_ERROR_NAMESPACE(arg->common.value.string, status); 691 return_ACPI_STATUS(status); 692 } 693 694 /* 695 * Third arg is the bank_value 696 * This arg is a term_arg, not a constant 697 * It will be evaluated later, by acpi_ds_eval_bank_field_operands 698 */ 699 arg = arg->common.next; 700 701 /* Fourth arg is the field flags */ 702 703 arg = arg->common.next; 704 info.field_flags = (u8) arg->common.value.integer; 705 706 /* Each remaining arg is a Named Field */ 707 708 info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; 709 info.region_node = region_node; 710 711 /* 712 * Use Info.data_register_node to store bank_field Op 713 * It's safe because data_register_node will never be used when create bank field 714 * We store aml_start and aml_length in the bank_field Op for late evaluation 715 * Used in acpi_ex_prep_field_value(Info) 716 * 717 * TBD: Or, should we add a field in struct acpi_create_field_info, like "void *ParentOp"? 718 */ 719 info.data_register_node = (struct acpi_namespace_node *)op; 720 721 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 722 return_ACPI_STATUS(status); 723 } 724 725 /******************************************************************************* 726 * 727 * FUNCTION: acpi_ds_create_index_field 728 * 729 * PARAMETERS: op - Op containing the Field definition and args 730 * region_node - Object for the containing Operation Region 731 * ` walk_state - Current method state 732 * 733 * RETURN: Status 734 * 735 * DESCRIPTION: Create a new index field in the specified operation region 736 * 737 ******************************************************************************/ 738 739 acpi_status 740 acpi_ds_create_index_field(union acpi_parse_object *op, 741 struct acpi_namespace_node *region_node, 742 struct acpi_walk_state *walk_state) 743 { 744 acpi_status status; 745 union acpi_parse_object *arg; 746 struct acpi_create_field_info info; 747 748 ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op); 749 750 /* First arg is the name of the Index register (must already exist) */ 751 752 arg = op->common.value.arg; 753 status = 754 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string, 755 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 756 ACPI_NS_SEARCH_PARENT, walk_state, 757 &info.register_node); 758 if (ACPI_FAILURE(status)) { 759 ACPI_ERROR_NAMESPACE(arg->common.value.string, status); 760 return_ACPI_STATUS(status); 761 } 762 763 /* Second arg is the data register (must already exist) */ 764 765 arg = arg->common.next; 766 status = 767 acpi_ns_lookup(walk_state->scope_info, arg->common.value.string, 768 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 769 ACPI_NS_SEARCH_PARENT, walk_state, 770 &info.data_register_node); 771 if (ACPI_FAILURE(status)) { 772 ACPI_ERROR_NAMESPACE(arg->common.value.string, status); 773 return_ACPI_STATUS(status); 774 } 775 776 /* Next arg is the field flags */ 777 778 arg = arg->common.next; 779 info.field_flags = (u8) arg->common.value.integer; 780 781 /* Each remaining arg is a Named Field */ 782 783 info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD; 784 info.region_node = region_node; 785 786 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 787 return_ACPI_STATUS(status); 788 } 789