Example #1
0
acpi_status
acpi_tb_get_this_table (
	struct acpi_pointer             *address,
	struct acpi_table_header        *header,
	struct acpi_table_desc          *table_info)
{
	struct acpi_table_header        *full_table = NULL;
	u8                              allocation;
	acpi_status                     status = AE_OK;


	ACPI_FUNCTION_TRACE ("tb_get_this_table");


	/*
	 * Flags contains the current processor mode (Virtual or Physical addressing)
	 * The pointer_type is either Logical or Physical
	 */
	switch (address->pointer_type) {
	case ACPI_PHYSMODE_PHYSPTR:
	case ACPI_LOGMODE_LOGPTR:

		/* Pointer matches processor mode, copy the table to a new buffer */

		full_table = ACPI_MEM_ALLOCATE (header->length);
		if (!full_table) {
			ACPI_REPORT_ERROR (("Could not allocate table memory for [%4.4s] length %X\n",
				header->signature, header->length));
			return_ACPI_STATUS (AE_NO_MEMORY);
		}

		/* Copy the entire table (including header) to the local buffer */

		ACPI_MEMCPY (full_table, address->pointer.logical, header->length);

		/* Save allocation type */

		allocation = ACPI_MEM_ALLOCATED;
		break;


	case ACPI_LOGMODE_PHYSPTR:

		/*
		 * Just map the table's physical memory
		 * into our address space.
		 */
		status = acpi_os_map_memory (address->pointer.physical, (acpi_size) header->length,
				  (void *) &full_table);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
				header->signature,
				ACPI_FORMAT_UINT64 (address->pointer.physical), header->length));
			return (status);
		}

		/* Save allocation type */

		allocation = ACPI_MEM_MAPPED;
		break;


	default:

		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid address flags %X\n",
			address->pointer_type));
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	/*
	 * Validate checksum for _most_ tables,
	 * even the ones whose signature we don't recognize
	 */
	if (table_info->type != ACPI_TABLE_FACS) {
		status = acpi_tb_verify_table_checksum (full_table);

#if (!ACPI_CHECKSUM_ABORT)
		if (ACPI_FAILURE (status)) {
			/* Ignore the error if configuration says so */

			status = AE_OK;
		}
#endif
	}

	/* Return values */

	table_info->pointer     = full_table;
	table_info->length      = (acpi_size) header->length;
	table_info->allocation  = allocation;

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
		"Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
		full_table->signature,
		ACPI_FORMAT_UINT64 (address->pointer.physical), full_table));

	return_ACPI_STATUS (status);
}
/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_store_buffer_to_buffer
 *
 * PARAMETERS:  source_desc         - Source object to copy
 *              target_desc         - Destination object of the copy
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Copy a buffer object to another buffer object.
 *
 ******************************************************************************/
acpi_status
acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
			       union acpi_operand_object *target_desc)
{
	u32 length;
	u8 *buffer;

	ACPI_FUNCTION_TRACE_PTR("ex_store_buffer_to_buffer", source_desc);

	/* We know that source_desc is a buffer by now */

	buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer);
	length = source_desc->buffer.length;

	/*
	 * If target is a buffer of length zero or is a static buffer,
	 * allocate a new buffer of the proper length
	 */
	if ((target_desc->buffer.length == 0) ||
	    (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
		target_desc->buffer.pointer = ACPI_MEM_ALLOCATE(length);
		if (!target_desc->buffer.pointer) {
			return_ACPI_STATUS(AE_NO_MEMORY);
		}

		target_desc->buffer.length = length;
	}

	/* Copy source buffer to target buffer */

	if (length <= target_desc->buffer.length) {
		/* Clear existing buffer and copy in the new one */

		ACPI_MEMSET(target_desc->buffer.pointer, 0,
			    target_desc->buffer.length);
		ACPI_MEMCPY(target_desc->buffer.pointer, buffer, length);

#ifdef ACPI_OBSOLETE_BEHAVIOR
		/*
		 * NOTE: ACPI versions up to 3.0 specified that the buffer must be
		 * truncated if the string is smaller than the buffer.  However, "other"
		 * implementations of ACPI never did this and thus became the defacto
		 * standard. ACPi 3.0_a changes this behavior such that the buffer
		 * is no longer truncated.
		 */

		/*
		 * OBSOLETE BEHAVIOR:
		 * If the original source was a string, we must truncate the buffer,
		 * according to the ACPI spec.  Integer-to-Buffer and Buffer-to-Buffer
		 * copy must not truncate the original buffer.
		 */
		if (original_src_type == ACPI_TYPE_STRING) {
			/* Set the new length of the target */

			target_desc->buffer.length = length;
		}
#endif
	} else {
		/* Truncate the source, copy only what will fit */

		ACPI_MEMCPY(target_desc->buffer.pointer, buffer,
			    target_desc->buffer.length);

		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "Truncating source buffer from %X to %X\n",
				  length, target_desc->buffer.length));
	}

	/* Copy flags */

	target_desc->buffer.flags = source_desc->buffer.flags;
	target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
	return_ACPI_STATUS(AE_OK);
}
acpi_status
acpi_get_firmware_table(acpi_string signature,
			u32 instance,
			u32 flags, struct acpi_table_header **table_pointer)
{
	acpi_status status;
	struct acpi_pointer address;
	struct acpi_table_header *header = NULL;
	struct acpi_table_desc *table_info = NULL;
	struct acpi_table_desc *rsdt_info;
	u32 table_count;
	u32 i;
	u32 j;

	ACPI_FUNCTION_TRACE("acpi_get_firmware_table");

	/*
	 * Ensure that at least the table manager is initialized.  We don't
	 * require that the entire ACPI subsystem is up for this interface.
	 * If we have a buffer, we must have a length too
	 */
	if ((instance == 0) || (!signature) || (!table_pointer)) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	/* Ensure that we have a RSDP */

	if (!acpi_gbl_RSDP) {
		/* Get the RSDP */

		status = acpi_os_get_root_pointer(flags, &address);
		if (ACPI_FAILURE(status)) {
			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "RSDP not found\n"));
			return_ACPI_STATUS(AE_NO_ACPI_TABLES);
		}

		/* Map and validate the RSDP */

		if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
			status = acpi_os_map_memory(address.pointer.physical,
						    sizeof(struct
							   rsdp_descriptor),
						    (void *)&acpi_gbl_RSDP);
			if (ACPI_FAILURE(status)) {
				return_ACPI_STATUS(status);
			}
		} else {
			acpi_gbl_RSDP = address.pointer.logical;
		}

		/* The RDSP signature and checksum must both be correct */

		status = acpi_tb_validate_rsdp(acpi_gbl_RSDP);
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}
	}

	/* Get the RSDT address via the RSDP */

	acpi_tb_get_rsdt_address(&address);
	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
			  "RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
			  acpi_gbl_RSDP,
			  ACPI_FORMAT_UINT64(address.pointer.value)));

	/* Insert processor_mode flags */

	address.pointer_type |= flags;

	/* Get and validate the RSDT */

	rsdt_info = ACPI_MEM_CALLOCATE(sizeof(struct acpi_table_desc));
	if (!rsdt_info) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	status = acpi_tb_get_table(&address, rsdt_info);
	if (ACPI_FAILURE(status)) {
		goto cleanup;
	}

	status = acpi_tb_validate_rsdt(rsdt_info->pointer);
	if (ACPI_FAILURE(status)) {
		goto cleanup;
	}

	/* Allocate a scratch table header and table descriptor */

	header = ACPI_MEM_ALLOCATE(sizeof(struct acpi_table_header));
	if (!header) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

	table_info = ACPI_MEM_ALLOCATE(sizeof(struct acpi_table_desc));
	if (!table_info) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

	/* Get the number of table pointers within the RSDT */

	table_count =
	    acpi_tb_get_table_count(acpi_gbl_RSDP, rsdt_info->pointer);
	address.pointer_type = acpi_gbl_table_flags | flags;

	/*
	 * Search the RSDT/XSDT for the correct instance of the
	 * requested table
	 */
	for (i = 0, j = 0; i < table_count; i++) {
		/*
		 * Get the next table pointer, handle RSDT vs. XSDT
		 * RSDT pointers are 32 bits, XSDT pointers are 64 bits
		 */
		if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
			address.pointer.value =
			    (ACPI_CAST_PTR
			     (RSDT_DESCRIPTOR,
			      rsdt_info->pointer))->table_offset_entry[i];
		} else {
			address.pointer.value =
			    (ACPI_CAST_PTR
			     (XSDT_DESCRIPTOR,
			      rsdt_info->pointer))->table_offset_entry[i];
		}

		/* Get the table header */

		status = acpi_tb_get_table_header(&address, header);
		if (ACPI_FAILURE(status)) {
			goto cleanup;
		}

		/* Compare table signatures and table instance */

		if (!ACPI_STRNCMP(header->signature, signature, ACPI_NAME_SIZE)) {
			/* An instance of the table was found */

			j++;
			if (j >= instance) {
				/* Found the correct instance, get the entire table */

				status =
				    acpi_tb_get_table_body(&address, header,
							   table_info);
				if (ACPI_FAILURE(status)) {
					goto cleanup;
				}

				*table_pointer = table_info->pointer;
				goto cleanup;
			}
		}
	}

	/* Did not find the table */

	status = AE_NOT_EXIST;

      cleanup:
	if (rsdt_info->pointer) {
		acpi_os_unmap_memory(rsdt_info->pointer,
				     (acpi_size) rsdt_info->pointer->length);
	}
	ACPI_MEM_FREE(rsdt_info);

	if (header) {
		ACPI_MEM_FREE(header);
	}
	if (table_info) {
		ACPI_MEM_FREE(table_info);
	}
	return_ACPI_STATUS(status);
}
Example #4
0
acpi_status
acpi_hw_initialize (
	void)
{
	acpi_status             status = AE_OK;
	u32                     index;


	FUNCTION_TRACE ("Hw_initialize");


	/* We must have the ACPI tables by the time we get here */

	if (!acpi_gbl_FADT) {
		acpi_gbl_restore_acpi_chipset = FALSE;

		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No FADT!\n"));

		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
	}

	/* Identify current ACPI/legacy mode   */

	switch (acpi_gbl_system_flags & SYS_MODES_MASK) {
	case (SYS_MODE_ACPI):

		acpi_gbl_original_mode = SYS_MODE_ACPI;
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System supports ACPI mode only.\n"));
		break;


	case (SYS_MODE_LEGACY):

		acpi_gbl_original_mode = SYS_MODE_LEGACY;
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
			"Tables loaded from buffer, hardware assumed to support LEGACY mode only.\n"));
		break;


	case (SYS_MODE_ACPI | SYS_MODE_LEGACY):

		if (acpi_hw_get_mode () == SYS_MODE_ACPI) {
			acpi_gbl_original_mode = SYS_MODE_ACPI;
		}
		else {
			acpi_gbl_original_mode = SYS_MODE_LEGACY;
		}

		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
			"System supports both ACPI and LEGACY modes.\n"));

		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
			"System is currently in %s mode.\n",
			(acpi_gbl_original_mode == SYS_MODE_ACPI) ? "ACPI" : "LEGACY"));
		break;
	}


	if (acpi_gbl_system_flags & SYS_MODE_ACPI) {
		/* Target system supports ACPI mode */

		/*
		 * The purpose of this code is to save the initial state
		 * of the ACPI event enable registers. An exit function will be
		 * registered which will restore this state when the application
		 * exits. The exit function will also clear all of the ACPI event
		 * status bits prior to restoring the original mode.
		 *
		 * The location of the PM1a_evt_blk enable registers is defined as the
		 * base of PM1a_evt_blk + DIV_2(PM1a_evt_blk_length). Since the spec further
		 * fully defines the PM1a_evt_blk to be a total of 4 bytes, the offset
		 * for the enable registers is always 2 from the base. It is hard
		 * coded here. If this changes in the spec, this code will need to
		 * be modified. The PM1b_evt_blk behaves as expected.
		 */
		acpi_gbl_pm1_enable_register_save = (u16) acpi_hw_register_read (
				   ACPI_MTX_LOCK, PM1_EN);


		/*
		 * The GPEs behave similarly, except that the length of the register
		 * block is not fixed, so the buffer must be allocated with malloc
		 */
		if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) &&
			acpi_gbl_FADT->gpe0blk_len) {
			/* GPE0 specified in FADT  */

			acpi_gbl_gpe0enable_register_save = ACPI_MEM_ALLOCATE (
					   DIV_2 (acpi_gbl_FADT->gpe0blk_len));
			if (!acpi_gbl_gpe0enable_register_save) {
				return_ACPI_STATUS (AE_NO_MEMORY);
			}

			/* Save state of GPE0 enable bits */

			for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) {
				acpi_gbl_gpe0enable_register_save[index] =
					(u8) acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index);
			}
		}

		else {
			acpi_gbl_gpe0enable_register_save = NULL;
		}

		if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) &&
			acpi_gbl_FADT->gpe1_blk_len) {
			/* GPE1 defined */

			acpi_gbl_gpe1_enable_register_save = ACPI_MEM_ALLOCATE (
					   DIV_2 (acpi_gbl_FADT->gpe1_blk_len));
			if (!acpi_gbl_gpe1_enable_register_save) {
				return_ACPI_STATUS (AE_NO_MEMORY);
			}

			/* save state of GPE1 enable bits */

			for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) {
				acpi_gbl_gpe1_enable_register_save[index] =
					(u8) acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index);
			}
		}

		else {
			acpi_gbl_gpe1_enable_register_save = NULL;
		}
	}

	return_ACPI_STATUS (status);
}
Example #5
0
acpi_status
acpi_ex_store_buffer_to_buffer (
	acpi_object_type                original_src_type,
	union acpi_operand_object       *source_desc,
	union acpi_operand_object       *target_desc)
{
	u32                             length;
	u8                              *buffer;


