Ejemplo n.º 1
0
NATIVE_CHAR *
AcpiNsGetExternalPathname (
    ACPI_NAMESPACE_NODE     *Node)
{
    NATIVE_CHAR             *NameBuffer;
    ACPI_SIZE               Size;


    ACPI_FUNCTION_TRACE_PTR ("NsGetExternalPathname", Node);


    /* Calculate required buffer size based on depth below root */

    Size = AcpiNsGetPathnameLength (Node);

    /* Allocate a buffer to be returned to caller */

    NameBuffer = ACPI_MEM_CALLOCATE (Size);
    if (!NameBuffer)
    {
        ACPI_REPORT_ERROR (("NsGetTablePathname: allocation failure\n"));
        return_PTR (NULL);
    }

    /* Build the path in the allocated buffer */

    AcpiNsBuildExternalPath (Node, Size, NameBuffer);
    return_PTR (NameBuffer);
}
Ejemplo n.º 2
0
union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size)
{
	union acpi_operand_object *string_desc;
	char *string;

	ACPI_FUNCTION_TRACE_U32("ut_create_string_object", string_size);

	/* Create a new String object */

	string_desc = acpi_ut_create_internal_object(ACPI_TYPE_STRING);
	if (!string_desc) {
		return_PTR(NULL);
	}

	/*
	 * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
	 * NOTE: Zero-length strings are NULL terminated
	 */
	string = ACPI_MEM_CALLOCATE(string_size + 1);
	if (!string) {
		ACPI_REPORT_ERROR(("create_string: could not allocate size %X\n", (u32) string_size));
		acpi_ut_remove_reference(string_desc);
		return_PTR(NULL);
	}

	/* Complete string object initialization */

	string_desc->string.pointer = string;
	string_desc->string.length = (u32) string_size;

	/* Return the new string descriptor */

	return_PTR(string_desc);
}
Ejemplo n.º 3
0
acpi_status
acpi_ut_copy_ipackage_to_ipackage (
	acpi_operand_object     *source_obj,
	acpi_operand_object     *dest_obj,
	acpi_walk_state         *walk_state)
{
	acpi_status             status = AE_OK;


	FUNCTION_TRACE ("Ut_copy_ipackage_to_ipackage");


	dest_obj->common.type   = source_obj->common.type;
	dest_obj->package.count = source_obj->package.count;


	/*
	 * Create the object array and walk the source package tree
	 */
	dest_obj->package.elements = ACPI_MEM_CALLOCATE ((source_obj->package.count + 1) *
			 sizeof (void *));
	dest_obj->package.next_element = dest_obj->package.elements;

	if (!dest_obj->package.elements) {
		REPORT_ERROR (
			("Aml_build_copy_internal_package_object: Package allocation failure\n"));
		return_ACPI_STATUS (AE_NO_MEMORY);
	}


	status = acpi_ut_walk_package_tree (source_obj, dest_obj,
			 acpi_ut_copy_ielement_to_ielement, walk_state);

	return_ACPI_STATUS (status);
}
Ejemplo n.º 4
0
ACPI_PARSE_STATE *
AcpiPsCreateState (
    UINT8                   *Aml,
    UINT32                  AmlSize)
{
    ACPI_PARSE_STATE        *ParserState;


    FUNCTION_TRACE ("PsCreateState");


    ParserState = ACPI_MEM_CALLOCATE (sizeof (ACPI_PARSE_STATE));
    if (!ParserState)
    {
        return_PTR (NULL);
    }

    ParserState->Aml       = Aml;
    ParserState->AmlEnd    = Aml + AmlSize;
    ParserState->PkgEnd    = ParserState->AmlEnd;
    ParserState->AmlStart  = Aml;


    return_PTR (ParserState);
}
Ejemplo n.º 5
0
char *
acpi_ns_get_external_pathname (
	struct acpi_namespace_node      *node)
{
	char                            *name_buffer;
	acpi_size                       size;


	ACPI_FUNCTION_TRACE_PTR ("ns_get_external_pathname", node);


	/* Calculate required buffer size based on depth below root */

	size = acpi_ns_get_pathname_length (node);

	/* Allocate a buffer to be returned to caller */

	name_buffer = ACPI_MEM_CALLOCATE (size);
	if (!name_buffer) {
		ACPI_REPORT_ERROR (("ns_get_table_pathname: allocation failure\n"));
		return_PTR (NULL);
	}

	/* Build the path in the allocated buffer */

	acpi_ns_build_external_path (node, size, name_buffer);
	return_PTR (name_buffer);
}
Ejemplo n.º 6
0
acpi_status
acpi_ex_store_string_to_string (
	union acpi_operand_object       *source_desc,
	union acpi_operand_object       *target_desc)
{
	u32                             length;
	u8                              *buffer;


	ACPI_FUNCTION_TRACE_PTR ("ex_store_string_to_string", source_desc);


	/*
	 * We know that source_desc is a string by now.
	 */
	buffer = (u8 *) source_desc->string.pointer;
	length = source_desc->string.length;

