예제 #1
0
파일: utosi.c 프로젝트: bjayesh/chandra
acpi_status acpi_ut_install_interface(acpi_string interface_name)
{
	struct acpi_interface_info *interface_info;

	/* Allocate info block and space for the name string */

	interface_info =
	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_interface_info));
	if (!interface_info) {
		return (AE_NO_MEMORY);
	}

	interface_info->name =
	    ACPI_ALLOCATE_ZEROED(ACPI_STRLEN(interface_name) + 1);
	if (!interface_info->name) {
		ACPI_FREE(interface_info);
		return (AE_NO_MEMORY);
	}

	/* Initialize new info and insert at the head of the global list */

	ACPI_STRCPY(interface_info->name, interface_name);
	interface_info->flags = ACPI_OSI_DYNAMIC;
	interface_info->next = acpi_gbl_supported_interfaces;

	acpi_gbl_supported_interfaces = interface_info;
	return (AE_OK);
}
예제 #2
0
acpi_status acpi_ut_install_interface(acpi_string interface_name)
{
	struct acpi_interface_info *interface_info;

	

	interface_info =
	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_interface_info));
	if (!interface_info) {
		return (AE_NO_MEMORY);
	}

	interface_info->name =
	    ACPI_ALLOCATE_ZEROED(ACPI_STRLEN(interface_name) + 1);
	if (!interface_info->name) {
		ACPI_FREE(interface_info);
		return (AE_NO_MEMORY);
	}

	

	ACPI_STRCPY(interface_info->name, interface_name);
	interface_info->flags = ACPI_OSI_DYNAMIC;
	interface_info->next = acpi_gbl_supported_interfaces;

	acpi_gbl_supported_interfaces = interface_info;
	return (AE_OK);
}
예제 #3
0
void acpi_ut_get_expected_return_types(char *buffer, u32 expected_btypes)
{
	u32 this_rtype;
	u32 i;
	u32 j;

	if (!expected_btypes) {
		ACPI_STRCPY(buffer, "NONE");
		return;
	}

	j = 1;
	buffer[0] = 0;
	this_rtype = ACPI_RTYPE_INTEGER;

	for (i = 0; i < ACPI_NUM_RTYPES; i++) {

		/* If one of the expected types, concatenate the name of this type */

		if (expected_btypes & this_rtype) {
			ACPI_STRCAT(buffer, &ut_rtype_names[i][j]);
			j = 0;	/* Use name separator from now on */
		}

		this_rtype <<= 1;	/* Next Rtype */
	}
}
예제 #4
0
void
AcpiUtGetExpectedReturnTypes (
    char                    *Buffer,
    UINT32                  ExpectedBtypes)
{
    UINT32                  ThisRtype;
    UINT32                  i;
    UINT32                  j;


    if (!ExpectedBtypes)
    {
        ACPI_STRCPY (Buffer, "NONE");
        return;
    }

    j = 1;
    Buffer[0] = 0;
    ThisRtype = ACPI_RTYPE_INTEGER;

    for (i = 0; i < ACPI_NUM_RTYPES; i++)
    {
        /* If one of the expected types, concatenate the name of this type */

        if (ExpectedBtypes & ThisRtype)
        {
            ACPI_STRCAT (Buffer, &UtRtypeNames[i][j]);
            j = 0;              /* Use name separator from now on */
        }

        ThisRtype <<= 1;    /* Next Rtype */
    }
}
예제 #5
0
ACPI_STATUS
AcpiUtInstallInterface (
    ACPI_STRING             InterfaceName)
{
    ACPI_INTERFACE_INFO     *InterfaceInfo;


    /* Allocate info block and space for the name string */

    InterfaceInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_INTERFACE_INFO));
    if (!InterfaceInfo)
    {
        return (AE_NO_MEMORY);
    }

    InterfaceInfo->Name = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (InterfaceName) + 1);
    if (!InterfaceInfo->Name)
    {
        ACPI_FREE (InterfaceInfo);
        return (AE_NO_MEMORY);
    }

    /* Initialize new info and insert at the head of the global list */

    ACPI_STRCPY (InterfaceInfo->Name, InterfaceName);
    InterfaceInfo->Flags = ACPI_OSI_DYNAMIC;
    InterfaceInfo->Next = AcpiGbl_SupportedInterfaces;

    AcpiGbl_SupportedInterfaces = InterfaceInfo;
    return (AE_OK);
}
예제 #6
0
/*******************************************************************************
 *
 * FUNCTION:    acpi_ut_execute_HID
 *
 * PARAMETERS:  device_node         - Node for the device
 *              return_id           - Where the string HID is returned
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Executes the _HID control method that returns the hardware
 *              ID of the device. The HID is either an 32-bit encoded EISAID
 *              Integer or a String. A string is always returned. An EISAID
 *              is converted to a string.
 *
 *              NOTE: Internal function, no parameter validation
 *
 ******************************************************************************/
acpi_status
acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
		    struct acpi_pnp_device_id **return_id)
{
	union acpi_operand_object *obj_desc;
	struct acpi_pnp_device_id *hid;
	u32 length;
	acpi_status status;