	ACPI_FUNCTION_TRACE_PTR ("ex_store_buffer_to_buffer", source_desc);


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

	/*
	 * If target is a buffer of length zero or is a static buffer,
	 * allocate a new buffer of the proper length
	 */
	if ((target_desc->buffer.length == 0) ||
		(target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
		target_desc->buffer.pointer = ACPI_MEM_ALLOCATE (length);
		if (!target_desc->buffer.pointer) {
			return_ACPI_STATUS (AE_NO_MEMORY);
		}

		target_desc->buffer.length = length;
	}

	/* Copy source buffer to target buffer */

	if (length <= target_desc->buffer.length) {
		/* Clear existing buffer and copy in the new one */

		ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length);
		ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length);

		/*
		 * If the original source was a string, we must truncate the buffer,
		 * according to the ACPI spec.  Integer-to-Buffer and Buffer-to-Buffer
		 * copy must not truncate the original buffer.
		 */
		if (original_src_type == ACPI_TYPE_STRING) {
			/* Set the new length of the target */

			target_desc->buffer.length = length;
		}
	}
	else {
		/* Truncate the source, copy only what will fit */

		ACPI_MEMCPY (target_desc->buffer.pointer, buffer, target_desc->buffer.length);

		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
			"Truncating source buffer from %X to %X\n",
			length, target_desc->buffer.length));
	}

	/* Copy flags */

	target_desc->buffer.flags = source_desc->buffer.flags;
	target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
	return_ACPI_STATUS (AE_OK);
}
Example #6
0
ACPI_STATUS
AcpiExDoConcatenate (
    ACPI_OPERAND_OBJECT     *ObjDesc1,
    ACPI_OPERAND_OBJECT     *ObjDesc2,
    ACPI_OPERAND_OBJECT     **ActualReturnDesc,
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_STATUS             Status;
    UINT32                  i;
    ACPI_INTEGER            ThisInteger;
    ACPI_OPERAND_OBJECT     *ReturnDesc;
    NATIVE_CHAR             *NewBuf;


    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 (ObjDesc1))
    {
    case ACPI_TYPE_INTEGER:

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

        ReturnDesc = AcpiUtCreateBufferObject (AcpiGbl_IntegerByteWidth * 2);
        if (!ReturnDesc)
        {
            return (AE_NO_MEMORY);
        }

        NewBuf = (NATIVE_CHAR *) ReturnDesc->Buffer.Pointer;

        /* Convert the first integer */

        ThisInteger = ObjDesc1->Integer.Value;
        for (i = 0; i < AcpiGbl_IntegerByteWidth; i++)
        {
            NewBuf[i] = (NATIVE_CHAR) ThisInteger;
            ThisInteger >>= 8;
        }

        /* Convert the second integer */

        ThisInteger = ObjDesc2->Integer.Value;
        for (; i < (ACPI_MUL_2 (AcpiGbl_IntegerByteWidth)); i++)
        {
            NewBuf[i] = (NATIVE_CHAR) ThisInteger;
            ThisInteger >>= 8;
        }

        break;


    case ACPI_TYPE_STRING:

        /* Result of two Strings is a String */

        ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_STRING);
        if (!ReturnDesc)
        {
            return (AE_NO_MEMORY);
        }

        /* Operand0 is string  */

        NewBuf = ACPI_MEM_ALLOCATE ((ACPI_SIZE) ObjDesc1->String.Length +
                                    (ACPI_SIZE) ObjDesc2->String.Length + 1);
        if (!NewBuf)
        {
            ACPI_REPORT_ERROR
                (("ExDoConcatenate: String allocation failure\n"));
            Status = AE_NO_MEMORY;
            goto Cleanup;
        }

        /* Concatenate the strings */

        ACPI_STRCPY (NewBuf, ObjDesc1->String.Pointer);
        ACPI_STRCPY (NewBuf + ObjDesc1->String.Length,
                              ObjDesc2->String.Pointer);

        /* Complete the String object initialization */

        ReturnDesc->String.Pointer = NewBuf;
        ReturnDesc->String.Length  = ObjDesc1->String.Length +
                                     ObjDesc2->String.Length;
        break;


    case ACPI_TYPE_BUFFER:

        /* Result of two Buffers is a Buffer */

        ReturnDesc = AcpiUtCreateBufferObject (
                            (ACPI_SIZE) ObjDesc1->Buffer.Length +
                            (ACPI_SIZE) ObjDesc2->Buffer.Length);
        if (!ReturnDesc)
        {
            return (AE_NO_MEMORY);
        }

        NewBuf = (NATIVE_CHAR *) ReturnDesc->Buffer.Pointer;

        /* Concatenate the buffers */

        ACPI_MEMCPY (NewBuf, ObjDesc1->Buffer.Pointer,
                        ObjDesc1->Buffer.Length);
        ACPI_MEMCPY (NewBuf + ObjDesc1->Buffer.Length, ObjDesc2->Buffer.Pointer,
                         ObjDesc2->Buffer.Length);

        break;


    default:

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

        Status = AE_AML_INTERNAL;
        ReturnDesc = NULL;
    }

    *ActualReturnDesc = ReturnDesc;
    return (AE_OK);


