1 /****************************************************************************** 2 * 3 * Module Name: dsopcode - Dispatcher support for regions and fields 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 "acparser.h" 47 #include "amlcode.h" 48 #include "acdispat.h" 49 #include "acinterp.h" 50 #include "acnamesp.h" 51 #include "acevents.h" 52 #include "actables.h" 53 54 #define _COMPONENT ACPI_DISPATCHER 55 ACPI_MODULE_NAME("dsopcode") 56 57 /* Local prototypes */ 58 static acpi_status 59 acpi_ds_init_buffer_field(u16 aml_opcode, 60 union acpi_operand_object *obj_desc, 61 union acpi_operand_object *buffer_desc, 62 union acpi_operand_object *offset_desc, 63 union acpi_operand_object *length_desc, 64 union acpi_operand_object *result_desc); 65 66 /******************************************************************************* 67 * 68 * FUNCTION: acpi_ds_initialize_region 69 * 70 * PARAMETERS: obj_handle - Region namespace node 71 * 72 * RETURN: Status 73 * 74 * DESCRIPTION: Front end to ev_initialize_region 75 * 76 ******************************************************************************/ 77 78 acpi_status acpi_ds_initialize_region(acpi_handle obj_handle) 79 { 80 union acpi_operand_object *obj_desc; 81 acpi_status status; 82 83 obj_desc = acpi_ns_get_attached_object(obj_handle); 84 85 /* Namespace is NOT locked */ 86 87 status = acpi_ev_initialize_region(obj_desc, FALSE); 88 return (status); 89 } 90 91 /******************************************************************************* 92 * 93 * FUNCTION: acpi_ds_init_buffer_field 94 * 95 * PARAMETERS: aml_opcode - create_xxx_field 96 * obj_desc - buffer_field object 97 * buffer_desc - Host Buffer 98 * offset_desc - Offset into buffer 99 * length_desc - Length of field (CREATE_FIELD_OP only) 100 * result_desc - Where to store the result 101 * 102 * RETURN: Status 103 * 104 * DESCRIPTION: Perform actual initialization of a buffer field 105 * 106 ******************************************************************************/ 107 108 static acpi_status 109 acpi_ds_init_buffer_field(u16 aml_opcode, 110 union acpi_operand_object *obj_desc, 111 union acpi_operand_object *buffer_desc, 112 union acpi_operand_object *offset_desc, 113 union acpi_operand_object *length_desc, 114 union acpi_operand_object *result_desc) 115 { 116 u32 offset; 117 u32 bit_offset; 118 u32 bit_count; 119 u8 field_flags; 120 acpi_status status; 121 122 ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc); 123 124 /* Host object must be a Buffer */ 125 126 if (buffer_desc->common.type != ACPI_TYPE_BUFFER) { 127 ACPI_ERROR((AE_INFO, 128 "Target of Create Field is not a Buffer object - %s", 129 acpi_ut_get_object_type_name(buffer_desc))); 130 131 status = AE_AML_OPERAND_TYPE; 132 goto cleanup; 133 } 134 135 /* 136 * The last parameter to all of these opcodes (result_desc) started 137 * out as a name_string, and should therefore now be a NS node 138 * after resolution in acpi_ex_resolve_operands(). 139 */ 140 if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) { 141 ACPI_ERROR((AE_INFO, 142 "(%s) destination not a NS Node [%s]", 143 acpi_ps_get_opcode_name(aml_opcode), 144 acpi_ut_get_descriptor_name(result_desc))); 145 146 status = AE_AML_OPERAND_TYPE; 147 goto cleanup; 148 } 149 150 offset = (u32) offset_desc->integer.value; 151 152 /* 153 * Setup the Bit offsets and counts, according to the opcode 154 */ 155 switch (aml_opcode) { 156 case AML_CREATE_FIELD_OP: 157 158 /* Offset is in bits, count is in bits */ 159 160 field_flags = AML_FIELD_ACCESS_BYTE; 161 bit_offset = offset; 162 bit_count = (u32) length_desc->integer.value; 163 164 /* Must have a valid (>0) bit count */ 165 166 if (bit_count == 0) { 167 ACPI_ERROR((AE_INFO, 168 "Attempt to CreateField of length zero")); 169 status = AE_AML_OPERAND_VALUE; 170 goto cleanup; 171 } 172 break; 173 174 case AML_CREATE_BIT_FIELD_OP: 175 176 /* Offset is in bits, Field is one bit */ 177 178 bit_offset = offset; 179 bit_count = 1; 180 field_flags = AML_FIELD_ACCESS_BYTE; 181 break; 182 183 case AML_CREATE_BYTE_FIELD_OP: 184 185 /* Offset is in bytes, field is one byte */ 186 187 bit_offset = 8 * offset; 188 bit_count = 8; 189 field_flags = AML_FIELD_ACCESS_BYTE; 190 break; 191 192 case AML_CREATE_WORD_FIELD_OP: 193 194 /* Offset is in bytes, field is one word */ 195 196 bit_offset = 8 * offset; 197 bit_count = 16; 198 field_flags = AML_FIELD_ACCESS_WORD; 199 break; 200 201 case AML_CREATE_DWORD_FIELD_OP: 202 203 /* Offset is in bytes, field is one dword */ 204 205 bit_offset = 8 * offset; 206 bit_count = 32; 207 field_flags = AML_FIELD_ACCESS_DWORD; 208 break; 209 210 case AML_CREATE_QWORD_FIELD_OP: 211 212 /* Offset is in bytes, field is one qword */ 213 214 bit_offset = 8 * offset; 215 bit_count = 64; 216 field_flags = AML_FIELD_ACCESS_QWORD; 217 break; 218 219 default: 220 221 ACPI_ERROR((AE_INFO, 222 "Unknown field creation opcode 0x%02X", 223 aml_opcode)); 224 status = AE_AML_BAD_OPCODE; 225 goto cleanup; 226 } 227 228 /* Entire field must fit within the current length of the buffer */ 229 230 if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) { 231 ACPI_ERROR((AE_INFO, 232 "Field [%4.4s] at %u exceeds Buffer [%4.4s] size %u (bits)", 233 acpi_ut_get_node_name(result_desc), 234 bit_offset + bit_count, 235 acpi_ut_get_node_name(buffer_desc->buffer.node), 236 8 * (u32) buffer_desc->buffer.length)); 237 status = AE_AML_BUFFER_LIMIT; 238 goto cleanup; 239 } 240 241 /* 242 * Initialize areas of the field object that are common to all fields 243 * For field_flags, use LOCK_RULE = 0 (NO_LOCK), 244 * UPDATE_RULE = 0 (UPDATE_PRESERVE) 245 */ 246 status = acpi_ex_prep_common_field_object(obj_desc, field_flags, 0, 247 bit_offset, bit_count); 248 if (ACPI_FAILURE(status)) { 249 goto cleanup; 250 } 251 252 obj_desc->buffer_field.buffer_obj = buffer_desc; 253 254 /* Reference count for buffer_desc inherits obj_desc count */ 255 256 buffer_desc->common.reference_count = (u16) 257 (buffer_desc->common.reference_count + 258 obj_desc->common.reference_count); 259 260 cleanup: 261 262 /* Always delete the operands */ 263 264 acpi_ut_remove_reference(offset_desc); 265 acpi_ut_remove_reference(buffer_desc); 266 267 if (aml_opcode == AML_CREATE_FIELD_OP) { 268 acpi_ut_remove_reference(length_desc); 269 } 270 271 /* On failure, delete the result descriptor */ 272 273 if (ACPI_FAILURE(status)) { 274 acpi_ut_remove_reference(result_desc); /* Result descriptor */ 275 } else { 276 /* Now the address and length are valid for this buffer_field */ 277 278 obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID; 279 } 280 281 return_ACPI_STATUS(status); 282 } 283 284 /******************************************************************************* 285 * 286 * FUNCTION: acpi_ds_eval_buffer_field_operands 287 * 288 * PARAMETERS: walk_state - Current walk 289 * op - A valid buffer_field Op object 290 * 291 * RETURN: Status 292 * 293 * DESCRIPTION: Get buffer_field Buffer and Index 294 * Called from acpi_ds_exec_end_op during buffer_field parse tree walk 295 * 296 ******************************************************************************/ 297 298 acpi_status 299 acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, 300 union acpi_parse_object *op) 301 { 302 acpi_status status; 303 union acpi_operand_object *obj_desc; 304 struct acpi_namespace_node *node; 305 union acpi_parse_object *next_op; 306 307 ACPI_FUNCTION_TRACE_PTR(ds_eval_buffer_field_operands, op); 308 309 /* 310 * This is where we evaluate the address and length fields of the 311 * create_xxx_field declaration 312 */ 313 node = op->common.node; 314 315 /* next_op points to the op that holds the Buffer */ 316 317 next_op = op->common.value.arg; 318 319 /* Evaluate/create the address and length operands */ 320 321 status = acpi_ds_create_operands(walk_state, next_op); 322 if (ACPI_FAILURE(status)) { 323 return_ACPI_STATUS(status); 324 } 325 326 obj_desc = acpi_ns_get_attached_object(node); 327 if (!obj_desc) { 328 return_ACPI_STATUS(AE_NOT_EXIST); 329 } 330 331 /* Resolve the operands */ 332 333 status = acpi_ex_resolve_operands(op->common.aml_opcode, 334 ACPI_WALK_OPERANDS, walk_state); 335 if (ACPI_FAILURE(status)) { 336 ACPI_ERROR((AE_INFO, "(%s) bad operand(s), status 0x%X", 337 acpi_ps_get_opcode_name(op->common.aml_opcode), 338 status)); 339 340 return_ACPI_STATUS(status); 341 } 342 343 /* Initialize the Buffer Field */ 344 345 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { 346 347 /* NOTE: Slightly different operands for this opcode */ 348 349 status = 350 acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc, 351 walk_state->operands[0], 352 walk_state->operands[1], 353 walk_state->operands[2], 354 walk_state->operands[3]); 355 } else { 356 /* All other, create_xxx_field opcodes */ 357 358 status = 359 acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc, 360 walk_state->operands[0], 361 walk_state->operands[1], NULL, 362 walk_state->operands[2]); 363 } 364 365 return_ACPI_STATUS(status); 366 } 367 368 /******************************************************************************* 369 * 370 * FUNCTION: acpi_ds_eval_region_operands 371 * 372 * PARAMETERS: walk_state - Current walk 373 * op - A valid region Op object 374 * 375 * RETURN: Status 376 * 377 * DESCRIPTION: Get region address and length 378 * Called from acpi_ds_exec_end_op during op_region parse tree walk 379 * 380 ******************************************************************************/ 381 382 acpi_status 383 acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, 384 union acpi_parse_object *op) 385 { 386 acpi_status status; 387 union acpi_operand_object *obj_desc; 388 union acpi_operand_object *operand_desc; 389 struct acpi_namespace_node *node; 390 union acpi_parse_object *next_op; 391 392 ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op); 393 394 /* 395 * This is where we evaluate the address and length fields of the 396 * op_region declaration 397 */ 398 node = op->common.node; 399 400 /* next_op points to the op that holds the space_ID */ 401 402 next_op = op->common.value.arg; 403 404 /* next_op points to address op */ 405 406 next_op = next_op->common.next; 407 408 /* Evaluate/create the address and length operands */ 409 410 status = acpi_ds_create_operands(walk_state, next_op); 411 if (ACPI_FAILURE(status)) { 412 return_ACPI_STATUS(status); 413 } 414 415 /* Resolve the length and address operands to numbers */ 416 417 status = acpi_ex_resolve_operands(op->common.aml_opcode, 418 ACPI_WALK_OPERANDS, walk_state); 419 if (ACPI_FAILURE(status)) { 420 return_ACPI_STATUS(status); 421 } 422 423 obj_desc = acpi_ns_get_attached_object(node); 424 if (!obj_desc) { 425 return_ACPI_STATUS(AE_NOT_EXIST); 426 } 427 428 /* 429 * Get the length operand and save it 430 * (at Top of stack) 431 */ 432 operand_desc = walk_state->operands[walk_state->num_operands - 1]; 433 434 obj_desc->region.length = (u32) operand_desc->integer.value; 435 acpi_ut_remove_reference(operand_desc); 436 437 /* 438 * Get the address and save it 439 * (at top of stack - 1) 440 */ 441 operand_desc = walk_state->operands[walk_state->num_operands - 2]; 442 443 obj_desc->region.address = (acpi_physical_address) 444 operand_desc->integer.value; 445 acpi_ut_remove_reference(operand_desc); 446 447 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 448 obj_desc, 449 ACPI_FORMAT_UINT64(obj_desc->region.address), 450 obj_desc->region.length)); 451 452 /* Now the address and length are valid for this opregion */ 453 454 obj_desc->region.flags |= AOPOBJ_DATA_VALID; 455 456 return_ACPI_STATUS(status); 457 } 458 459 /******************************************************************************* 460 * 461 * FUNCTION: acpi_ds_eval_table_region_operands 462 * 463 * PARAMETERS: walk_state - Current walk 464 * op - A valid region Op object 465 * 466 * RETURN: Status 467 * 468 * DESCRIPTION: Get region address and length. 469 * Called from acpi_ds_exec_end_op during data_table_region parse 470 * tree walk. 471 * 472 ******************************************************************************/ 473 474 acpi_status 475 acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, 476 union acpi_parse_object *op) 477 { 478 acpi_status status; 479 union acpi_operand_object *obj_desc; 480 union acpi_operand_object **operand; 481 struct acpi_namespace_node *node; 482 union acpi_parse_object *next_op; 483 u32 table_index; 484 struct acpi_table_header *table; 485 486 ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); 487 488 /* 489 * This is where we evaluate the Signature string, oem_id string, 490 * and oem_table_id string of the Data Table Region declaration 491 */ 492 node = op->common.node; 493 494 /* next_op points to Signature string op */ 495 496 next_op = op->common.value.arg; 497 498 /* 499 * Evaluate/create the Signature string, oem_id string, 500 * and oem_table_id string operands 501 */ 502 status = acpi_ds_create_operands(walk_state, next_op); 503 if (ACPI_FAILURE(status)) { 504 return_ACPI_STATUS(status); 505 } 506 507 /* 508 * Resolve the Signature string, oem_id string, 509 * and oem_table_id string operands 510 */ 511 status = acpi_ex_resolve_operands(op->common.aml_opcode, 512 ACPI_WALK_OPERANDS, walk_state); 513 if (ACPI_FAILURE(status)) { 514 return_ACPI_STATUS(status); 515 } 516 517 operand = &walk_state->operands[0]; 518 519 /* Find the ACPI table */ 520 521 status = acpi_tb_find_table(operand[0]->string.pointer, 522 operand[1]->string.pointer, 523 operand[2]->string.pointer, &table_index); 524 if (ACPI_FAILURE(status)) { 525 return_ACPI_STATUS(status); 526 } 527 528 acpi_ut_remove_reference(operand[0]); 529 acpi_ut_remove_reference(operand[1]); 530 acpi_ut_remove_reference(operand[2]); 531 532 status = acpi_get_table_by_index(table_index, &table); 533 if (ACPI_FAILURE(status)) { 534 return_ACPI_STATUS(status); 535 } 536 537 obj_desc = acpi_ns_get_attached_object(node); 538 if (!obj_desc) { 539 return_ACPI_STATUS(AE_NOT_EXIST); 540 } 541 542 obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table); 543 obj_desc->region.length = table->length; 544 545 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 546 obj_desc, 547 ACPI_FORMAT_UINT64(obj_desc->region.address), 548 obj_desc->region.length)); 549 550 /* Now the address and length are valid for this opregion */ 551 552 obj_desc->region.flags |= AOPOBJ_DATA_VALID; 553 554 return_ACPI_STATUS(status); 555 } 556 557 /******************************************************************************* 558 * 559 * FUNCTION: acpi_ds_eval_data_object_operands 560 * 561 * PARAMETERS: walk_state - Current walk 562 * op - A valid data_object Op object 563 * obj_desc - data_object 564 * 565 * RETURN: Status 566 * 567 * DESCRIPTION: Get the operands and complete the following data object types: 568 * Buffer, Package. 569 * 570 ******************************************************************************/ 571 572 acpi_status 573 acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, 574 union acpi_parse_object *op, 575 union acpi_operand_object *obj_desc) 576 { 577 acpi_status status; 578 union acpi_operand_object *arg_desc; 579 u32 length; 580 581 ACPI_FUNCTION_TRACE(ds_eval_data_object_operands); 582 583 /* The first operand (for all of these data objects) is the length */ 584 585 /* 586 * Set proper index into operand stack for acpi_ds_obj_stack_push 587 * invoked inside acpi_ds_create_operand. 588 */ 589 walk_state->operand_index = walk_state->num_operands; 590 591 status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); 592 if (ACPI_FAILURE(status)) { 593 return_ACPI_STATUS(status); 594 } 595 596 status = acpi_ex_resolve_operands(walk_state->opcode, 597 &(walk_state-> 598 operands[walk_state->num_operands - 599 1]), walk_state); 600 if (ACPI_FAILURE(status)) { 601 return_ACPI_STATUS(status); 602 } 603 604 /* Extract length operand */ 605 606 arg_desc = walk_state->operands[walk_state->num_operands - 1]; 607 length = (u32) arg_desc->integer.value; 608 609 /* Cleanup for length operand */ 610 611 status = acpi_ds_obj_stack_pop(1, walk_state); 612 if (ACPI_FAILURE(status)) { 613 return_ACPI_STATUS(status); 614 } 615 616 acpi_ut_remove_reference(arg_desc); 617 618 /* 619 * Create the actual data object 620 */ 621 switch (op->common.aml_opcode) { 622 case AML_BUFFER_OP: 623 624 status = 625 acpi_ds_build_internal_buffer_obj(walk_state, op, length, 626 &obj_desc); 627 break; 628 629 case AML_PACKAGE_OP: 630 case AML_VAR_PACKAGE_OP: 631 632 status = 633 acpi_ds_build_internal_package_obj(walk_state, op, length, 634 &obj_desc); 635 break; 636 637 default: 638 639 return_ACPI_STATUS(AE_AML_BAD_OPCODE); 640 } 641 642 if (ACPI_SUCCESS(status)) { 643 /* 644 * Return the object in the walk_state, unless the parent is a package - 645 * in this case, the return object will be stored in the parse tree 646 * for the package. 647 */ 648 if ((!op->common.parent) || 649 ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) && 650 (op->common.parent->common.aml_opcode != 651 AML_VAR_PACKAGE_OP) 652 && (op->common.parent->common.aml_opcode != 653 AML_NAME_OP))) { 654 walk_state->result_obj = obj_desc; 655 } 656 } 657 658 return_ACPI_STATUS(status); 659 } 660 661 /******************************************************************************* 662 * 663 * FUNCTION: acpi_ds_eval_bank_field_operands 664 * 665 * PARAMETERS: walk_state - Current walk 666 * op - A valid bank_field Op object 667 * 668 * RETURN: Status 669 * 670 * DESCRIPTION: Get bank_field bank_value 671 * Called from acpi_ds_exec_end_op during bank_field parse tree walk 672 * 673 ******************************************************************************/ 674 675 acpi_status 676 acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, 677 union acpi_parse_object *op) 678 { 679 acpi_status status; 680 union acpi_operand_object *obj_desc; 681 union acpi_operand_object *operand_desc; 682 struct acpi_namespace_node *node; 683 union acpi_parse_object *next_op; 684 union acpi_parse_object *arg; 685 686 ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op); 687 688 /* 689 * This is where we evaluate the bank_value field of the 690 * bank_field declaration 691 */ 692 693 /* next_op points to the op that holds the Region */ 694 695 next_op = op->common.value.arg; 696 697 /* next_op points to the op that holds the Bank Register */ 698 699 next_op = next_op->common.next; 700 701 /* next_op points to the op that holds the Bank Value */ 702 703 next_op = next_op->common.next; 704 705 /* 706 * Set proper index into operand stack for acpi_ds_obj_stack_push 707 * invoked inside acpi_ds_create_operand. 708 * 709 * We use walk_state->Operands[0] to store the evaluated bank_value 710 */ 711 walk_state->operand_index = 0; 712 713 status = acpi_ds_create_operand(walk_state, next_op, 0); 714 if (ACPI_FAILURE(status)) { 715 return_ACPI_STATUS(status); 716 } 717 718 status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state); 719 if (ACPI_FAILURE(status)) { 720 return_ACPI_STATUS(status); 721 } 722 723 ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, 724 acpi_ps_get_opcode_name(op->common.aml_opcode), 1); 725 /* 726 * Get the bank_value operand and save it 727 * (at Top of stack) 728 */ 729 operand_desc = walk_state->operands[0]; 730 731 /* Arg points to the start Bank Field */ 732 733 arg = acpi_ps_get_arg(op, 4); 734 while (arg) { 735 736 /* Ignore OFFSET and ACCESSAS terms here */ 737 738 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { 739 node = arg->common.node; 740 741 obj_desc = acpi_ns_get_attached_object(node); 742 if (!obj_desc) { 743 return_ACPI_STATUS(AE_NOT_EXIST); 744 } 745 746 obj_desc->bank_field.value = 747 (u32) operand_desc->integer.value; 748 } 749 750 /* Move to next field in the list */ 751 752 arg = arg->common.next; 753 } 754 755 acpi_ut_remove_reference(operand_desc); 756 return_ACPI_STATUS(status); 757 } 758