コード例 #1
0
ファイル: evgpe.c プロジェクト: KroMignon/linux-emcraft
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
{
    struct acpi_gpe_event_info *gpe_event_info = (void *)context;
    acpi_status status;
    struct acpi_gpe_event_info local_gpe_event_info;
    struct acpi_evaluate_info *info;

    ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);

    status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
    if (ACPI_FAILURE(status)) {
        return_VOID;
    }

    /* Must revalidate the gpe_number/gpe_block */

    if (!acpi_ev_valid_gpe_event(gpe_event_info)) {
        status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
        return_VOID;
    }

    /* Set the GPE flags for return to enabled state */

    (void)acpi_ev_enable_gpe(gpe_event_info, FALSE);

    /*
     * Take a snapshot of the GPE info for this level - we copy the info to
     * prevent a race condition with remove_handler/remove_block.
     */
    ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info,
                sizeof(struct acpi_gpe_event_info));

    status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
    if (ACPI_FAILURE(status)) {
        return_VOID;
    }

    /*
     * Must check for control method type dispatch one more time to avoid a
     * race with ev_gpe_install_handler
     */
    if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) ==
            ACPI_GPE_DISPATCH_METHOD) {

        /* Allocate the evaluation information block */

        info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
        if (!info) {
            status = AE_NO_MEMORY;
        } else {
            /*
             * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
             * control method that corresponds to this GPE
             */
            info->prefix_node =
                local_gpe_event_info.dispatch.method_node;
            info->flags = ACPI_IGNORE_RETURN_VALUE;

            status = acpi_ns_evaluate(info);
            ACPI_FREE(info);
        }

        if (ACPI_FAILURE(status)) {
            ACPI_EXCEPTION((AE_INFO, status,
                            "while evaluating GPE method [%4.4s]",
                            acpi_ut_get_node_name
                            (local_gpe_event_info.dispatch.
                             method_node)));
        }
    }
    /* Defer enabling of GPE until all notify handlers are done */
    acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe,
                    gpe_event_info);
    return_VOID;
}
コード例 #2
0
ファイル: evgpe.c プロジェクト: AllenDou/linux
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
{
	struct acpi_gpe_event_info *gpe_event_info = context;
	acpi_status status;
	struct acpi_gpe_event_info *local_gpe_event_info;
	struct acpi_evaluate_info *info;
	struct acpi_gpe_notify_info *notify;

	ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);

	/* Allocate a local GPE block */

	local_gpe_event_info =
	    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info));
	if (!local_gpe_event_info) {
		ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE"));
		return_VOID;
	}

	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
	if (ACPI_FAILURE(status)) {
		ACPI_FREE(local_gpe_event_info);
		return_VOID;
	}

	/* Must revalidate the gpe_number/gpe_block */

	if (!acpi_ev_valid_gpe_event(gpe_event_info)) {
		status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
		ACPI_FREE(local_gpe_event_info);
		return_VOID;
	}

	/*
	 * Take a snapshot of the GPE info for this level - we copy the info to
	 * prevent a race condition with remove_handler/remove_block.
	 */
	ACPI_MEMCPY(local_gpe_event_info, gpe_event_info,
		    sizeof(struct acpi_gpe_event_info));

	status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
	if (ACPI_FAILURE(status)) {
		return_VOID;
	}

	/* Do the correct dispatch - normal method or implicit notify */

	switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
	case ACPI_GPE_DISPATCH_NOTIFY:

		/*
		 * Implicit notify.
		 * Dispatch a DEVICE_WAKE notify to the appropriate handler.
		 * NOTE: the request is queued for execution after this method
		 * completes. The notify handlers are NOT invoked synchronously
		 * from this thread -- because handlers may in turn run other
		 * control methods.
		 *
		 * June 2012: Expand implicit notify mechanism to support
		 * notifies on multiple device objects.
		 */
		notify = local_gpe_event_info->dispatch.notify_list;
		while (ACPI_SUCCESS(status) && notify) {
			status =
			    acpi_ev_queue_notify_request(notify->device_node,
							 ACPI_NOTIFY_DEVICE_WAKE);

			notify = notify->next;
		}

		break;

	case ACPI_GPE_DISPATCH_METHOD:

		/* Allocate the evaluation information block */

		info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
		if (!info) {
			status = AE_NO_MEMORY;
		} else {
			/*
			 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
			 * control method that corresponds to this GPE
			 */
			info->prefix_node =
			    local_gpe_event_info->dispatch.method_node;
			info->flags = ACPI_IGNORE_RETURN_VALUE;

			status = acpi_ns_evaluate(info);
			ACPI_FREE(info);
		}

		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"while evaluating GPE method [%4.4s]",
					acpi_ut_get_node_name
					(local_gpe_event_info->dispatch.
					 method_node)));
		}

		break;

	default:
		return_VOID;    /* Should never happen */
	}

	/* Defer enabling of GPE until all notify handlers are done */

	status = acpi_os_execute(OSL_NOTIFY_HANDLER,
				 acpi_ev_asynch_enable_gpe,
				 local_gpe_event_info);
	if (ACPI_FAILURE(status)) {
		ACPI_FREE(local_gpe_event_info);
	}
	return_VOID;
}
コード例 #3
0
ファイル: evgpe.c プロジェクト: dduval/kernel-rhel3
static void ACPI_SYSTEM_XFACE
acpi_ev_asynch_execute_gpe_method (
	void                            *context)
{
	struct acpi_gpe_event_info      *gpe_event_info = (void *) context;
	u32                             gpe_number = 0;
	acpi_status                     status;
	struct acpi_gpe_event_info      local_gpe_event_info;


	ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method");


	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_VOID;
	}

	/* Must revalidate the gpe_number/gpe_block */

	if (!acpi_ev_valid_gpe_event (gpe_event_info)) {
		status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
		return_VOID;
	}

	/*
	 * Take a snapshot of the GPE info for this level - we copy the
	 * info to prevent a race condition with remove_handler/remove_block.
	 */
	ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, sizeof (struct acpi_gpe_event_info));

	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_VOID;
	}

	if (local_gpe_event_info.method_node) {
		/*
		 * Invoke the GPE Method (_Lxx, _Exx):
		 * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.)
		 */
		status = acpi_ns_evaluate_by_handle (local_gpe_event_info.method_node, NULL, NULL);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n",
				acpi_format_exception (status),
				local_gpe_event_info.method_node->name.ascii, gpe_number));
		}
	}

	if (local_gpe_event_info.flags & ACPI_EVENT_LEVEL_TRIGGERED) {
		/*
		 * GPE is level-triggered, we clear the GPE status bit after handling
		 * the event.
		 */
		status = acpi_hw_clear_gpe (&local_gpe_event_info);
		if (ACPI_FAILURE (status)) {
			return_VOID;
		}
	}

	/* Enable this GPE */

	(void) acpi_hw_enable_gpe (&local_gpe_event_info);
	return_VOID;
}
コード例 #4
0
ファイル: evgpe.c プロジェクト: BackupTheBerlios/tuxap
static void ACPI_SYSTEM_XFACE
acpi_ev_asynch_execute_gpe_method (
	void                            *context)
{
	struct acpi_gpe_event_info      *gpe_event_info = (void *) context;
	u32                             gpe_number = 0;
	acpi_status                     status;
	struct acpi_gpe_event_info      local_gpe_event_info;
	struct acpi_parameter_info      info;


	ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method");


	status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_VOID;
	}

	/* Must revalidate the gpe_number/gpe_block */

	if (!acpi_ev_valid_gpe_event (gpe_event_info)) {
		status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
		return_VOID;
	}

	/* Set the GPE flags for return to enabled state */

	(void) acpi_ev_enable_gpe (gpe_event_info, FALSE);

	/*
	 * Take a snapshot of the GPE info for this level - we copy the
	 * info to prevent a race condition with remove_handler/remove_block.
	 */
	ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, sizeof (struct acpi_gpe_event_info));

	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
	if (ACPI_FAILURE (status)) {
		return_VOID;
	}

	/*
	 * Must check for control method type dispatch one more
	 * time to avoid race with ev_gpe_install_handler
	 */
	if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) {
		/*
		 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
		 * control method that corresponds to this GPE
		 */
		info.node = local_gpe_event_info.dispatch.method_node;
		info.parameters = ACPI_CAST_PTR (union acpi_operand_object *, gpe_event_info);
		info.parameter_type = ACPI_PARAM_GPE;

		status = acpi_ns_evaluate_by_handle (&info);
		if (ACPI_FAILURE (status)) {
			ACPI_REPORT_ERROR ((
				"%s while evaluating method [%4.4s] for GPE[%2X]\n",
				acpi_format_exception (status),
				acpi_ut_get_node_name (local_gpe_event_info.dispatch.method_node),
				gpe_number));
		}
	}