	/*
	 * Replace existing string value if it will fit and the string
	 * pointer is not a static pointer (part of an ACPI table)
	 */
	if ((length < target_desc->string.length) &&
	   (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
		/*
		 * String will fit in existing non-static buffer.
		 * Clear old string and copy in the new one
		 */
		ACPI_MEMSET (target_desc->string.pointer, 0, (acpi_size) target_desc->string.length + 1);
		ACPI_MEMCPY (target_desc->string.pointer, buffer, length);
	}
	else {
		/*
		 * Free the current buffer, then allocate a new buffer
		 * large enough to hold the value
		 */
		if (target_desc->string.pointer &&
		   (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
			/*
			 * Only free if not a pointer into the DSDT
			 */
			ACPI_MEM_FREE (target_desc->string.pointer);
		}

		target_desc->string.pointer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1);
		if (!target_desc->string.pointer) {
			return_ACPI_STATUS (AE_NO_MEMORY);
		}

		target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
		ACPI_MEMCPY (target_desc->string.pointer, buffer, length);
	}

	/* Set the new target length */

	target_desc->string.length = length;
	return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 7
0
ACPI_STATUS
AcpiTbConvertToXsdt (
    ACPI_TABLE_DESC         *TableInfo)
{
    ACPI_SIZE               TableSize;
    UINT32                  i;
    XSDT_DESCRIPTOR         *NewTable;


    ACPI_FUNCTION_ENTRY ();


    /* Compute size of the converted XSDT */

    TableSize = ((ACPI_SIZE) AcpiGbl_RsdtTableCount * sizeof (UINT64)) +
                    sizeof (ACPI_TABLE_HEADER);

    /* Allocate an XSDT */

    NewTable = ACPI_MEM_CALLOCATE (TableSize);
    if (!NewTable)
    {
        return (AE_NO_MEMORY);
    }

    /* Copy the header and set the length */

    ACPI_MEMCPY (NewTable, TableInfo->Pointer, sizeof (ACPI_TABLE_HEADER));
    NewTable->Header.Length = (UINT32) TableSize;

    /* Copy the table pointers */

    for (i = 0; i < AcpiGbl_RsdtTableCount; i++)
    {
        if (AcpiGbl_RSDP->Revision < 2)
        {
            ACPI_STORE_ADDRESS (NewTable->TableOffsetEntry[i],
                ((RSDT_DESCRIPTOR_REV1 *) TableInfo->Pointer)->TableOffsetEntry[i]);
        }
        else
        {
            NewTable->TableOffsetEntry[i] =
                ((XSDT_DESCRIPTOR *) TableInfo->Pointer)->TableOffsetEntry[i];
        }
    }

    /* Delete the original table (either mapped or in a buffer) */

    AcpiTbDeleteSingleTable (TableInfo);

    /* Point the table descriptor to the new table */

    TableInfo->Pointer      = (ACPI_TABLE_HEADER *) NewTable;
    TableInfo->Length       = TableSize;
    TableInfo->Allocation   = ACPI_MEM_ALLOCATED;

    return (AE_OK);
}
Ejemplo n.º 8
0
void *
AcpiUtAcquireFromCache (
    UINT32                  ListId)
{
    ACPI_MEMORY_LIST        *CacheInfo;
    void                    *Object;


    PROC_NAME ("UtAcquireFromCache");


    CacheInfo = &AcpiGbl_MemoryLists[ListId];
    AcpiUtAcquireMutex (ACPI_MTX_CACHES);
    ACPI_MEM_TRACKING (CacheInfo->CacheRequests++);

    /* Check the cache first */

    if (CacheInfo->ListHead)
    {
        /* There is an object available, use it */

        Object = CacheInfo->ListHead;
        CacheInfo->ListHead = * (char **) (((char *) Object) + CacheInfo->LinkOffset);

        ACPI_MEM_TRACKING (CacheInfo->CacheHits++);
        CacheInfo->CacheDepth--;

#ifdef ACPI_DBG_TRACK_ALLOCATIONS
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p from %s\n",
            Object, AcpiGbl_MemoryLists[ListId].ListName));
#endif

        AcpiUtReleaseMutex (ACPI_MTX_CACHES);

        /* Clear (zero) the previously used Object */

        MEMSET (Object, 0, CacheInfo->ObjectSize);
    }

    else
    {
        /* The cache is empty, create a new object */

        /* Avoid deadlock with ACPI_MEM_CALLOCATE */

        AcpiUtReleaseMutex (ACPI_MTX_CACHES);

        Object = ACPI_MEM_CALLOCATE (CacheInfo->ObjectSize);
        ACPI_MEM_TRACKING (CacheInfo->TotalAllocated++);
    }

    return (Object);
}
Ejemplo n.º 9
0
acpi_status
acpi_ns_internalize_name (
	NATIVE_CHAR             *external_name,
	NATIVE_CHAR             **converted_name)
{
	NATIVE_CHAR             *internal_name;
	acpi_namestring_info    info;
	acpi_status             status;


	FUNCTION_TRACE ("Ns_internalize_name");


	if ((!external_name)     ||
		(*external_name == 0) ||
		(!converted_name)) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}


	/* Get the length of the new internal name */

	info.external_name = external_name;
	acpi_ns_get_internal_name_length (&info);

	/* We need a segment to store the internal  name */

	internal_name = ACPI_MEM_CALLOCATE (info.length);
	if (!internal_name) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/* Build the name */

	info.internal_name = internal_name;
	status = acpi_ns_build_internal_name (&info);
	if (ACPI_FAILURE (status)) {
		ACPI_MEM_FREE (internal_name);
		return_ACPI_STATUS (status);
	}

	*converted_name = internal_name;
	return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 10
0
acpi_status
acpi_ut_copy_ipackage_to_ipackage (
	union acpi_operand_object       *source_obj,
	union acpi_operand_object       *dest_obj,
	struct acpi_walk_state          *walk_state)
{
	acpi_status                     status = AE_OK;


	ACPI_FUNCTION_TRACE ("ut_copy_ipackage_to_ipackage");


	dest_obj->common.type   = ACPI_GET_OBJECT_TYPE (source_obj);
	dest_obj->common.flags  = source_obj->common.flags;
	dest_obj->package.count = source_obj->package.count;

	/*
	 * Create the object array and walk the source package tree
	 */
	dest_obj->package.elements = ACPI_MEM_CALLOCATE (
			   ((acpi_size) source_obj->package.count + 1) *
			   sizeof (void *));
	if (!dest_obj->package.elements) {
		ACPI_REPORT_ERROR (
			("aml_build_copy_internal_package_object: Package allocation failure\n"));
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/*
	 * Copy the package element-by-element by walking the package "tree".
	 * This handles nested packages of arbitrary depth.
	 */
	status = acpi_ut_walk_package_tree (source_obj, dest_obj,
			 acpi_ut_copy_ielement_to_ielement, walk_state);
	if (ACPI_FAILURE (status)) {
		/* On failure, delete the destination package object */

		acpi_ut_remove_reference (dest_obj);
	}

	return_ACPI_STATUS (status);
}
Ejemplo n.º 11
0
union acpi_operand_object *
acpi_ut_create_buffer_object (
	acpi_size                       buffer_size)
{
	union acpi_operand_object       *buffer_desc;
	u8                              *buffer = NULL;


	ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size);


	/* Create a new Buffer object */

	buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
	if (!buffer_desc) {
		return_PTR (NULL);
	}

	/* Create an actual buffer only if size > 0 */