	ACPI_FUNCTION_TRACE(ut_execute_HID);

	status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
					 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
					 &obj_desc);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/* Get the size of the String to be returned, includes null terminator */

	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
		length = ACPI_EISAID_STRING_SIZE;
	} else {
		length = obj_desc->string.length + 1;
	}

	/* Allocate a buffer for the HID */

	hid =
	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
				 (acpi_size) length);
	if (!hid) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

	/* Area for the string starts after PNP_DEVICE_ID struct */

	hid->string =
	    ACPI_ADD_PTR(char, hid, sizeof(struct acpi_pnp_device_id));

	/* Convert EISAID to a string or simply copy existing string */

	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
		acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value);
	} else {
		ACPI_STRCPY(hid->string, obj_desc->string.pointer);
	}

	hid->length = length;
	*return_id = hid;

cleanup:

	/* On exit, we must delete the return object */

	acpi_ut_remove_reference(obj_desc);
	return_ACPI_STATUS(status);
}
예제 #7
0
acpi_status
acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
		    struct acpica_device_id **return_id)
{
	union acpi_operand_object *obj_desc;
	struct acpica_device_id *uid;
	u32 length;
	acpi_status status;

	ACPI_FUNCTION_TRACE(ut_execute_UID);

	status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
					 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
					 &obj_desc);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/* Get the size of the String to be returned, includes null terminator */

	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
		length = ACPI_MAX64_DECIMAL_DIGITS + 1;
	} else {
		length = obj_desc->string.length + 1;
	}

	/* Allocate a buffer for the UID */

	uid =
	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) +
				 (acpi_size) length);
	if (!uid) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

	/* Area for the string starts after DEVICE_ID struct */

	uid->string = ACPI_ADD_PTR(char, uid, sizeof(struct acpica_device_id));

	/* Convert an Integer to string, or just copy an existing string */

	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
		acpi_ex_integer_to_string(uid->string, obj_desc->integer.value);
	} else {
		ACPI_STRCPY(uid->string, obj_desc->string.pointer);
	}

	uid->length = length;
	*return_id = uid;

cleanup:

	/* On exit, we must delete the return object */

	acpi_ut_remove_reference(obj_desc);
	return_ACPI_STATUS(status);
}
예제 #8
0
파일: dbhistry.c 프로젝트: Alkzndr/freebsd
void
AcpiDbAddToHistory (
    char                    *CommandLine)
{
    UINT16                  CmdLen;
    UINT16                  BufferLen;

    /* Put command into the next available slot */

    CmdLen = (UINT16) ACPI_STRLEN (CommandLine);
    if (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command != NULL)
    {
        BufferLen = (UINT16) ACPI_STRLEN (
            AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command);
        if (CmdLen > BufferLen)
        {
            AcpiOsFree (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].
                Command);
            AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command =
                AcpiOsAllocate (CmdLen + 1);
        }
    }
    else
    {
        AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command =
            AcpiOsAllocate (CmdLen + 1);
    }

    ACPI_STRCPY (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command,
        CommandLine);

    AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].CmdNum =
        AcpiGbl_NextCmdNum;

    /* Adjust indexes */

    if ((AcpiGbl_NumHistory == HISTORY_SIZE) &&
        (AcpiGbl_NextHistoryIndex == AcpiGbl_LoHistory))
    {
        AcpiGbl_LoHistory++;
        if (AcpiGbl_LoHistory >= HISTORY_SIZE)
        {
            AcpiGbl_LoHistory = 0;
        }
    }

    AcpiGbl_NextHistoryIndex++;
    if (AcpiGbl_NextHistoryIndex >= HISTORY_SIZE)
    {
        AcpiGbl_NextHistoryIndex = 0;
    }

    AcpiGbl_NextCmdNum++;
    if (AcpiGbl_NumHistory < HISTORY_SIZE)
    {
        AcpiGbl_NumHistory++;
    }
}
예제 #9
0
파일: utstring.c 프로젝트: 7799/linux
u8 acpi_ut_safe_strcpy(char *dest, acpi_size dest_size, char *source)
{

	if (ACPI_STRLEN(source) >= dest_size) {
		return (TRUE);
	}

	ACPI_STRCPY(dest, source);
	return (FALSE);
}
예제 #10
0
void
AcpiDbSetScope (
    char                    *Name)
{
    ACPI_STATUS             Status;
    ACPI_NAMESPACE_NODE     *Node;


    if (!Name || Name[0] == 0)
    {
        AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
        return;
    }

    AcpiDbPrepNamestring (Name);

    if (Name[0] == '\\')
    {
        /* Validate new scope from the root */

        Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
                    &Node);
        if (ACPI_FAILURE (Status))
        {
            goto ErrorExit;
        }

        ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
        ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
    }
    else
    {
        /* Validate new scope relative to old scope */

        Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
                    &Node);
        if (ACPI_FAILURE (Status))
        {
            goto ErrorExit;
        }

        ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
        ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
    }

    AcpiGbl_DbScopeNode = Node;
    AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
    return;