Cleanup:

    AcpiUtRemoveReference (ReturnDesc);
    return (Status);
}
Example #7
0
acpi_status
acpi_ex_do_concatenate (
	acpi_operand_object     *obj_desc,
	acpi_operand_object     *obj_desc2,
	acpi_operand_object     **actual_return_desc,
	acpi_walk_state         *walk_state)
{
	acpi_status             status;
	u32                     i;
	acpi_integer            this_integer;
	acpi_operand_object     *return_desc;
	NATIVE_CHAR             *new_buf;
	u32                     integer_size = sizeof (acpi_integer);


	FUNCTION_ENTRY ();


	/*
	 * There are three cases to handle:
	 * 1) Two Integers concatenated to produce a buffer
	 * 2) Two Strings concatenated to produce a string
	 * 3) Two Buffers concatenated to produce a buffer
	 */
	switch (obj_desc->common.type) {
	case ACPI_TYPE_INTEGER:

		/* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */

		if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
			/*
			 * We are running a method that exists in a 32-bit ACPI table.
			 * Truncate the value to 32 bits by zeroing out the upper
			 * 32-bit field
			 */
			integer_size = sizeof (u32);
		}

		/* Result of two integers is a buffer */

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

		/* Need enough space for two integers */

		return_desc->buffer.length = integer_size * 2;
		new_buf = ACPI_MEM_CALLOCATE (return_desc->buffer.length);
		if (!new_buf) {
			REPORT_ERROR
				(("Ex_do_concatenate: Buffer allocation failure\n"));
			status = AE_NO_MEMORY;
			goto cleanup;
		}

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

		/* Convert the first integer */

		this_integer = obj_desc->integer.value;
		for (i = 0; i < integer_size; i++) {
			new_buf[i] = (u8) this_integer;
			this_integer >>= 8;
		}

		/* Convert the second integer */

		this_integer = obj_desc2->integer.value;
		for (; i < (integer_size * 2); i++) {
			new_buf[i] = (u8) this_integer;
			this_integer >>= 8;
		}

		break;


	case ACPI_TYPE_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_ALLOCATE (obj_desc->string.length +
				  obj_desc2->string.length + 1);
		if (!new_buf) {
			REPORT_ERROR
				(("Ex_do_concatenate: String allocation failure\n"));
			status = AE_NO_MEMORY;
			goto cleanup;
		}

		STRCPY (new_buf, obj_desc->string.pointer);
		STRCPY (new_buf + obj_desc->string.length,
				  obj_desc2->string.pointer);

		/* Point the return object to the new string */

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


	case ACPI_TYPE_BUFFER:

		/* Operand0 is a buffer */

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

		new_buf = ACPI_MEM_ALLOCATE (obj_desc->buffer.length +
				  obj_desc2->buffer.length);
		if (!new_buf) {
			REPORT_ERROR
				(("Ex_do_concatenate: Buffer allocation failure\n"));
			status = AE_NO_MEMORY;
			goto cleanup;
		}

		MEMCPY (new_buf, obj_desc->buffer.pointer,
				  obj_desc->buffer.length);
		MEMCPY (new_buf + obj_desc->buffer.length, obj_desc2->buffer.pointer,
				   obj_desc2->buffer.length);

		/*
		 * Point the return object to the new buffer
		 */

		return_desc->buffer.pointer    = (u8 *) new_buf;
		return_desc->buffer.length     = obj_desc->buffer.length +
				 obj_desc2->buffer.length;
		break;


	default:
		status = AE_AML_INTERNAL;
		return_desc = NULL;
	}


	*actual_return_desc = return_desc;
	return (AE_OK);


