acpi_status
acpi_ut_get_object_size(
	acpi_operand_object     *internal_object,
	u32                     *obj_length)
{
	acpi_status             status;


	FUNCTION_ENTRY ();


	if ((VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_INTERNAL)) &&
		(IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE))) {
		status = acpi_ut_get_package_object_size (internal_object, obj_length);
	}

	else {
		status = acpi_ut_get_simple_object_size (internal_object, obj_length);
	}

	return (status);
}
acpi_status
acpi_ut_copy_iobject_to_eobject (
	acpi_operand_object     *internal_object,
	acpi_buffer             *ret_buffer)
{
	acpi_status             status;


	FUNCTION_TRACE ("Ut_copy_iobject_to_eobject");


	if (IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE)) {
		/*
		 * Package object:  Copy all subobjects (including
		 * nested packages)
		 */
		status = acpi_ut_copy_ipackage_to_epackage (internal_object,
				  ret_buffer->pointer, &ret_buffer->length);
	}

	else {
		/*
		 * Build a simple object (no nested objects)
		 */
		status = acpi_ut_copy_isimple_to_esimple (internal_object,
				  (acpi_object *) ret_buffer->pointer,
				  ((u8 *) ret_buffer->pointer +
				  ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object))),
				  &ret_buffer->length);
		/*
		 * build simple does not include the object size in the length
		 * so we add it in here
		 */
		ret_buffer->length += sizeof (acpi_object);
	}

	return_ACPI_STATUS (status);
}
Beispiel #3
0
ACPI_STATUS
AcpiUtGetObjectSize(
    ACPI_OPERAND_OBJECT     *InternalObject,
    UINT32                  *ObjLength)
{
    ACPI_STATUS             Status;


    FUNCTION_ENTRY ();


    if ((VALID_DESCRIPTOR_TYPE (InternalObject, ACPI_DESC_TYPE_INTERNAL)) &&
        (IS_THIS_OBJECT_TYPE (InternalObject, ACPI_TYPE_PACKAGE)))
    {
        Status = AcpiUtGetPackageObjectSize (InternalObject, ObjLength);
    }

    else
    {
        Status = AcpiUtGetSimpleObjectSize (InternalObject, ObjLength);
    }

    return (Status);
}
Beispiel #4
0
ACPI_STATUS
acpi_ev_addr_handler_helper (
	ACPI_HANDLE             obj_handle,
	u32                     level,
	void                    *context,
	void                    **return_value)
{
	ACPI_OPERAND_OBJECT     *handler_obj;
	ACPI_OPERAND_OBJECT     *tmp_obj;
	ACPI_OPERAND_OBJECT     *obj_desc;
	ACPI_NAMESPACE_NODE     *node;
	ACPI_STATUS             status;


	handler_obj = (ACPI_OPERAND_OBJECT *) context;

	/* Parameter validation */

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

	/* Convert and validate the device handle */

	node = acpi_ns_convert_handle_to_entry (obj_handle);
	if (!node) {
		return (AE_BAD_PARAMETER);
	}

	/*
	 *  We only care about regions.and objects
	 *  that can have address handlers
	 */

	if ((node->type != ACPI_TYPE_DEVICE) &&
		(node->type != ACPI_TYPE_REGION) &&
		(node != acpi_gbl_root_node))
	{
		return (AE_OK);
	}

	/* Check for an existing internal object */

	obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) node);
	if (!obj_desc) {
		/*
		 *  The object DNE, we don't care about it
		 */
		return (AE_OK);
	}

	/*
	 *  Devices are handled different than regions
	 */
	if (IS_THIS_OBJECT_TYPE (obj_desc, ACPI_TYPE_DEVICE)) {
		/*
		 *  See if this guy has any handlers
		 */
		tmp_obj = obj_desc->device.addr_handler;
		while (tmp_obj) {
			/*
			 *  Now let's see if it's for the same address space.
			 */
			if (tmp_obj->addr_handler.space_id == handler_obj->addr_handler.space_id) {
				/*
				 *  It's for the same address space
				 */

				/*
				 *  Since the object we found it on was a device, then it
				 *  means that someone has already installed a handler for
				 *  the branch of the namespace from this device on.  Just
				 *  bail out telling the walk routine to not traverse this
				 *  branch.  This preserves the scoping rule for handlers.
				 */
				return (AE_CTRL_DEPTH);
			}

			/*
			 *  Move through the linked list of handlers
			 */
			tmp_obj = tmp_obj->addr_handler.next;
		}

		/*
		 *  As long as the device didn't have a handler for this
		 *  space we don't care about it.  We just ignore it and
		 *  proceed.
		 */
		return (AE_OK);
	}

	/*
	 *  Only here if it was a region
	 */
	ACPI_ASSERT (obj_desc->common.type == ACPI_TYPE_REGION);

	if (obj_desc->region.space_id != handler_obj->addr_handler.space_id) {
		/*
		 *  This region is for a different address space
		 *  ignore it
		 */
		return (AE_OK);
	}

	/*
	 *  Now we have a region and it is for the handler's address
	 *  space type.
	 *
	 *  First disconnect region for any previous handler (if any)
	 */
	acpi_ev_disassociate_region_from_handler (obj_desc, FALSE);

	/*
	 *  Then connect the region to the new handler
	 */
	status = acpi_ev_associate_region_and_handler (handler_obj, obj_desc, FALSE);

	return (status);
}
Beispiel #5
0
acpi_status
acpi_ut_walk_package_tree (
	acpi_operand_object     *source_object,
	void                    *target_object,
	ACPI_PKG_CALLBACK       walk_callback,
	void                    *context)
{
	acpi_status             status = AE_OK;
	acpi_generic_state      *state_list = NULL;
	acpi_generic_state      *state;
	u32                     this_index;
	acpi_operand_object     *this_source_obj;


	FUNCTION_TRACE ("Ut_walk_package_tree");


	state = acpi_ut_create_pkg_state (source_object, target_object, 0);
	if (!state) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	while (state) {
		this_index    = state->pkg.index;
		this_source_obj = (acpi_operand_object *)
				  state->pkg.source_object->package.elements[this_index];

		/*
		 * Check for
		 * 1) An uninitialized package element.  It is completely
		 *      legal to declare a package and leave it uninitialized
		 * 2) Not an internal object - can be a namespace node instead
		 * 3) Any type other than a package.  Packages are handled in else
		 *      case below.
		 */
		if ((!this_source_obj) ||
			(!VALID_DESCRIPTOR_TYPE (
					this_source_obj, ACPI_DESC_TYPE_INTERNAL)) ||
			(!IS_THIS_OBJECT_TYPE (
					this_source_obj, ACPI_TYPE_PACKAGE))) {

			status = walk_callback (ACPI_COPY_TYPE_SIMPLE, this_source_obj,
					 state, context);
			if (ACPI_FAILURE (status)) {
				/* TBD: must delete package created up to this point */

				return_ACPI_STATUS (status);
			}

			state->pkg.index++;
			while (state->pkg.index >= state->pkg.source_object->package.count) {
				/*
				 * We've handled all of the objects at this level,  This means
				 * that we have just completed a package.  That package may
				 * have contained one or more packages itself.
				 *
				 * Delete this state and pop the previous state (package).
				 */
				acpi_ut_delete_generic_state (state);
				state = acpi_ut_pop_generic_state (&state_list);


				/* Finished when there are no more states */

				if (!state) {
					/*
					 * We have handled all of the objects in the top level
					 * package just add the length of the package objects
					 * and exit
					 */
					return_ACPI_STATUS (AE_OK);
				}

				/*
				 * Go back up a level and move the index past the just
				 * completed package object.
				 */
				state->pkg.index++;
			}
		}

		else {
			/* This is a sub-object of type package */

			status = walk_callback (ACPI_COPY_TYPE_PACKAGE, this_source_obj,
					  state, context);
			if (ACPI_FAILURE (status)) {
				/* TBD: must delete package created up to this point */

				return_ACPI_STATUS (status);
			}


			/*
			 * The callback above returned a new target package object.
			 */

			/*
			 * Push the current state and create a new one
			 */
			acpi_ut_push_generic_state (&state_list, state);
			state = acpi_ut_create_pkg_state (this_source_obj,
					   state->pkg.this_target_obj, 0);
			if (!state) {
				/* TBD: must delete package created up to this point */

				return_ACPI_STATUS (AE_NO_MEMORY);
			}
		}
	}

	/* We should never get here */

	return (AE_AML_INTERNAL);
}
Beispiel #6
0
ACPI_STATUS
AcpiUtWalkPackageTree (
    ACPI_OPERAND_OBJECT     *SourceObject,
    void                    *TargetObject,
    ACPI_PKG_CALLBACK       WalkCallback,
    void                    *Context)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GENERIC_STATE      *StateList = NULL;
    ACPI_GENERIC_STATE      *State;
    UINT32                  ThisIndex;
    ACPI_OPERAND_OBJECT     *ThisSourceObj;


    FUNCTION_TRACE ("UtWalkPackageTree");


    State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
    if (!State)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    while (State)
    {
        ThisIndex     = State->Pkg.Index;
        ThisSourceObj = (ACPI_OPERAND_OBJECT *)
                        State->Pkg.SourceObject->Package.Elements[ThisIndex];

        /*
         * Check for
         * 1) An uninitialized package element.  It is completely
         *      legal to declare a package and leave it uninitialized
         * 2) Not an internal object - can be a namespace node instead
         * 3) Any type other than a package.  Packages are handled in else
         *      case below.
         */
        if ((!ThisSourceObj) ||
                (!VALID_DESCRIPTOR_TYPE (
                     ThisSourceObj, ACPI_DESC_TYPE_INTERNAL)) ||
                (!IS_THIS_OBJECT_TYPE (
                     ThisSourceObj, ACPI_TYPE_PACKAGE)))
        {

            Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
                                   State, Context);
            if (ACPI_FAILURE (Status))
            {
                /* TBD: must delete package created up to this point */

                return_ACPI_STATUS (Status);
            }

            State->Pkg.Index++;
            while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
            {
                /*
                 * We've handled all of the objects at this level,  This means
                 * that we have just completed a package.  That package may
                 * have contained one or more packages itself.
                 *
                 * Delete this state and pop the previous state (package).
                 */
                AcpiUtDeleteGenericState (State);
                State = AcpiUtPopGenericState (&StateList);


                /* Finished when there are no more states */

                if (!State)
                {
                    /*
                     * We have handled all of the objects in the top level
                     * package just add the length of the package objects
                     * and exit
                     */
                    return_ACPI_STATUS (AE_OK);
                }

                /*
                 * Go back up a level and move the index past the just
                 * completed package object.
                 */
                State->Pkg.Index++;
            }
        }

        else
        {
            /* This is a sub-object of type package */

            Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
                                   State, Context);
            if (ACPI_FAILURE (Status))
            {
                /* TBD: must delete package created up to this point */

                return_ACPI_STATUS (Status);
            }


            /*
             * The callback above returned a new target package object.
             */

            /*
             * Push the current state and create a new one
             */
            AcpiUtPushGenericState (&StateList, State);
            State = AcpiUtCreatePkgState (ThisSourceObj,
                                          State->Pkg.ThisTargetObj, 0);
            if (!State)
            {
                /* TBD: must delete package created up to this point */

                return_ACPI_STATUS (AE_NO_MEMORY);
            }
        }
    }

    /* We should never get here */

    return (AE_AML_INTERNAL);
}