ErrorExit:

    AcpiOsPrintf ("Could not attach scope: %s, %s\n",
        Name, AcpiFormatException (Status));
}
예제 #11
0
ACPI_STATUS
AcpiUtExecute_SUB (
    ACPI_NAMESPACE_NODE     *DeviceNode,
    ACPI_PNP_DEVICE_ID      **ReturnId)
{
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_PNP_DEVICE_ID      *Sub;
    UINT32                  Length;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (UtExecute_SUB);


    Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__SUB,
                                   ACPI_BTYPE_STRING, &ObjDesc);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Get the size of the String to be returned, includes null terminator */

    Length = ObjDesc->String.Length + 1;

    /* Allocate a buffer for the SUB */

    Sub = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length);
    if (!Sub)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    /* Area for the string starts after PNP_DEVICE_ID struct */

    Sub->String = ACPI_ADD_PTR (char, Sub, sizeof (ACPI_PNP_DEVICE_ID));

    /* Simply copy existing string */

    ACPI_STRCPY (Sub->String, ObjDesc->String.Pointer);
    Sub->Length = Length;
    *ReturnId = Sub;


Cleanup:

    /* On exit, we must delete the return object */

    AcpiUtRemoveReference (ObjDesc);
    return_ACPI_STATUS (Status);
}
예제 #12
0
void
AcpiDbUInt32ToHexString (
    UINT32                  Value,
    char                    *Buffer)
{
    UINT8                   i;


    if (Value == 0)
    {
        ACPI_STRCPY (Buffer, "0");
        return;
    }

    ACPI_STRCPY (Buffer, "0x");
    Buffer[10] = '\0';

    for (i = 9; i > 1; i--)
    {
        Buffer[i] = Converter [Value & 0x0F];
        Value = Value >> 4;
    }
}
예제 #13
0
acpi_status
acpi_ut_execute_SUB(struct acpi_namespace_node *device_node,
		    struct acpi_pnp_device_id **return_id)
{
	union acpi_operand_object *obj_desc;
	struct acpi_pnp_device_id *sub;
	u32 length;
	acpi_status status;

	ACPI_FUNCTION_TRACE(ut_execute_SUB);

	status = acpi_ut_evaluate_object(device_node, METHOD_NAME__SUB,
					 ACPI_BTYPE_STRING, &obj_desc);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/* Get the size of the String to be returned, includes null terminator */

	length = obj_desc->string.length + 1;

	/* Allocate a buffer for the SUB */

	sub =
	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) +
				 (acpi_size) length);
	if (!sub) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

	/* Area for the string starts after PNP_DEVICE_ID struct */

	sub->string =
	    ACPI_ADD_PTR(char, sub, sizeof(struct acpi_pnp_device_id));

	/* Simply copy existing string */

	ACPI_STRCPY(sub->string, obj_desc->string.pointer);
	sub->length = length;
	*return_id = sub;

