void AcpiUtInitStaticObject ( ACPI_OPERAND_OBJECT *ObjDesc) { FUNCTION_TRACE_PTR ("UtInitStaticObject", ObjDesc); if (!ObjDesc) { return_VOID; } /* * Clear the entire descriptor */ MEMSET ((void *) ObjDesc, 0, sizeof (ACPI_OPERAND_OBJECT)); /* * Initialize the header fields * 1) This is an ACPI_OPERAND_OBJECT descriptor * 2) The size is the full object (worst case) * 3) The flags field indicates static allocation * 4) Reference count starts at one (not really necessary since the * object can't be deleted, but keeps everything sane) */ ObjDesc->Common.DataType = ACPI_DESC_TYPE_INTERNAL; ObjDesc->Common.Flags = AOPOBJ_STATIC_ALLOCATION; ObjDesc->Common.ReferenceCount = 1; return_VOID; }
ACPI_GENERIC_STATE * AcpiUtCreateUpdateState ( ACPI_OPERAND_OBJECT *Object, UINT16 Action) { ACPI_GENERIC_STATE *State; FUNCTION_TRACE_PTR ("UtCreateUpdateState", Object); /* Create the generic state object */ State = AcpiUtCreateGenericState (); if (!State) { return (NULL); } /* Init fields specific to the update struct */ State->Update.Object = Object; State->Update.Value = Action; return_PTR (State); }
acpi_generic_state * acpi_ut_create_pkg_state ( void *internal_object, void *external_object, u16 index) { acpi_generic_state *state; FUNCTION_TRACE_PTR ("Ut_create_pkg_state", internal_object); /* Create the generic state object */ state = acpi_ut_create_generic_state (); if (!state) { return (NULL); } /* Init fields specific to the update struct */ state->common.data_type = ACPI_DESC_TYPE_STATE_PACKAGE; state->pkg.source_object = (acpi_operand_object *) internal_object; state->pkg.dest_object = external_object; state->pkg.index = index; state->pkg.num_packages = 1; return_PTR (state); }
void AcpiUtFree ( void *Address, UINT32 Component, NATIVE_CHAR *Module, UINT32 Line) { ACPI_DEBUG_MEM_BLOCK *DebugBlock; FUNCTION_TRACE_PTR ("UtFree", Address); if (NULL == Address) { _REPORT_ERROR (Module, Line, Component, ("AcpiUtFree: Trying to delete a NULL address\n")); return_VOID; } DebugBlock = (ACPI_DEBUG_MEM_BLOCK *) (((char *) Address) - sizeof (ACPI_DEBUG_MEM_HEADER)); AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].TotalFreed++; AcpiGbl_MemoryLists[ACPI_MEM_LIST_GLOBAL].CurrentTotalSize -= DebugBlock->Size; AcpiUtDeleteElementFromAllocList (ACPI_MEM_LIST_GLOBAL, DebugBlock, Component, Module, Line); AcpiOsFree (DebugBlock); ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", Address)); return_VOID; }
acpi_generic_state * acpi_ut_create_update_state ( acpi_operand_object *object, u16 action) { acpi_generic_state *state; FUNCTION_TRACE_PTR ("Ut_create_update_state", object); /* Create the generic state object */ state = acpi_ut_create_generic_state (); if (!state) { return (NULL); } /* Init fields specific to the update struct */ state->common.data_type = ACPI_DESC_TYPE_STATE_UPDATE; state->update.object = object; state->update.value = action; return_PTR (state); }
acpi_status acpi_ut_get_package_object_size ( acpi_operand_object *internal_object, u32 *obj_length) { acpi_status status; acpi_pkg_info info; FUNCTION_TRACE_PTR ("Ut_get_package_object_size", internal_object); info.length = 0; info.object_space = 0; info.num_packages = 1; status = acpi_ut_walk_package_tree (internal_object, NULL, acpi_ut_get_element_length, &info); /* * We have handled all of the objects in all levels of the package. * just add the length of the package objects themselves. * Round up to the next machine word. */ info.length += ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object)) * info.num_packages; /* Return the total package length */ *obj_length = info.length; return_ACPI_STATUS (status); }
ACPI_GENERIC_STATE * AcpiUtCreatePkgState ( void *InternalObject, void *ExternalObject, UINT16 Index) { ACPI_GENERIC_STATE *State; FUNCTION_TRACE_PTR ("UtCreatePkgState", InternalObject); /* Create the generic state object */ State = AcpiUtCreateGenericState (); if (!State) { return (NULL); } /* Init fields specific to the update struct */ State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject; State->Pkg.DestObject = ExternalObject; State->Pkg.Index = Index; State->Pkg.NumPackages = 1; return_PTR (State); }
ACPI_STATUS AcpiUtGetPackageObjectSize ( ACPI_OPERAND_OBJECT *InternalObject, UINT32 *ObjLength) { ACPI_STATUS Status; ACPI_PKG_INFO Info; FUNCTION_TRACE_PTR ("UtGetPackageObjectSize", InternalObject); Info.Length = 0; Info.ObjectSpace = 0; Info.NumPackages = 1; Status = AcpiUtWalkPackageTree (InternalObject, NULL, AcpiUtGetElementLength, &Info); /* * We have handled all of the objects in all levels of the package. * just add the length of the package objects themselves. * Round up to the next machine word. */ Info.Length += ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) * Info.NumPackages; /* Return the total package length */ *ObjLength = Info.Length; return_ACPI_STATUS (Status); }
void acpi_tb_free_acpi_tables_of_type ( acpi_table_desc *list_head) { acpi_table_desc *table_desc; u32 count; u32 i; FUNCTION_TRACE_PTR ("Tb_free_acpi_tables_of_type", list_head); /* Get the head of the list */ table_desc = list_head; count = list_head->count; /* * Walk the entire list, deleting both the allocated tables * and the table descriptors */ for (i = 0; i < count; i++) { table_desc = acpi_tb_uninstall_table (table_desc); } return_VOID; }
acpi_status acpi_ns_get_node ( NATIVE_CHAR *pathname, acpi_namespace_node *start_node, acpi_namespace_node **return_node) { acpi_generic_state scope_info; acpi_status status; NATIVE_CHAR *internal_path = NULL; FUNCTION_TRACE_PTR ("Ns_get_node", pathname); /* Ensure that the namespace has been initialized */ if (!acpi_gbl_root_node) { return_ACPI_STATUS (AE_NO_NAMESPACE); } if (!pathname) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Convert path to internal representation */ status = acpi_ns_internalize_name (pathname, &internal_path); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); /* Setup lookup scope (search starting point) */ scope_info.scope.node = start_node; /* Lookup the name in the namespace */ status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, NULL, return_node); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %s\n", internal_path, acpi_format_exception (status))); } acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); /* Cleanup */ ACPI_MEM_FREE (internal_path); return_ACPI_STATUS (status); }
acpi_status acpi_ex_get_object_reference ( acpi_operand_object *obj_desc, acpi_operand_object **return_desc, acpi_walk_state *walk_state) { acpi_status status = AE_OK; FUNCTION_TRACE_PTR ("Ex_get_object_reference", obj_desc); if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) { if (obj_desc->common.type != INTERNAL_TYPE_REFERENCE) { *return_desc = NULL; status = AE_TYPE; goto cleanup; } /* * Not a Name -- an indirect name pointer would have * been converted to a direct name pointer in Acpi_ex_resolve_operands */ switch (obj_desc->reference.opcode) { case AML_LOCAL_OP: case AML_ARG_OP: *return_desc = (void *) acpi_ds_method_data_get_node (obj_desc->reference.opcode, obj_desc->reference.offset, walk_state); break; default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(Internal) Unknown Ref subtype %02x\n", obj_desc->reference.opcode)); *return_desc = NULL; status = AE_AML_INTERNAL; goto cleanup; } } else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { /* Must be a named object; Just return the Node */ *return_desc = obj_desc; } else { *return_desc = NULL; status = AE_TYPE; } cleanup: ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p Ref=%p\n", obj_desc, *return_desc)); return_ACPI_STATUS (status); }
acpi_table_desc * acpi_tb_uninstall_table ( acpi_table_desc *table_desc) { acpi_table_desc *next_desc; FUNCTION_TRACE_PTR ("Tb_delete_single_table", table_desc); if (!table_desc) { return_PTR (NULL); } /* Unlink the descriptor */ if (table_desc->prev) { table_desc->prev->next = table_desc->next; } if (table_desc->next) { table_desc->next->prev = table_desc->prev; } /* Free the memory allocated for the table itself */ acpi_tb_delete_single_table (table_desc); /* Free the table descriptor (Don't delete the list head, tho) */ if ((table_desc->prev) == (table_desc->next)) { next_desc = NULL; /* Clear the list head */ table_desc->pointer = NULL; table_desc->length = 0; table_desc->count = 0; } else { /* Free the table descriptor */ next_desc = table_desc->next; ACPI_MEM_FREE (table_desc); } return_PTR (next_desc); }
acpi_status acpi_ex_acquire_mutex ( acpi_operand_object *time_desc, acpi_operand_object *obj_desc, acpi_walk_state *walk_state) { acpi_status status; FUNCTION_TRACE_PTR ("Ex_acquire_mutex", obj_desc); if (!obj_desc) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* * Current Sync must be less than or equal to the sync level of the * mutex. This mechanism provides some deadlock prevention */ if (walk_state->current_sync_level > obj_desc->mutex.sync_level) { return_ACPI_STATUS (AE_AML_MUTEX_ORDER); } /* * If the mutex is already owned by this thread, * just increment the acquisition depth */ if (obj_desc->mutex.owner == walk_state) { obj_desc->mutex.acquisition_depth++; return_ACPI_STATUS (AE_OK); } /* Acquire the mutex, wait if necessary */ status = acpi_ex_system_acquire_mutex (time_desc, obj_desc); if (ACPI_FAILURE (status)) { /* Includes failure from a timeout on Time_desc */ return_ACPI_STATUS (status); } /* Have the mutex, update mutex and walk info */ obj_desc->mutex.owner = walk_state; obj_desc->mutex.acquisition_depth = 1; walk_state->current_sync_level = obj_desc->mutex.sync_level; /* Link the mutex to the walk state for force-unlock at method exit */ acpi_ex_link_mutex (obj_desc, (acpi_operand_object *) &(walk_state->walk_list->acquired_mutex_list)); return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiDsMethodDataInitArgs ( ACPI_OPERAND_OBJECT **Params, UINT32 MaxParamCount, ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status; UINT32 Mindex; UINT32 Pindex; FUNCTION_TRACE_PTR ("DsMethodDataInitArgs", Params); if (!Params) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n")); return_ACPI_STATUS (AE_OK); } /* Copy passed parameters into the new method stack frame */ for (Pindex = Mindex = 0; (Mindex < MTH_NUM_ARGS) && (Pindex < MaxParamCount); Mindex++) { if (Params[Pindex]) { /* * A valid parameter. * Set the current method argument to the * Params[Pindex++] argument object descriptor */ Status = AcpiDsStoreObjectToLocal (AML_ARG_OP, Mindex, Params[Pindex], WalkState); if (ACPI_FAILURE (Status)) { break; } Pindex++; } else { break; } } ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", Pindex)); return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiExResolveToValue ( ACPI_OPERAND_OBJECT **StackPtr, ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status; FUNCTION_TRACE_PTR ("ExResolveToValue", StackPtr); if (!StackPtr || !*StackPtr) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n")); return_ACPI_STATUS (AE_AML_NO_OPERAND); } /* * The entity pointed to by the StackPtr can be either * 1) A valid ACPI_OPERAND_OBJECT, or * 2) A ACPI_NAMESPACE_NODE (NamedObj) */ if (VALID_DESCRIPTOR_TYPE (*StackPtr, ACPI_DESC_TYPE_INTERNAL)) { Status = AcpiExResolveObjectToValue (StackPtr, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } /* * Object on the stack may have changed if AcpiExResolveObjectToValue() * was called (i.e., we can't use an _else_ here.) */ if (VALID_DESCRIPTOR_TYPE (*StackPtr, ACPI_DESC_TYPE_NAMED)) { Status = AcpiExResolveNodeToValue ((ACPI_NAMESPACE_NODE **) StackPtr, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Resolved object %p\n", *StackPtr)); return_ACPI_STATUS (AE_OK); }
acpi_status acpi_ds_method_data_init_args ( acpi_operand_object **params, u32 max_param_count, acpi_walk_state *walk_state) { acpi_status status; u32 mindex; u32 pindex; FUNCTION_TRACE_PTR ("Ds_method_data_init_args", params); if (!params) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n")); return_ACPI_STATUS (AE_OK); } /* Copy passed parameters into the new method stack frame */ for (pindex = mindex = 0; (mindex < MTH_NUM_ARGS) && (pindex < max_param_count); mindex++) { if (params[pindex]) { /* * A valid parameter. * Set the current method argument to the * Params[Pindex++] argument object descriptor */ status = acpi_ds_store_object_to_local (AML_ARG_OP, mindex, params[pindex], walk_state); if (ACPI_FAILURE (status)) { break; } pindex++; } else { break; } } ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", pindex)); return_ACPI_STATUS (AE_OK); }
void acpi_ut_delete_object_desc ( acpi_operand_object *object) { FUNCTION_TRACE_PTR ("Ut_delete_object_desc", object); /* Object must be an acpi_operand_object */ if (object->common.data_type != ACPI_DESC_TYPE_INTERNAL) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Obj %p is not an ACPI object\n", object)); return_VOID; } acpi_ut_release_to_cache (ACPI_MEM_LIST_OPERAND, object); return_VOID; }
void AcpiUtDeleteObjectDesc ( ACPI_OPERAND_OBJECT *Object) { FUNCTION_TRACE_PTR ("UtDeleteObjectDesc", Object); /* Object must be an ACPI_OPERAND_OBJECT */ if (Object->Common.DataType != ACPI_DESC_TYPE_INTERNAL) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Obj %p is not an ACPI object\n", Object)); return_VOID; } AcpiUtReleaseToCache (ACPI_MEM_LIST_OPERAND, Object); return_VOID; }
ACPI_PARSE_OBJECT * AcpiPsGetNextArg ( ACPI_PARSE_STATE *ParserState, UINT32 ArgType, UINT32 *ArgCount) { ACPI_PARSE_OBJECT *Arg = NULL; ACPI_PARSE_OBJECT *Prev = NULL; ACPI_PARSE_OBJECT *Field; UINT32 Subop; FUNCTION_TRACE_PTR ("PsGetNextArg", ParserState); switch (ArgType) { case ARGP_BYTEDATA: case ARGP_WORDDATA: case ARGP_DWORDDATA: case ARGP_CHARLIST: case ARGP_NAME: case ARGP_NAMESTRING: /* constants, strings, and namestrings are all the same size */ Arg = AcpiPsAllocOp (AML_BYTE_OP); if (Arg) { AcpiPsGetNextSimpleArg (ParserState, ArgType, Arg); } break; case ARGP_PKGLENGTH: /* package length, nothing returned */ ParserState->PkgEnd = AcpiPsGetNextPackageEnd (ParserState); break; case ARGP_FIELDLIST: if (ParserState->Aml < ParserState->PkgEnd) { /* non-empty list */ while (ParserState->Aml < ParserState->PkgEnd) { Field = AcpiPsGetNextField (ParserState); if (!Field) { break; } if (Prev) { Prev->Next = Field; } else { Arg = Field; } Prev = Field; } /* skip to End of byte data */ ParserState->Aml = ParserState->PkgEnd; } break; case ARGP_BYTELIST: if (ParserState->Aml < ParserState->PkgEnd) { /* non-empty list */ Arg = AcpiPsAllocOp (AML_INT_BYTELIST_OP); if (Arg) { /* fill in bytelist data */ Arg->Value.Size = (ParserState->PkgEnd - ParserState->Aml); ((ACPI_PARSE2_OBJECT *) Arg)->Data = ParserState->Aml; } /* skip to End of byte data */ ParserState->Aml = ParserState->PkgEnd; } break; case ARGP_TARGET: case ARGP_SUPERNAME: { Subop = AcpiPsPeekOpcode (ParserState); if (Subop == 0 || AcpiPsIsLeadingChar (Subop) || AcpiPsIsPrefixChar (Subop)) { /* NullName or NameString */ Arg = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); if (Arg) { AcpiPsGetNextNamepath (ParserState, Arg, ArgCount, 0); } } else { /* single complex argument, nothing returned */ *ArgCount = 1; } } break; case ARGP_DATAOBJ: case ARGP_TERMARG: /* single complex argument, nothing returned */ *ArgCount = 1; break; case ARGP_DATAOBJLIST: case ARGP_TERMLIST: case ARGP_OBJLIST: if (ParserState->Aml < ParserState->PkgEnd) { /* non-empty list of variable arguments, nothing returned */ *ArgCount = ACPI_VAR_ARGS; } break; } return_PTR (Arg); }
static ACPI_STATUS AcpiPsNextParseState ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op, ACPI_STATUS CallbackStatus) { ACPI_PARSE_STATE *ParserState = WalkState->ParserState; ACPI_STATUS Status = AE_CTRL_PENDING; UINT8 *Start; UINT32 PackageLength; FUNCTION_TRACE_PTR ("PsNextParseState", Op); switch (CallbackStatus) { case AE_CTRL_TERMINATE: /* * A control method was terminated via a RETURN statement. * The walk of this method is complete. */ ParserState->Aml = ParserState->AmlEnd; Status = AE_CTRL_TERMINATE; break; case AE_CTRL_PENDING: /* * Predicate of a WHILE was true and the loop just completed an * execution. Go back to the start of the loop and reevaluate the * predicate. */ /* TBD: How to handle a break within a while. */ /* This code attempts it */ ParserState->Aml = WalkState->AmlLastWhile; break; case AE_CTRL_TRUE: /* * Predicate of an IF was true, and we are at the matching ELSE. * Just close out this package * * Note: ParserState->Aml is modified by the package length procedure * TBD: [Investigate] perhaps it shouldn't, too much trouble */ Start = ParserState->Aml; PackageLength = AcpiPsGetNextPackageLength (ParserState); ParserState->Aml = Start + PackageLength; break; case AE_CTRL_FALSE: /* * Either an IF/WHILE Predicate was false or we encountered a BREAK * opcode. In both cases, we do not execute the rest of the * package; We simply close out the parent (finishing the walk of * this branch of the tree) and continue execution at the parent * level. */ ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd; /* In the case of a BREAK, just force a predicate (if any) to FALSE */ WalkState->ControlState->Common.Value = FALSE; Status = AE_CTRL_END; break; case AE_CTRL_TRANSFER: /* * A method call (invocation) -- transfer control */ Status = AE_CTRL_TRANSFER; WalkState->PrevOp = Op; WalkState->MethodCallOp = Op; WalkState->MethodCallNode = (Op->Value.Arg)->Node; /* Will return value (if any) be used by the caller? */ WalkState->ReturnUsed = AcpiDsIsResultUsed (Op, WalkState); break; default: Status = CallbackStatus; if ((CallbackStatus & AE_CODE_MASK) == AE_CODE_CONTROL) { Status = AE_OK; } break; } return_ACPI_STATUS (Status); }
NATIVE_CHAR * acpi_ns_get_table_pathname ( acpi_namespace_node *node) { NATIVE_CHAR *name_buffer; u32 size; acpi_name name; acpi_namespace_node *child_node; acpi_namespace_node *parent_node; FUNCTION_TRACE_PTR ("Ns_get_table_pathname", node); if (!acpi_gbl_root_node || !node) { /* * If the name space has not been initialized, * this function should not have been called. */ return_PTR (NULL); } child_node = node->child; /* Calculate required buffer size based on depth below root */ size = 1; parent_node = child_node; while (parent_node) { parent_node = acpi_ns_get_parent_object (parent_node); if (parent_node) { size += ACPI_NAME_SIZE; } } /* Allocate a buffer to be returned to caller */ name_buffer = ACPI_MEM_CALLOCATE (size + 1); if (!name_buffer) { REPORT_ERROR (("Ns_get_table_pathname: allocation failure\n")); return_PTR (NULL); } /* Store terminator byte, then build name backwards */ name_buffer[size] = '\0'; while ((size > ACPI_NAME_SIZE) && acpi_ns_get_parent_object (child_node)) { size -= ACPI_NAME_SIZE; name = acpi_ns_find_parent_name (child_node); /* Put the name into the buffer */ MOVE_UNALIGNED32_TO_32 ((name_buffer + size), &name); child_node = acpi_ns_get_parent_object (child_node); } name_buffer[--size] = AML_ROOT_PREFIX; if (size != 0) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad pointer returned; size=%X\n", size)); } return_PTR (name_buffer); }
acpi_status acpi_ns_handle_to_pathname ( acpi_handle target_handle, u32 *buf_size, NATIVE_CHAR *user_buffer) { acpi_status status = AE_OK; acpi_namespace_node *node; u32 path_length; u32 user_buf_size; acpi_name name; u32 size; FUNCTION_TRACE_PTR ("Ns_handle_to_pathname", target_handle); if (!acpi_gbl_root_node) { /* * If the name space has not been initialized, * this function should not have been called. */ return_ACPI_STATUS (AE_NO_NAMESPACE); } node = acpi_ns_map_handle_to_node (target_handle); if (!node) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Set return length to the required path length */ path_length = acpi_ns_get_pathname_length (node); size = path_length - 1; user_buf_size = *buf_size; *buf_size = path_length; /* Check if the user buffer is sufficiently large */ if (path_length > user_buf_size) { status = AE_BUFFER_OVERFLOW; goto exit; } /* Store null terminator */ user_buffer[size] = 0; size -= ACPI_NAME_SIZE; /* Put the original ACPI name at the end of the path */ MOVE_UNALIGNED32_TO_32 ((user_buffer + size), &node->name); user_buffer[--size] = PATH_SEPARATOR; /* Build name backwards, putting "." between segments */ while ((size > ACPI_NAME_SIZE) && node) { size -= ACPI_NAME_SIZE; name = acpi_ns_find_parent_name (node); MOVE_UNALIGNED32_TO_32 ((user_buffer + size), &name); user_buffer[--size] = PATH_SEPARATOR; node = acpi_ns_get_parent_object (node); } /* * Overlay the "." preceding the first segment with * the root name "\" */ user_buffer[size] = '\\'; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Len=%X, %s \n", path_length, user_buffer)); exit: return_ACPI_STATUS (status); }
ACPI_STATUS AcpiPsParseLoop ( ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status = AE_OK; ACPI_PARSE_OBJECT *Op = NULL; /* current op */ const ACPI_OPCODE_INFO *OpInfo; ACPI_PARSE_OBJECT *Arg = NULL; ACPI_PARSE2_OBJECT *DeferredOp; UINT32 ArgCount; /* push for fixed or var args */ UINT32 ArgTypes = 0; UINT32 AmlOffset; UINT16 Opcode; ACPI_PARSE_OBJECT PreOp; ACPI_PARSE_STATE *ParserState; UINT8 *AmlOpStart; FUNCTION_TRACE_PTR ("PsParseLoop", WalkState); ParserState = WalkState->ParserState; #ifndef PARSER_ONLY if (WalkState->WalkType & WALK_METHOD_RESTART) { /* We are restarting a preempted control method */ if (AcpiPsHasCompletedScope (ParserState)) { /* * We must check if a predicate to an IF or WHILE statement * was just completed */ if ((ParserState->Scope->ParseScope.Op) && ((ParserState->Scope->ParseScope.Op->Opcode == AML_IF_OP) || (ParserState->Scope->ParseScope.Op->Opcode == AML_WHILE_OP)) && (WalkState->ControlState) && (WalkState->ControlState->Common.State == CONTROL_PREDICATE_EXECUTING)) { /* * A predicate was just completed, get the value of the * predicate and branch based on that value */ Status = AcpiDsGetPredicateValue (WalkState, NULL, TRUE); if (ACPI_FAILURE (Status) && ((Status & AE_CODE_MASK) != AE_CODE_CONTROL)) { if (Status == AE_AML_NO_RETURN_VALUE) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invoked method did not return a value, %s\n", AcpiFormatException (Status))); } ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "GetPredicate Failed, %s\n", AcpiFormatException (Status))); return_ACPI_STATUS (Status); } Status = AcpiPsNextParseState (WalkState, Op, Status); } AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op)); } else if (WalkState->PrevOp) { /* We were in the middle of an op */ Op = WalkState->PrevOp; ArgTypes = WalkState->PrevArgTypes; } } #endif /* * Iterative parsing loop, while there is more aml to process: */ while ((ParserState->Aml < ParserState->AmlEnd) || (Op)) { if (!Op) { /* Get the next opcode from the AML stream */ AmlOpStart = ParserState->Aml; AmlOffset = ParserState->Aml - ParserState->AmlStart; Opcode = AcpiPsPeekOpcode (ParserState); /* * First cut to determine what we have found: * 1) A valid AML opcode * 2) A name string * 3) An unknown/invalid opcode */ OpInfo = AcpiPsGetOpcodeInfo (Opcode); switch (ACPI_GET_OP_TYPE (OpInfo)) { case ACPI_OP_TYPE_OPCODE: /* Found opcode info, this is a normal opcode */ ParserState->Aml += AcpiPsGetOpcodeSize (Opcode); ArgTypes = OpInfo->ParseArgs; break; case ACPI_OP_TYPE_ASCII: case ACPI_OP_TYPE_PREFIX: /* * Starts with a valid prefix or ASCII char, this is a name * string. Convert the bare name string to a namepath. */ Opcode = AML_INT_NAMEPATH_OP; ArgTypes = ARGP_NAMESTRING; break; case ACPI_OP_TYPE_UNKNOWN: /* The opcode is unrecognized. Just skip unknown opcodes */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found unknown opcode %lX at AML offset %X, ignoring\n", Opcode, AmlOffset)); DUMP_BUFFER (ParserState->Aml, 128); /* Assume one-byte bad opcode */ ParserState->Aml++; continue; } /* Create Op structure and append to parent's argument list */ if (OpInfo->Flags & AML_NAMED) { PreOp.Value.Arg = NULL; PreOp.Opcode = Opcode; while (GET_CURRENT_ARG_TYPE (ArgTypes) != ARGP_NAME) { Arg = AcpiPsGetNextArg (ParserState, GET_CURRENT_ARG_TYPE (ArgTypes), &ArgCount); AcpiPsAppendArg (&PreOp, Arg); INCREMENT_ARG_LIST (ArgTypes); } /* We know that this arg is a name, move to next arg */ INCREMENT_ARG_LIST (ArgTypes); if (WalkState->DescendingCallback != NULL) { /* * Find the object. This will either insert the object into * the namespace or simply look it up */ Status = WalkState->DescendingCallback (Opcode, NULL, WalkState, &Op); if (Op == NULL) { continue; } Status = AcpiPsNextParseState (WalkState, Op, Status); if (Status == AE_CTRL_PENDING) { Status = AE_OK; goto CloseThisOp; } if (ACPI_FAILURE (Status)) { goto CloseThisOp; } } AcpiPsAppendArg (Op, PreOp.Value.Arg); AcpiGbl_Depth++; if (Op->Opcode == AML_REGION_OP) { DeferredOp = (ACPI_PARSE2_OBJECT *) Op; /* * Defer final parsing of an OperationRegion body, * because we don't have enough info in the first pass * to parse it correctly (i.e., there may be method * calls within the TermArg elements of the body. * * However, we must continue parsing because * the opregion is not a standalone package -- * we don't know where the end is at this point. * * (Length is unknown until parse of the body complete) */ DeferredOp->Data = AmlOpStart; DeferredOp->Length = 0; } } else { /* Not a named opcode, just allocate Op and append to parent */ OpInfo = AcpiPsGetOpcodeInfo (Opcode); Op = AcpiPsAllocOp (Opcode); if (!Op) { return_ACPI_STATUS (AE_NO_MEMORY); } if (OpInfo->Flags & AML_CREATE) { /* * Backup to beginning of CreateXXXfield declaration * BodyLength is unknown until we parse the body */ DeferredOp = (ACPI_PARSE2_OBJECT *) Op; DeferredOp->Data = AmlOpStart; DeferredOp->Length = 0; } AcpiPsAppendArg (AcpiPsGetParentScope (ParserState), Op); if ((WalkState->DescendingCallback != NULL)) { /* * Find the object. This will either insert the object into * the namespace or simply look it up */ Status = WalkState->DescendingCallback (Opcode, Op, WalkState, &Op); Status = AcpiPsNextParseState (WalkState, Op, Status); if (Status == AE_CTRL_PENDING) { Status = AE_OK; goto CloseThisOp; } if (ACPI_FAILURE (Status)) { goto CloseThisOp; } } } Op->AmlOffset = AmlOffset; if (OpInfo) { ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Op=%p Opcode=%4.4lX Aml %p Oft=%5.5lX\n", Op, Op->Opcode, ParserState->Aml, Op->AmlOffset)); } } /* Start ArgCount at zero because we don't know if there are any args yet */ ArgCount = 0; if (ArgTypes) /* Are there any arguments that must be processed? */ { /* get arguments */ switch (Op->Opcode) { case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ case AML_WORD_OP: /* AML_WORDDATA_ARG */ case AML_DWORD_OP: /* AML_DWORDATA_ARG */ case AML_QWORD_OP: /* AML_QWORDATA_ARG */ case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ /* fill in constant or string argument directly */ AcpiPsGetNextSimpleArg (ParserState, GET_CURRENT_ARG_TYPE (ArgTypes), Op); break; case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ AcpiPsGetNextNamepath (ParserState, Op, &ArgCount, 1); ArgTypes = 0; break; default: /* Op is not a constant or string, append each argument */ while (GET_CURRENT_ARG_TYPE (ArgTypes) && !ArgCount) { AmlOffset = ParserState->Aml - ParserState->AmlStart; Arg = AcpiPsGetNextArg (ParserState, GET_CURRENT_ARG_TYPE (ArgTypes), &ArgCount); if (Arg) { Arg->AmlOffset = AmlOffset; AcpiPsAppendArg (Op, Arg); } INCREMENT_ARG_LIST (ArgTypes); } /* For a method, save the length and address of the body */ if (Op->Opcode == AML_METHOD_OP) { DeferredOp = (ACPI_PARSE2_OBJECT *) Op; /* * Skip parsing of control method or opregion body, * because we don't have enough info in the first pass * to parse them correctly. */ DeferredOp->Data = ParserState->Aml; DeferredOp->Length = (UINT32) (ParserState->PkgEnd - ParserState->Aml); /* * Skip body of method. For OpRegions, we must continue * parsing because the opregion is not a standalone * package (We don't know where the end is). */ ParserState->Aml = ParserState->PkgEnd; ArgCount = 0; } break; } } /* * Zero ArgCount means that all arguments for this op have been processed */ if (!ArgCount) { /* completed Op, prepare for next */ OpInfo = AcpiPsGetOpcodeInfo (Op->Opcode); if (OpInfo->Flags & AML_NAMED) { if (AcpiGbl_Depth) { AcpiGbl_Depth--; } if (Op->Opcode == AML_REGION_OP) { DeferredOp = (ACPI_PARSE2_OBJECT *) Op; /* * Skip parsing of control method or opregion body, * because we don't have enough info in the first pass * to parse them correctly. * * Completed parsing an OpRegion declaration, we now * know the length. */ DeferredOp->Length = (UINT32) (ParserState->Aml - DeferredOp->Data); } } if (OpInfo->Flags & AML_CREATE) { /* * Backup to beginning of CreateXXXfield declaration (1 for * Opcode) * * BodyLength is unknown until we parse the body */ DeferredOp = (ACPI_PARSE2_OBJECT *) Op; DeferredOp->Length = (UINT32) (ParserState->Aml - DeferredOp->Data); } /* This op complete, notify the dispatcher */ if (WalkState->AscendingCallback != NULL) { Status = WalkState->AscendingCallback (WalkState, Op); Status = AcpiPsNextParseState (WalkState, Op, Status); if (Status == AE_CTRL_PENDING) { Status = AE_OK; goto CloseThisOp; } } CloseThisOp: /* * Finished one argument of the containing scope */ ParserState->Scope->ParseScope.ArgCount--; /* Close this Op (may result in parse subtree deletion) */ if (AcpiPsCompleteThisOp (WalkState, Op)) { Op = NULL; } switch (Status) { case AE_OK: break; case AE_CTRL_TRANSFER: /* * We are about to transfer to a called method. */ WalkState->PrevOp = Op; WalkState->PrevArgTypes = ArgTypes; return_ACPI_STATUS (Status); break; case AE_CTRL_END: AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); Status = WalkState->AscendingCallback (WalkState, Op); Status = AcpiPsNextParseState (WalkState, Op, Status); AcpiPsCompleteThisOp (WalkState, Op); Op = NULL; Status = AE_OK; break; case AE_CTRL_TERMINATE: Status = AE_OK; /* Clean up */ do { if (Op) { AcpiPsCompleteThisOp (WalkState, Op); } AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); } while (Op); return_ACPI_STATUS (Status); break; default: /* All other non-AE_OK status */ if (Op == NULL) { AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); } WalkState->PrevOp = Op; WalkState->PrevArgTypes = ArgTypes; /* * TEMP: */ return_ACPI_STATUS (Status); break; } /* This scope complete? */ if (AcpiPsHasCompletedScope (ParserState)) { AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op)); } else { Op = NULL; } } /* ArgCount is non-zero */ else { /* complex argument, push Op and prepare for argument */ AcpiPsPushScope (ParserState, Op, ArgTypes, ArgCount); Op = NULL; } } /* while ParserState->Aml */ /* * Complete the last Op (if not completed), and clear the scope stack. * It is easily possible to end an AML "package" with an unbounded number * of open scopes (such as when several AML blocks are closed with * sequential closing braces). We want to terminate each one cleanly. */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Package complete at Op %p\n", Op)); do { if (Op) { if (WalkState->AscendingCallback != NULL) { Status = WalkState->AscendingCallback (WalkState, Op); Status = AcpiPsNextParseState (WalkState, Op, Status); if (Status == AE_CTRL_PENDING) { Status = AE_OK; goto CloseThisOp; } if (Status == AE_CTRL_TERMINATE) { Status = AE_OK; /* Clean up */ do { if (Op) { AcpiPsCompleteThisOp (WalkState, Op); } AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); } while (Op); return_ACPI_STATUS (Status); } else if (ACPI_FAILURE (Status)) { AcpiPsCompleteThisOp (WalkState, Op); return_ACPI_STATUS (Status); } } AcpiPsCompleteThisOp (WalkState, Op); } AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); } while (Op); return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiUtGetSimpleObjectSize ( ACPI_OPERAND_OBJECT *InternalObject, UINT32 *ObjLength) { UINT32 Length; ACPI_STATUS Status = AE_OK; FUNCTION_TRACE_PTR ("UtGetSimpleObjectSize", InternalObject); /* Handle a null object (Could be a uninitialized package element -- which is legal) */ if (!InternalObject) { *ObjLength = 0; return_ACPI_STATUS (AE_OK); } /* Start with the length of the Acpi object */ Length = sizeof (ACPI_OBJECT); if (VALID_DESCRIPTOR_TYPE (InternalObject, ACPI_DESC_TYPE_NAMED)) { /* Object is a named object (reference), just return the length */ *ObjLength = (UINT32) ROUND_UP_TO_NATIVE_WORD (Length); return_ACPI_STATUS (Status); } /* * The final length depends on the object type * Strings and Buffers are packed right up against the parent object and * must be accessed bytewise or there may be alignment problems on * certain processors */ switch (InternalObject->Common.Type) { case ACPI_TYPE_STRING: Length += InternalObject->String.Length + 1; break; case ACPI_TYPE_BUFFER: Length += InternalObject->Buffer.Length; break; case ACPI_TYPE_INTEGER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_POWER: /* * No extra data for these types */ break; case INTERNAL_TYPE_REFERENCE: /* * The only type that should be here is internal opcode NAMEPATH_OP -- since * this means an object reference */ if (InternalObject->Reference.Opcode != AML_INT_NAMEPATH_OP) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode=%X in object %p\n", InternalObject->Reference.Opcode, InternalObject)); Status = AE_TYPE; } else { /* * Get the actual length of the full pathname to this object. * The reference will be converted to the pathname to the object */ Length += ROUND_UP_TO_NATIVE_WORD (AcpiNsGetPathnameLength (InternalObject->Reference.Node)); } break; default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported type=%X in object %p\n", InternalObject->Common.Type, InternalObject)); Status = AE_TYPE; break; } /* * Account for the space required by the object rounded up to the next * multiple of the machine word size. This keeps each object aligned * on a machine word boundary. (preventing alignment faults on some * machines.) */ *ObjLength = (UINT32) ROUND_UP_TO_NATIVE_WORD (Length); return_ACPI_STATUS (Status); }
acpi_status acpi_ut_get_simple_object_size ( acpi_operand_object *internal_object, u32 *obj_length) { u32 length; acpi_status status = AE_OK; FUNCTION_TRACE_PTR ("Ut_get_simple_object_size", internal_object); /* Handle a null object (Could be a uninitialized package element -- which is legal) */ if (!internal_object) { *obj_length = 0; return_ACPI_STATUS (AE_OK); } /* Start with the length of the Acpi object */ length = sizeof (acpi_object); if (VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_NAMED)) { /* Object is a named object (reference), just return the length */ *obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length); return_ACPI_STATUS (status); } /* * The final length depends on the object type * Strings and Buffers are packed right up against the parent object and * must be accessed bytewise or there may be alignment problems on * certain processors */ switch (internal_object->common.type) { case ACPI_TYPE_STRING: length += internal_object->string.length + 1; break; case ACPI_TYPE_BUFFER: length += internal_object->buffer.length; break; case ACPI_TYPE_INTEGER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_POWER: /* * No extra data for these types */ break; case INTERNAL_TYPE_REFERENCE: /* * The only type that should be here is internal opcode NAMEPATH_OP -- since * this means an object reference */ if (internal_object->reference.opcode != AML_INT_NAMEPATH_OP) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode=%X in object %p\n", internal_object->reference.opcode, internal_object)); status = AE_TYPE; } else { /* * Get the actual length of the full pathname to this object. * The reference will be converted to the pathname to the object */ length += ROUND_UP_TO_NATIVE_WORD (acpi_ns_get_pathname_length (internal_object->reference.node)); } break; default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported type=%X in object %p\n", internal_object->common.type, internal_object)); status = AE_TYPE; break; } /* * Account for the space required by the object rounded up to the next * multiple of the machine word size. This keeps each object aligned * on a machine word boundary. (preventing alignment faults on some * machines.) */ *obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length); return_ACPI_STATUS (status); }
static BOOLEAN AcpiPsCompleteThisOp ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op) { #ifndef PARSER_ONLY ACPI_PARSE_OBJECT *Prev; ACPI_PARSE_OBJECT *Next; const ACPI_OPCODE_INFO *OpInfo; const ACPI_OPCODE_INFO *ParentInfo; UINT32 OpcodeClass; ACPI_PARSE_OBJECT *ReplacementOp = NULL; FUNCTION_TRACE_PTR ("PsCompleteThisOp", Op); OpInfo = AcpiPsGetOpcodeInfo (Op->Opcode); OpcodeClass = ACPI_GET_OP_CLASS (OpInfo); /* Delete this op and the subtree below it if asked to */ if (((WalkState->ParseFlags & ACPI_PARSE_TREE_MASK) == ACPI_PARSE_DELETE_TREE) && (OpcodeClass != OPTYPE_CONSTANT) && (OpcodeClass != OPTYPE_LITERAL) && (OpcodeClass != OPTYPE_LOCAL_VARIABLE) && (OpcodeClass != OPTYPE_METHOD_ARGUMENT) && (OpcodeClass != OPTYPE_DATA_TERM) && (Op->Opcode != AML_INT_NAMEPATH_OP)) { /* Make sure that we only delete this subtree */ if (Op->Parent) { /* * Check if we need to replace the operator and its subtree * with a return value op (placeholder op) */ ParentInfo = AcpiPsGetOpcodeInfo (Op->Parent->Opcode); switch (ACPI_GET_OP_CLASS (ParentInfo)) { case OPTYPE_CONTROL: /* IF, ELSE, WHILE only */ break; case OPTYPE_NAMED_OBJECT: /* Scope, method, etc. */ /* * These opcodes contain TermArg operands. The current * op must be replace by a placeholder return op */ if ((Op->Parent->Opcode == AML_REGION_OP) || (Op->Parent->Opcode == AML_CREATE_FIELD_OP) || (Op->Parent->Opcode == AML_CREATE_BIT_FIELD_OP) || (Op->Parent->Opcode == AML_CREATE_BYTE_FIELD_OP) || (Op->Parent->Opcode == AML_CREATE_WORD_FIELD_OP) || (Op->Parent->Opcode == AML_CREATE_DWORD_FIELD_OP) || (Op->Parent->Opcode == AML_CREATE_QWORD_FIELD_OP)) { ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP); if (!ReplacementOp) { return_VALUE (FALSE); } } break; default: ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP); if (!ReplacementOp) { return_VALUE (FALSE); } } /* We must unlink this op from the parent tree */ Prev = Op->Parent->Value.Arg; if (Prev == Op) { /* This op is the first in the list */ if (ReplacementOp) { ReplacementOp->Parent = Op->Parent; ReplacementOp->Value.Arg = NULL; Op->Parent->Value.Arg = ReplacementOp; ReplacementOp->Next = Op->Next; } else { Op->Parent->Value.Arg = Op->Next; } } /* Search the parent list */ else while (Prev) { /* Traverse all siblings in the parent's argument list */ Next = Prev->Next; if (Next == Op) { if (ReplacementOp) { ReplacementOp->Parent = Op->Parent; ReplacementOp->Value.Arg = NULL; Prev->Next = ReplacementOp; ReplacementOp->Next = Op->Next; Next = NULL; } else { Prev->Next = Op->Next; Next = NULL; } } Prev = Next; } } /* Now we can actually delete the subtree rooted at op */ AcpiPsDeleteParseTree (Op); return_VALUE (TRUE); } return_VALUE (FALSE); #else return (FALSE); #endif }
ACPI_STATUS AcpiNsHandleToPathname ( ACPI_HANDLE TargetHandle, UINT32 *BufSize, NATIVE_CHAR *UserBuffer) { ACPI_STATUS Status = AE_OK; ACPI_NAMESPACE_NODE *Node; UINT32 PathLength; UINT32 UserBufSize; ACPI_NAME Name; UINT32 Size; FUNCTION_TRACE_PTR ("NsHandleToPathname", TargetHandle); if (!AcpiGbl_RootNode) { /* * If the name space has not been initialized, * this function should not have been called. */ return_ACPI_STATUS (AE_NO_NAMESPACE); } Node = AcpiNsConvertHandleToEntry (TargetHandle); if (!Node) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Set return length to the required path length */ PathLength = AcpiNsGetPathnameLength (Node); Size = PathLength - 1; UserBufSize = *BufSize; *BufSize = PathLength; /* Check if the user buffer is sufficiently large */ if (PathLength > UserBufSize) { Status = AE_BUFFER_OVERFLOW; goto Exit; } /* Store null terminator */ UserBuffer[Size] = 0; Size -= ACPI_NAME_SIZE; /* Put the original ACPI name at the end of the path */ MOVE_UNALIGNED32_TO_32 ((UserBuffer + Size), &Node->Name); UserBuffer[--Size] = PATH_SEPARATOR; /* Build name backwards, putting "." between segments */ while ((Size > ACPI_NAME_SIZE) && Node) { Size -= ACPI_NAME_SIZE; Name = AcpiNsFindParentName (Node); MOVE_UNALIGNED32_TO_32 ((UserBuffer + Size), &Name); UserBuffer[--Size] = PATH_SEPARATOR; Node = AcpiNsGetParentObject (Node); } /* * Overlay the "." preceding the first segment with * the root name "\" */ UserBuffer[Size] = '\\'; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Len=%X, %s \n", PathLength, UserBuffer)); Exit: return_ACPI_STATUS (Status); }
NATIVE_CHAR * AcpiNsGetTablePathname ( ACPI_NAMESPACE_NODE *Node) { NATIVE_CHAR *NameBuffer; UINT32 Size; ACPI_NAME Name; ACPI_NAMESPACE_NODE *ChildNode; ACPI_NAMESPACE_NODE *ParentNode; FUNCTION_TRACE_PTR ("NsGetTablePathname", Node); if (!AcpiGbl_RootNode || !Node) { /* * If the name space has not been initialized, * this function should not have been called. */ return_PTR (NULL); } ChildNode = Node->Child; /* Calculate required buffer size based on depth below root */ Size = 1; ParentNode = ChildNode; while (ParentNode) { ParentNode = AcpiNsGetParentObject (ParentNode); if (ParentNode) { Size += ACPI_NAME_SIZE; } } /* Allocate a buffer to be returned to caller */ NameBuffer = ACPI_MEM_CALLOCATE (Size + 1); if (!NameBuffer) { REPORT_ERROR (("NsGetTablePathname: allocation failure\n")); return_PTR (NULL); } /* Store terminator byte, then build name backwards */ NameBuffer[Size] = '\0'; while ((Size > ACPI_NAME_SIZE) && AcpiNsGetParentObject (ChildNode)) { Size -= ACPI_NAME_SIZE; Name = AcpiNsFindParentName (ChildNode); /* Put the name into the buffer */ MOVE_UNALIGNED32_TO_32 ((NameBuffer + Size), &Name); ChildNode = AcpiNsGetParentObject (ChildNode); } NameBuffer[--Size] = AML_ROOT_PREFIX; if (Size != 0) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad pointer returned; size=%X\n", Size)); } return_PTR (NameBuffer); }
ACPI_STATUS AcpiUtAddElementToAllocList ( UINT32 ListId, ACPI_DEBUG_MEM_BLOCK *Address, UINT32 Size, UINT8 AllocType, UINT32 Component, NATIVE_CHAR *Module, UINT32 Line) { ACPI_MEMORY_LIST *MemList; ACPI_DEBUG_MEM_BLOCK *Element; ACPI_STATUS Status = AE_OK; FUNCTION_TRACE_PTR ("UtAddElementToAllocList", Address); if (ListId > ACPI_MEM_LIST_MAX) { return_ACPI_STATUS (AE_BAD_PARAMETER); } MemList = &AcpiGbl_MemoryLists[ListId]; AcpiUtAcquireMutex (ACPI_MTX_MEMORY); /* * Search list for this address to make sure it is not already on the list. * This will catch several kinds of problems. */ Element = AcpiUtSearchAllocList (ListId, Address); if (Element) { REPORT_ERROR (("UtAddElementToAllocList: Address already present in list! (%p)\n", Address)); ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", Element, Address)); goto UnlockAndExit; } /* Fill in the instance data. */ Address->Size = Size; Address->AllocType = AllocType; Address->Component = Component; Address->Line = Line; STRNCPY (Address->Module, Module, MAX_MODULE_NAME); /* Insert at list head */ if (MemList->ListHead) { ((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous = Address; } Address->Next = MemList->ListHead; Address->Previous = NULL; MemList->ListHead = Address; UnlockAndExit: AcpiUtReleaseMutex (ACPI_MTX_MEMORY); return_ACPI_STATUS (Status); }
acpi_status acpi_ex_get_name_string ( acpi_object_type8 data_type, u8 *in_aml_address, NATIVE_CHAR **out_name_string, u32 *out_name_length) { acpi_status status = AE_OK; u8 *aml_address = in_aml_address; NATIVE_CHAR *name_string = NULL; u32 num_segments; u32 prefix_count = 0; u8 prefix = 0; u8 has_prefix = FALSE; FUNCTION_TRACE_PTR ("Ex_get_name_string", aml_address); if (INTERNAL_TYPE_REGION_FIELD == data_type || INTERNAL_TYPE_BANK_FIELD == data_type || INTERNAL_TYPE_INDEX_FIELD == data_type) { /* Disallow prefixes for types associated with Field_unit names */ name_string = acpi_ex_allocate_name_string (0, 1); if (!name_string) { status = AE_NO_MEMORY; } else { status = acpi_ex_name_segment (&aml_address, name_string); } } else { /* * Data_type is not a field name. * Examine first character of name for root or parent prefix operators */ switch (*aml_address) { case AML_ROOT_PREFIX: prefix = *aml_address++; ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Root_prefix: %x\n", prefix)); /* * Remember that we have a Root_prefix -- * see comment in Acpi_ex_allocate_name_string() */ prefix_count = (u32) -1; has_prefix = TRUE; break; case AML_PARENT_PREFIX: /* Increment past possibly multiple parent prefixes */ do { prefix = *aml_address++; ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Parent_prefix: %x\n", prefix)); ++prefix_count; } while (*aml_address == AML_PARENT_PREFIX); has_prefix = TRUE; break; default: break; } /* Examine first character of name for name segment prefix operator */ switch (*aml_address) { case AML_DUAL_NAME_PREFIX: prefix = *aml_address++; ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Dual_name_prefix: %x\n", prefix)); name_string = acpi_ex_allocate_name_string (prefix_count, 2); if (!name_string) { status = AE_NO_MEMORY; break; } /* Indicate that we processed a prefix */ has_prefix = TRUE; status = acpi_ex_name_segment (&aml_address, name_string); if (ACPI_SUCCESS (status)) { status = acpi_ex_name_segment (&aml_address, name_string); } break; case AML_MULTI_NAME_PREFIX_OP: prefix = *aml_address++; ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Multi_name_prefix: %x\n", prefix)); /* Fetch count of segments remaining in name path */ num_segments = *aml_address++; name_string = acpi_ex_allocate_name_string (prefix_count, num_segments); if (!name_string) { status = AE_NO_MEMORY; break; } /* Indicate that we processed a prefix */ has_prefix = TRUE; while (num_segments && (status = acpi_ex_name_segment (&aml_address, name_string)) == AE_OK) { --num_segments; } break; case 0: /* Null_name valid as of 8-12-98 ASL/AML Grammar Update */ if (-1 == prefix_count) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Name_seg is \"\\\" followed by NULL\n")); } /* Consume the NULL byte */ aml_address++; name_string = acpi_ex_allocate_name_string (prefix_count, 0); if (!name_string) { status = AE_NO_MEMORY; break; } break; default: /* Name segment string */ name_string = acpi_ex_allocate_name_string (prefix_count, 1); if (!name_string) { status = AE_NO_MEMORY; break; } status = acpi_ex_name_segment (&aml_address, name_string); break; } /* Switch (Peek_op ()) */ } if (AE_CTRL_PENDING == status && has_prefix) { /* Ran out of segments after processing a prefix */ REPORT_ERROR ( ("Ex_do_name: Malformed Name at %p\n", name_string)); status = AE_AML_BAD_NAME; } *out_name_string = name_string; *out_name_length = (u32) (aml_address - in_aml_address); return_ACPI_STATUS (status); }