	if (buffer_size > 0) {
		/* Allocate the actual buffer */

		buffer = ACPI_MEM_CALLOCATE (buffer_size);
		if (!buffer) {
			ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n",
				(u32) buffer_size));
			acpi_ut_remove_reference (buffer_desc);
			return_PTR (NULL);
		}
	}

	/* Complete buffer object initialization */

	buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID;
	buffer_desc->buffer.pointer = buffer;
	buffer_desc->buffer.length = (u32) buffer_size;

	/* Return the new buffer descriptor */

	return_PTR (buffer_desc);
}
Ejemplo n.º 12
0
ACPI_OPERAND_OBJECT *
AcpiUtCreateBufferObject (
    ACPI_SIZE               BufferSize)
{
    ACPI_OPERAND_OBJECT     *BufferDesc;
    UINT8                   *Buffer;


    ACPI_FUNCTION_TRACE_U32 ("UtCreateBufferObject", BufferSize);


    /*
     * Create a new Buffer object
     */
    BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_BUFFER);
    if (!BufferDesc)
    {
        return_PTR (NULL);
    }

    /* Allocate the actual buffer */

    Buffer = ACPI_MEM_CALLOCATE (BufferSize);
    if (!Buffer)
    {
        ACPI_REPORT_ERROR (("CreateBuffer: could not allocate size %X\n", 
            (UINT32) BufferSize));
        AcpiUtRemoveReference (BufferDesc);
        return_PTR (NULL);
    }

    /* Complete buffer object initialization */

    BufferDesc->Buffer.Flags |= AOPOBJ_DATA_VALID;
    BufferDesc->Buffer.Pointer = Buffer;
    BufferDesc->Buffer.Length = (UINT32) BufferSize;

    /* Return the new buffer descriptor */

    return_PTR (BufferDesc);
}
Ejemplo n.º 13
0
ACPI_STATUS
AcpiEvSystemMemoryRegionSetup (
    ACPI_HANDLE             Handle,
    UINT32                  Function,
    void                    *HandlerContext,
    void                    **RegionContext)
{
    ACPI_OPERAND_OBJECT     *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle;
    ACPI_MEM_SPACE_CONTEXT  *LocalRegionContext;


    ACPI_FUNCTION_TRACE ("EvSystemMemoryRegionSetup");


    if (Function == ACPI_REGION_DEACTIVATE)
    {
        if (*RegionContext)
        {
            ACPI_MEM_FREE (*RegionContext);
            *RegionContext = NULL;
        }
        return_ACPI_STATUS (AE_OK);
    }

    /* Create a new context */

    LocalRegionContext = ACPI_MEM_CALLOCATE (sizeof (ACPI_MEM_SPACE_CONTEXT));
    if (!(LocalRegionContext))
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Save the region length and address for use in the handler */

    LocalRegionContext->Length  = RegionDesc->Region.Length;
    LocalRegionContext->Address = RegionDesc->Region.Address;

    *RegionContext = LocalRegionContext;
    return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 14
0
struct acpi_namespace_node *
acpi_ns_create_node (
	u32                             name)
{
	struct acpi_namespace_node      *node;


	ACPI_FUNCTION_TRACE ("ns_create_node");


	node = ACPI_MEM_CALLOCATE (sizeof (struct acpi_namespace_node));
	if (!node) {
		return_PTR (NULL);
	}

	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_allocated++);

	node->name.integer   = name;
	node->reference_count = 1;
	ACPI_SET_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED);

	return_PTR (node);
}
Ejemplo n.º 15
0
acpi_status
acpi_tb_convert_to_xsdt (
	struct acpi_table_desc          *table_info)
{
	acpi_size                       table_size;
	u32                             i;
	XSDT_DESCRIPTOR         *new_table;


	ACPI_FUNCTION_ENTRY ();


	/* Compute size of the converted XSDT */

	table_size = ((acpi_size) acpi_gbl_rsdt_table_count * sizeof (u64)) +
			  sizeof (struct acpi_table_header);

	/* Allocate an XSDT */

	new_table = ACPI_MEM_CALLOCATE (table_size);
	if (!new_table) {
		return (AE_NO_MEMORY);
	}

	/* Copy the header and set the length */

	ACPI_MEMCPY (new_table, table_info->pointer, sizeof (struct acpi_table_header));
	new_table->length = (u32) table_size;

	/* Copy the table pointers */

	for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
		if (acpi_gbl_RSDP->revision < 2) {
			ACPI_STORE_ADDRESS (new_table->table_offset_entry[i],
				(ACPI_CAST_PTR (struct rsdt_descriptor_rev1, table_info->pointer))->table_offset_entry[i]);
		}
		else {
Ejemplo n.º 16
0
acpi_status
acpi_ev_system_memory_region_setup (
	acpi_handle                     handle,
	u32                             function,
	void                            *handler_context,
	void                            **region_context)
{
	union acpi_operand_object       *region_desc = (union acpi_operand_object *) handle;
	struct acpi_mem_space_context   *local_region_context;


	ACPI_FUNCTION_TRACE ("ev_system_memory_region_setup");


	if (function == ACPI_REGION_DEACTIVATE) {
		if (*region_context) {
			ACPI_MEM_FREE (*region_context);
			*region_context = NULL;
		}
		return_ACPI_STATUS (AE_OK);
	}

	/* Create a new context */

	local_region_context = ACPI_MEM_CALLOCATE (sizeof (struct acpi_mem_space_context));
	if (!(local_region_context)) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/* Save the region length and address for use in the handler */

	local_region_context->length = region_desc->region.length;
	local_region_context->address = region_desc->region.address;

	*region_context = local_region_context;
	return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 17
0
static struct acpi_gpe_xrupt_info *
acpi_ev_get_gpe_xrupt_block (
	u32                             interrupt_level)
{
	struct acpi_gpe_xrupt_info      *next_gpe_xrupt;
	struct acpi_gpe_xrupt_info      *gpe_xrupt;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("ev_get_gpe_xrupt_block");


	/* No need for spin lock since we are not changing any list elements here */

	next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
	while (next_gpe_xrupt) {
		if (next_gpe_xrupt->interrupt_level == interrupt_level) {
			return_PTR (next_gpe_xrupt);
		}

		next_gpe_xrupt = next_gpe_xrupt->next;
	}

	/* Not found, must allocate a new xrupt descriptor */

	gpe_xrupt = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_xrupt_info));
	if (!gpe_xrupt) {
		return_PTR (NULL);
	}

	gpe_xrupt->interrupt_level = interrupt_level;

	/* Install new interrupt descriptor with spin lock */

	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
	if (acpi_gbl_gpe_xrupt_list_head) {
		next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
		while (next_gpe_xrupt->next) {
			next_gpe_xrupt = next_gpe_xrupt->next;
		}

		next_gpe_xrupt->next = gpe_xrupt;
		gpe_xrupt->previous = next_gpe_xrupt;
	}
	else {
		acpi_gbl_gpe_xrupt_list_head = gpe_xrupt;
	}
	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);

	/* Install new interrupt handler if not SCI_INT */