cleanup:

	acpi_ut_remove_reference (return_desc);
	return (status);
}
static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs)
{
	char *temp_ptr;
	char *name_string;
	u32 size_needed;

	ACPI_FUNCTION_TRACE("ex_allocate_name_string");

	/*
	 * Allow room for all \ and ^ prefixes, all segments and a multi_name_prefix.
	 * Also, one byte for the null terminator.
	 * This may actually be somewhat longer than needed.
	 */
	if (prefix_count == ACPI_UINT32_MAX) {
		/* Special case for root */

		size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
	} else {
		size_needed =
		    prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
	}

	/*
	 * Allocate a buffer for the name.
	 * This buffer must be deleted by the caller!
	 */
	name_string = ACPI_MEM_ALLOCATE(size_needed);
	if (!name_string) {
		ACPI_ERROR((AE_INFO,
			    "Could not allocate size %d", size_needed));
		return_PTR(NULL);
	}

	temp_ptr = name_string;

	/* Set up Root or Parent prefixes if needed */

	if (prefix_count == ACPI_UINT32_MAX) {
		*temp_ptr++ = AML_ROOT_PREFIX;
	} else {
		while (prefix_count--) {
			*temp_ptr++ = AML_PARENT_PREFIX;
		}
	}

	/* Set up Dual or Multi prefixes if needed */

	if (num_name_segs > 2) {
		/* Set up multi prefixes   */

		*temp_ptr++ = AML_MULTI_NAME_PREFIX_OP;
		*temp_ptr++ = (char)num_name_segs;
	} else if (2 == num_name_segs) {
		/* Set up dual prefixes */

		*temp_ptr++ = AML_DUAL_NAME_PREFIX;
	}

	/*
	 * Terminate string following prefixes. acpi_ex_name_segment() will
	 * append the segment(s)
	 */
	*temp_ptr = 0;

	return_PTR(name_string);
}
Example #9
0
NATIVE_CHAR *
AcpiExAllocateNameString (
    UINT32                  PrefixCount,
    UINT32                  NumNameSegs)
{
    NATIVE_CHAR             *TempPtr;
    NATIVE_CHAR             *NameString;
    UINT32                   SizeNeeded;

    ACPI_FUNCTION_TRACE ("ExAllocateNameString");


    /*
     * Allow room for all \ and ^ prefixes, all segments, and a MultiNamePrefix.
     * Also, one byte for the null terminator.
     * This may actually be somewhat longer than needed.
     */
    if (PrefixCount == ACPI_UINT32_MAX)
    {
        /* Special case for root */

        SizeNeeded = 1 + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1;
    }
    else
    {
        SizeNeeded = PrefixCount + (ACPI_NAME_SIZE * NumNameSegs) + 2 + 1;
    }

    /*
     * Allocate a buffer for the name.
     * This buffer must be deleted by the caller!
     */
    NameString = ACPI_MEM_ALLOCATE (SizeNeeded);
    if (!NameString)
    {
        ACPI_REPORT_ERROR (("ExAllocateNameString: Could not allocate size %d\n", SizeNeeded));
        return_PTR (NULL);
    }

    TempPtr = NameString;

    /* Set up Root or Parent prefixes if needed */

    if (PrefixCount == ACPI_UINT32_MAX)
    {
        *TempPtr++ = AML_ROOT_PREFIX;
    }
    else
    {
        while (PrefixCount--)
        {
            *TempPtr++ = AML_PARENT_PREFIX;
        }
    }


    /* Set up Dual or Multi prefixes if needed */

    if (NumNameSegs > 2)
    {
        /* Set up multi prefixes   */

        *TempPtr++ = AML_MULTI_NAME_PREFIX_OP;
        *TempPtr++ = (char) NumNameSegs;
    }
    else if (2 == NumNameSegs)
    {
        /* Set up dual prefixes */

        *TempPtr++ = AML_DUAL_NAME_PREFIX;
    }

    /*
     * Terminate string following prefixes. AcpiExNameSegment() will
     * append the segment(s)
     */
    *TempPtr = 0;

    return_PTR (NameString);
}