예제 #1
0
acpi_status
acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
{
	union acpi_operand_object *obj_desc;
	acpi_status status;

	ACPI_FUNCTION_TRACE(ut_execute_STA);

	status = acpi_ut_evaluate_object(device_node, METHOD_NAME__STA,
					 ACPI_BTYPE_INTEGER, &obj_desc);
	if (ACPI_FAILURE(status)) {
		if (AE_NOT_FOUND == status) {
			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
					  "_STA on %4.4s was not found, assuming device is present\n",
					  acpi_ut_get_node_name(device_node)));

			*flags = ACPI_UINT32_MAX;
			status = AE_OK;
		}

		return_ACPI_STATUS(status);
	}

	/* Extract the status flags */

	*flags = (u32) obj_desc->integer.value;

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

	acpi_ut_remove_reference(obj_desc);
	return_ACPI_STATUS(status);
}
예제 #2
0
acpi_status
acpi_ut_execute_UID (
	struct acpi_namespace_node      *device_node,
	struct acpi_device_id           *uid)
{
	union acpi_operand_object       *obj_desc;
	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);
	}

	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
		/* Convert the Numeric UID to string */

		acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value);
	}
	else {
		/* Copy the String UID from the returned object */

		acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer,
				sizeof (uid->value));
	}

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

	acpi_ut_remove_reference (obj_desc);
	return_ACPI_STATUS (status);
}
예제 #3
0
acpi_status
acpi_ut_evaluate_numeric_object(char *object_name,
				struct acpi_namespace_node *device_node,
				u64 *value)
{
	union acpi_operand_object *obj_desc;
	acpi_status status;

	ACPI_FUNCTION_TRACE(ut_evaluate_numeric_object);

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

	/* Get the returned Integer */

	*value = obj_desc->integer.value;

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

	acpi_ut_remove_reference(obj_desc);
	return_ACPI_STATUS(status);
}
예제 #4
0
파일: utids.c 프로젝트: 1314cc/linux
/*******************************************************************************
 *
 * 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 {
		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);
}
예제 #5
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_ut_copy_id_string(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);
}
예제 #6
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);
}
예제 #7
0
acpi_status
acpi_ut_execute_sxds (
	struct acpi_namespace_node      *device_node,
	u8                              *highest)
{
	union acpi_operand_object       *obj_desc;
	acpi_status                     status;
	u32                             i;


	ACPI_FUNCTION_TRACE ("ut_execute_Sxds");


	for (i = 0; i < 4; i++) {
		highest[i] = 0xFF;
		status = acpi_ut_evaluate_object (device_node,
				 (char *) acpi_gbl_highest_dstate_names[i],
				 ACPI_BTYPE_INTEGER, &obj_desc);
		if (ACPI_FAILURE (status)) {
			if (status != AE_NOT_FOUND) {
				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
					"%s on Device %4.4s, %s\n",
					(char *) acpi_gbl_highest_dstate_names[i],
					acpi_ut_get_node_name (device_node),
					acpi_format_exception (status)));

				return_ACPI_STATUS (status);
			}
		}
		else {
			/* Extract the Dstate value */

			highest[i] = (u8) obj_desc->integer.value;

			/* Delete the return object */

			acpi_ut_remove_reference (obj_desc);
		}
	}

	return_ACPI_STATUS (AE_OK);
}
예제 #8
0
파일: evgpeblk.c 프로젝트: 274914765/C
static acpi_status
acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
              u32 level, void *info, void **return_value)
{
    struct acpi_gpe_walk_info *gpe_info = (void *)info;
    struct acpi_namespace_node *gpe_device;
    struct acpi_gpe_block_info *gpe_block;
    struct acpi_namespace_node *target_gpe_device;
    struct acpi_gpe_event_info *gpe_event_info;
    union acpi_operand_object *pkg_desc;
    union acpi_operand_object *obj_desc;
    u32 gpe_number;
    acpi_status status;

    ACPI_FUNCTION_TRACE(ev_match_prw_and_gpe);

    /* Check for a _PRW method under this device */

    status = acpi_ut_evaluate_object(obj_handle, METHOD_NAME__PRW,
                     ACPI_BTYPE_PACKAGE, &pkg_desc);
    if (ACPI_FAILURE(status)) {

        /* Ignore all errors from _PRW, we don't want to abort the subsystem */

        return_ACPI_STATUS(AE_OK);
    }

    /* The returned _PRW package must have at least two elements */

    if (pkg_desc->package.count < 2) {
        goto cleanup;
    }

    /* Extract pointers from the input context */

    gpe_device = gpe_info->gpe_device;
    gpe_block = gpe_info->gpe_block;

    /*
     * The _PRW object must return a package, we are only interested
     * in the first element
     */
    obj_desc = pkg_desc->package.elements[0];

    if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {

        /* Use FADT-defined GPE device (from definition of _PRW) */

        target_gpe_device = acpi_gbl_fadt_gpe_device;

        /* Integer is the GPE number in the FADT described GPE blocks */

        gpe_number = (u32) obj_desc->integer.value;
    } else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {

        /* Package contains a GPE reference and GPE number within a GPE block */

        if ((obj_desc->package.count < 2) ||
            (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[0]) !=
             ACPI_TYPE_LOCAL_REFERENCE)
            || (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[1]) !=
            ACPI_TYPE_INTEGER)) {
            goto cleanup;
        }

        /* Get GPE block reference and decode */

        target_gpe_device =
            obj_desc->package.elements[0]->reference.node;
        gpe_number = (u32) obj_desc->package.elements[1]->integer.value;
    } else {
        /* Unknown type, just ignore it */

        goto cleanup;
    }

    /*
     * Is this GPE within this block?
     *
     * TRUE iff these conditions are true:
     *     1) The GPE devices match.
     *     2) The GPE index(number) is within the range of the Gpe Block
     *          associated with the GPE device.
     */
    if ((gpe_device == target_gpe_device) &&
        (gpe_number >= gpe_block->block_base_number) &&
        (gpe_number <
         gpe_block->block_base_number + (gpe_block->register_count * 8))) {
        gpe_event_info =
            &gpe_block->event_info[gpe_number -
                       gpe_block->block_base_number];

        /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */

        gpe_event_info->flags &=
            ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);

        status =
            acpi_ev_set_gpe_type(gpe_event_info, ACPI_GPE_TYPE_WAKE);
        if (ACPI_FAILURE(status)) {
            goto cleanup;
        }
        status =
            acpi_ev_update_gpe_enable_masks(gpe_event_info,
                            ACPI_GPE_DISABLE);
    }

      cleanup:
    acpi_ut_remove_reference(pkg_desc);
    return_ACPI_STATUS(AE_OK);
}
예제 #9
0
acpi_status
acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
		    struct acpica_device_id_list **return_cid_list)
{
	union acpi_operand_object **cid_objects;
	union acpi_operand_object *obj_desc;
	struct acpica_device_id_list *cid_list;
	char *next_id_string;
	u32 string_area_size;
	u32 length;
	u32 cid_list_size;
	acpi_status status;
	u32 count;
	u32 i;