	if (interrupt_level != acpi_gbl_FADT->sci_int) {
		status = acpi_os_install_interrupt_handler (interrupt_level,
				 acpi_ev_gpe_xrupt_handler, gpe_xrupt);
		if (ACPI_FAILURE (status)) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Could not install GPE interrupt handler at level 0x%X\n",
				interrupt_level));
			return_PTR (NULL);
		}
	}

	return_PTR (gpe_xrupt);
}
Ejemplo n.º 18
0
acpi_status
acpi_tb_init_table_descriptor (
    acpi_table_type         table_type,
    acpi_table_desc         *table_info)
{
    acpi_table_desc         *list_head;
    acpi_table_desc         *table_desc;


    FUNCTION_TRACE_U32 ("Tb_init_table_descriptor", table_type);

    /*
     * Install the table into the global data structure
     */
    list_head   = &acpi_gbl_acpi_tables[table_type];
    table_desc  = list_head;


    /*
     * Two major types of tables:  1) Only one instance is allowed.  This
     * includes most ACPI tables such as the DSDT.  2) Multiple instances of
     * the table are allowed.  This includes SSDT and PSDTs.
     */
    if (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags)) {
        /*
         * Only one table allowed, and a table has alread been installed
         *  at this location, so return an error.
         */
        if (list_head->pointer) {
            return_ACPI_STATUS (AE_EXIST);
        }

        table_desc->count = 1;
    }


    else {
        /*
         * Multiple tables allowed for this table type, we must link
         * the new table in to the list of tables of this type.
         */
        if (list_head->pointer) {
            table_desc = ACPI_MEM_CALLOCATE (sizeof (acpi_table_desc));
            if (!table_desc) {
                return_ACPI_STATUS (AE_NO_MEMORY);
            }

            list_head->count++;

            /* Update the original previous */

            list_head->prev->next = table_desc;

            /* Update new entry */

            table_desc->prev = list_head->prev;
            table_desc->next = list_head;

            /* Update list head */

            list_head->prev = table_desc;
        }

        else {
            table_desc->count = 1;
        }
    }


    /* Common initialization of the table descriptor */

    table_desc->pointer             = table_info->pointer;
    table_desc->base_pointer        = table_info->base_pointer;
    table_desc->length              = table_info->length;
    table_desc->allocation          = table_info->allocation;
    table_desc->aml_start           = (u8 *) (table_desc->pointer + 1),
                table_desc->aml_length          = (u32) (table_desc->length -
                        (u32) sizeof (acpi_table_header));
    table_desc->table_id            = acpi_ut_allocate_owner_id (OWNER_TYPE_TABLE);
    table_desc->loaded_into_namespace = FALSE;

    /*
     * Set the appropriate global pointer (if there is one) to point to the
     * newly installed table
     */
    if (acpi_gbl_acpi_table_data[table_type].global_ptr) {
        *(acpi_gbl_acpi_table_data[table_type].global_ptr) = table_info->pointer;
    }


    /* Return Data */

    table_info->table_id        = table_desc->table_id;
    table_info->installed_desc  = table_desc;

    return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 19