cleanup:

	/* On exit, we must delete the return object */

	acpi_ut_remove_reference(obj_desc);
	return_ACPI_STATUS(status);
}
예제 #14
0
BOOLEAN
AcpiUtSafeStrcpy (
    char                    *Dest,
    ACPI_SIZE               DestSize,
    char                    *Source)
{

    if (ACPI_STRLEN (Source) >= DestSize)
    {
        return (TRUE);
    }

    ACPI_STRCPY (Dest, Source);
    return (FALSE);
}
예제 #15
0
ACPI_STATUS
AcpiUtDeleteCaches (
    void)
{
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
    char                    Buffer[7];

    if (AcpiGbl_DisplayFinalMemStats)
    {
        ACPI_STRCPY (Buffer, "MEMORY");
        (void) AcpiDbDisplayStatistics (Buffer);
    }
#endif

    (void) AcpiOsDeleteCache (AcpiGbl_NamespaceCache);
    AcpiGbl_NamespaceCache = NULL;

    (void) AcpiOsDeleteCache (AcpiGbl_StateCache);
    AcpiGbl_StateCache = NULL;

    (void) AcpiOsDeleteCache (AcpiGbl_OperandCache);
    AcpiGbl_OperandCache = NULL;

    (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache);
    AcpiGbl_PsNodeCache = NULL;

    (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache);
    AcpiGbl_PsNodeExtCache = NULL;


#ifdef ACPI_DBG_TRACK_ALLOCATIONS

    /* Debug only - display leftover memory allocation, if any */

    AcpiUtDumpAllocations (ACPI_UINT32_MAX, NULL);

    /* Free memory lists */

    AcpiOsFree (AcpiGbl_GlobalList);
    AcpiGbl_GlobalList = NULL;

    AcpiOsFree (AcpiGbl_NsNodeList);
    AcpiGbl_NsNodeList = NULL;
#endif

    return (AE_OK);
}
예제 #16
0
파일: dmextern.c 프로젝트: DonCN/haiku
ACPI_STATUS
AcpiDmAddToExternalFileList (
    char                    *PathList)
{
    ACPI_EXTERNAL_FILE      *ExternalFile;
    char                    *Path;
    char                    *TmpPath;


    if (!PathList)
    {
        return (AE_OK);
    }

    Path = strtok (PathList, ",");

    while (Path)
    {
        TmpPath = ACPI_ALLOCATE_ZEROED (ACPI_STRLEN (Path) + 1);
        if (!TmpPath)
        {
            return (AE_NO_MEMORY);
        }

        ACPI_STRCPY (TmpPath, Path);

        ExternalFile = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EXTERNAL_FILE));
        if (!ExternalFile)
        {
            ACPI_FREE (TmpPath);
            return (AE_NO_MEMORY);
        }

        ExternalFile->Path = TmpPath;

        if (AcpiGbl_ExternalFileList)
        {
            ExternalFile->Next = AcpiGbl_ExternalFileList;
        }

        AcpiGbl_ExternalFileList = ExternalFile;
        Path = strtok (NULL, ",");
    }

    return (AE_OK);
}
예제 #17
0
static void acpi_ut_copy_id_string(char *destination, char *source)
{

	/*
	 * Workaround for ID strings that have a leading asterisk. This construct
	 * is not allowed by the ACPI specification  (ID strings must be
	 * alphanumeric), but enough existing machines have this embedded in their
	 * ID strings that the following code is useful.
	 */
	if (*source == '*') {
		source++;
	}

	/* Do the actual copy */

	ACPI_STRCPY(destination, source);
}
예제 #18
0
파일: utalloc.c 프로젝트: PyroOS/Pyro
acpi_status acpi_ut_delete_caches(void)
{
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
	char buffer[7];

	if (acpi_gbl_display_final_mem_stats) {
		ACPI_STRCPY(buffer, "MEMORY");
		(void)acpi_db_display_statistics(buffer);
	}
#endif

	(void)acpi_os_delete_cache(acpi_gbl_namespace_cache);
	acpi_gbl_namespace_cache = NULL;

	(void)acpi_os_delete_cache(acpi_gbl_state_cache);
	acpi_gbl_state_cache = NULL;

	(void)acpi_os_delete_cache(acpi_gbl_operand_cache);
	acpi_gbl_operand_cache = NULL;

	(void)acpi_os_delete_cache(acpi_gbl_ps_node_cache);
	acpi_gbl_ps_node_cache = NULL;

	(void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache);
	acpi_gbl_ps_node_ext_cache = NULL;

#ifdef ACPI_DBG_TRACK_ALLOCATIONS

	/* Debug only - display leftover memory allocation, if any */

	acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL);

	/* Free memory lists */

	ACPI_FREE(acpi_gbl_global_list);
	acpi_gbl_global_list = NULL;

	ACPI_FREE(acpi_gbl_ns_node_list);
	acpi_gbl_ns_node_list = NULL;