	ACPI_FUNCTION_TRACE(ut_execute_CID);

	/* Evaluate the _CID method for this device */

	status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
					 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
					 | ACPI_BTYPE_PACKAGE, &obj_desc);
	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 (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
		count = obj_desc->package.count;
		cid_objects = obj_desc->package.elements;
	} else {		/* Single Integer or String CID */

		count = 1;
		cid_objects = &obj_desc;
	}

	string_area_size = 0;
	for (i = 0; i < count; i++) {

		/* String lengths include null terminator */

		switch (cid_objects[i]->common.type) {
		case ACPI_TYPE_INTEGER:
			string_area_size += ACPI_EISAID_STRING_SIZE;
			break;

		case ACPI_TYPE_STRING:
			string_area_size += cid_objects[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 DEVICE_ID array +
	 * 3) Size of the actual CID strings
	 */
	cid_list_size = sizeof(struct acpica_device_id_list) +
	    ((count - 1) * sizeof(struct acpica_device_id)) + string_area_size;

	cid_list = ACPI_ALLOCATE_ZEROED(cid_list_size);
	if (!cid_list) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

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

	next_id_string = ACPI_CAST_PTR(char, cid_list->ids) +
	    ((acpi_size) count * sizeof(struct acpica_device_id));

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

	for (i = 0; i < count; i++) {
		if (cid_objects[i]->common.type == ACPI_TYPE_INTEGER) {

			/* Convert the Integer (EISAID) CID to a string */

			acpi_ex_eisa_id_to_string(next_id_string,
						  cid_objects[i]->integer.
						  value);
			length = ACPI_EISAID_STRING_SIZE;
		} else {	/* ACPI_TYPE_STRING */

			/* Copy the String CID from the returned object */

			acpi_ut_copy_id_string(next_id_string,
					       cid_objects[i]->string.pointer);
			length = cid_objects[i]->string.length + 1;
		}

		cid_list->ids[i].string = next_id_string;
		cid_list->ids[i].length = length;
		next_id_string += length;
	}

	/* Finish the CID list */

	cid_list->count = count;
	cid_list->list_size = cid_list_size;
	*return_cid_list = cid_list;

cleanup:

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

	acpi_ut_remove_reference(obj_desc);
	return_ACPI_STATUS(status);
}
예제 #10
0
파일: utids.c 프로젝트: 1314cc/linux
acpi_status
acpi_ut_execute_CLS(struct acpi_namespace_node *device_node,
		    struct acpi_pnp_device_id **return_id)
{
	union acpi_operand_object *obj_desc;
	union acpi_operand_object **cls_objects;
	u32 count;
	struct acpi_pnp_device_id *cls;
	u32 length;
	acpi_status status;
	u8 class_code[3] = { 0, 0, 0 };

	ACPI_FUNCTION_TRACE(ut_execute_CLS);

	status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CLS,
					 ACPI_BTYPE_PACKAGE, &obj_desc);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

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

	length = ACPI_PCICLS_STRING_SIZE;
	cls_objects = obj_desc->package.elements;
	count = obj_desc->package.count;

	if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
		if (count > 0
		    && cls_objects[0]->common.type == ACPI_TYPE_INTEGER) {
			class_code[0] = (u8)cls_objects[0]->integer.value;
		}
		if (count > 1
		    && cls_objects[1]->common.type == ACPI_TYPE_INTEGER) {
			class_code[1] = (u8)cls_objects[1]->integer.value;
		}
		if (count > 2
		    && cls_objects[2]->common.type == ACPI_TYPE_INTEGER) {
			class_code[2] = (u8)cls_objects[2]->integer.value;
		}
	}

	/* Allocate a buffer for the CLS */

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

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

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

	/* Simply copy existing string */

	acpi_ex_pci_cls_to_string(cls->string, class_code);
	cls->length = length;
	*return_id = cls;