0
ACPI_STATUS
AcpiRsSetSrsMethodData (
    ACPI_HANDLE             Handle,
    ACPI_BUFFER             *InBuffer)
{
    ACPI_OPERAND_OBJECT     *Params[2];
    ACPI_OPERAND_OBJECT     ParamObj;
    ACPI_STATUS             Status;
    UINT8                   *ByteStream = NULL;
    UINT32                  BufferSizeNeeded = 0;


    FUNCTION_TRACE ("RsSetSrsMethodData");


    /* already validated params, so we won't repeat here */

    /*
     * The InBuffer parameter will point to a linked list of
     * resource parameters.  It needs to be formatted into a
     * byte stream to be sent in as an input parameter.
     */
    BufferSizeNeeded = 0;

    /*
     * First call is to get the buffer size needed
     */
    Status = AcpiRsCreateByteStream (InBuffer->Pointer, ByteStream,
                &BufferSizeNeeded);
    /*
     * We expect a return of AE_BUFFER_OVERFLOW
     * if not, exit with the error
     */
    if (AE_BUFFER_OVERFLOW != Status)
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * Allocate the buffer needed
     */
    ByteStream = ACPI_MEM_CALLOCATE (BufferSizeNeeded);
    if (NULL == ByteStream)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /*
     * Now call to convert the linked list into a byte stream
     */
    Status = AcpiRsCreateByteStream (InBuffer->Pointer, ByteStream,
                &BufferSizeNeeded);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    /*
     * Init the param object
     */
    AcpiUtInitStaticObject (&ParamObj);

    /*
     * Method requires one parameter.  Set it up
     */
    Params [0] = &ParamObj;
    Params [1] = NULL;

    /*
     *  Set up the parameter object
     */
    ParamObj.Common.Type    = ACPI_TYPE_BUFFER;
    ParamObj.Buffer.Length  = BufferSizeNeeded;
    ParamObj.Buffer.Pointer = ByteStream;

    /*
     * Execute the method, no return value
     */
    Status = AcpiNsEvaluateRelative (Handle, "_SRS", Params, NULL);

    /*
     * Clean up and return the status from AcpiNsEvaluateRelative
     */
Cleanup:

    ACPI_MEM_FREE (ByteStream);
    return_ACPI_STATUS (Status);
}
Ejemplo n.º 20
0
acpi_status
acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
{
	acpi_status status;
	struct acpi_namespace_node *node;
	struct acpi_device_info *info;
	struct acpi_device_info *return_info;
	struct acpi_compatible_id_list *cid_list = NULL;
	acpi_size size;

	/* Parameter validation */

	if (!handle || !buffer) {
		return (AE_BAD_PARAMETER);
	}

	status = acpi_ut_validate_buffer(buffer);
	if (ACPI_FAILURE(status)) {
		return (status);
	}

	info = ACPI_MEM_CALLOCATE(sizeof(struct acpi_device_info));
	if (!info) {
		return (AE_NO_MEMORY);
	}

	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
		goto cleanup;
	}

	node = acpi_ns_map_handle_to_node(handle);
	if (!node) {
		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
		goto cleanup;
	}

	/* Init return structure */

	size = sizeof(struct acpi_device_info);

	info->type = node->type;
	info->name = node->name.integer;
	info->valid = 0;

	status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
	if (ACPI_FAILURE(status)) {
		goto cleanup;
	}

	/* If not a device, we are all done */

	if (info->type == ACPI_TYPE_DEVICE) {
		/*
		 * Get extra info for ACPI Devices objects only:
		 * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods.
		 *
		 * Note: none of these methods are required, so they may or may
		 * not be present for this device.  The Info->Valid bitfield is used
		 * to indicate which methods were found and ran successfully.
		 */

		/* Execute the Device._HID method */

		status = acpi_ut_execute_HID(node, &info->hardware_id);
		if (ACPI_SUCCESS(status)) {
			info->valid |= ACPI_VALID_HID;
		}

		/* Execute the Device._UID method */

		status = acpi_ut_execute_UID(node, &info->unique_id);
		if (ACPI_SUCCESS(status)) {
			info->valid |= ACPI_VALID_UID;
		}

		/* Execute the Device._CID method */

		status = acpi_ut_execute_CID(node, &cid_list);
		if (ACPI_SUCCESS(status)) {
			size += ((acpi_size) cid_list->count - 1) *
			    sizeof(struct acpi_compatible_id);
			info->valid |= ACPI_VALID_CID;
		}

		/* Execute the Device._STA method */

		status = acpi_ut_execute_STA(node, &info->current_status);
		if (ACPI_SUCCESS(status)) {
			info->valid |= ACPI_VALID_STA;
		}

		/* Execute the Device._ADR method */

		status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node,
							 &info->address);
		if (ACPI_SUCCESS(status)) {
			info->valid |= ACPI_VALID_ADR;
		}

		/* Execute the Device._sx_d methods */

		status = acpi_ut_execute_sxds(node, info->highest_dstates);
		if (ACPI_SUCCESS(status)) {
			info->valid |= ACPI_VALID_SXDS;
		}
	}

	/* Validate/Allocate/Clear caller buffer */

	status = acpi_ut_initialize_buffer(buffer, size);
	if (ACPI_FAILURE(status)) {
		goto cleanup;
	}

	/* Populate the return buffer */

	return_info = buffer->pointer;
	ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info));

	if (cid_list) {
		ACPI_MEMCPY(&return_info->compatibility_id, cid_list,
			    cid_list->size);
	}

      cleanup:
	ACPI_MEM_FREE(info);
	if (cid_list) {
		ACPI_MEM_FREE(cid_list);
	}
	return (status);
}
Ejemplo n.º 21
0
ACPI_STATUS
AcpiTbConvertTableFadt (void)
{
    FADT_DESCRIPTOR_REV2   *LocalFadt;
    ACPI_TABLE_DESC        *TableDesc;


    ACPI_FUNCTION_TRACE ("TbConvertTableFadt");


    /*
     * AcpiGbl_FADT is valid
     * Allocate and zero the 2.0 FADT buffer
     */
    LocalFadt = ACPI_MEM_CALLOCATE (sizeof (FADT_DESCRIPTOR_REV2));
    if (LocalFadt == NULL)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /*
     * FADT length and version validation.  The table must be at least as
     * long as the version 1.0 FADT
     */
    if (AcpiGbl_FADT->Header.Length < sizeof (FADT_DESCRIPTOR_REV1))
    {
        ACPI_REPORT_ERROR (("Invalid FADT table length: 0x%X\n", AcpiGbl_FADT->Header.Length));
        return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
    }

    if (AcpiGbl_FADT->Header.Revision >= FADT2_REVISION_ID)
    {
        if (AcpiGbl_FADT->Header.Length < sizeof (FADT_DESCRIPTOR_REV2))
        {
            /* Length is too short to be a V2.0 table */

            ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n",
                        AcpiGbl_FADT->Header.Length, AcpiGbl_FADT->Header.Revision));

            AcpiTbConvertFadt1 (LocalFadt, (void *) AcpiGbl_FADT);
        }
        else
        {
            /* Valid V2.0 table */

            AcpiTbConvertFadt2 (LocalFadt, AcpiGbl_FADT);
        }
    }
    else
    {
        /* Valid V1.0 table */

        AcpiTbConvertFadt1 (LocalFadt, (void *) AcpiGbl_FADT);
    }

    /*
     * Global FADT pointer will point to the new common V2.0 FADT
     */
    AcpiGbl_FADT = LocalFadt;
    AcpiGbl_FADT->Header.Length = sizeof (FADT_DESCRIPTOR);

    /* Free the original table */

    TableDesc = &AcpiGbl_AcpiTables[ACPI_TABLE_FADT];
    AcpiTbDeleteSingleTable (TableDesc);

    /* Install the new table */

    TableDesc->Pointer      = (ACPI_TABLE_HEADER *) AcpiGbl_FADT;
    TableDesc->Allocation   = ACPI_MEM_ALLOCATED;
    TableDesc->Length       = sizeof (FADT_DESCRIPTOR_REV2);

    /* Dump the entire FADT */

    ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
        "Hex dump of common internal FADT, size %d (%X)\n",
        AcpiGbl_FADT->Header.Length, AcpiGbl_FADT->Header.Length));
    ACPI_DUMP_BUFFER ((UINT8 *) (AcpiGbl_FADT), AcpiGbl_FADT->Header.Length);

    return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 22
0
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);
}
Ejemplo n.º 23
0
acpi_status
acpi_ut_copy_ielement_to_ielement (
	u8                              object_type,
	union acpi_operand_object       *source_object,
	union acpi_generic_state        *state,
	void                            *context)
{
	acpi_status                     status = AE_OK;
	u32                             this_index;
	union acpi_operand_object       **this_target_ptr;
	union acpi_operand_object       *target_object;


	ACPI_FUNCTION_ENTRY ();


	this_index    = state->pkg.index;
	this_target_ptr = (union acpi_operand_object **)
			   &state->pkg.dest_object->package.elements[this_index];

	switch (object_type) {
	case ACPI_COPY_TYPE_SIMPLE:

		/* A null source object indicates a (legal) null package element */

		if (source_object) {
			/*
			 * This is a simple object, just copy it
			 */
			target_object = acpi_ut_create_internal_object (
					   ACPI_GET_OBJECT_TYPE (source_object));
			if (!target_object) {
				return (AE_NO_MEMORY);
			}

			status = acpi_ut_copy_simple_object (source_object, target_object);
			if (ACPI_FAILURE (status)) {
				goto error_exit;
			}

			*this_target_ptr = target_object;
		}
		else {
			/* Pass through a null element */

			*this_target_ptr = NULL;
		}
		break;


	case ACPI_COPY_TYPE_PACKAGE:

		/*
		 * This object is a package - go down another nesting level
		 * Create and build the package object
		 */
		target_object = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
		if (!target_object) {
			return (AE_NO_MEMORY);
		}

		target_object->package.count = source_object->package.count;
		target_object->common.flags = source_object->common.flags;

		/*
		 * Create the object array
		 */
		target_object->package.elements =
			ACPI_MEM_CALLOCATE (((acpi_size) source_object->package.count + 1) *
					 sizeof (void *));
		if (!target_object->package.elements) {
			status = AE_NO_MEMORY;
			goto error_exit;
		}

		/*
		 * Pass the new package object back to the package walk routine
		 */
		state->pkg.this_target_obj = target_object;

		/*
		 * Store the object pointer in the parent package object
		 */
		*this_target_ptr = target_object;
		break;


	default:
		return (AE_BAD_PARAMETER);
	}

	return (status);

error_exit:
	acpi_ut_remove_reference (target_object);
	return (status);
}
Ejemplo n.º 24
0
acpi_status
acpi_ut_copy_esimple_to_isimple (
	union acpi_object               *external_object,
	union acpi_operand_object       **ret_internal_object)
{
	union acpi_operand_object       *internal_object;


