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