1 /****************************************************************************** 2 * 3 * Module Name: dswload2 - Dispatcher second pass namespace load callbacks 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 #define __DSWLOAD2_C__ 45 46 #include "acpi.h" 47 #include "accommon.h" 48 #include "acparser.h" 49 #include "amlcode.h" 50 #include "acdispat.h" 51 #include "acinterp.h" 52 #include "acnamesp.h" 53 #include "acevents.h" 54 55 #define _COMPONENT ACPI_DISPATCHER 56 ACPI_MODULE_NAME ("dswload2") 57 58 59 /******************************************************************************* 60 * 61 * FUNCTION: AcpiDsLoad2BeginOp 62 * 63 * PARAMETERS: WalkState - Current state of the parse tree walk 64 * OutOp - Wher to return op if a new one is created 65 * 66 * RETURN: Status 67 * 68 * DESCRIPTION: Descending callback used during the loading of ACPI tables. 69 * 70 ******************************************************************************/ 71 72 ACPI_STATUS 73 AcpiDsLoad2BeginOp ( 74 ACPI_WALK_STATE *WalkState, 75 ACPI_PARSE_OBJECT **OutOp) 76 { 77 ACPI_PARSE_OBJECT *Op; 78 ACPI_NAMESPACE_NODE *Node; 79 ACPI_STATUS Status; 80 ACPI_OBJECT_TYPE ObjectType; 81 char *BufferPtr; 82 UINT32 Flags; 83 84 85 ACPI_FUNCTION_TRACE (DsLoad2BeginOp); 86 87 88 Op = WalkState->Op; 89 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState)); 90 91 if (Op) 92 { 93 if ((WalkState->ControlState) && 94 (WalkState->ControlState->Common.State == 95 ACPI_CONTROL_CONDITIONAL_EXECUTING)) 96 { 97 /* We are executing a while loop outside of a method */ 98 99 Status = AcpiDsExecBeginOp (WalkState, OutOp); 100 return_ACPI_STATUS (Status); 101 } 102 103 /* We only care about Namespace opcodes here */ 104 105 if ((!(WalkState->OpInfo->Flags & AML_NSOPCODE) && 106 (WalkState->Opcode != AML_INT_NAMEPATH_OP)) || 107 (!(WalkState->OpInfo->Flags & AML_NAMED))) 108 { 109 return_ACPI_STATUS (AE_OK); 110 } 111 112 /* Get the name we are going to enter or lookup in the namespace */ 113 114 if (WalkState->Opcode == AML_INT_NAMEPATH_OP) 115 { 116 /* For Namepath op, get the path string */ 117 118 BufferPtr = Op->Common.Value.String; 119 if (!BufferPtr) 120 { 121 /* No name, just exit */ 122 123 return_ACPI_STATUS (AE_OK); 124 } 125 } 126 else 127 { 128 /* Get name from the op */ 129 130 BufferPtr = ACPI_CAST_PTR (char, &Op->Named.Name); 131 } 132 } 133 else 134 { 135 /* Get the namestring from the raw AML */ 136 137 BufferPtr = AcpiPsGetNextNamestring (&WalkState->ParserState); 138 } 139 140 /* Map the opcode into an internal object type */ 141 142 ObjectType = WalkState->OpInfo->ObjectType; 143 144 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 145 "State=%p Op=%p Type=%X\n", WalkState, Op, ObjectType)); 146 147 switch (WalkState->Opcode) 148 { 149 case AML_FIELD_OP: 150 case AML_BANK_FIELD_OP: 151 case AML_INDEX_FIELD_OP: 152 153 Node = NULL; 154 Status = AE_OK; 155 break; 156 157 case AML_INT_NAMEPATH_OP: 158 /* 159 * The NamePath is an object reference to an existing object. 160 * Don't enter the name into the namespace, but look it up 161 * for use later. 162 */ 163 Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType, 164 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 165 WalkState, &(Node)); 166 break; 167 168 case AML_SCOPE_OP: 169 170 /* Special case for Scope(\) -> refers to the Root node */ 171 172 if (Op && (Op->Named.Node == AcpiGbl_RootNode)) 173 { 174 Node = Op->Named.Node; 175 176 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 177 if (ACPI_FAILURE (Status)) 178 { 179 return_ACPI_STATUS (Status); 180 } 181 } 182 else 183 { 184 /* 185 * The Path is an object reference to an existing object. 186 * Don't enter the name into the namespace, but look it up 187 * for use later. 188 */ 189 Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType, 190 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 191 WalkState, &(Node)); 192 if (ACPI_FAILURE (Status)) 193 { 194 #ifdef ACPI_ASL_COMPILER 195 if (Status == AE_NOT_FOUND) 196 { 197 Status = AE_OK; 198 } 199 else 200 { 201 ACPI_ERROR_NAMESPACE (BufferPtr, Status); 202 } 203 #else 204 ACPI_ERROR_NAMESPACE (BufferPtr, Status); 205 #endif 206 return_ACPI_STATUS (Status); 207 } 208 } 209 210 /* 211 * We must check to make sure that the target is 212 * one of the opcodes that actually opens a scope 213 */ 214 switch (Node->Type) 215 { 216 case ACPI_TYPE_ANY: 217 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ 218 case ACPI_TYPE_DEVICE: 219 case ACPI_TYPE_POWER: 220 case ACPI_TYPE_PROCESSOR: 221 case ACPI_TYPE_THERMAL: 222 223 /* These are acceptable types */ 224 break; 225 226 case ACPI_TYPE_INTEGER: 227 case ACPI_TYPE_STRING: 228 case ACPI_TYPE_BUFFER: 229 230 /* 231 * These types we will allow, but we will change the type. 232 * This enables some existing code of the form: 233 * 234 * Name (DEB, 0) 235 * Scope (DEB) { ... } 236 */ 237 ACPI_WARNING ((AE_INFO, 238 "Type override - [%4.4s] had invalid type (%s) " 239 "for Scope operator, changed to type ANY", 240 AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type))); 241 242 Node->Type = ACPI_TYPE_ANY; 243 WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY; 244 break; 245 246 case ACPI_TYPE_METHOD: 247 248 /* 249 * Allow scope change to root during execution of module-level 250 * code. Root is typed METHOD during this time. 251 */ 252 if ((Node == AcpiGbl_RootNode) && 253 (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 254 { 255 break; 256 } 257 258 /*lint -fallthrough */ 259 260 default: 261 262 /* All other types are an error */ 263 264 ACPI_ERROR ((AE_INFO, 265 "Invalid type (%s) for target of " 266 "Scope operator [%4.4s] (Cannot override)", 267 AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node))); 268 269 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 270 } 271 break; 272 273 default: 274 275 /* All other opcodes */ 276 277 if (Op && Op->Common.Node) 278 { 279 /* This op/node was previously entered into the namespace */ 280 281 Node = Op->Common.Node; 282 283 if (AcpiNsOpensScope (ObjectType)) 284 { 285 Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 286 if (ACPI_FAILURE (Status)) 287 { 288 return_ACPI_STATUS (Status); 289 } 290 } 291 292 return_ACPI_STATUS (AE_OK); 293 } 294 295 /* 296 * Enter the named type into the internal namespace. We enter the name 297 * as we go downward in the parse tree. Any necessary subobjects that 298 * involve arguments to the opcode must be created as we go back up the 299 * parse tree later. 300 * 301 * Note: Name may already exist if we are executing a deferred opcode. 302 */ 303 if (WalkState->DeferredNode) 304 { 305 /* This name is already in the namespace, get the node */ 306 307 Node = WalkState->DeferredNode; 308 Status = AE_OK; 309 break; 310 } 311 312 Flags = ACPI_NS_NO_UPSEARCH; 313 if (WalkState->PassNumber == ACPI_IMODE_EXECUTE) 314 { 315 /* Execution mode, node cannot already exist, node is temporary */ 316 317 Flags |= ACPI_NS_ERROR_IF_FOUND; 318 319 if (!(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 320 { 321 Flags |= ACPI_NS_TEMPORARY; 322 } 323 } 324 325 /* Add new entry or lookup existing entry */ 326 327 Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType, 328 ACPI_IMODE_LOAD_PASS2, Flags, WalkState, &Node); 329 330 if (ACPI_SUCCESS (Status) && (Flags & ACPI_NS_TEMPORARY)) 331 { 332 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 333 "***New Node [%4.4s] %p is temporary\n", 334 AcpiUtGetNodeName (Node), Node)); 335 } 336 break; 337 } 338 339 if (ACPI_FAILURE (Status)) 340 { 341 ACPI_ERROR_NAMESPACE (BufferPtr, Status); 342 return_ACPI_STATUS (Status); 343 } 344 345 if (!Op) 346 { 347 /* Create a new op */ 348 349 Op = AcpiPsAllocOp (WalkState->Opcode); 350 if (!Op) 351 { 352 return_ACPI_STATUS (AE_NO_MEMORY); 353 } 354 355 /* Initialize the new op */ 356 357 if (Node) 358 { 359 Op->Named.Name = Node->Name.Integer; 360 } 361 *OutOp = Op; 362 } 363 364 /* 365 * Put the Node in the "op" object that the parser uses, so we 366 * can get it again quickly when this scope is closed 367 */ 368 Op->Common.Node = Node; 369 return_ACPI_STATUS (Status); 370 } 371 372 373 /******************************************************************************* 374 * 375 * FUNCTION: AcpiDsLoad2EndOp 376 * 377 * PARAMETERS: WalkState - Current state of the parse tree walk 378 * 379 * RETURN: Status 380 * 381 * DESCRIPTION: Ascending callback used during the loading of the namespace, 382 * both control methods and everything else. 383 * 384 ******************************************************************************/ 385 386 ACPI_STATUS 387 AcpiDsLoad2EndOp ( 388 ACPI_WALK_STATE *WalkState) 389 { 390 ACPI_PARSE_OBJECT *Op; 391 ACPI_STATUS Status = AE_OK; 392 ACPI_OBJECT_TYPE ObjectType; 393 ACPI_NAMESPACE_NODE *Node; 394 ACPI_PARSE_OBJECT *Arg; 395 ACPI_NAMESPACE_NODE *NewNode; 396 #ifndef ACPI_NO_METHOD_EXECUTION 397 UINT32 i; 398 UINT8 RegionSpace; 399 #endif 400 401 402 ACPI_FUNCTION_TRACE (DsLoad2EndOp); 403 404 Op = WalkState->Op; 405 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n", 406 WalkState->OpInfo->Name, Op, WalkState)); 407 408 /* Check if opcode had an associated namespace object */ 409 410 if (!(WalkState->OpInfo->Flags & AML_NSOBJECT)) 411 { 412 return_ACPI_STATUS (AE_OK); 413 } 414 415 if (Op->Common.AmlOpcode == AML_SCOPE_OP) 416 { 417 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 418 "Ending scope Op=%p State=%p\n", Op, WalkState)); 419 } 420 421 ObjectType = WalkState->OpInfo->ObjectType; 422 423 /* 424 * Get the Node/name from the earlier lookup 425 * (It was saved in the *op structure) 426 */ 427 Node = Op->Common.Node; 428 429 /* 430 * Put the Node on the object stack (Contains the ACPI Name of 431 * this object) 432 */ 433 WalkState->Operands[0] = (void *) Node; 434 WalkState->NumOperands = 1; 435 436 /* Pop the scope stack */ 437 438 if (AcpiNsOpensScope (ObjectType) && 439 (Op->Common.AmlOpcode != AML_INT_METHODCALL_OP)) 440 { 441 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n", 442 AcpiUtGetTypeName (ObjectType), Op)); 443 444 Status = AcpiDsScopeStackPop (WalkState); 445 if (ACPI_FAILURE (Status)) 446 { 447 goto Cleanup; 448 } 449 } 450 451 /* 452 * Named operations are as follows: 453 * 454 * AML_ALIAS 455 * AML_BANKFIELD 456 * AML_CREATEBITFIELD 457 * AML_CREATEBYTEFIELD 458 * AML_CREATEDWORDFIELD 459 * AML_CREATEFIELD 460 * AML_CREATEQWORDFIELD 461 * AML_CREATEWORDFIELD 462 * AML_DATA_REGION 463 * AML_DEVICE 464 * AML_EVENT 465 * AML_FIELD 466 * AML_INDEXFIELD 467 * AML_METHOD 468 * AML_METHODCALL 469 * AML_MUTEX 470 * AML_NAME 471 * AML_NAMEDFIELD 472 * AML_OPREGION 473 * AML_POWERRES 474 * AML_PROCESSOR 475 * AML_SCOPE 476 * AML_THERMALZONE 477 */ 478 479 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 480 "Create-Load [%s] State=%p Op=%p NamedObj=%p\n", 481 AcpiPsGetOpcodeName (Op->Common.AmlOpcode), WalkState, Op, Node)); 482 483 /* Decode the opcode */ 484 485 Arg = Op->Common.Value.Arg; 486 487 switch (WalkState->OpInfo->Type) 488 { 489 #ifndef ACPI_NO_METHOD_EXECUTION 490 491 case AML_TYPE_CREATE_FIELD: 492 /* 493 * Create the field object, but the field buffer and index must 494 * be evaluated later during the execution phase 495 */ 496 Status = AcpiDsCreateBufferField (Op, WalkState); 497 break; 498 499 case AML_TYPE_NAMED_FIELD: 500 /* 501 * If we are executing a method, initialize the field 502 */ 503 if (WalkState->MethodNode) 504 { 505 Status = AcpiDsInitFieldObjects (Op, WalkState); 506 } 507 508 switch (Op->Common.AmlOpcode) 509 { 510 case AML_INDEX_FIELD_OP: 511 512 Status = AcpiDsCreateIndexField (Op, (ACPI_HANDLE) Arg->Common.Node, 513 WalkState); 514 break; 515 516 case AML_BANK_FIELD_OP: 517 518 Status = AcpiDsCreateBankField (Op, Arg->Common.Node, WalkState); 519 break; 520 521 case AML_FIELD_OP: 522 523 Status = AcpiDsCreateField (Op, Arg->Common.Node, WalkState); 524 break; 525 526 default: 527 528 /* All NAMED_FIELD opcodes must be handled above */ 529 break; 530 } 531 break; 532 533 case AML_TYPE_NAMED_SIMPLE: 534 535 Status = AcpiDsCreateOperands (WalkState, Arg); 536 if (ACPI_FAILURE (Status)) 537 { 538 goto Cleanup; 539 } 540 541 switch (Op->Common.AmlOpcode) 542 { 543 case AML_PROCESSOR_OP: 544 545 Status = AcpiExCreateProcessor (WalkState); 546 break; 547 548 case AML_POWER_RES_OP: 549 550 Status = AcpiExCreatePowerResource (WalkState); 551 break; 552 553 case AML_MUTEX_OP: 554 555 Status = AcpiExCreateMutex (WalkState); 556 break; 557 558 case AML_EVENT_OP: 559 560 Status = AcpiExCreateEvent (WalkState); 561 break; 562 563 case AML_ALIAS_OP: 564 565 Status = AcpiExCreateAlias (WalkState); 566 break; 567 568 default: 569 570 /* Unknown opcode */ 571 572 Status = AE_OK; 573 goto Cleanup; 574 } 575 576 /* Delete operands */ 577 578 for (i = 1; i < WalkState->NumOperands; i++) 579 { 580 AcpiUtRemoveReference (WalkState->Operands[i]); 581 WalkState->Operands[i] = NULL; 582 } 583 584 break; 585 #endif /* ACPI_NO_METHOD_EXECUTION */ 586 587 case AML_TYPE_NAMED_COMPLEX: 588 589 switch (Op->Common.AmlOpcode) 590 { 591 #ifndef ACPI_NO_METHOD_EXECUTION 592 case AML_REGION_OP: 593 case AML_DATA_REGION_OP: 594 595 if (Op->Common.AmlOpcode == AML_REGION_OP) 596 { 597 RegionSpace = (ACPI_ADR_SPACE_TYPE) 598 ((Op->Common.Value.Arg)->Common.Value.Integer); 599 } 600 else 601 { 602 RegionSpace = ACPI_ADR_SPACE_DATA_TABLE; 603 } 604 605 /* 606 * The OpRegion is not fully parsed at this time. The only valid 607 * argument is the SpaceId. (We must save the address of the 608 * AML of the address and length operands) 609 * 610 * If we have a valid region, initialize it. The namespace is 611 * unlocked at this point. 612 * 613 * Need to unlock interpreter if it is locked (if we are running 614 * a control method), in order to allow _REG methods to be run 615 * during AcpiEvInitializeRegion. 616 */ 617 if (WalkState->MethodNode) 618 { 619 /* 620 * Executing a method: initialize the region and unlock 621 * the interpreter 622 */ 623 Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length, 624 RegionSpace, WalkState); 625 if (ACPI_FAILURE (Status)) 626 { 627 return_ACPI_STATUS (Status); 628 } 629 630 AcpiExExitInterpreter (); 631 } 632 633 Status = AcpiEvInitializeRegion (AcpiNsGetAttachedObject (Node), 634 FALSE); 635 if (WalkState->MethodNode) 636 { 637 AcpiExEnterInterpreter (); 638 } 639 640 if (ACPI_FAILURE (Status)) 641 { 642 /* 643 * If AE_NOT_EXIST is returned, it is not fatal 644 * because many regions get created before a handler 645 * is installed for said region. 646 */ 647 if (AE_NOT_EXIST == Status) 648 { 649 Status = AE_OK; 650 } 651 } 652 break; 653 654 case AML_NAME_OP: 655 656 Status = AcpiDsCreateNode (WalkState, Node, Op); 657 break; 658 659 case AML_METHOD_OP: 660 /* 661 * MethodOp PkgLength NameString MethodFlags TermList 662 * 663 * Note: We must create the method node/object pair as soon as we 664 * see the method declaration. This allows later pass1 parsing 665 * of invocations of the method (need to know the number of 666 * arguments.) 667 */ 668 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 669 "LOADING-Method: State=%p Op=%p NamedObj=%p\n", 670 WalkState, Op, Op->Named.Node)); 671 672 if (!AcpiNsGetAttachedObject (Op->Named.Node)) 673 { 674 WalkState->Operands[0] = ACPI_CAST_PTR (void, Op->Named.Node); 675 WalkState->NumOperands = 1; 676 677 Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg); 678 if (ACPI_SUCCESS (Status)) 679 { 680 Status = AcpiExCreateMethod (Op->Named.Data, 681 Op->Named.Length, WalkState); 682 } 683 WalkState->Operands[0] = NULL; 684 WalkState->NumOperands = 0; 685 686 if (ACPI_FAILURE (Status)) 687 { 688 return_ACPI_STATUS (Status); 689 } 690 } 691 break; 692 693 #endif /* ACPI_NO_METHOD_EXECUTION */ 694 695 default: 696 697 /* All NAMED_COMPLEX opcodes must be handled above */ 698 break; 699 } 700 break; 701 702 case AML_CLASS_INTERNAL: 703 704 /* case AML_INT_NAMEPATH_OP: */ 705 break; 706 707 case AML_CLASS_METHOD_CALL: 708 709 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 710 "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n", 711 WalkState, Op, Node)); 712 713 /* 714 * Lookup the method name and save the Node 715 */ 716 Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String, 717 ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS2, 718 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 719 WalkState, &(NewNode)); 720 if (ACPI_SUCCESS (Status)) 721 { 722 /* 723 * Make sure that what we found is indeed a method 724 * We didn't search for a method on purpose, to see if the name 725 * would resolve 726 */ 727 if (NewNode->Type != ACPI_TYPE_METHOD) 728 { 729 Status = AE_AML_OPERAND_TYPE; 730 } 731 732 /* We could put the returned object (Node) on the object stack for 733 * later, but for now, we will put it in the "op" object that the 734 * parser uses, so we can get it again at the end of this scope 735 */ 736 Op->Common.Node = NewNode; 737 } 738 else 739 { 740 ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status); 741 } 742 break; 743 744 745 default: 746 747 break; 748 } 749 750 Cleanup: 751 752 /* Remove the Node pushed at the very beginning */ 753 754 WalkState->Operands[0] = NULL; 755 WalkState->NumOperands = 0; 756 return_ACPI_STATUS (Status); 757 }