	ACPI_FUNCTION_TRACE ("ut_copy_esimple_to_isimple");


	/*
	 * Simple types supported are: String, Buffer, Integer
	 */
	switch (external_object->type) {
	case ACPI_TYPE_STRING:
	case ACPI_TYPE_BUFFER:
	case ACPI_TYPE_INTEGER:

		internal_object = acpi_ut_create_internal_object ((u8) external_object->type);
		if (!internal_object) {
			return_ACPI_STATUS (AE_NO_MEMORY);
		}
		break;

	default:
		/* All other types are not supported */

		return_ACPI_STATUS (AE_SUPPORT);
	}


	/* Must COPY string and buffer contents */

	switch (external_object->type) {
	case ACPI_TYPE_STRING:

		internal_object->string.pointer =
			ACPI_MEM_CALLOCATE ((acpi_size) external_object->string.length + 1);
		if (!internal_object->string.pointer) {
			goto error_exit;
		}

		ACPI_MEMCPY (internal_object->string.pointer,
				  external_object->string.pointer,
				  external_object->string.length);

		internal_object->string.length = external_object->string.length;
		break;


	case ACPI_TYPE_BUFFER:

		internal_object->buffer.pointer =
			ACPI_MEM_CALLOCATE (external_object->buffer.length);
		if (!internal_object->buffer.pointer) {
			goto error_exit;
		}

		ACPI_MEMCPY (internal_object->buffer.pointer,
				  external_object->buffer.pointer,
				  external_object->buffer.length);

		internal_object->buffer.length = external_object->buffer.length;
		break;


	case ACPI_TYPE_INTEGER:

		internal_object->integer.value  = external_object->integer.value;
		break;

	default:
		/* Other types can't get here */
		break;
	}

	*ret_internal_object = internal_object;
	return_ACPI_STATUS (AE_OK);


error_exit:
	acpi_ut_remove_reference (internal_object);
	return_ACPI_STATUS (AE_NO_MEMORY);
}
Ejemplo n.º 25
0
acpi_status
acpi_ev_create_gpe_block (
	struct acpi_namespace_node      *gpe_device,
	struct acpi_generic_address     *gpe_block_address,
	u32                             register_count,
	u8                              gpe_block_base_number,
	u32                             interrupt_level,
	struct acpi_gpe_block_info      **return_gpe_block)
{
	struct acpi_gpe_block_info      *gpe_block;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("ev_create_gpe_block");


	if (!register_count) {
		return_ACPI_STATUS (AE_OK);
	}

	/* Allocate a new GPE block */

	gpe_block = ACPI_MEM_CALLOCATE (sizeof (struct acpi_gpe_block_info));
	if (!gpe_block) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/* Initialize the new GPE block */

	gpe_block->register_count = register_count;
	gpe_block->block_base_number = gpe_block_base_number;

	ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address));

	/* Create the register_info and event_info sub-structures */

	status = acpi_ev_create_gpe_info_blocks (gpe_block);
	if (ACPI_FAILURE (status)) {
		ACPI_MEM_FREE (gpe_block);
		return_ACPI_STATUS (status);
	}

	/* Install the new block in the global list(s) */

	status = acpi_ev_install_gpe_block (gpe_block, interrupt_level);
	if (ACPI_FAILURE (status)) {
		ACPI_MEM_FREE (gpe_block);
		return_ACPI_STATUS (status);
	}

	/* Dump info about this GPE block */

	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n",
		gpe_block->block_base_number,
		(u32) (gpe_block->block_base_number +
				((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
		gpe_device->name.ascii,
		gpe_block->register_count,
		ACPI_HIDWORD (gpe_block->block_address.address),
		ACPI_LODWORD (gpe_block->block_address.address),
		interrupt_level));

	/* Find all GPE methods (_Lxx, _Exx) for this block */

	status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device,
			  ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, acpi_ev_save_method_info,
			  gpe_block, NULL);

	/* Return the new block */

	if (return_gpe_block) {
		(*return_gpe_block) = gpe_block;
	}

	return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 26
