1 /****************************************************************************** 2 * 3 * Module Name: psobject - Support for parse objects 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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.h" 45 #include "accommon.h" 46 #include "acparser.h" 47 #include "amlcode.h" 48 #include "acconvert.h" 49 50 #define _COMPONENT ACPI_PARSER 51 ACPI_MODULE_NAME ("psobject") 52 53 54 /* Local prototypes */ 55 56 static ACPI_STATUS 57 AcpiPsGetAmlOpcode ( 58 ACPI_WALK_STATE *WalkState); 59 60 61 /******************************************************************************* 62 * 63 * FUNCTION: AcpiPsGetAmlOpcode 64 * 65 * PARAMETERS: WalkState - Current state 66 * 67 * RETURN: Status 68 * 69 * DESCRIPTION: Extract the next AML opcode from the input stream. 70 * 71 ******************************************************************************/ 72 73 static ACPI_STATUS 74 AcpiPsGetAmlOpcode ( 75 ACPI_WALK_STATE *WalkState) 76 { 77 UINT32 AmlOffset; 78 79 80 ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState); 81 82 83 WalkState->Aml = WalkState->ParserState.Aml; 84 WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState)); 85 86 /* 87 * First cut to determine what we have found: 88 * 1) A valid AML opcode 89 * 2) A name string 90 * 3) An unknown/invalid opcode 91 */ 92 WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); 93 94 switch (WalkState->OpInfo->Class) 95 { 96 case AML_CLASS_ASCII: 97 case AML_CLASS_PREFIX: 98 /* 99 * Starts with a valid prefix or ASCII char, this is a name 100 * string. Convert the bare name string to a namepath. 101 */ 102 WalkState->Opcode = AML_INT_NAMEPATH_OP; 103 WalkState->ArgTypes = ARGP_NAMESTRING; 104 break; 105 106 case AML_CLASS_UNKNOWN: 107 108 /* The opcode is unrecognized. Complain and skip unknown opcodes */ 109 110 if (WalkState->PassNumber == 2) 111 { 112 AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->Aml, 113 WalkState->ParserState.AmlStart); 114 115 ACPI_ERROR ((AE_INFO, 116 "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring", 117 WalkState->Opcode, 118 (UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER)))); 119 120 ACPI_DUMP_BUFFER ((WalkState->ParserState.Aml - 16), 48); 121 122 #ifdef ACPI_ASL_COMPILER 123 /* 124 * This is executed for the disassembler only. Output goes 125 * to the disassembled ASL output file. 126 */ 127 AcpiOsPrintf ( 128 "/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n", 129 WalkState->Opcode, 130 (UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER))); 131 132 /* Dump the context surrounding the invalid opcode */ 133 134 AcpiUtDumpBuffer (((UINT8 *) WalkState->ParserState.Aml - 16), 135 48, DB_BYTE_DISPLAY, 136 (AmlOffset + sizeof (ACPI_TABLE_HEADER) - 16)); 137 AcpiOsPrintf (" */\n"); 138 #endif 139 } 140 141 /* Increment past one-byte or two-byte opcode */ 142 143 WalkState->ParserState.Aml++; 144 if (WalkState->Opcode > 0xFF) /* Can only happen if first byte is 0x5B */ 145 { 146 WalkState->ParserState.Aml++; 147 } 148 149 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 150 151 default: 152 153 /* Found opcode info, this is a normal opcode */ 154 155 WalkState->ParserState.Aml += 156 AcpiPsGetOpcodeSize (WalkState->Opcode); 157 WalkState->ArgTypes = WalkState->OpInfo->ParseArgs; 158 break; 159 } 160 161 return_ACPI_STATUS (AE_OK); 162 } 163 164 165 /******************************************************************************* 166 * 167 * FUNCTION: AcpiPsBuildNamedOp 168 * 169 * PARAMETERS: WalkState - Current state 170 * AmlOpStart - Begin of named Op in AML 171 * UnnamedOp - Early Op (not a named Op) 172 * Op - Returned Op 173 * 174 * RETURN: Status 175 * 176 * DESCRIPTION: Parse a named Op 177 * 178 ******************************************************************************/ 179 180 ACPI_STATUS 181 AcpiPsBuildNamedOp ( 182 ACPI_WALK_STATE *WalkState, 183 UINT8 *AmlOpStart, 184 ACPI_PARSE_OBJECT *UnnamedOp, 185 ACPI_PARSE_OBJECT **Op) 186 { 187 ACPI_STATUS Status = AE_OK; 188 ACPI_PARSE_OBJECT *Arg = NULL; 189 190 191 ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState); 192 193 194 UnnamedOp->Common.Value.Arg = NULL; 195 UnnamedOp->Common.ArgListLength = 0; 196 UnnamedOp->Common.AmlOpcode = WalkState->Opcode; 197 198 /* 199 * Get and append arguments until we find the node that contains 200 * the name (the type ARGP_NAME). 201 */ 202 while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && 203 (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME)) 204 { 205 ASL_CV_CAPTURE_COMMENTS (WalkState); 206 Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState), 207 GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg); 208 if (ACPI_FAILURE (Status)) 209 { 210 return_ACPI_STATUS (Status); 211 } 212 213 AcpiPsAppendArg (UnnamedOp, Arg); 214 INCREMENT_ARG_LIST (WalkState->ArgTypes); 215 } 216 217 /* are there any inline comments associated with the NameSeg?? If so, save this. */ 218 219 ASL_CV_CAPTURE_COMMENTS (WalkState); 220 221 #ifdef ACPI_ASL_COMPILER 222 if (AcpiGbl_CurrentInlineComment != NULL) 223 { 224 UnnamedOp->Common.NameComment = AcpiGbl_CurrentInlineComment; 225 AcpiGbl_CurrentInlineComment = NULL; 226 } 227 #endif 228 229 /* 230 * Make sure that we found a NAME and didn't run out of arguments 231 */ 232 if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes)) 233 { 234 return_ACPI_STATUS (AE_AML_NO_OPERAND); 235 } 236 237 /* We know that this arg is a name, move to next arg */ 238 239 INCREMENT_ARG_LIST (WalkState->ArgTypes); 240 241 /* 242 * Find the object. This will either insert the object into 243 * the namespace or simply look it up 244 */ 245 WalkState->Op = NULL; 246 247 Status = WalkState->DescendingCallback (WalkState, Op); 248 if (ACPI_FAILURE (Status)) 249 { 250 if (Status != AE_CTRL_TERMINATE) 251 { 252 ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog")); 253 } 254 return_ACPI_STATUS (Status); 255 } 256 257 if (!*Op) 258 { 259 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 260 } 261 262 Status = AcpiPsNextParseState (WalkState, *Op, Status); 263 if (ACPI_FAILURE (Status)) 264 { 265 if (Status == AE_CTRL_PENDING) 266 { 267 Status = AE_CTRL_PARSE_PENDING; 268 } 269 return_ACPI_STATUS (Status); 270 } 271 272 AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg); 273 274 #ifdef ACPI_ASL_COMPILER 275 276 /* save any comments that might be associated with UnnamedOp. */ 277 278 (*Op)->Common.InlineComment = UnnamedOp->Common.InlineComment; 279 (*Op)->Common.EndNodeComment = UnnamedOp->Common.EndNodeComment; 280 (*Op)->Common.CloseBraceComment = UnnamedOp->Common.CloseBraceComment; 281 (*Op)->Common.NameComment = UnnamedOp->Common.NameComment; 282 (*Op)->Common.CommentList = UnnamedOp->Common.CommentList; 283 (*Op)->Common.EndBlkComment = UnnamedOp->Common.EndBlkComment; 284 (*Op)->Common.CvFilename = UnnamedOp->Common.CvFilename; 285 (*Op)->Common.CvParentFilename = UnnamedOp->Common.CvParentFilename; 286 (*Op)->Named.Aml = UnnamedOp->Common.Aml; 287 288 UnnamedOp->Common.InlineComment = NULL; 289 UnnamedOp->Common.EndNodeComment = NULL; 290 UnnamedOp->Common.CloseBraceComment = NULL; 291 UnnamedOp->Common.NameComment = NULL; 292 UnnamedOp->Common.CommentList = NULL; 293 UnnamedOp->Common.EndBlkComment = NULL; 294 #endif 295 296 if ((*Op)->Common.AmlOpcode == AML_REGION_OP || 297 (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP) 298 { 299 /* 300 * Defer final parsing of an OperationRegion body, because we don't 301 * have enough info in the first pass to parse it correctly (i.e., 302 * there may be method calls within the TermArg elements of the body.) 303 * 304 * However, we must continue parsing because the opregion is not a 305 * standalone package -- we don't know where the end is at this point. 306 * 307 * (Length is unknown until parse of the body complete) 308 */ 309 (*Op)->Named.Data = AmlOpStart; 310 (*Op)->Named.Length = 0; 311 } 312 313 return_ACPI_STATUS (AE_OK); 314 } 315 316 317 /******************************************************************************* 318 * 319 * FUNCTION: AcpiPsCreateOp 320 * 321 * PARAMETERS: WalkState - Current state 322 * AmlOpStart - Op start in AML 323 * NewOp - Returned Op 324 * 325 * RETURN: Status 326 * 327 * DESCRIPTION: Get Op from AML 328 * 329 ******************************************************************************/ 330 331 ACPI_STATUS 332 AcpiPsCreateOp ( 333 ACPI_WALK_STATE *WalkState, 334 UINT8 *AmlOpStart, 335 ACPI_PARSE_OBJECT **NewOp) 336 { 337 ACPI_STATUS Status = AE_OK; 338 ACPI_PARSE_OBJECT *Op; 339 ACPI_PARSE_OBJECT *NamedOp = NULL; 340 ACPI_PARSE_OBJECT *ParentScope; 341 UINT8 ArgumentCount; 342 const ACPI_OPCODE_INFO *OpInfo; 343 344 345 ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState); 346 347 348 Status = AcpiPsGetAmlOpcode (WalkState); 349 if (Status == AE_CTRL_PARSE_CONTINUE) 350 { 351 return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE); 352 } 353 354 /* Create Op structure and append to parent's argument list */ 355 356 WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); 357 Op = AcpiPsAllocOp (WalkState->Opcode, AmlOpStart); 358 if (!Op) 359 { 360 return_ACPI_STATUS (AE_NO_MEMORY); 361 } 362 363 if (WalkState->OpInfo->Flags & AML_NAMED) 364 { 365 Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp); 366 AcpiPsFreeOp (Op); 367 if (ACPI_FAILURE (Status)) 368 { 369 return_ACPI_STATUS (Status); 370 } 371 372 *NewOp = NamedOp; 373 return_ACPI_STATUS (AE_OK); 374 } 375 376 /* Not a named opcode, just allocate Op and append to parent */ 377 378 if (WalkState->OpInfo->Flags & AML_CREATE) 379 { 380 /* 381 * Backup to beginning of CreateXXXfield declaration 382 * BodyLength is unknown until we parse the body 383 */ 384 Op->Named.Data = AmlOpStart; 385 Op->Named.Length = 0; 386 } 387 388 if (WalkState->Opcode == AML_BANK_FIELD_OP) 389 { 390 /* 391 * Backup to beginning of BankField declaration 392 * BodyLength is unknown until we parse the body 393 */ 394 Op->Named.Data = AmlOpStart; 395 Op->Named.Length = 0; 396 } 397 398 ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState)); 399 AcpiPsAppendArg (ParentScope, Op); 400 401 if (ParentScope) 402 { 403 OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode); 404 if (OpInfo->Flags & AML_HAS_TARGET) 405 { 406 ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type); 407 if (ParentScope->Common.ArgListLength > ArgumentCount) 408 { 409 Op->Common.Flags |= ACPI_PARSEOP_TARGET; 410 } 411 } 412 413 /* 414 * Special case for both Increment() and Decrement(), where 415 * the lone argument is both a source and a target. 416 */ 417 else if ((ParentScope->Common.AmlOpcode == AML_INCREMENT_OP) || 418 (ParentScope->Common.AmlOpcode == AML_DECREMENT_OP)) 419 { 420 Op->Common.Flags |= ACPI_PARSEOP_TARGET; 421 } 422 } 423 424 if (WalkState->DescendingCallback != NULL) 425 { 426 /* 427 * Find the object. This will either insert the object into 428 * the namespace or simply look it up 429 */ 430 WalkState->Op = *NewOp = Op; 431 432 Status = WalkState->DescendingCallback (WalkState, &Op); 433 Status = AcpiPsNextParseState (WalkState, Op, Status); 434 if (Status == AE_CTRL_PENDING) 435 { 436 Status = AE_CTRL_PARSE_PENDING; 437 } 438 } 439 440 return_ACPI_STATUS (Status); 441 } 442 443 444 /******************************************************************************* 445 * 446 * FUNCTION: AcpiPsCompleteOp 447 * 448 * PARAMETERS: WalkState - Current state 449 * Op - Returned Op 450 * Status - Parse status before complete Op 451 * 452 * RETURN: Status 453 * 454 * DESCRIPTION: Complete Op 455 * 456 ******************************************************************************/ 457 458 ACPI_STATUS 459 AcpiPsCompleteOp ( 460 ACPI_WALK_STATE *WalkState, 461 ACPI_PARSE_OBJECT **Op, 462 ACPI_STATUS Status) 463 { 464 ACPI_STATUS Status2; 465 466 467 ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState); 468 469 470 /* 471 * Finished one argument of the containing scope 472 */ 473 WalkState->ParserState.Scope->ParseScope.ArgCount--; 474 475 /* Close this Op (will result in parse subtree deletion) */ 476 477 Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 478 if (ACPI_FAILURE (Status2)) 479 { 480 return_ACPI_STATUS (Status2); 481 } 482 483 *Op = NULL; 484 485 switch (Status) 486 { 487 case AE_OK: 488 489 break; 490 491 case AE_CTRL_TRANSFER: 492 493 /* We are about to transfer to a called method */ 494 495 WalkState->PrevOp = NULL; 496 WalkState->PrevArgTypes = WalkState->ArgTypes; 497 return_ACPI_STATUS (Status); 498 499 case AE_CTRL_END: 500 501 AcpiPsPopScope (&(WalkState->ParserState), Op, 502 &WalkState->ArgTypes, &WalkState->ArgCount); 503 504 if (*Op) 505 { 506 WalkState->Op = *Op; 507 WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 508 WalkState->Opcode = (*Op)->Common.AmlOpcode; 509 510 Status = WalkState->AscendingCallback (WalkState); 511 Status = AcpiPsNextParseState (WalkState, *Op, Status); 512 513 Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 514 if (ACPI_FAILURE (Status2)) 515 { 516 return_ACPI_STATUS (Status2); 517 } 518 } 519 520 Status = AE_OK; 521 break; 522 523 case AE_CTRL_BREAK: 524 case AE_CTRL_CONTINUE: 525 526 /* Pop off scopes until we find the While */ 527 528 while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP)) 529 { 530 AcpiPsPopScope (&(WalkState->ParserState), Op, 531 &WalkState->ArgTypes, &WalkState->ArgCount); 532 } 533 534 /* Close this iteration of the While loop */ 535 536 WalkState->Op = *Op; 537 WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode); 538 WalkState->Opcode = (*Op)->Common.AmlOpcode; 539 540 Status = WalkState->AscendingCallback (WalkState); 541 Status = AcpiPsNextParseState (WalkState, *Op, Status); 542 543 Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 544 if (ACPI_FAILURE (Status2)) 545 { 546 return_ACPI_STATUS (Status2); 547 } 548 549 Status = AE_OK; 550 break; 551 552 case AE_CTRL_TERMINATE: 553 554 /* Clean up */ 555 do 556 { 557 if (*Op) 558 { 559 Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 560 if (ACPI_FAILURE (Status2)) 561 { 562 return_ACPI_STATUS (Status2); 563 } 564 565 AcpiUtDeleteGenericState ( 566 AcpiUtPopGenericState (&WalkState->ControlState)); 567 } 568 569 AcpiPsPopScope (&(WalkState->ParserState), Op, 570 &WalkState->ArgTypes, &WalkState->ArgCount); 571 572 } while (*Op); 573 574 return_ACPI_STATUS (AE_OK); 575 576 default: /* All other non-AE_OK status */ 577 578 do 579 { 580 if (*Op) 581 { 582 Status2 = AcpiPsCompleteThisOp (WalkState, *Op); 583 if (ACPI_FAILURE (Status2)) 584 { 585 return_ACPI_STATUS (Status2); 586 } 587 } 588 589 AcpiPsPopScope (&(WalkState->ParserState), Op, 590 &WalkState->ArgTypes, &WalkState->ArgCount); 591 592 } while (*Op); 593 594 595 #if 0 596 /* 597 * TBD: Cleanup parse ops on error 598 */ 599 if (*Op == NULL) 600 { 601 AcpiPsPopScope (ParserState, Op, 602 &WalkState->ArgTypes, &WalkState->ArgCount); 603 } 604 #endif 605 WalkState->PrevOp = NULL; 606 WalkState->PrevArgTypes = WalkState->ArgTypes; 607 return_ACPI_STATUS (Status); 608 } 609 610 /* This scope complete? */ 611 612 if (AcpiPsHasCompletedScope (&(WalkState->ParserState))) 613 { 614 AcpiPsPopScope (&(WalkState->ParserState), Op, 615 &WalkState->ArgTypes, &WalkState->ArgCount); 616 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op)); 617 } 618 else 619 { 620 *Op = NULL; 621 } 622 623 return_ACPI_STATUS (AE_OK); 624 } 625 626 627 /******************************************************************************* 628 * 629 * FUNCTION: AcpiPsCompleteFinalOp 630 * 631 * PARAMETERS: WalkState - Current state 632 * Op - Current Op 633 * Status - Current parse status before complete last 634 * Op 635 * 636 * RETURN: Status 637 * 638 * DESCRIPTION: Complete last Op. 639 * 640 ******************************************************************************/ 641 642 ACPI_STATUS 643 AcpiPsCompleteFinalOp ( 644 ACPI_WALK_STATE *WalkState, 645 ACPI_PARSE_OBJECT *Op, 646 ACPI_STATUS Status) 647 { 648 ACPI_STATUS Status2; 649 650 651 ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState); 652 653 654 /* 655 * Complete the last Op (if not completed), and clear the scope stack. 656 * It is easily possible to end an AML "package" with an unbounded number 657 * of open scopes (such as when several ASL blocks are closed with 658 * sequential closing braces). We want to terminate each one cleanly. 659 */ 660 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op)); 661 do 662 { 663 if (Op) 664 { 665 if (WalkState->AscendingCallback != NULL) 666 { 667 WalkState->Op = Op; 668 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 669 WalkState->Opcode = Op->Common.AmlOpcode; 670 671 Status = WalkState->AscendingCallback (WalkState); 672 Status = AcpiPsNextParseState (WalkState, Op, Status); 673 if (Status == AE_CTRL_PENDING) 674 { 675 Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK); 676 if (ACPI_FAILURE (Status)) 677 { 678 return_ACPI_STATUS (Status); 679 } 680 } 681 682 if (Status == AE_CTRL_TERMINATE) 683 { 684 Status = AE_OK; 685 686 /* Clean up */ 687 do 688 { 689 if (Op) 690 { 691 Status2 = AcpiPsCompleteThisOp (WalkState, Op); 692 if (ACPI_FAILURE (Status2)) 693 { 694 return_ACPI_STATUS (Status2); 695 } 696 } 697 698 AcpiPsPopScope (&(WalkState->ParserState), &Op, 699 &WalkState->ArgTypes, &WalkState->ArgCount); 700 701 } while (Op); 702 703 return_ACPI_STATUS (Status); 704 } 705 706 else if (ACPI_FAILURE (Status)) 707 { 708 /* First error is most important */ 709 710 (void) AcpiPsCompleteThisOp (WalkState, Op); 711 return_ACPI_STATUS (Status); 712 } 713 } 714 715 Status2 = AcpiPsCompleteThisOp (WalkState, Op); 716 if (ACPI_FAILURE (Status2)) 717 { 718 return_ACPI_STATUS (Status2); 719 } 720 } 721 722 AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes, 723 &WalkState->ArgCount); 724 725 } while (Op); 726 727 return_ACPI_STATUS (Status); 728 } 729