#endif

	return (AE_OK);
}
예제 #19
0
void
AcpiDbOpenDebugFile (
    char                    *Name)
{

#ifdef ACPI_APPLICATION

    AcpiDbCloseDebugFile ();
    AcpiGbl_DebugFile = fopen (Name, "w+");
    if (!AcpiGbl_DebugFile)
    {
        AcpiOsPrintf ("Could not open debug file %s\n", Name);
        return;
    }

    AcpiOsPrintf ("Debug output file %s opened\n", Name);
    ACPI_STRCPY (AcpiGbl_DbDebugFilename, Name);
    AcpiGbl_DbOutputToFile = TRUE;

#endif
}
예제 #20
0
UINT32
AcpiDbGetLine (
    NATIVE_CHAR             *InputBuffer)
{
    UINT32                  i;
    UINT32                  Count;
    NATIVE_CHAR             *Next;
    NATIVE_CHAR             *This;


    ACPI_STRCPY (AcpiGbl_DbParsedBuf, InputBuffer);
    ACPI_STRUPR (AcpiGbl_DbParsedBuf);

    This = AcpiGbl_DbParsedBuf;
    for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
    {
        AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next);
        if (!AcpiGbl_DbArgs[i])
        {
            break;
        }

        This = Next;
    }

    /* Uppercase the actual command */

    if (AcpiGbl_DbArgs[0])
    {
        ACPI_STRUPR (AcpiGbl_DbArgs[0]);
    }

    Count = i;
    if (Count)
    {
        Count--;  /* Number of args only */
    }

    return (Count);
}
예제 #21
0
static UINT32
AcpiDbGetLine (
    char                    *InputBuffer)
{
    UINT32                  i;
    UINT32                  Count;
    char                    *Next;
    char                    *This;


    ACPI_STRCPY (AcpiGbl_DbParsedBuf, InputBuffer);

    This = AcpiGbl_DbParsedBuf;
    for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++)
    {
        AcpiGbl_DbArgs[i] = AcpiDbGetNextToken (This, &Next,
            &AcpiGbl_DbArgTypes[i]);
        if (!AcpiGbl_DbArgs[i])
        {
            break;
        }

        This = Next;
    }

    /* Uppercase the actual command */

    if (AcpiGbl_DbArgs[0])
    {
        AcpiUtStrupr (AcpiGbl_DbArgs[0]);
    }

    Count = i;
    if (Count)
    {
        Count--;  /* Number of args only */
    }

    return (Count);
}
예제 #22
0
void
AcpiDbUint32ToHexString (
    UINT32                  Value,
    char                    *Buffer)
{
    int                     i;


    if (Value == 0)
    {
        ACPI_STRCPY (Buffer, "0");
        return;
    }

    Buffer[8] = '\0';

    for (i = 7; i >= 0; i--)
    {
        Buffer[i] = Converter [Value & 0x0F];
        Value = Value >> 4;
    }
}
예제 #23
0
void
AcpiDbAddToHistory (
    char                    *CommandLine)
{

    /* Put command into the next available slot */

    ACPI_STRCPY (AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].Command,
        CommandLine);

    AcpiGbl_HistoryBuffer[AcpiGbl_NextHistoryIndex].CmdNum = AcpiGbl_NextCmdNum;

    /* Adjust indexes */

    if ((AcpiGbl_NumHistory == HISTORY_SIZE) &&
        (AcpiGbl_NextHistoryIndex == AcpiGbl_LoHistory))
    {
        AcpiGbl_LoHistory++;
        if (AcpiGbl_LoHistory >= HISTORY_SIZE)
        {
            AcpiGbl_LoHistory = 0;
        }
    }

    AcpiGbl_NextHistoryIndex++;
    if (AcpiGbl_NextHistoryIndex >= HISTORY_SIZE)
    {
        AcpiGbl_NextHistoryIndex = 0;
    }

    AcpiGbl_NextCmdNum++;
    if (AcpiGbl_NumHistory < HISTORY_SIZE)
    {
        AcpiGbl_NumHistory++;
    }
}
예제 #24
0
ACPI_STATUS
AcpiOsGetTableByName (
    char                    *Signature,
    UINT32                  Instance,
    ACPI_TABLE_HEADER       **Table,
    ACPI_PHYSICAL_ADDRESS   *Address)
{
    HKEY                    Handle = NULL;
    LONG                    WinStatus;
    ULONG                   Type;
    ULONG                   NameSize;
    ULONG                   DataSize;
    HKEY                    SubKey;
    ULONG                   i;
    ACPI_TABLE_HEADER       *ReturnTable;
    ACPI_STATUS             Status = AE_OK;


    /*
     * Windows has no SSDTs in the registry, so multiple instances are
     * not supported.
     */
    if (Instance > 0)
    {
        return (AE_LIMIT);
    }

    /* Get a handle to the table key */

    while (1)
    {
        ACPI_STRCPY (KeyBuffer, "HARDWARE\\ACPI\\");
        if (AcpiUtSafeStrcat (KeyBuffer, sizeof (KeyBuffer), Signature))
        {
            return (AE_BUFFER_OVERFLOW);
        }

        WinStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE, KeyBuffer,
            0L, KEY_READ, &Handle);

        if (WinStatus != ERROR_SUCCESS)
        {
            /*
             * Somewhere along the way, MS changed the registry entry for
             * the FADT from
             * HARDWARE/ACPI/FACP  to
             * HARDWARE/ACPI/FADT.
             *
             * This code allows for both.
             */
            if (ACPI_COMPARE_NAME (Signature, "FACP"))
            {
                Signature = "FADT";
            }
            else if (ACPI_COMPARE_NAME (Signature, "XSDT"))
            {
                Signature = "RSDT";
            }
            else
            {
                fprintf (stderr,
                    "Could not find %s in registry at %s: %s (WinStatus=0x%X)\n",
                    Signature, KeyBuffer, WindowsFormatException (WinStatus), WinStatus);
                return (AE_NOT_FOUND);
            }
        }
        else
        {
            break;
        }
    }

    /* Actual data for the table is down a couple levels */

    for (i = 0; ;)
    {
        WinStatus = RegEnumKey (Handle, i, KeyBuffer, sizeof (KeyBuffer));
        i++;
        if (WinStatus == ERROR_NO_MORE_ITEMS)
        {
            break;
        }

        WinStatus = RegOpenKey (Handle, KeyBuffer, &SubKey);
        if (WinStatus != ERROR_SUCCESS)
        {
            fprintf (stderr, "Could not open %s entry: %s\n",
                Signature, WindowsFormatException (WinStatus));
            Status = AE_ERROR;
            goto Cleanup;
        }

        RegCloseKey (Handle);
        Handle = SubKey;
        i = 0;
    }

    /* Find the (binary) table entry */

    for (i = 0; ; i++)
    {
        NameSize = sizeof (KeyBuffer);
        WinStatus = RegEnumValue (Handle, i, KeyBuffer, &NameSize, NULL,
            &Type, NULL, 0);
        if (WinStatus != ERROR_SUCCESS)
        {
            fprintf (stderr, "Could not get %s registry entry: %s\n",
                Signature, WindowsFormatException (WinStatus));
            Status = AE_ERROR;
            goto Cleanup;
        }

        if (Type == REG_BINARY)
        {
            break;
        }
    }

    /* Get the size of the table */

    WinStatus = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL,
        NULL, &DataSize);
    if (WinStatus = ERROR_SUCCESS)
    {
        fprintf (stderr, "Could not read the %s table size: %s\n",
            Signature, WindowsFormatException (WinStatus));
        Status = AE_ERROR;
        goto Cleanup;
    }

    /* Allocate a new buffer for the table */

    ReturnTable = malloc (DataSize);
    if (!ReturnTable)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    /* Get the actual table from the registry */

    WinStatus = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL,
        (UCHAR *) ReturnTable, &DataSize);
    if (WinStatus = ERROR_SUCCESS)
    {
        fprintf (stderr, "Could not read %s data: %s\n",
            Signature, WindowsFormatException (WinStatus));
        free (ReturnTable);
        Status = AE_ERROR;
        goto Cleanup;
    }

    *Table = ReturnTable;
    *Address = 0;