0
acpi_status
acpi_ev_pci_config_region_setup (
	acpi_handle                     handle,
	u32                             function,
	void                            *handler_context,
	void                            **region_context)
{
	acpi_status                     status = AE_OK;
	acpi_integer                    pci_value;
	struct acpi_pci_id              *pci_id = *region_context;
	union acpi_operand_object       *handler_obj;
	struct acpi_namespace_node      *parent_node;
	struct acpi_namespace_node      *pci_root_node;
	union acpi_operand_object       *region_obj = (union acpi_operand_object   *) handle;
	struct acpi_device_id           object_hID;


	ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup");


	handler_obj = region_obj->region.handler;
	if (!handler_obj) {
		/*
		 * No installed handler. This shouldn't happen because the dispatch
		 * routine checks before we get here, but we check again just in case.
		 */
		ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
			"Attempting to init a region %p, with no handler\n", region_obj));
		return_ACPI_STATUS (AE_NOT_EXIST);
	}

	*region_context = NULL;
	if (function == ACPI_REGION_DEACTIVATE) {
		if (pci_id) {
			ACPI_MEM_FREE (pci_id);
		}
		return_ACPI_STATUS (status);
	}

	parent_node = acpi_ns_get_parent_node (region_obj->region.node);

	/*
	 * Get the _SEG and _BBN values from the device upon which the handler
	 * is installed.
	 *
	 * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
	 * This is the device the handler has been registered to handle.
	 */

	/*
	 * If the address_space.Node is still pointing to the root, we need
	 * to scan upward for a PCI Root bridge and re-associate the op_region
	 * handlers with that device.
	 */
	if (handler_obj->address_space.node == acpi_gbl_root_node) {
		/* Start search from the parent object */

		pci_root_node = parent_node;
		while (pci_root_node != acpi_gbl_root_node) {
			status = acpi_ut_execute_HID (pci_root_node, &object_hID);
			if (ACPI_SUCCESS (status)) {
				/* Got a valid _HID, check if this is a PCI root */

				if (!(ACPI_STRNCMP (object_hID.value, PCI_ROOT_HID_STRING,
						   sizeof (PCI_ROOT_HID_STRING)))) {
					/* Install a handler for this PCI root bridge */

					status = acpi_install_address_space_handler ((acpi_handle) pci_root_node,
							   ACPI_ADR_SPACE_PCI_CONFIG,
							   ACPI_DEFAULT_HANDLER, NULL, NULL);
					if (ACPI_FAILURE (status)) {
						if (status == AE_SAME_HANDLER) {
							/*
							 * It is OK if the handler is already installed on the root
							 * bridge.  Still need to return a context object for the
							 * new PCI_Config operation region, however.
							 */
							status = AE_OK;
						}
						else {
							ACPI_REPORT_ERROR ((
								"Could not install pci_config handler for Root Bridge %4.4s, %s\n",
								acpi_ut_get_node_name (pci_root_node), acpi_format_exception (status)));
						}
					}
					break;
				}
			}

			pci_root_node = acpi_ns_get_parent_node (pci_root_node);
		}

		/* PCI root bridge not found, use namespace root node */
	}
	else {
		pci_root_node = handler_obj->address_space.node;
	}

	/*
	 * If this region is now initialized, we are done.
	 * (install_address_space_handler could have initialized it)
	 */
	if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
		return_ACPI_STATUS (AE_OK);
	}

	/* Region is still not initialized. Create a new context */

	pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id));
	if (!pci_id) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/*
	 * For PCI_Config space access, we need the segment, bus,
	 * device and function numbers.  Acquire them here.
	 */

	/*
	 * Get the PCI device and function numbers from the _ADR object
	 * contained in the parent's scope.
	 */
	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, parent_node, &pci_value);

	/*
	 * The default is zero, and since the allocation above zeroed
	 * the data, just do nothing on failure.
	 */
	if (ACPI_SUCCESS (status)) {
		pci_id->device  = ACPI_HIWORD (ACPI_LODWORD (pci_value));
		pci_id->function = ACPI_LOWORD (ACPI_LODWORD (pci_value));
	}

	/* The PCI segment number comes from the _SEG method */

	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, pci_root_node, &pci_value);
	if (ACPI_SUCCESS (status)) {
		pci_id->segment = ACPI_LOWORD (pci_value);
	}

	/* The PCI bus number comes from the _BBN method */

	status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, pci_root_node, &pci_value);
	if (ACPI_SUCCESS (status)) {
		pci_id->bus = ACPI_LOWORD (pci_value);
	}

	/* Complete this device's pci_id */

	acpi_os_derive_pci_id (pci_root_node, region_obj->region.node, &pci_id);

	*region_context = pci_id;
	return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 27
0
acpi_status
acpi_ns_externalize_name (
	u32                     internal_name_length,
	char                    *internal_name,
	u32                     *converted_name_length,
	char                    **converted_name)
{
	u32                     prefix_length = 0;
	u32                     names_index = 0;
	u32                     names_count = 0;
	u32                     i = 0;
	u32                     j = 0;


	FUNCTION_TRACE ("Ns_externalize_name");


	if (!internal_name_length   ||
		!internal_name          ||
		!converted_name_length  ||
		!converted_name) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}


	/*
	 * Check for a prefix (one '\' | one or more '^').
	 */
	switch (internal_name[0]) {
	case '\\':
		prefix_length = 1;
		break;

	case '^':
		for (i = 0; i < internal_name_length; i++) {
			if (internal_name[i] != '^') {
				prefix_length = i + 1;
			}
		}

		if (i == internal_name_length) {
			prefix_length = i;
		}

		break;
	}

	/*
	 * Check for object names.  Note that there could be 0-255 of these
	 * 4-byte elements.
	 */
	if (prefix_length < internal_name_length) {
		switch (internal_name[prefix_length]) {

		/* <count> 4-byte names */

		case AML_MULTI_NAME_PREFIX_OP:
			names_index = prefix_length + 2;
			names_count = (u32) internal_name[prefix_length + 1];
			break;


		/* two 4-byte names */

		case AML_DUAL_NAME_PREFIX:
			names_index = prefix_length + 1;
			names_count = 2;
			break;


		/* Null_name */

		case 0:
			names_index = 0;
			names_count = 0;
			break;


		/* one 4-byte name */

		default:
			names_index = prefix_length;
			names_count = 1;
			break;
		}
	}

	/*
	 * Calculate the length of Converted_name, which equals the length
	 * of the prefix, length of all object names, length of any required
	 * punctuation ('.') between object names, plus the NULL terminator.
	 */
	*converted_name_length = prefix_length + (4 * names_count) +
			   ((names_count > 0) ? (names_count - 1) : 0) + 1;

	/*
	 * Check to see if we're still in bounds.  If not, there's a problem
	 * with Internal_name (invalid format).
	 */
	if (*converted_name_length > internal_name_length) {
		REPORT_ERROR (("Ns_externalize_name: Invalid internal name\n"));
		return_ACPI_STATUS (AE_BAD_PATHNAME);
	}

	/*
	 * Build Converted_name...
	 */

	(*converted_name) = ACPI_MEM_CALLOCATE (*converted_name_length);
	if (!(*converted_name)) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	j = 0;

	for (i = 0; i < prefix_length; i++) {
		(*converted_name)[j++] = internal_name[i];
	}

	if (names_count > 0) {
		for (i = 0; i < names_count; i++) {
			if (i > 0) {
				(*converted_name)[j++] = '.';
			}

			(*converted_name)[j++] = internal_name[names_index++];
			(*converted_name)[j++] = internal_name[names_index++];
			(*converted_name)[j++] = internal_name[names_index++];
			(*converted_name)[j++] = internal_name[names_index++];
		}
	}

	return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 28