cleanup:

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

	acpi_ut_remove_reference(obj_desc);
	return_ACPI_STATUS(status);
}
예제 #11
0
acpi_status
acpi_ut_execute_CID (
	struct acpi_namespace_node      *device_node,
	struct acpi_compatible_id_list **return_cid_list)
{
	union acpi_operand_object       *obj_desc;
	acpi_status                     status;
	u32                             count;
	u32                             size;
	struct acpi_compatible_id_list *cid_list;
	acpi_native_uint                i;


	ACPI_FUNCTION_TRACE ("ut_execute_CID");


	/* Evaluate the _CID method for this device */

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

	/* Get the number of _CIDs returned */

	count = 1;
	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
		count = obj_desc->package.count;
	}

	/* Allocate a worst-case buffer for the _CIDs */

	size = (((count - 1) * sizeof (struct acpi_compatible_id)) +
			   sizeof (struct acpi_compatible_id_list));

	cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size);
	if (!cid_list) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/* Init CID list */

	cid_list->count = count;
	cid_list->size = size;

	/*
	 *  A _CID can return either a single compatible ID or a package of compatible
	 *  IDs.  Each compatible ID can be one of the following:
	 *  -- Number (32 bit compressed EISA ID) or
	 *  -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
	 */

	/* The _CID object can be either a single CID or a package (list) of CIDs */

	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) {
		/* Translate each package element */

		for (i = 0; i < count; i++) {
			status = acpi_ut_translate_one_cid (obj_desc->package.elements[i],
					  &cid_list->id[i]);
			if (ACPI_FAILURE (status)) {
				break;
			}
		}
	}
	else {
		/* Only one CID, translate to a string */

		status = acpi_ut_translate_one_cid (obj_desc, cid_list->id);
	}

	/* Cleanup on error */

	if (ACPI_FAILURE (status)) {
		ACPI_MEM_FREE (cid_list);
	}
	else {
		*return_cid_list = cid_list;
	}

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

	acpi_ut_remove_reference (obj_desc);
	return_ACPI_STATUS (status);
}