Cleanup:
    RegCloseKey (Handle);
    return (Status);
}
예제 #25
0
static void
OpnDoDefinitionBlock (
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_PARSE_OBJECT       *Child;
    ACPI_SIZE               Length;
    UINT32                  i;
    char                    *Filename;


    /*
     * These nodes get stuffed into the table header. They are special
     * cased when the table is written to the output file.
     *
     * Mark all of these nodes as non-usable so they won't get output
     * as AML opcodes!
     */

    /* Get AML filename. Use it if non-null */

    Child = Op->Asl.Child;
    if (Child->Asl.Value.Buffer  &&
        *Child->Asl.Value.Buffer &&
        (Gbl_UseDefaultAmlFilename))
    {
        /*
         * We will use the AML filename that is embedded in the source file
         * for the output filename.
         */
        Filename = UtStringCacheCalloc (strlen (Gbl_DirectoryPath) +
            strlen ((char *) Child->Asl.Value.Buffer) + 1);

        /* Prepend the current directory path */

        strcpy (Filename, Gbl_DirectoryPath);
        strcat (Filename, (char *) Child->Asl.Value.Buffer);

        Gbl_OutputFilenamePrefix = Filename;
        UtConvertBackslashes (Gbl_OutputFilenamePrefix);
    }
    Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;

    /* Signature */

    Child = Child->Asl.Next;
    Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    if (Child->Asl.Value.String)
    {
        Gbl_TableSignature = Child->Asl.Value.String;
        if (ACPI_STRLEN (Gbl_TableSignature) != 4)
        {
            AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child,
                "Length not exactly 4");
        }

        for (i = 0; i < 4; i++)
        {
            if (!isalnum ((int) Gbl_TableSignature[i]))
            {
                AslError (ASL_ERROR, ASL_MSG_TABLE_SIGNATURE, Child,
                    "Contains non-alphanumeric characters");
            }
        }
    }

    /* Revision */

    Child = Child->Asl.Next;
    Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    /*
     * We used the revision to set the integer width earlier
     */

    /* OEMID */

    Child = Child->Asl.Next;
    Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;

    /* OEM TableID */

    Child = Child->Asl.Next;
    Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
    if (Child->Asl.Value.String)
    {
        Length = ACPI_STRLEN (Child->Asl.Value.String);
        Gbl_TableId = UtStringCacheCalloc (Length + 1);
        ACPI_STRCPY (Gbl_TableId, Child->Asl.Value.String);

        /*
         * Convert anything non-alphanumeric to an underscore. This
         * allows us to use the TableID to generate unique C symbols.
         */
        for (i = 0; i < Length; i++)
        {
            if (!isalnum ((int) Gbl_TableId[i]))
            {
                Gbl_TableId[i] = '_';
            }
        }
    }

    /* OEM Revision */

    Child = Child->Asl.Next;
    Child->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
}
예제 #26
0
ACPI_STATUS
AcpiUtExecute_HID (
    ACPI_NAMESPACE_NODE     *DeviceNode,
    ACPI_PNP_DEVICE_ID      **ReturnId)
{
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_PNP_DEVICE_ID      *Hid;
    UINT32                  Length;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (UtExecute_HID);


    Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__HID,
                                   ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Get the size of the String to be returned, includes null terminator */

    if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
    {
        Length = ACPI_EISAID_STRING_SIZE;
    }
    else
    {
        Length = ObjDesc->String.Length + 1;
    }

    /* Allocate a buffer for the HID */

    Hid = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PNP_DEVICE_ID) + (ACPI_SIZE) Length);
    if (!Hid)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    /* Area for the string starts after PNP_DEVICE_ID struct */

    Hid->String = ACPI_ADD_PTR (char, Hid, sizeof (ACPI_PNP_DEVICE_ID));

    /* Convert EISAID to a string or simply copy existing string */

    if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
    {
        AcpiExEisaIdToString (Hid->String, ObjDesc->Integer.Value);
    }
    else
    {
        ACPI_STRCPY (Hid->String, ObjDesc->String.Pointer);
    }

    Hid->Length = Length;
    *ReturnId = Hid;