0
acpi_status
acpi_ns_externalize_name (
	u32                             internal_name_length,
	char                            *internal_name,
	u32                             *converted_name_length,
	char                            **converted_name)
{
	acpi_native_uint                names_index = 0;
	acpi_native_uint                num_segments = 0;
	acpi_native_uint                required_length;
	acpi_native_uint                prefix_length = 0;
	acpi_native_uint                i = 0;
	acpi_native_uint                j = 0;


	ACPI_FUNCTION_TRACE ("ns_externalize_name");


	if (!internal_name_length   ||
		!internal_name          ||
		!converted_name) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	/*
	 * Check for a prefix (one '\' | one or more '^').
	 */
	switch (internal_name[0]) {
	case '\\':
		prefix_length = 1;
		break;

	case '^':
		for (i = 0; i < internal_name_length; i++) {
			if (internal_name[i] == '^') {
				prefix_length = i + 1;
			}
			else {
				break;
			}
		}

		if (i == internal_name_length) {
			prefix_length = i;
		}

		break;

	default:
		break;
	}

	/*
	 * Check for object names.  Note that there could be 0-255 of these
	 * 4-byte elements.
	 */
	if (prefix_length < internal_name_length) {
		switch (internal_name[prefix_length]) {
		case AML_MULTI_NAME_PREFIX_OP:

			/* <count> 4-byte names */

			names_index = prefix_length + 2;
			num_segments = (acpi_native_uint) (u8)
					   internal_name[(acpi_native_uint) (prefix_length + 1)];
			break;

		case AML_DUAL_NAME_PREFIX:

			/* Two 4-byte names */

			names_index = prefix_length + 1;
			num_segments = 2;
			break;

		case 0:

			/* null_name */

			names_index = 0;
			num_segments = 0;
			break;

		default:

			/* one 4-byte name */

			names_index = prefix_length;
			num_segments = 1;
			break;
		}
	}

	/*
	 * Calculate the length of converted_name, which equals the length
	 * of the prefix, length of all object names, length of any required
	 * punctuation ('.') between object names, plus the NULL terminator.
	 */
	required_length = prefix_length + (4 * num_segments) +
			   ((num_segments > 0) ? (num_segments - 1) : 0) + 1;

	/*
	 * Check to see if we're still in bounds.  If not, there's a problem
	 * with internal_name (invalid format).
	 */
	if (required_length > internal_name_length) {
		ACPI_REPORT_ERROR (("ns_externalize_name: Invalid internal name\n"));
		return_ACPI_STATUS (AE_BAD_PATHNAME);
	}

	/*
	 * Build converted_name
	 */
	*converted_name = ACPI_MEM_CALLOCATE (required_length);
	if (!(*converted_name)) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	j = 0;

	for (i = 0; i < prefix_length; i++) {
		(*converted_name)[j++] = internal_name[i];
	}

	if (num_segments > 0) {
		for (i = 0; i < num_segments; i++) {
			if (i > 0) {
				(*converted_name)[j++] = '.';
			}

			(*converted_name)[j++] = internal_name[names_index++];
			(*converted_name)[j++] = internal_name[names_index++];
			(*converted_name)[j++] = internal_name[names_index++];
			(*converted_name)[j++] = internal_name[names_index++];
		}
	}

	if (converted_name_length) {
		*converted_name_length = (u32) required_length;
	}

	return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 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);
}
Ejemplo n.º 30
0
static acpi_status
acpi_ev_create_gpe_info_blocks (
	struct acpi_gpe_block_info      *gpe_block)
{
	struct acpi_gpe_register_info   *gpe_register_info = NULL;
	struct acpi_gpe_event_info      *gpe_event_info = NULL;
	struct acpi_gpe_event_info      *this_event;
	struct acpi_gpe_register_info   *this_register;
	acpi_native_uint                i;
	acpi_native_uint                j;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("ev_create_gpe_info_blocks");


	/* Allocate the GPE register information block */

	gpe_register_info = ACPI_MEM_CALLOCATE (
			  (acpi_size) gpe_block->register_count *
			  sizeof (struct acpi_gpe_register_info));
	if (!gpe_register_info) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
			"Could not allocate the gpe_register_info table\n"));
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/*
	 * Allocate the GPE event_info block. There are eight distinct GPEs
	 * per register.  Initialization to zeros is sufficient.
	 */
	gpe_event_info = ACPI_MEM_CALLOCATE (
			   ((acpi_size) gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) *
			   sizeof (struct acpi_gpe_event_info));
	if (!gpe_event_info) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the gpe_event_info table\n"));
		status = AE_NO_MEMORY;
		goto error_exit;
	}

	/* Save the new Info arrays in the GPE block */

	gpe_block->register_info = gpe_register_info;
	gpe_block->event_info  = gpe_event_info;

	/*
	 * Initialize the GPE Register and Event structures.  A goal of these
	 * tables is to hide the fact that there are two separate GPE register sets
	 * in a given gpe hardware block, the status registers occupy the first half,
	 * and the enable registers occupy the second half.
	 */
	this_register = gpe_register_info;
	this_event   = gpe_event_info;

	for (i = 0; i < gpe_block->register_count; i++) {
		/* Init the register_info for this GPE register (8 GPEs) */

		this_register->base_gpe_number = (u8) (gpe_block->block_base_number +
				   (i * ACPI_GPE_REGISTER_WIDTH));

		ACPI_STORE_ADDRESS (this_register->status_address.address,
				 (gpe_block->block_address.address
				 + i));

		ACPI_STORE_ADDRESS (this_register->enable_address.address,
				 (gpe_block->block_address.address
				 + i
				 + gpe_block->register_count));

		this_register->status_address.address_space_id = gpe_block->block_address.address_space_id;
		this_register->enable_address.address_space_id = gpe_block->block_address.address_space_id;
		this_register->status_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
		this_register->enable_address.register_bit_width = ACPI_GPE_REGISTER_WIDTH;
		this_register->status_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;
		this_register->enable_address.register_bit_offset = ACPI_GPE_REGISTER_WIDTH;

		/* Init the event_info for each GPE within this register */

		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
			this_event->bit_mask = acpi_gbl_decode_to8bit[j];
			this_event->register_info = this_register;
			this_event++;
		}

		/*
		 * Clear the status/enable registers.  Note that status registers
		 * are cleared by writing a '1', while enable registers are cleared
		 * by writing a '0'.
		 */
		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00,
				 &this_register->enable_address);
		if (ACPI_FAILURE (status)) {
			goto error_exit;
		}

		status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF,
				 &this_register->status_address);
		if (ACPI_FAILURE (status)) {
			goto error_exit;
		}

		this_register++;
	}

	return_ACPI_STATUS (AE_OK);


error_exit:
	if (gpe_register_info) {
		ACPI_MEM_FREE (gpe_register_info);
	}
	if (gpe_event_info) {
		ACPI_MEM_FREE (gpe_event_info);
	}

	return_ACPI_STATUS (status);
}