char * MpGetConnectionInfo ( ACPI_PARSE_OBJECT *Op, UINT32 PinIndex, ACPI_NAMESPACE_NODE **TargetNode, char **TargetName) { ACPI_PARSE_OBJECT *NextOp; UINT32 i; /* * Handle Connection() here. Find the next named FieldUnit. * Note: we look at the ParseOpcode for the compiler, look * at the AmlOpcode for the disassembler. */ if ((Op->Asl.AmlOpcode == AML_INT_CONNECTION_OP) || (Op->Asl.ParseOpcode == PARSEOP_CONNECTION)) { /* Find the correct field unit definition */ NextOp = Op; for (i = 0; i <= PinIndex;) { NextOp = NextOp->Asl.Next; while (NextOp && (NextOp->Asl.ParseOpcode != PARSEOP_NAMESEG) && (NextOp->Asl.AmlOpcode != AML_INT_NAMEDFIELD_OP)) { NextOp = NextOp->Asl.Next; } if (!NextOp) { return ("UNKNOWN"); } /* Add length of this field to the current pin index */ if (NextOp->Asl.ParseOpcode == PARSEOP_NAMESEG) { i += (UINT32) NextOp->Asl.Child->Asl.Value.Integer; } else /* AML_INT_NAMEDFIELD_OP */ { i += (UINT32) NextOp->Asl.Value.Integer; } } /* Return the node and pathname for the field unit */ *TargetNode = NextOp->Asl.Node; *TargetName = AcpiNsGetExternalPathname (*TargetNode); return ("-Field-"); } return (NULL); }
static ACPI_STATUS AcpiDbWalkForPredefinedNames ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; UINT32 *Count = (UINT32 *) Context; const ACPI_PREDEFINED_INFO *Predefined; const ACPI_PREDEFINED_INFO *Package = NULL; char *Pathname; char StringBuffer[48]; Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii); if (!Predefined) { return (AE_OK); } Pathname = AcpiNsGetExternalPathname (Node); if (!Pathname) { return (AE_OK); } /* If method returns a package, the info is in the next table entry */ if (Predefined->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE) { Package = Predefined + 1; } AcpiUtGetExpectedReturnTypes (StringBuffer, Predefined->Info.ExpectedBtypes); AcpiOsPrintf ("%-32s Arguments %X, Return Types: %s", Pathname, METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList), StringBuffer); if (Package) { AcpiOsPrintf (" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)", Package->RetInfo.Type, Package->RetInfo.ObjectType1, Package->RetInfo.Count1); } AcpiOsPrintf("\n"); /* Check that the declared argument count matches the ACPI spec */ AcpiNsCheckAcpiCompliance (Pathname, Node, Predefined); ACPI_FREE (Pathname); (*Count)++; return (AE_OK); }
static ACPI_STATUS AcpiDbWalkForPredefinedNames ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; UINT32 *Count = (UINT32 *) Context; const ACPI_PREDEFINED_INFO *Predefined; const ACPI_PREDEFINED_INFO *Package = NULL; char *Pathname; Predefined = AcpiNsCheckForPredefinedName (Node); if (!Predefined) { return (AE_OK); } Pathname = AcpiNsGetExternalPathname (Node); if (!Pathname) { return (AE_OK); } /* If method returns a package, the info is in the next table entry */ if (Predefined->Info.ExpectedBtypes & ACPI_BTYPE_PACKAGE) { Package = Predefined + 1; } AcpiOsPrintf ("%-32s arg %X ret %2.2X", Pathname, Predefined->Info.ParamCount, Predefined->Info.ExpectedBtypes); if (Package) { AcpiOsPrintf (" PkgType %2.2X ObjType %2.2X Count %2.2X", Package->RetInfo.Type, Package->RetInfo.ObjectType1, Package->RetInfo.Count1); } AcpiOsPrintf("\n"); AcpiNsCheckParameterCount (Pathname, Node, ACPI_UINT32_MAX, Predefined); ACPI_FREE (Pathname); (*Count)++; return (AE_OK); }
static ACPI_STATUS AcpiDbDisplayNonRootHandlers ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); ACPI_OPERAND_OBJECT *ObjDesc; ACPI_OPERAND_OBJECT *HandlerObj; char *Pathname; ObjDesc = AcpiNsGetAttachedObject (Node); if (!ObjDesc) { return (AE_OK); } Pathname = AcpiNsGetExternalPathname (Node); if (!Pathname) { return (AE_OK); } /* Display all handlers associated with this device */ HandlerObj = ObjDesc->Device.Handler; while (HandlerObj) { AcpiOsPrintf (ACPI_PREDEFINED_PREFIX, AcpiUtGetRegionName ((UINT8) HandlerObj->AddressSpace.SpaceId), HandlerObj->AddressSpace.SpaceId); AcpiOsPrintf (ACPI_HANDLER_PRESENT_STRING2, (HandlerObj->AddressSpace.HandlerFlags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default" : "User", HandlerObj->AddressSpace.Handler); AcpiOsPrintf (" Device Name: %s (%p)\n", Pathname, Node); HandlerObj = HandlerObj->AddressSpace.Next; } ACPI_FREE (Pathname); return (AE_OK); }
static ACPI_STATUS AcpiNsDumpOneObjectPath ( ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue) { UINT32 MaxLevel = *((UINT32 *) Context); char *Pathname; ACPI_NAMESPACE_NODE *Node; int PathIndent; if (!ObjHandle) { return (AE_OK); } Node = AcpiNsValidateHandle (ObjHandle); if (!Node) { /* Ignore bad node during namespace walk */ return (AE_OK); } Pathname = AcpiNsGetExternalPathname (Node); PathIndent = 1; if (Level <= MaxLevel) { PathIndent = MaxLevel - Level + 1; } AcpiOsPrintf ("%2d%*s%-12s%*s", Level, Level, " ", AcpiUtGetTypeName (Node->Type), PathIndent, " "); AcpiOsPrintf ("%s\n", &Pathname[1]); ACPI_FREE (Pathname); return (AE_OK); }
static ACPI_STATUS MpEmitOneDevice ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { char *DevicePathname; char *DdnString; char *HidString; const AH_DEVICE_ID *HidInfo; /* Device pathname */ DevicePathname = AcpiNsGetExternalPathname ( ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle)); FlPrintFile (ASL_FILE_MAP_OUTPUT, "%-32s", DevicePathname); /* _HID or _DDN */ HidString = MpGetHidValue ( ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle)); FlPrintFile (ASL_FILE_MAP_OUTPUT, "%8s", HidString); HidInfo = AcpiAhMatchHardwareId (HidString); if (HidInfo) { FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s", HidInfo->Description); } else if ((DdnString = MpGetDdnValue (DevicePathname))) { FlPrintFile (ASL_FILE_MAP_OUTPUT, " // %s (_DDN)", DdnString); } FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n"); ACPI_FREE (DevicePathname); return (AE_OK); }
char * MpGetParentDeviceHid ( ACPI_PARSE_OBJECT *Op, ACPI_NAMESPACE_NODE **TargetNode, char **ParentDeviceName) { ACPI_NAMESPACE_NODE *DeviceNode; /* Find parent Device() or Scope() Op */ while (Op && (Op->Asl.AmlOpcode != AML_DEVICE_OP) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) { Op = Op->Asl.Parent; } if (!Op) { FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Parent_Device "); goto ErrorExit; } /* Get the full pathname to the device and the _HID */ DeviceNode = Op->Asl.Node; if (!DeviceNode) { FlPrintFile (ASL_FILE_MAP_OUTPUT, " No_Device_Node "); goto ErrorExit; } *ParentDeviceName = AcpiNsGetExternalPathname (DeviceNode); return (MpGetHidValue (DeviceNode)); ErrorExit: return ("-No HID-"); }
static char * AcpiDmNormalizeParentPrefix ( ACPI_PARSE_OBJECT *Op, char *Path) { ACPI_NAMESPACE_NODE *Node; char *Fullpath; char *ParentPath; ACPI_SIZE Length; UINT32 Index = 0; if (!Op) { return (NULL); } /* Search upwards in the parse tree until we reach the next namespace node */ Op = Op->Common.Parent; while (Op) { if (Op->Common.Node) { break; } Op = Op->Common.Parent; } if (!Op) { return (NULL); } /* * Find the actual parent node for the reference: * Remove all carat prefixes from the input path. * There may be multiple parent prefixes (For example, ^^^M000) */ Node = Op->Common.Node; while (Node && (*Path == (UINT8) AML_PARENT_PREFIX)) { Node = Node->Parent; Path++; } if (!Node) { return (NULL); } /* Get the full pathname for the parent node */ ParentPath = AcpiNsGetExternalPathname (Node); if (!ParentPath) { return (NULL); } Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1); if (ParentPath[1]) { /* * If ParentPath is not just a simple '\', increment the length * for the required dot separator (ParentPath.Path) */ Length++; /* For External() statements, we do not want a leading '\' */ if (*ParentPath == AML_ROOT_PREFIX) { Index = 1; } } Fullpath = ACPI_ALLOCATE_ZEROED (Length); if (!Fullpath) { goto Cleanup; } /* * Concatenate parent fullpath and path. For example, * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT" * * Copy the parent path */ ACPI_STRCPY (Fullpath, &ParentPath[Index]); /* * Add dot separator * (don't need dot if parent fullpath is a single backslash) */ if (ParentPath[1]) { ACPI_STRCAT (Fullpath, "."); } /* Copy child path (carat parent prefix(es) were skipped above) */ ACPI_STRCAT (Fullpath, Path); Cleanup: ACPI_FREE (ParentPath); return (Fullpath); }
static void LsWriteNodeToListing ( ACPI_PARSE_OBJECT *Op, UINT32 FileId) { const ACPI_OPCODE_INFO *OpInfo; UINT32 OpClass; char *Pathname; UINT32 Length; UINT32 i; OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); OpClass = OpInfo->Class; /* TBD: clean this up with a single flag that says: * I start a named output block */ if (FileId == ASL_FILE_C_SOURCE_OUTPUT) { switch (Op->Asl.ParseOpcode) { case PARSEOP_DEFINITION_BLOCK: case PARSEOP_METHODCALL: case PARSEOP_INCLUDE: case PARSEOP_INCLUDE_END: case PARSEOP_DEFAULT_ARG: break; default: switch (OpClass) { case AML_CLASS_NAMED_OBJECT: switch (Op->Asl.AmlOpcode) { case AML_SCOPE_OP: case AML_ALIAS_OP: break; default: if (Op->Asl.ExternalName) { LsFlushListingBuffer (FileId); FlPrintFile (FileId, " };\n"); } break; } break; default: /* Don't care about other objects */ break; } break; } } /* These cases do not have a corresponding AML opcode */ switch (Op->Asl.ParseOpcode) { case PARSEOP_DEFINITION_BLOCK: /* Always start a definition block at AML offset zero */ Gbl_CurrentAmlOffset = 0; LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, FileId); /* Use the table Signature and TableId to build a unique name */ switch (FileId) { case ASL_FILE_ASM_SOURCE_OUTPUT: FlPrintFile (FileId, "%s_%s_Header \\\n", Gbl_TableSignature, Gbl_TableId); break; case ASL_FILE_C_SOURCE_OUTPUT: FlPrintFile (FileId, " unsigned char %s_%s_Header [] =\n {\n", Gbl_TableSignature, Gbl_TableId); break; case ASL_FILE_ASM_INCLUDE_OUTPUT: FlPrintFile (FileId, "extrn %s_%s_Header : byte\n", Gbl_TableSignature, Gbl_TableId); break; case ASL_FILE_C_INCLUDE_OUTPUT: FlPrintFile (FileId, "extern unsigned char %s_%s_Header [];\n", Gbl_TableSignature, Gbl_TableId); break; default: break; } return; case PARSEOP_METHODCALL: LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, FileId); return; case PARSEOP_INCLUDE: /* Flush everything up to and including the include source line */ LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, FileId); /* Create a new listing node and push it */ LsPushNode (Op->Asl.Value.String); return; case PARSEOP_INCLUDE_END: /* Flush out the rest of the include file */ LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, FileId); /* Pop off this listing node and go back to the parent file */ (void) LsPopNode (); return; case PARSEOP_DEFAULT_ARG: if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) { LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.EndLogicalLine, FileId); } return; default: /* All other opcodes have an AML opcode */ break; } /* * Otherwise, we look at the AML opcode because we can * switch on the opcode type, getting an entire class * at once */ switch (OpClass) { case AML_CLASS_ARGUMENT: /* argument type only */ case AML_CLASS_INTERNAL: break; case AML_CLASS_NAMED_OBJECT: switch (Op->Asl.AmlOpcode) { case AML_FIELD_OP: case AML_INDEX_FIELD_OP: case AML_BANK_FIELD_OP: /* * For fields, we want to dump all the AML after the * entire definition */ LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, FileId); break; case AML_NAME_OP: if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) { LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, FileId); } else { /* * For fields, we want to dump all the AML after the * entire definition */ LsWriteSourceLines (Op->Asl.EndLine, Op->Asl.EndLogicalLine, FileId); } break; default: LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, FileId); break; } switch (Op->Asl.AmlOpcode) { case AML_SCOPE_OP: case AML_ALIAS_OP: /* These opcodes do not declare a new object, ignore them */ break; default: /* All other named object opcodes come here */ switch (FileId) { case ASL_FILE_ASM_SOURCE_OUTPUT: case ASL_FILE_C_SOURCE_OUTPUT: case ASL_FILE_ASM_INCLUDE_OUTPUT: case ASL_FILE_C_INCLUDE_OUTPUT: /* * For named objects, we will create a valid symbol so that the * AML code can be referenced from C or ASM */ if (Op->Asl.ExternalName) { /* Get the full pathname associated with this node */ Pathname = AcpiNsGetExternalPathname (Op->Asl.Node); Length = strlen (Pathname); if (Length >= 4) { /* Convert all dots in the path to underscores */ for (i = 0; i < Length; i++) { if (Pathname[i] == '.') { Pathname[i] = '_'; } } /* Create the appropriate symbol in the output file */ switch (FileId) { case ASL_FILE_ASM_SOURCE_OUTPUT: FlPrintFile (FileId, "%s_%s_%s \\\n", Gbl_TableSignature, Gbl_TableId, &Pathname[1]); break; case ASL_FILE_C_SOURCE_OUTPUT: FlPrintFile (FileId, " unsigned char %s_%s_%s [] =\n {\n", Gbl_TableSignature, Gbl_TableId, &Pathname[1]); break; case ASL_FILE_ASM_INCLUDE_OUTPUT: FlPrintFile (FileId, "extrn %s_%s_%s : byte\n", Gbl_TableSignature, Gbl_TableId, &Pathname[1]); break; case ASL_FILE_C_INCLUDE_OUTPUT: FlPrintFile (FileId, "extern unsigned char %s_%s_%s [];\n", Gbl_TableSignature, Gbl_TableId, &Pathname[1]); break; default: break; } } ACPI_FREE (Pathname); } break; default: /* Nothing to do for listing file */ break; } } break; case AML_CLASS_EXECUTE: case AML_CLASS_CREATE: default: if ((Op->Asl.ParseOpcode == PARSEOP_BUFFER) && (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC)) { return; } LsWriteSourceLines (Op->Asl.LineNumber, Op->Asl.LogicalLineNumber, FileId); break; case AML_CLASS_UNKNOWN: break; } }
static ACPI_STATUS AcpiDbDeviceResources ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_NAMESPACE_NODE *Node; ACPI_NAMESPACE_NODE *PrtNode = NULL; ACPI_NAMESPACE_NODE *CrsNode = NULL; ACPI_NAMESPACE_NODE *PrsNode = NULL; ACPI_NAMESPACE_NODE *AeiNode = NULL; char *ParentPath; ACPI_BUFFER ReturnObj; ACPI_STATUS Status; Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); ParentPath = AcpiNsGetExternalPathname (Node); if (!ParentPath) { return (AE_NO_MEMORY); } /* Get handles to the resource methods for this device */ (void) AcpiGetHandle (Node, METHOD_NAME__PRT, ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode)); (void) AcpiGetHandle (Node, METHOD_NAME__CRS, ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode)); (void) AcpiGetHandle (Node, METHOD_NAME__PRS, ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode)); (void) AcpiGetHandle (Node, METHOD_NAME__AEI, ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode)); if (!PrtNode && !CrsNode && !PrsNode && !AeiNode) { goto Cleanup; /* Nothing to do */ } AcpiOsPrintf ("\nDevice: %s\n", ParentPath); /* Prepare for a return object of arbitrary size */ ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; /* _PRT */ if (PrtNode) { AcpiOsPrintf ("Evaluating _PRT\n"); Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not evaluate _PRT: %s\n", AcpiFormatException (Status)); goto GetCrs; } ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiGetIrqRoutingTable (Node, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n", AcpiFormatException (Status)); goto GetCrs; } AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer)); } /* _CRS */ GetCrs: if (CrsNode) { AcpiOsPrintf ("Evaluating _CRS\n"); ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not evaluate _CRS: %s\n", AcpiFormatException (Status)); goto GetPrs; } /* This code is here to exercise the AcpiWalkResources interface */ Status = AcpiWalkResources (Node, METHOD_NAME__CRS, AcpiDbResourceCallback, NULL); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("AcpiWalkResources failed: %s\n", AcpiFormatException (Status)); goto GetPrs; } /* Get the _CRS resource list */ ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiGetCurrentResources (Node, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", AcpiFormatException (Status)); goto GetPrs; } /* Dump the _CRS resource list */ AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, ReturnObj.Pointer)); /* * Perform comparison of original AML to newly created AML. This tests both * the AML->Resource conversion and the Resource->Aml conversion. */ Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS); /* Execute _SRS with the resource list */ Status = AcpiSetCurrentResources (Node, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n", AcpiFormatException (Status)); goto GetPrs; } } /* _PRS */ GetPrs: if (PrsNode) { AcpiOsPrintf ("Evaluating _PRS\n"); ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not evaluate _PRS: %s\n", AcpiFormatException (Status)); goto GetAei; } ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiGetPossibleResources (Node, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n", AcpiFormatException (Status)); goto GetAei; } AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer)); } /* _AEI */ GetAei: if (AeiNode) { AcpiOsPrintf ("Evaluating _AEI\n"); ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not evaluate _AEI: %s\n", AcpiFormatException (Status)); goto Cleanup; } ReturnObj.Pointer = AcpiGbl_DbBuffer; ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; Status = AcpiGetEventResources (Node, &ReturnObj); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("AcpiGetEventResources failed: %s\n", AcpiFormatException (Status)); goto Cleanup; } AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer)); } Cleanup: ACPI_FREE (ParentPath); return (AE_OK); }
static ACPI_STATUS AcpiDbWalkForExecute ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; ACPI_EXECUTE_WALK *Info = (ACPI_EXECUTE_WALK *) Context; ACPI_BUFFER ReturnObj; ACPI_STATUS Status; char *Pathname; UINT32 i; ACPI_DEVICE_INFO *ObjInfo; ACPI_OBJECT_LIST ParamObjects; ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; const ACPI_PREDEFINED_INFO *Predefined; Predefined = AcpiNsCheckForPredefinedName (Node); if (!Predefined) { return (AE_OK); } if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) { return (AE_OK); } Pathname = AcpiNsGetExternalPathname (Node); if (!Pathname) { return (AE_OK); } /* Get the object info for number of method parameters */ Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo); if (ACPI_FAILURE (Status)) { return (Status); } ParamObjects.Pointer = NULL; ParamObjects.Count = 0; if (ObjInfo->Type == ACPI_TYPE_METHOD) { /* Setup default parameters */ for (i = 0; i < ObjInfo->ParamCount; i++) { Params[i].Type = ACPI_TYPE_INTEGER; Params[i].Integer.Value = 1; } ParamObjects.Pointer = Params; ParamObjects.Count = ObjInfo->ParamCount; } ACPI_FREE (ObjInfo); ReturnObj.Pointer = NULL; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; /* Do the actual method execution */ AcpiGbl_MethodExecuting = TRUE; Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj); AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status)); AcpiGbl_MethodExecuting = FALSE; ACPI_FREE (Pathname); /* Ignore status from method execution */ Status = AE_OK; /* Update count, check if we have executed enough methods */ Info->Count++; if (Info->Count >= Info->MaxCount) { Status = AE_CTRL_TERMINATE; } return (Status); }
ACPI_STATUS AcpiEvaluateObjectTyped ( ACPI_HANDLE Handle, ACPI_STRING Pathname, ACPI_OBJECT_LIST *ExternalParams, ACPI_BUFFER *ReturnBuffer, ACPI_OBJECT_TYPE ReturnType) { ACPI_STATUS Status; BOOLEAN FreeBufferOnError = FALSE; ACPI_HANDLE TargetHandle; char *FullPathname; ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped); /* Return buffer must be valid */ if (!ReturnBuffer) { return_ACPI_STATUS (AE_BAD_PARAMETER); } if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER) { FreeBufferOnError = TRUE; } /* Get a handle here, in order to build an error message if needed */ TargetHandle = Handle; if (Pathname) { Status = AcpiGetHandle (Handle, Pathname, &TargetHandle); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } FullPathname = AcpiNsGetExternalPathname (TargetHandle); if (!FullPathname) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Evaluate the object */ Status = AcpiEvaluateObject (TargetHandle, NULL, ExternalParams, ReturnBuffer); if (ACPI_FAILURE (Status)) { goto Exit; } /* Type ANY means "don't care about return value type" */ if (ReturnType == ACPI_TYPE_ANY) { goto Exit; } if (ReturnBuffer->Length == 0) { /* Error because caller specifically asked for a return value */ ACPI_ERROR ((AE_INFO, "%s did not return any object", FullPathname)); Status = AE_NULL_OBJECT; goto Exit; } /* Examine the object type returned from EvaluateObject */ if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType) { goto Exit; } /* Return object type does not match requested type */ ACPI_ERROR ((AE_INFO, "Incorrect return type from %s - received [%s], requested [%s]", FullPathname, AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type), AcpiUtGetTypeName (ReturnType))); if (FreeBufferOnError) { /* * Free a buffer created via ACPI_ALLOCATE_BUFFER. * Note: We use AcpiOsFree here because AcpiOsAllocate was used * to allocate the buffer. This purposefully bypasses the * (optionally enabled) allocation tracking mechanism since we * only want to track internal allocations. */ AcpiOsFree (ReturnBuffer->Pointer); ReturnBuffer->Pointer = NULL; } ReturnBuffer->Length = 0; Status = AE_TYPE; Exit: ACPI_FREE (FullPathname); return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiNsCheckPredefinedNames ( ACPI_NAMESPACE_NODE *Node, UINT32 UserParamCount, ACPI_STATUS ReturnStatus, ACPI_OPERAND_OBJECT **ReturnObjectPtr) { ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; ACPI_STATUS Status = AE_OK; const ACPI_PREDEFINED_INFO *Predefined; char *Pathname; ACPI_PREDEFINED_DATA *Data; /* Match the name for this method/object against the predefined list */ Predefined = AcpiNsCheckForPredefinedName (Node); /* Get the full pathname to the object, for use in warning messages */ #ifdef ACPI_DEBUG_OUTPUT /* AB */ Pathname = AcpiNsGetExternalPathname (Node); #else Pathname = NULL; #endif if (!Pathname) { return (AE_OK); /* Could not get pathname, ignore */ } /* * Check that the parameter count for this method matches the ASL * definition. For predefined names, ensure that both the caller and * the method itself are in accordance with the ACPI specification. */ AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined); /* If not a predefined name, we cannot validate the return object */ if (!Predefined) { goto Cleanup; } /* * If the method failed or did not actually return an object, we cannot * validate the return object */ if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE)) { goto Cleanup; } /* * If there is no return value, check if we require a return value for * this predefined name. Either one return value is expected, or none, * for both methods and other objects. * * Exit now if there is no return object. Warning if one was expected. */ if (!ReturnObject) { if ((Predefined->Info.ExpectedBtypes) && (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE))) { ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, "Missing expected return value")); Status = AE_AML_NO_RETURN_VALUE; } goto Cleanup; } /* * 1) We have a return value, but if one wasn't expected, just exit, this is * not a problem. For example, if the "Implicit Return" feature is * enabled, methods will always return a value. * * 2) If the return value can be of any type, then we cannot perform any * validation, exit. */ if ((!Predefined->Info.ExpectedBtypes) || (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL)) { goto Cleanup; } /* Create the parameter data block for object validation */ Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA)); if (!Data) { goto Cleanup; } Data->Predefined = Predefined; Data->NodeFlags = Node->Flags; Data->Pathname = Pathname; /* * Check that the type of the return object is what is expected for * this predefined name */ Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr, Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT); if (ACPI_FAILURE (Status)) { goto CheckValidationStatus; } /* For returned Package objects, check the type of all sub-objects */ if (ReturnObject->Common.Type == ACPI_TYPE_PACKAGE) { Status = AcpiNsCheckPackage (Data, ReturnObjectPtr); } CheckValidationStatus: /* * If the object validation failed or if we successfully repaired one * or more objects, mark the parent node to suppress further warning * messages during the next evaluation of the same method/object. */ if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED)) { Node->Flags |= ANOBJ_EVALUATED; } ACPI_FREE (Data); Cleanup: ACPI_FREE (Pathname); return (Status); }
static ACPI_STATUS MpNamespaceXrefBegin ( ACPI_PARSE_OBJECT *Op, UINT32 Level, void *Context) { ACPI_GPIO_INFO *Info = ACPI_CAST_PTR (ACPI_GPIO_INFO, Context); const ACPI_OPCODE_INFO *OpInfo; char *DevicePathname; ACPI_PARSE_OBJECT *ParentOp; char *HidString; ACPI_FUNCTION_TRACE_PTR (MpNamespaceXrefBegin, Op); /* * If this node is the actual declaration of a name * [such as the XXXX name in "Method (XXXX)"], * we are not interested in it here. We only care about names that * are references to other objects within the namespace and the * parent objects of name declarations */ if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION) { return (AE_OK); } /* We are only interested in opcodes that have an associated name */ OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); if ((OpInfo->Flags & AML_NAMED) || (OpInfo->Flags & AML_CREATE)) { return (AE_OK); } if ((Op->Asl.ParseOpcode != PARSEOP_NAMESTRING) && (Op->Asl.ParseOpcode != PARSEOP_NAMESEG) && (Op->Asl.ParseOpcode != PARSEOP_METHODCALL)) { return (AE_OK); } if (!Op->Asl.Node) { return (AE_OK); } ParentOp = Op->Asl.Parent; if (ParentOp->Asl.ParseOpcode == PARSEOP_FIELD) { return (AE_OK); } if (Op->Asl.Node == Info->TargetNode) { while (ParentOp && (!ParentOp->Asl.Node)) { ParentOp = ParentOp->Asl.Parent; } if (ParentOp) { DevicePathname = AcpiNsGetExternalPathname ( ParentOp->Asl.Node); if (!Info->References) { FlPrintFile (ASL_FILE_MAP_OUTPUT, " // References:"); } HidString = MpGetHidViaNamestring (DevicePathname); FlPrintFile (ASL_FILE_MAP_OUTPUT, " %s [%s]", DevicePathname, HidString); Info->References++; ACPI_FREE (DevicePathname); } } return (AE_OK); }
ACPI_STATUS AcpiNsCheckPredefinedNames ( ACPI_NAMESPACE_NODE *Node, UINT32 UserParamCount, ACPI_STATUS ReturnStatus, ACPI_OPERAND_OBJECT **ReturnObjectPtr) { ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; ACPI_STATUS Status = AE_OK; const ACPI_PREDEFINED_INFO *Predefined; char *Pathname; ACPI_PREDEFINED_DATA *Data; /* Match the name for this method/object against the predefined list */ Predefined = AcpiNsCheckForPredefinedName (Node); /* Get the full pathname to the object, for use in warning messages */ Pathname = AcpiNsGetExternalPathname (Node); if (!Pathname) { return (AE_OK); /* Could not get pathname, ignore */ } /* * Check that the parameter count for this method matches the ASL * definition. For predefined names, ensure that both the caller and * the method itself are in accordance with the ACPI specification. */ AcpiNsCheckParameterCount (Pathname, Node, UserParamCount, Predefined); /* If not a predefined name, we cannot validate the return object */ if (!Predefined) { goto Cleanup; } /* * If the method failed or did not actually return an object, we cannot * validate the return object */ if ((ReturnStatus != AE_OK) && (ReturnStatus != AE_CTRL_RETURN_VALUE)) { goto Cleanup; } /* * If there is no return value, check if we require a return value for * this predefined name. Either one return value is expected, or none, * for both methods and other objects. * * Exit now if there is no return object. Warning if one was expected. */ if (!ReturnObject) { if ((Predefined->Info.ExpectedBtypes) && (!(Predefined->Info.ExpectedBtypes & ACPI_RTYPE_NONE))) { ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, "Missing expected return value")); Status = AE_AML_NO_RETURN_VALUE; } goto Cleanup; } /* * Return value validation and possible repair. * * 1) Don't perform return value validation/repair if this feature * has been disabled via a global option. * * 2) We have a return value, but if one wasn't expected, just exit, * this is not a problem. For example, if the "Implicit Return" * feature is enabled, methods will always return a value. * * 3) If the return value can be of any type, then we cannot perform * any validation, just exit. */ if (AcpiGbl_DisableAutoRepair || (!Predefined->Info.ExpectedBtypes) || (Predefined->Info.ExpectedBtypes == ACPI_RTYPE_ALL)) { goto Cleanup; } /* Create the parameter data block for object validation */ Data = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PREDEFINED_DATA)); if (!Data) { goto Cleanup; } Data->Predefined = Predefined; Data->Node = Node; Data->NodeFlags = Node->Flags; Data->Pathname = Pathname; /* * Check that the type of the main return object is what is expected * for this predefined name */ Status = AcpiNsCheckObjectType (Data, ReturnObjectPtr, Predefined->Info.ExpectedBtypes, ACPI_NOT_PACKAGE_ELEMENT); if (ACPI_FAILURE (Status)) { goto Exit; } /* * For returned Package objects, check the type of all sub-objects. * Note: Package may have been newly created by call above. */ if ((*ReturnObjectPtr)->Common.Type == ACPI_TYPE_PACKAGE) { Data->ParentPackage = *ReturnObjectPtr; Status = AcpiNsCheckPackage (Data, ReturnObjectPtr); if (ACPI_FAILURE (Status)) { goto Exit; } } /* * The return object was OK, or it was successfully repaired above. * Now make some additional checks such as verifying that package * objects are sorted correctly (if required) or buffer objects have * the correct data width (bytes vs. dwords). These repairs are * performed on a per-name basis, i.e., the code is specific to * particular predefined names. */ Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr); Exit: /* * If the object validation failed or if we successfully repaired one * or more objects, mark the parent node to suppress further warning * messages during the next evaluation of the same method/object. */ if (ACPI_FAILURE (Status) || (Data->Flags & ACPI_OBJECT_REPAIRED)) { Node->Flags |= ANOBJ_EVALUATED; } ACPI_FREE (Data); Cleanup: ACPI_FREE (Pathname); return (Status); }
ACPI_STATUS AcpiNsEvaluate ( ACPI_EVALUATE_INFO *Info) { ACPI_STATUS Status; ACPI_FUNCTION_TRACE (NsEvaluate); if (!Info) { return_ACPI_STATUS (AE_BAD_PARAMETER); } if (!Info->Node) { /* * Get the actual namespace node for the target object if we * need to. Handles these cases: * * 1) Null node, valid pathname from root (absolute path) * 2) Node and valid pathname (path relative to Node) * 3) Node, Null pathname */ Status = AcpiNsGetNode (Info->PrefixNode, Info->RelativePathname, ACPI_NS_NO_UPSEARCH, &Info->Node); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } /* * For a method alias, we must grab the actual method node so that * proper scoping context will be established before execution. */ if (AcpiNsGetType (Info->Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) { Info->Node = ACPI_CAST_PTR ( ACPI_NAMESPACE_NODE, Info->Node->Object); } /* Complete the info block initialization */ Info->ReturnObject = NULL; Info->NodeFlags = Info->Node->Flags; Info->ObjDesc = AcpiNsGetAttachedObject (Info->Node); ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", Info->RelativePathname, Info->Node, AcpiNsGetAttachedObject (Info->Node))); /* Get info if we have a predefined name (_HID, etc.) */ Info->Predefined = AcpiUtMatchPredefinedMethod (Info->Node->Name.Ascii); /* Get the full pathname to the object, for use in warning messages */ Info->FullPathname = AcpiNsGetExternalPathname (Info->Node); if (!Info->FullPathname) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Count the number of arguments being passed in */ Info->ParamCount = 0; if (Info->Parameters) { while (Info->Parameters[Info->ParamCount]) { Info->ParamCount++; } /* Warn on impossible argument count */ if (Info->ParamCount > ACPI_METHOD_NUM_ARGS) { ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS, "Excess arguments (%u) - using only %u", Info->ParamCount, ACPI_METHOD_NUM_ARGS)); Info->ParamCount = ACPI_METHOD_NUM_ARGS; } } /* * For predefined names: Check that the declared argument count * matches the ACPI spec -- otherwise this is a BIOS error. */ AcpiNsCheckAcpiCompliance (Info->FullPathname, Info->Node, Info->Predefined); /* * For all names: Check that the incoming argument count for * this method/object matches the actual ASL/AML definition. */ AcpiNsCheckArgumentCount (Info->FullPathname, Info->Node, Info->ParamCount, Info->Predefined); /* For predefined names: Typecheck all incoming arguments */ AcpiNsCheckArgumentTypes (Info); /* * Three major evaluation cases: * * 1) Object types that cannot be evaluated by definition * 2) The object is a control method -- execute it * 3) The object is not a method -- just return it's current value */ switch (AcpiNsGetType (Info->Node)) { case ACPI_TYPE_DEVICE: case ACPI_TYPE_EVENT: case ACPI_TYPE_MUTEX: case ACPI_TYPE_REGION: case ACPI_TYPE_THERMAL: case ACPI_TYPE_LOCAL_SCOPE: /* * 1) Disallow evaluation of certain object types. For these, * object evaluation is undefined and not supported. */ ACPI_ERROR ((AE_INFO, "%s: Evaluation of object type [%s] is not supported", Info->FullPathname, AcpiUtGetTypeName (Info->Node->Type))); Status = AE_TYPE; goto Cleanup; case ACPI_TYPE_METHOD: /* * 2) Object is a control method - execute it */ /* Verify that there is a method object associated with this node */ if (!Info->ObjDesc) { ACPI_ERROR ((AE_INFO, "%s: Method has no attached sub-object", Info->FullPathname)); Status = AE_NULL_OBJECT; goto Cleanup; } ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "**** Execute method [%s] at AML address %p length %X\n", Info->FullPathname, Info->ObjDesc->Method.AmlStart + 1, Info->ObjDesc->Method.AmlLength - 1)); /* * Any namespace deletion must acquire both the namespace and * interpreter locks to ensure that no thread is using the portion of * the namespace that is being deleted. * * Execute the method via the interpreter. The interpreter is locked * here before calling into the AML parser */ AcpiExEnterInterpreter (); Status = AcpiPsExecuteMethod (Info); AcpiExExitInterpreter (); break; default: /* * 3) All other non-method objects -- get the current object value */ /* * Some objects require additional resolution steps (e.g., the Node * may be a field that must be read, etc.) -- we can't just grab * the object out of the node. * * Use ResolveNodeToValue() to get the associated value. * * NOTE: we can get away with passing in NULL for a walk state because * the Node is guaranteed to not be a reference to either a method * local or a method argument (because this interface is never called * from a running method.) * * Even though we do not directly invoke the interpreter for object * resolution, we must lock it because we could access an OpRegion. * The OpRegion access code assumes that the interpreter is locked. */ AcpiExEnterInterpreter (); /* TBD: ResolveNodeToValue has a strange interface, fix */ Info->ReturnObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Info->Node); Status = AcpiExResolveNodeToValue (ACPI_CAST_INDIRECT_PTR ( ACPI_NAMESPACE_NODE, &Info->ReturnObject), NULL); AcpiExExitInterpreter (); if (ACPI_FAILURE (Status)) { goto Cleanup; } ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returned object %p [%s]\n", Info->ReturnObject, AcpiUtGetObjectTypeName (Info->ReturnObject))); Status = AE_CTRL_RETURN_VALUE; /* Always has a "return value" */ break; } /* * For predefined names, check the return value against the ACPI * specification. Some incorrect return value types are repaired. */ (void) AcpiNsCheckReturnValue (Info->Node, Info, Info->ParamCount, Status, &Info->ReturnObject); /* Check if there is a return value that must be dealt with */ if (Status == AE_CTRL_RETURN_VALUE) { /* If caller does not want the return value, delete it */ if (Info->Flags & ACPI_IGNORE_RETURN_VALUE) { AcpiUtRemoveReference (Info->ReturnObject); Info->ReturnObject = NULL; } /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ Status = AE_OK; } ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed evaluation of object %s ***\n", Info->RelativePathname)); Cleanup: /* * Namespace was unlocked by the handling AcpiNs* function, so we * just free the pathname and return */ ACPI_FREE (Info->FullPathname); Info->FullPathname = NULL; return_ACPI_STATUS (Status); }
static char * AcpiDmNormalizeParentPrefix ( ACPI_PARSE_OBJECT *Op, char *Path) { ACPI_NAMESPACE_NODE *Node; char *Fullpath; char *ParentPath; ACPI_SIZE Length; /* Search upwards in the parse tree until we reach a namespace node */ while (Op) { if (Op->Common.Node) { break; } Op = Op->Common.Parent; } if (!Op) { return (NULL); } /* * Find the actual parent node for the reference: * Remove all carat prefixes from the input path. * There may be multiple parent prefixes (For example, ^^^M000) */ Node = Op->Common.Node; while (Node && (*Path == (UINT8) AML_PARENT_PREFIX)) { Node = AcpiNsGetParentNode (Node); Path++; } if (!Node) { return (NULL); } /* Get the full pathname for the parent node */ ParentPath = AcpiNsGetExternalPathname (Node); if (!ParentPath) { return (NULL); } Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1); Fullpath = ACPI_ALLOCATE_ZEROED (Length); if (!Fullpath) { goto Cleanup; } /* * Concatenate parent fullpath and path. For example, * parent fullpath "\_SB_", Path "^INIT", Fullpath "\_SB_.INIT" * * Copy the parent path */ ACPI_STRCAT (Fullpath, ParentPath); /* Add dot separator (don't need dot if parent fullpath is a single "\") */ if (ParentPath[1]) { ACPI_STRCAT (Fullpath, "."); } /* Copy child path (carat parent prefix(es) were skipped above) */ ACPI_STRCAT (Fullpath, Path); Cleanup: ACPI_FREE (ParentPath); return (Fullpath); }
static ACPI_STATUS AcpiNsInitOneDevice ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_DEVICE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context); ACPI_EVALUATE_INFO *Info = WalkInfo->EvaluateInfo; UINT32 Flags; ACPI_STATUS Status; ACPI_NAMESPACE_NODE *DeviceNode; ACPI_FUNCTION_TRACE (NsInitOneDevice); /* We are interested in Devices, Processors and ThermalZones only */ DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); if ((DeviceNode->Type != ACPI_TYPE_DEVICE) && (DeviceNode->Type != ACPI_TYPE_PROCESSOR) && (DeviceNode->Type != ACPI_TYPE_THERMAL)) { return_ACPI_STATUS (AE_OK); } /* * Because of an earlier namespace analysis, all subtrees that contain an * _INI method are tagged. * * If this device subtree does not contain any _INI methods, we * can exit now and stop traversing this entire subtree. */ if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI)) { return_ACPI_STATUS (AE_CTRL_DEPTH); } /* * Run _STA to determine if this device is present and functioning. We * must know this information for two important reasons (from ACPI spec): * * 1) We can only run _INI if the device is present. * 2) We must abort the device tree walk on this subtree if the device is * not present and is not functional (we will not examine the children) * * The _STA method is not required to be present under the device, we * assume the device is present if _STA does not exist. */ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA)); Status = AcpiUtExecute_STA (DeviceNode, &Flags); if (ACPI_FAILURE (Status)) { /* Ignore error and move on to next device */ return_ACPI_STATUS (AE_OK); } /* * Flags == -1 means that _STA was not found. In this case, we assume that * the device is both present and functional. * * From the ACPI spec, description of _STA: * * "If a device object (including the processor object) does not have an * _STA object, then OSPM assumes that all of the above bits are set (in * other words, the device is present, ..., and functioning)" */ if (Flags != ACPI_UINT32_MAX) { WalkInfo->Num_STA++; } /* * Examine the PRESENT and FUNCTIONING status bits * * Note: ACPI spec does not seem to specify behavior for the present but * not functioning case, so we assume functioning if present. */ if (!(Flags & ACPI_STA_DEVICE_PRESENT)) { /* Device is not present, we must examine the Functioning bit */ if (Flags & ACPI_STA_DEVICE_FUNCTIONING) { /* * Device is not present but is "functioning". In this case, * we will not run _INI, but we continue to examine the children * of this device. * * From the ACPI spec, description of _STA: (Note - no mention * of whether to run _INI or not on the device in question) * * "_STA may return bit 0 clear (not present) with bit 3 set * (device is functional). This case is used to indicate a valid * device for which no device driver should be loaded (for example, * a bridge device.) Children of this device may be present and * valid. OSPM should continue enumeration below a device whose * _STA returns this bit combination" */ return_ACPI_STATUS (AE_OK); } else { /* * Device is not present and is not functioning. We must abort the * walk of this subtree immediately -- don't look at the children * of such a device. * * From the ACPI spec, description of _INI: * * "If the _STA method indicates that the device is not present, * OSPM will not run the _INI and will not examine the children * of the device for _INI methods" */ return_ACPI_STATUS (AE_CTRL_DEPTH); } } /* * The device is present or is assumed present if no _STA exists. * Run the _INI if it exists (not required to exist) * * Note: We know there is an _INI within this subtree, but it may not be * under this particular device, it may be lower in the branch. */ ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname ( ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI)); ACPI_MEMSET (Info, 0, sizeof (ACPI_EVALUATE_INFO)); Info->PrefixNode = DeviceNode; Info->RelativePathname = METHOD_NAME__INI; Info->Parameters = NULL; Info->Flags = ACPI_IGNORE_RETURN_VALUE; Status = AcpiNsEvaluate (Info); if (ACPI_SUCCESS (Status)) { WalkInfo->Num_INI++; } #ifdef ACPI_DEBUG_OUTPUT else if (Status != AE_NOT_FOUND) { /* Ignore error and move on to next device */ char *ScopeName = AcpiNsGetExternalPathname (Info->Node); ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution", ScopeName)); ACPI_FREE (ScopeName); } #endif /* Ignore errors from above */ Status = AE_OK; /* * The _INI method has been run if present; call the Global Initialization * Handler for this device. */ if (AcpiGbl_InitHandler) { Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI); } return_ACPI_STATUS (Status); }
static ACPI_STATUS AcpiDbWalkForExecute ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; ACPI_DB_EXECUTE_WALK *Info = (ACPI_DB_EXECUTE_WALK *) Context; char *Pathname; const ACPI_PREDEFINED_INFO *Predefined; ACPI_DEVICE_INFO *ObjInfo; ACPI_OBJECT_LIST ParamObjects; ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; ACPI_OBJECT *ThisParam; ACPI_BUFFER ReturnObj; ACPI_STATUS Status; UINT16 ArgTypeList; UINT8 ArgCount; UINT8 ArgType; UINT32 i; /* The name must be a predefined ACPI name */ Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii); if (!Predefined) { return (AE_OK); } if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) { return (AE_OK); } Pathname = AcpiNsGetExternalPathname (Node); if (!Pathname) { return (AE_OK); } /* Get the object info for number of method parameters */ Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo); if (ACPI_FAILURE (Status)) { return (Status); } ParamObjects.Count = 0; ParamObjects.Pointer = NULL; if (ObjInfo->Type == ACPI_TYPE_METHOD) { /* Setup default parameters (with proper types) */ ArgTypeList = Predefined->Info.ArgumentList; ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList); /* * Setup the ACPI-required number of arguments, regardless of what * the actual method defines. If there is a difference, then the * method is wrong and a warning will be issued during execution. */ ThisParam = Params; for (i = 0; i < ArgCount; i++) { ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList); ThisParam->Type = ArgType; switch (ArgType) { case ACPI_TYPE_INTEGER: ThisParam->Integer.Value = 1; break; case ACPI_TYPE_STRING: ThisParam->String.Pointer = __UNCONST( "This is the default argument string"); ThisParam->String.Length = ACPI_STRLEN (ThisParam->String.Pointer); break; case ACPI_TYPE_BUFFER: ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */ ThisParam->Buffer.Length = 48; break; case ACPI_TYPE_PACKAGE: ThisParam->Package.Elements = NULL; ThisParam->Package.Count = 0; break; default: AcpiOsPrintf ("%s: Unsupported argument type: %u\n", Pathname, ArgType); break; } ThisParam++; } ParamObjects.Count = ArgCount; ParamObjects.Pointer = Params; } ACPI_FREE (ObjInfo); ReturnObj.Pointer = NULL; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; /* Do the actual method execution */ AcpiGbl_MethodExecuting = TRUE; Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj); AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status)); AcpiGbl_MethodExecuting = FALSE; ACPI_FREE (Pathname); /* Ignore status from method execution */ Status = AE_OK; /* Update count, check if we have executed enough methods */ Info->Count++; if (Info->Count >= Info->MaxCount) { Status = AE_CTRL_TERMINATE; } return (Status); }
void AcpiDmAddNodeToExternalList ( ACPI_NAMESPACE_NODE *Node, UINT8 Type, UINT32 Value, UINT16 Flags) { char *ExternalPath; char *InternalPath; char *Temp; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (DmAddNodeToExternalList); if (!Node) { return_VOID; } /* Get the full external and internal pathnames to the node */ ExternalPath = AcpiNsGetExternalPathname (Node); if (!ExternalPath) { return_VOID; } Status = AcpiNsInternalizeName (ExternalPath, &InternalPath); if (ACPI_FAILURE (Status)) { ACPI_FREE (ExternalPath); return_VOID; } /* Remove the root backslash */ if ((*ExternalPath == AML_ROOT_PREFIX) && (ExternalPath[1])) { Temp = ACPI_ALLOCATE_ZEROED (strlen (ExternalPath) + 1); if (!Temp) { return_VOID; } strcpy (Temp, &ExternalPath[1]); ACPI_FREE (ExternalPath); ExternalPath = Temp; } /* Create the new External() declaration node */ Status = AcpiDmCreateNewExternal (ExternalPath, InternalPath, Type, Value, (Flags | ACPI_EXT_INTERNAL_PATH_ALLOCATED)); if (ACPI_FAILURE (Status)) { ACPI_FREE (ExternalPath); ACPI_FREE (InternalPath); } return_VOID; }