Cleanup:

    /* On exit, we must delete the return object */

    AcpiUtRemoveReference (ObjDesc);
    return_ACPI_STATUS (Status);
}
예제 #27
0
ACPI_STATUS
AcpiUtExecute_CID (
    ACPI_NAMESPACE_NODE     *DeviceNode,
    ACPI_PNP_DEVICE_ID_LIST **ReturnCidList)
{
    ACPI_OPERAND_OBJECT     **CidObjects;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_PNP_DEVICE_ID_LIST *CidList;
    char                    *NextIdString;
    UINT32                  StringAreaSize;
    UINT32                  Length;
    UINT32                  CidListSize;
    ACPI_STATUS             Status;
    UINT32                  Count;
    UINT32                  i;


    ACPI_FUNCTION_TRACE (UtExecute_CID);


    /* Evaluate the _CID method for this device */

    Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__CID,
                                   ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
                                   &ObjDesc);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * Get the count and size of the returned _CIDs. _CID can return either
     * a Package of Integers/Strings or a single Integer or String.
     * Note: This section also validates that all CID elements are of the
     * correct type (Integer or String).
     */
    if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
    {
        Count = ObjDesc->Package.Count;
        CidObjects = ObjDesc->Package.Elements;
    }
    else /* Single Integer or String CID */
    {
        Count = 1;
        CidObjects = &ObjDesc;
    }

    StringAreaSize = 0;
    for (i = 0; i < Count; i++)
    {
        /* String lengths include null terminator */

        switch (CidObjects[i]->Common.Type)
        {
        case ACPI_TYPE_INTEGER:

            StringAreaSize += ACPI_EISAID_STRING_SIZE;
            break;

        case ACPI_TYPE_STRING:

            StringAreaSize += CidObjects[i]->String.Length + 1;
            break;

        default:

            Status = AE_TYPE;
            goto Cleanup;
        }
    }

    /*
     * Now that we know the length of the CIDs, allocate return buffer:
     * 1) Size of the base structure +
     * 2) Size of the CID PNP_DEVICE_ID array +
     * 3) Size of the actual CID strings
     */
    CidListSize = sizeof (ACPI_PNP_DEVICE_ID_LIST) +
                  ((Count - 1) * sizeof (ACPI_PNP_DEVICE_ID)) +
                  StringAreaSize;

    CidList = ACPI_ALLOCATE_ZEROED (CidListSize);
    if (!CidList)
    {
        Status = AE_NO_MEMORY;
        goto Cleanup;
    }

    /* Area for CID strings starts after the CID PNP_DEVICE_ID array */

    NextIdString = ACPI_CAST_PTR (char, CidList->Ids) +
                   ((ACPI_SIZE) Count * sizeof (ACPI_PNP_DEVICE_ID));

    /* Copy/convert the CIDs to the return buffer */

    for (i = 0; i < Count; i++)
    {
        if (CidObjects[i]->Common.Type == ACPI_TYPE_INTEGER)
        {
            /* Convert the Integer (EISAID) CID to a string */

            AcpiExEisaIdToString (NextIdString, CidObjects[i]->Integer.Value);
            Length = ACPI_EISAID_STRING_SIZE;
        }
        else /* ACPI_TYPE_STRING */
        {
            /* Copy the String CID from the returned object */

            ACPI_STRCPY (NextIdString, CidObjects[i]->String.Pointer);
            Length = CidObjects[i]->String.Length + 1;
        }

        CidList->Ids[i].String = NextIdString;
        CidList->Ids[i].Length = Length;
        NextIdString += Length;
    }

    /* Finish the CID list */

    CidList->Count = Count;
    CidList->ListSize = CidListSize;
    *ReturnCidList = CidList;


Cleanup:

    /* On exit, we must delete the _CID return object */

    AcpiUtRemoveReference (ObjDesc);
    return_ACPI_STATUS (Status);
}
예제 #28
0
파일: dbexec.c 프로젝트: Lxg1582/freebsd
void
AcpiDbExecute (
    char                    *Name,
    char                    **Args,
    ACPI_OBJECT_TYPE        *Types,
    UINT32                  Flags)
{
    ACPI_STATUS             Status;
    ACPI_BUFFER             ReturnObj;
    char                    *NameString;


#ifdef ACPI_DEBUG_OUTPUT
    UINT32                  PreviousAllocations;
    UINT32                  Allocations;


    /* Memory allocation tracking */

    PreviousAllocations = AcpiDbGetOutstandingAllocations ();
#endif

    if (*Name == '*')
    {
        (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT,
                    ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL);
        return;
    }
    else
    {
        NameString = ACPI_ALLOCATE (ACPI_STRLEN (Name) + 1);
        if (!NameString)
        {
            return;
        }

        ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO));

        ACPI_STRCPY (NameString, Name);
        AcpiUtStrupr (NameString);
        AcpiGbl_DbMethodInfo.Name = NameString;
        AcpiGbl_DbMethodInfo.Args = Args;
        AcpiGbl_DbMethodInfo.Types = Types;
        AcpiGbl_DbMethodInfo.Flags = Flags;

        ReturnObj.Pointer = NULL;
        ReturnObj.Length = ACPI_ALLOCATE_BUFFER;

        Status = AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo);
        if (ACPI_FAILURE (Status))
        {
            ACPI_FREE (NameString);
            return;
        }

        /* Get the NS node, determines existence also */

        Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname,
            &AcpiGbl_DbMethodInfo.Method);
        if (ACPI_SUCCESS (Status))
        {
            Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj);
        }
        ACPI_FREE (NameString);
    }

    /*
     * Allow any handlers in separate threads to complete.
     * (Such as Notify handlers invoked from AML executed above).
     */
    AcpiOsSleep ((UINT64) 10);