コード例 #5
0
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
{
	struct acpi_gpe_event_info *gpe_event_info = (void *)context;
	acpi_status status;
	struct acpi_gpe_event_info local_gpe_event_info;
	struct acpi_evaluate_info *info;

	ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);

	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
	if (ACPI_FAILURE(status)) {
		return_VOID;
	}

	

	if (!acpi_ev_valid_gpe_event(gpe_event_info)) {
		status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
		return_VOID;
	}

	

	(void)acpi_ev_enable_gpe(gpe_event_info, FALSE);

	
	ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info,
		    sizeof(struct acpi_gpe_event_info));

	status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
	if (ACPI_FAILURE(status)) {
		return_VOID;
	}

	
	if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) ==
	    ACPI_GPE_DISPATCH_METHOD) {

		

		info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
		if (!info) {
			status = AE_NO_MEMORY;
		} else {
			
			info->prefix_node =
			    local_gpe_event_info.dispatch.method_node;
			info->flags = ACPI_IGNORE_RETURN_VALUE;

			status = acpi_ns_evaluate(info);
			ACPI_FREE(info);
		}

		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"while evaluating GPE method [%4.4s]",
					acpi_ut_get_node_name
					(local_gpe_event_info.dispatch.
					 method_node)));
		}
	}
	
	acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe,
				gpe_event_info);
	return_VOID;
}