#ifdef ACPI_DEBUG_OUTPUT

    /* Memory allocation tracking */

    Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations;

    AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);

    if (Allocations > 0)
    {
        AcpiOsPrintf ("0x%X Outstanding allocations after evaluation of %s\n",
                        Allocations, AcpiGbl_DbMethodInfo.Pathname);
    }
#endif

    if (ACPI_FAILURE (Status))
    {
        AcpiOsPrintf ("Evaluation of %s failed with status %s\n",
            AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status));
    }
    else
    {
        /* Display a return object, if any */

        if (ReturnObj.Length)
        {
            AcpiOsPrintf (
                "Evaluation of %s returned object %p, external buffer length %X\n",
                AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer,
                (UINT32) ReturnObj.Length);
            AcpiDbDumpExternalObject (ReturnObj.Pointer, 1);

            /* Dump a _PLD buffer if present */

            if (ACPI_COMPARE_NAME ((ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
                    AcpiGbl_DbMethodInfo.Method)->Name.Ascii), METHOD_NAME__PLD))
            {
                AcpiDbDumpPldBuffer (ReturnObj.Pointer);
            }
        }
        else
        {
            AcpiOsPrintf ("No object was returned from evaluation of %s\n",
                AcpiGbl_DbMethodInfo.Pathname);
        }
    }

    AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
}
예제 #29
0
acpi_status
acpi_ex_do_concatenate (
	union acpi_operand_object       *obj_desc1,
	union acpi_operand_object       *obj_desc2,
	union acpi_operand_object       **actual_return_desc,
	struct acpi_walk_state          *walk_state)
{
	acpi_status                     status;
	u32                             i;
	acpi_integer                    this_integer;
	union acpi_operand_object       *return_desc;
	char                            *new_buf;


	ACPI_FUNCTION_ENTRY ();


	/*
	 * There are three cases to handle:
	 *
	 * 1) Two Integers concatenated to produce a new Buffer
	 * 2) Two Strings concatenated to produce a new String
	 * 3) Two Buffers concatenated to produce a new Buffer
	 */
	switch (ACPI_GET_OBJECT_TYPE (obj_desc1)) {
	case ACPI_TYPE_INTEGER:

		/* Result of two Integers is a Buffer */
		/* Need enough buffer space for two integers */

		return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width * 2);
		if (!return_desc) {
			return (AE_NO_MEMORY);
		}

		new_buf = (char *) return_desc->buffer.pointer;

		/* Convert the first integer */

		this_integer = obj_desc1->integer.value;
		for (i = 0; i < acpi_gbl_integer_byte_width; i++) {
			new_buf[i] = (char) this_integer;
			this_integer >>= 8;
		}

		/* Convert the second integer */

		this_integer = obj_desc2->integer.value;
		for (; i < (ACPI_MUL_2 (acpi_gbl_integer_byte_width)); i++) {
			new_buf[i] = (char) this_integer;
			this_integer >>= 8;
		}

		break;


	case ACPI_TYPE_STRING:

		/* Result of two Strings is a String */

		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
		if (!return_desc) {
			return (AE_NO_MEMORY);
		}

		/* Operand0 is string  */

		new_buf = ACPI_MEM_CALLOCATE ((acpi_size) obj_desc1->string.length +
				   (acpi_size) obj_desc2->string.length + 1);
		if (!new_buf) {
			ACPI_REPORT_ERROR
				(("ex_do_concatenate: String allocation failure\n"));
			status = AE_NO_MEMORY;
			goto cleanup;
		}

		/* Concatenate the strings */

		ACPI_STRCPY (new_buf, obj_desc1->string.pointer);
		ACPI_STRCPY (new_buf + obj_desc1->string.length,
				  obj_desc2->string.pointer);

		/* Complete the String object initialization */

		return_desc->string.pointer = new_buf;
		return_desc->string.length = obj_desc1->string.length +
				   obj_desc2->string.length;
		break;


	case ACPI_TYPE_BUFFER:

		/* Result of two Buffers is a Buffer */

		return_desc = acpi_ut_create_buffer_object (
				   (acpi_size) obj_desc1->buffer.length +
				   (acpi_size) obj_desc2->buffer.length);
		if (!return_desc) {
			return (AE_NO_MEMORY);
		}

		new_buf = (char *) return_desc->buffer.pointer;

		/* Concatenate the buffers */

		ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer,
				  obj_desc1->buffer.length);
		ACPI_MEMCPY (new_buf + obj_desc1->buffer.length, obj_desc2->buffer.pointer,
				   obj_desc2->buffer.length);

		break;


	default:

		/* Invalid object type, should not happen here */

		ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n",
				ACPI_GET_OBJECT_TYPE (obj_desc1)));
		status = AE_AML_INTERNAL;
		return_desc = NULL;
	}

	*actual_return_desc = return_desc;
	return (AE_OK);


cleanup:

	acpi_ut_remove_reference (return_desc);
	return (status);
}
예제 #30
0
파일: dmextern.c 프로젝트: DonCN/haiku
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);
}