mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
ACPICA: Add support for multiple notify handlers
This change adds support to allow multiple notify handlers on Device, ThermalZone, and Processor objects. Also re-worked and restructured the entire notify support code for handler installation, handler removal, notify event queuing, and notify dispatch to handler. Extends and updates original commit 3f0be67("ACPI / ACPICA: Multiple system notify handlers per device") by Rafael Wysocki. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
parent
5134abfcfb
commit
86ed4bc83a
9 changed files with 294 additions and 469 deletions
|
@ -278,8 +278,7 @@ ACPI_EXTERN acpi_cache_t *acpi_gbl_operand_cache;
|
||||||
|
|
||||||
/* Global handlers */
|
/* Global handlers */
|
||||||
|
|
||||||
ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_device_notify;
|
ACPI_EXTERN struct acpi_global_notify_handler acpi_gbl_global_notify[2];
|
||||||
ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_system_notify;
|
|
||||||
ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler;
|
ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler;
|
||||||
ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler;
|
ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler;
|
||||||
ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler;
|
ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler;
|
||||||
|
|
|
@ -600,13 +600,22 @@ acpi_status(*acpi_parse_downwards) (struct acpi_walk_state * walk_state,
|
||||||
|
|
||||||
typedef acpi_status(*acpi_parse_upwards) (struct acpi_walk_state * walk_state);
|
typedef acpi_status(*acpi_parse_upwards) (struct acpi_walk_state * walk_state);
|
||||||
|
|
||||||
|
/* Global handlers for AML Notifies */
|
||||||
|
|
||||||
|
struct acpi_global_notify_handler {
|
||||||
|
acpi_notify_handler handler;
|
||||||
|
void *context;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Notify info - used to pass info to the deferred notify
|
* Notify info - used to pass info to the deferred notify
|
||||||
* handler/dispatcher.
|
* handler/dispatcher.
|
||||||
*/
|
*/
|
||||||
struct acpi_notify_info {
|
struct acpi_notify_info {
|
||||||
ACPI_STATE_COMMON struct acpi_namespace_node *node;
|
ACPI_STATE_COMMON u8 handler_list_id;
|
||||||
union acpi_operand_object *handler_obj;
|
struct acpi_namespace_node *node;
|
||||||
|
union acpi_operand_object *handler_list_head;
|
||||||
|
struct acpi_global_notify_handler *global;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Generic state is union of structs above */
|
/* Generic state is union of structs above */
|
||||||
|
|
|
@ -206,8 +206,7 @@ struct acpi_object_method {
|
||||||
* Common fields for objects that support ASL notifications
|
* Common fields for objects that support ASL notifications
|
||||||
*/
|
*/
|
||||||
#define ACPI_COMMON_NOTIFY_INFO \
|
#define ACPI_COMMON_NOTIFY_INFO \
|
||||||
union acpi_operand_object *system_notify; /* Handler for system notifies */\
|
union acpi_operand_object *notify_list[2]; /* Handlers for system/device notifies */\
|
||||||
union acpi_operand_object *device_notify; /* Handler for driver notifies */\
|
|
||||||
union acpi_operand_object *handler; /* Handler for Address space */
|
union acpi_operand_object *handler; /* Handler for Address space */
|
||||||
|
|
||||||
struct acpi_object_notify_common { /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */
|
struct acpi_object_notify_common { /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */
|
||||||
|
@ -296,10 +295,10 @@ struct acpi_object_buffer_field {
|
||||||
|
|
||||||
struct acpi_object_notify_handler {
|
struct acpi_object_notify_handler {
|
||||||
ACPI_OBJECT_COMMON_HEADER struct acpi_namespace_node *node; /* Parent device */
|
ACPI_OBJECT_COMMON_HEADER struct acpi_namespace_node *node; /* Parent device */
|
||||||
u32 handler_type;
|
u32 handler_type; /* Type: Device/System/Both */
|
||||||
acpi_notify_handler handler;
|
acpi_notify_handler handler; /* Handler address */
|
||||||
void *context;
|
void *context;
|
||||||
struct acpi_object_notify_handler *next;
|
union acpi_operand_object *next[2]; /* Device and System handler lists */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct acpi_object_addr_handler {
|
struct acpi_object_addr_handler {
|
||||||
|
|
|
@ -101,102 +101,77 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
|
||||||
u32 notify_value)
|
u32 notify_value)
|
||||||
{
|
{
|
||||||
union acpi_operand_object *obj_desc;
|
union acpi_operand_object *obj_desc;
|
||||||
union acpi_operand_object *handler_obj = NULL;
|
union acpi_operand_object *handler_list_head = NULL;
|
||||||
union acpi_generic_state *notify_info;
|
union acpi_generic_state *info;
|
||||||
|
u8 handler_list_id = 0;
|
||||||
acpi_status status = AE_OK;
|
acpi_status status = AE_OK;
|
||||||
|
|
||||||
ACPI_FUNCTION_NAME(ev_queue_notify_request);
|
ACPI_FUNCTION_NAME(ev_queue_notify_request);
|
||||||
|
|
||||||
|
/* Are Notifies allowed on this object? */
|
||||||
|
|
||||||
|
if (!acpi_ev_is_notify_object(node)) {
|
||||||
|
return (AE_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the correct notify list type (System or Device) */
|
||||||
|
|
||||||
|
if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
|
||||||
|
handler_list_id = ACPI_SYSTEM_HANDLER_LIST;
|
||||||
|
} else {
|
||||||
|
handler_list_id = ACPI_DEVICE_HANDLER_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the notify object attached to the namespace Node */
|
||||||
|
|
||||||
|
obj_desc = acpi_ns_get_attached_object(node);
|
||||||
|
if (obj_desc) {
|
||||||
|
|
||||||
|
/* We have an attached object, Get the correct handler list */
|
||||||
|
|
||||||
|
handler_list_head =
|
||||||
|
obj_desc->common_notify.notify_list[handler_list_id];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For value 0x03 (Ejection Request), may need to run a device method.
|
* If there is no notify handler (Global or Local)
|
||||||
* For value 0x02 (Device Wake), if _PRW exists, may need to run
|
* for this object, just ignore the notify
|
||||||
* the _PS0 method.
|
|
||||||
* For value 0x80 (Status Change) on the power button or sleep button,
|
|
||||||
* initiate soft-off or sleep operation.
|
|
||||||
*
|
|
||||||
* For all cases, simply dispatch the notify to the handler.
|
|
||||||
*/
|
*/
|
||||||
|
if (!acpi_gbl_global_notify[handler_list_id].handler
|
||||||
|
&& !handler_list_head) {
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||||
|
"No notify handler for Notify, ignoring (%4.4s, %X) node %p\n",
|
||||||
|
acpi_ut_get_node_name(node), notify_value,
|
||||||
|
node));
|
||||||
|
|
||||||
|
return (AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup notify info and schedule the notify dispatcher */
|
||||||
|
|
||||||
|
info = acpi_ut_create_generic_state();
|
||||||
|
if (!info) {
|
||||||
|
return (AE_NO_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
info->common.descriptor_type = ACPI_DESC_TYPE_STATE_NOTIFY;
|
||||||
|
|
||||||
|
info->notify.node = node;
|
||||||
|
info->notify.value = (u16)notify_value;
|
||||||
|
info->notify.handler_list_id = handler_list_id;
|
||||||
|
info->notify.handler_list_head = handler_list_head;
|
||||||
|
info->notify.global = &acpi_gbl_global_notify[handler_list_id];
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||||
"Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
|
"Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
|
||||||
acpi_ut_get_node_name(node),
|
acpi_ut_get_node_name(node),
|
||||||
acpi_ut_get_type_name(node->type), notify_value,
|
acpi_ut_get_type_name(node->type), notify_value,
|
||||||
acpi_ut_get_notify_name(notify_value), node));
|
acpi_ut_get_notify_name(notify_value), node));
|
||||||
|
|
||||||
/* Get the notify object attached to the NS Node */
|
status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
|
||||||
|
info);
|
||||||
obj_desc = acpi_ns_get_attached_object(node);
|
if (ACPI_FAILURE(status)) {
|
||||||
if (obj_desc) {
|
acpi_ut_delete_generic_state(info);
|
||||||
|
|
||||||
/* We have the notify object, Get the correct handler */
|
|
||||||
|
|
||||||
switch (node->type) {
|
|
||||||
|
|
||||||
/* Notify is allowed only on these types */
|
|
||||||
|
|
||||||
case ACPI_TYPE_DEVICE:
|
|
||||||
case ACPI_TYPE_THERMAL:
|
|
||||||
case ACPI_TYPE_PROCESSOR:
|
|
||||||
|
|
||||||
if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
|
|
||||||
handler_obj =
|
|
||||||
obj_desc->common_notify.system_notify;
|
|
||||||
} else {
|
|
||||||
handler_obj =
|
|
||||||
obj_desc->common_notify.device_notify;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
/* All other types are not supported */
|
|
||||||
|
|
||||||
return (AE_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If there is a handler to run, schedule the dispatcher.
|
|
||||||
* Check for:
|
|
||||||
* 1) Global system notify handler
|
|
||||||
* 2) Global device notify handler
|
|
||||||
* 3) Per-device notify handler
|
|
||||||
*/
|
|
||||||
if ((acpi_gbl_system_notify.handler &&
|
|
||||||
(notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
|
|
||||||
(acpi_gbl_device_notify.handler &&
|
|
||||||
(notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
|
|
||||||
notify_info = acpi_ut_create_generic_state();
|
|
||||||
if (!notify_info) {
|
|
||||||
return (AE_NO_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!handler_obj) {
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
|
||||||
"Executing system notify handler for Notify (%4.4s, %X) "
|
|
||||||
"node %p\n",
|
|
||||||
acpi_ut_get_node_name(node),
|
|
||||||
notify_value, node));
|
|
||||||
}
|
|
||||||
|
|
||||||
notify_info->common.descriptor_type =
|
|
||||||
ACPI_DESC_TYPE_STATE_NOTIFY;
|
|
||||||
notify_info->notify.node = node;
|
|
||||||
notify_info->notify.value = (u16) notify_value;
|
|
||||||
notify_info->notify.handler_obj = handler_obj;
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
|
|
||||||
notify_info);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
acpi_ut_delete_generic_state(notify_info);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* There is no notify handler (per-device or system) for this device */
|
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
|
||||||
"No notify handler for Notify (%4.4s, %X) node %p\n",
|
|
||||||
acpi_ut_get_node_name(node), notify_value,
|
|
||||||
node));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (status);
|
return (status);
|
||||||
|
@ -217,60 +192,34 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
|
||||||
|
|
||||||
static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
|
static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
|
||||||
{
|
{
|
||||||
union acpi_generic_state *notify_info =
|
union acpi_generic_state *info = (union acpi_generic_state *)context;
|
||||||
(union acpi_generic_state *)context;
|
|
||||||
acpi_notify_handler global_handler = NULL;
|
|
||||||
void *global_context = NULL;
|
|
||||||
union acpi_operand_object *handler_obj;
|
union acpi_operand_object *handler_obj;
|
||||||
|
|
||||||
ACPI_FUNCTION_ENTRY();
|
ACPI_FUNCTION_ENTRY();
|
||||||
|
|
||||||
/*
|
/* Invoke a global notify handler if installed */
|
||||||
* We will invoke a global notify handler if installed. This is done
|
|
||||||
* _before_ we invoke the per-device handler attached to the device.
|
|
||||||
*/
|
|
||||||
if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) {
|
|
||||||
|
|
||||||
/* Global system notification handler */
|
if (info->notify.global->handler) {
|
||||||
|
info->notify.global->handler(info->notify.node,
|
||||||
if (acpi_gbl_system_notify.handler) {
|
info->notify.value,
|
||||||
global_handler = acpi_gbl_system_notify.handler;
|
info->notify.global->context);
|
||||||
global_context = acpi_gbl_system_notify.context;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Global driver notification handler */
|
|
||||||
|
|
||||||
if (acpi_gbl_device_notify.handler) {
|
|
||||||
global_handler = acpi_gbl_device_notify.handler;
|
|
||||||
global_context = acpi_gbl_device_notify.context;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Invoke the system handler first, if present */
|
/* Now invoke the local notify handler(s) if any are installed */
|
||||||
|
|
||||||
if (global_handler) {
|
handler_obj = info->notify.handler_list_head;
|
||||||
global_handler(notify_info->notify.node,
|
while (handler_obj) {
|
||||||
notify_info->notify.value, global_context);
|
handler_obj->notify.handler(info->notify.node,
|
||||||
}
|
info->notify.value,
|
||||||
|
handler_obj->notify.context);
|
||||||
|
|
||||||
/* Now invoke the per-device handler, if present */
|
handler_obj =
|
||||||
|
handler_obj->notify.next[info->notify.handler_list_id];
|
||||||
handler_obj = notify_info->notify.handler_obj;
|
|
||||||
if (handler_obj) {
|
|
||||||
struct acpi_object_notify_handler *notifier;
|
|
||||||
|
|
||||||
notifier = &handler_obj->notify;
|
|
||||||
while (notifier) {
|
|
||||||
notifier->handler(notify_info->notify.node,
|
|
||||||
notify_info->notify.value,
|
|
||||||
notifier->context);
|
|
||||||
notifier = notifier->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All done with the info object */
|
/* All done with the info object */
|
||||||
|
|
||||||
acpi_ut_delete_generic_state(notify_info);
|
acpi_ut_delete_generic_state(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (!ACPI_REDUCED_HARDWARE)
|
#if (!ACPI_REDUCED_HARDWARE)
|
||||||
|
|
|
@ -52,88 +52,27 @@
|
||||||
ACPI_MODULE_NAME("evxface")
|
ACPI_MODULE_NAME("evxface")
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_populate_handler_object
|
|
||||||
*
|
|
||||||
* PARAMETERS: handler_obj - Handler object to populate
|
|
||||||
* handler_type - The type of handler:
|
|
||||||
* ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
|
|
||||||
* ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
|
|
||||||
* ACPI_ALL_NOTIFY: both system and device
|
|
||||||
* handler - Address of the handler
|
|
||||||
* context - Value passed to the handler on each GPE
|
|
||||||
* next - Address of a handler object to link to
|
|
||||||
*
|
|
||||||
* RETURN: None
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Populate a handler object.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
static void
|
|
||||||
acpi_populate_handler_object(struct acpi_object_notify_handler *handler_obj,
|
|
||||||
u32 handler_type,
|
|
||||||
acpi_notify_handler handler, void *context,
|
|
||||||
struct acpi_object_notify_handler *next)
|
|
||||||
{
|
|
||||||
handler_obj->handler_type = handler_type;
|
|
||||||
handler_obj->handler = handler;
|
|
||||||
handler_obj->context = context;
|
|
||||||
handler_obj->next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_add_handler_object
|
|
||||||
*
|
|
||||||
* PARAMETERS: parent_obj - Parent of the new object
|
|
||||||
* handler - Address of the handler
|
|
||||||
* context - Value passed to the handler on each GPE
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Create a new handler object and populate it.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
static acpi_status
|
|
||||||
acpi_add_handler_object(struct acpi_object_notify_handler *parent_obj,
|
|
||||||
acpi_notify_handler handler, void *context)
|
|
||||||
{
|
|
||||||
struct acpi_object_notify_handler *handler_obj;
|
|
||||||
|
|
||||||
/* The parent must not be a defice notify handler object. */
|
|
||||||
if (parent_obj->handler_type & ACPI_DEVICE_NOTIFY)
|
|
||||||
return AE_BAD_PARAMETER;
|
|
||||||
|
|
||||||
handler_obj = ACPI_ALLOCATE_ZEROED(sizeof(*handler_obj));
|
|
||||||
if (!handler_obj)
|
|
||||||
return AE_NO_MEMORY;
|
|
||||||
|
|
||||||
acpi_populate_handler_object(handler_obj,
|
|
||||||
ACPI_SYSTEM_NOTIFY,
|
|
||||||
handler, context,
|
|
||||||
parent_obj->next);
|
|
||||||
parent_obj->next = handler_obj;
|
|
||||||
|
|
||||||
return AE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_install_notify_handler
|
* FUNCTION: acpi_install_notify_handler
|
||||||
*
|
*
|
||||||
* PARAMETERS: Device - The device for which notifies will be handled
|
* PARAMETERS: Device - The device for which notifies will be handled
|
||||||
* handler_type - The type of handler:
|
* handler_type - The type of handler:
|
||||||
* ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
|
* ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
|
||||||
* ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
|
* ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
|
||||||
* ACPI_ALL_NOTIFY: both system and device
|
* ACPI_ALL_NOTIFY: Both System and Device
|
||||||
* Handler - Address of the handler
|
* Handler - Address of the handler
|
||||||
* Context - Value passed to the handler on each GPE
|
* Context - Value passed to the handler on each GPE
|
||||||
*
|
*
|
||||||
* RETURN: Status
|
* RETURN: Status
|
||||||
*
|
*
|
||||||
* DESCRIPTION: Install a handler for notifies on an ACPI device
|
* DESCRIPTION: Install a handler for notifications on an ACPI Device,
|
||||||
|
* thermal_zone, or Processor object.
|
||||||
|
*
|
||||||
|
* NOTES: The Root namespace object may have only one handler for each
|
||||||
|
* type of notify (System/Device). Device/Thermal/Processor objects
|
||||||
|
* may have one device notify handler, and multiple system notify
|
||||||
|
* handlers.
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
acpi_status
|
acpi_status
|
||||||
|
@ -141,17 +80,19 @@ acpi_install_notify_handler(acpi_handle device,
|
||||||
u32 handler_type,
|
u32 handler_type,
|
||||||
acpi_notify_handler handler, void *context)
|
acpi_notify_handler handler, void *context)
|
||||||
{
|
{
|
||||||
|
struct acpi_namespace_node *node =
|
||||||
|
ACPI_CAST_PTR(struct acpi_namespace_node, device);
|
||||||
union acpi_operand_object *obj_desc;
|
union acpi_operand_object *obj_desc;
|
||||||
union acpi_operand_object *notify_obj;
|
union acpi_operand_object *handler_obj;
|
||||||
struct acpi_namespace_node *node;
|
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(acpi_install_notify_handler);
|
ACPI_FUNCTION_TRACE(acpi_install_notify_handler);
|
||||||
|
|
||||||
/* Parameter validation */
|
/* Parameter validation */
|
||||||
|
|
||||||
if ((!device) ||
|
if ((!device) || (!handler) || (!handler_type) ||
|
||||||
(!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
|
(handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
|
||||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,144 +101,112 @@ acpi_install_notify_handler(acpi_handle device,
|
||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert and validate the device handle */
|
|
||||||
|
|
||||||
node = acpi_ns_validate_handle(device);
|
|
||||||
if (!node) {
|
|
||||||
status = AE_BAD_PARAMETER;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Root Object:
|
* Root Object:
|
||||||
* Registering a notify handler on the root object indicates that the
|
* Registering a notify handler on the root object indicates that the
|
||||||
* caller wishes to receive notifications for all objects. Note that
|
* caller wishes to receive notifications for all objects. Note that
|
||||||
* only one <external> global handler can be regsitered (per notify type).
|
* only one global handler can be registered per notify type.
|
||||||
|
* Ensure that a handler is not already installed.
|
||||||
*/
|
*/
|
||||||
if (device == ACPI_ROOT_OBJECT) {
|
if (device == ACPI_ROOT_OBJECT) {
|
||||||
|
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
|
||||||
/* Make sure the handler is not already installed */
|
if (handler_type & (i + 1)) {
|
||||||
|
if (acpi_gbl_global_notify[i].handler) {
|
||||||
if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
|
|
||||||
acpi_gbl_system_notify.handler) ||
|
|
||||||
((handler_type & ACPI_DEVICE_NOTIFY) &&
|
|
||||||
acpi_gbl_device_notify.handler)) {
|
|
||||||
status = AE_ALREADY_EXISTS;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler_type & ACPI_SYSTEM_NOTIFY) {
|
|
||||||
acpi_gbl_system_notify.node = node;
|
|
||||||
acpi_gbl_system_notify.handler = handler;
|
|
||||||
acpi_gbl_system_notify.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler_type & ACPI_DEVICE_NOTIFY) {
|
|
||||||
acpi_gbl_device_notify.node = node;
|
|
||||||
acpi_gbl_device_notify.handler = handler;
|
|
||||||
acpi_gbl_device_notify.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Global notify handler installed */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* All Other Objects:
|
|
||||||
* Caller will only receive notifications specific to the target object.
|
|
||||||
* Note that only certain object types can receive notifications.
|
|
||||||
*/
|
|
||||||
else {
|
|
||||||
/* Notifies allowed on this object? */
|
|
||||||
|
|
||||||
if (!acpi_ev_is_notify_object(node)) {
|
|
||||||
status = AE_TYPE;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for an existing internal object */
|
|
||||||
|
|
||||||
obj_desc = acpi_ns_get_attached_object(node);
|
|
||||||
if (obj_desc) {
|
|
||||||
|
|
||||||
/* Object exists. */
|
|
||||||
|
|
||||||
/* For a device notify, make sure there's no handler. */
|
|
||||||
if ((handler_type & ACPI_DEVICE_NOTIFY) &&
|
|
||||||
obj_desc->common_notify.device_notify) {
|
|
||||||
status = AE_ALREADY_EXISTS;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* System notifies may have more handlers installed. */
|
|
||||||
notify_obj = obj_desc->common_notify.system_notify;
|
|
||||||
|
|
||||||
if ((handler_type & ACPI_SYSTEM_NOTIFY) && notify_obj) {
|
|
||||||
struct acpi_object_notify_handler *parent_obj;
|
|
||||||
|
|
||||||
if (handler_type & ACPI_DEVICE_NOTIFY) {
|
|
||||||
status = AE_ALREADY_EXISTS;
|
status = AE_ALREADY_EXISTS;
|
||||||
goto unlock_and_exit;
|
goto unlock_and_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent_obj = ¬ify_obj->notify;
|
acpi_gbl_global_notify[i].handler = handler;
|
||||||
status = acpi_add_handler_object(parent_obj,
|
acpi_gbl_global_notify[i].context = context;
|
||||||
handler,
|
|
||||||
context);
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Create a new object */
|
|
||||||
|
|
||||||
obj_desc = acpi_ut_create_internal_object(node->type);
|
|
||||||
if (!obj_desc) {
|
|
||||||
status = AE_NO_MEMORY;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Attach new object to the Node */
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_attach_object(device, obj_desc, node->type);
|
|
||||||
|
|
||||||
/* Remove local reference to the object */
|
|
||||||
|
|
||||||
acpi_ut_remove_reference(obj_desc);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Install the handler */
|
goto unlock_and_exit; /* Global notify handler installed, all done */
|
||||||
|
}
|
||||||
|
|
||||||
notify_obj =
|
/*
|
||||||
acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_NOTIFY);
|
* All Other Objects:
|
||||||
if (!notify_obj) {
|
* Caller will only receive notifications specific to the target
|
||||||
|
* object. Note that only certain object types are allowed to
|
||||||
|
* receive notifications.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Are Notifies allowed on this object? */
|
||||||
|
|
||||||
|
if (!acpi_ev_is_notify_object(node)) {
|
||||||
|
status = AE_TYPE;
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for an existing internal object, might not exist */
|
||||||
|
|
||||||
|
obj_desc = acpi_ns_get_attached_object(node);
|
||||||
|
if (!obj_desc) {
|
||||||
|
|
||||||
|
/* Create a new object */
|
||||||
|
|
||||||
|
obj_desc = acpi_ut_create_internal_object(node->type);
|
||||||
|
if (!obj_desc) {
|
||||||
status = AE_NO_MEMORY;
|
status = AE_NO_MEMORY;
|
||||||
goto unlock_and_exit;
|
goto unlock_and_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
acpi_populate_handler_object(¬ify_obj->notify,
|
/* Attach new object to the Node, remove local reference */
|
||||||
handler_type,
|
|
||||||
handler, context,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (handler_type & ACPI_SYSTEM_NOTIFY) {
|
status = acpi_ns_attach_object(device, obj_desc, node->type);
|
||||||
obj_desc->common_notify.system_notify = notify_obj;
|
acpi_ut_remove_reference(obj_desc);
|
||||||
}
|
if (ACPI_FAILURE(status)) {
|
||||||
|
goto unlock_and_exit;
|
||||||
if (handler_type & ACPI_DEVICE_NOTIFY) {
|
|
||||||
obj_desc->common_notify.device_notify = notify_obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler_type == ACPI_ALL_NOTIFY) {
|
|
||||||
|
|
||||||
/* Extra ref if installed in both */
|
|
||||||
|
|
||||||
acpi_ut_add_reference(notify_obj);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_and_exit:
|
/* Ensure that the handler is not already installed in the lists */
|
||||||
|
|
||||||
|
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
|
||||||
|
if (handler_type & (i + 1)) {
|
||||||
|
handler_obj = obj_desc->common_notify.notify_list[i];
|
||||||
|
while (handler_obj) {
|
||||||
|
if (handler_obj->notify.handler == handler) {
|
||||||
|
status = AE_ALREADY_EXISTS;
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler_obj = handler_obj->notify.next[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create and populate a new notify handler object */
|
||||||
|
|
||||||
|
handler_obj = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_NOTIFY);
|
||||||
|
if (!handler_obj) {
|
||||||
|
status = AE_NO_MEMORY;
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler_obj->notify.node = node;
|
||||||
|
handler_obj->notify.handler_type = handler_type;
|
||||||
|
handler_obj->notify.handler = handler;
|
||||||
|
handler_obj->notify.context = context;
|
||||||
|
|
||||||
|
/* Install the handler at the list head(s) */
|
||||||
|
|
||||||
|
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
|
||||||
|
if (handler_type & (i + 1)) {
|
||||||
|
handler_obj->notify.next[i] =
|
||||||
|
obj_desc->common_notify.notify_list[i];
|
||||||
|
|
||||||
|
obj_desc->common_notify.notify_list[i] = handler_obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add an extra reference if handler was installed in both lists */
|
||||||
|
|
||||||
|
if (handler_type == ACPI_ALL_NOTIFY) {
|
||||||
|
acpi_ut_add_reference(handler_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock_and_exit:
|
||||||
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
@ -308,11 +217,11 @@ ACPI_EXPORT_SYMBOL(acpi_install_notify_handler)
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_remove_notify_handler
|
* FUNCTION: acpi_remove_notify_handler
|
||||||
*
|
*
|
||||||
* PARAMETERS: Device - The device for which notifies will be handled
|
* PARAMETERS: Device - The device for which the handler is installed
|
||||||
* handler_type - The type of handler:
|
* handler_type - The type of handler:
|
||||||
* ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
|
* ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
|
||||||
* ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
|
* ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
|
||||||
* ACPI_ALL_NOTIFY: both system and device
|
* ACPI_ALL_NOTIFY: Both System and Device
|
||||||
* Handler - Address of the handler
|
* Handler - Address of the handler
|
||||||
*
|
*
|
||||||
* RETURN: Status
|
* RETURN: Status
|
||||||
|
@ -324,165 +233,106 @@ acpi_status
|
||||||
acpi_remove_notify_handler(acpi_handle device,
|
acpi_remove_notify_handler(acpi_handle device,
|
||||||
u32 handler_type, acpi_notify_handler handler)
|
u32 handler_type, acpi_notify_handler handler)
|
||||||
{
|
{
|
||||||
union acpi_operand_object *notify_obj;
|
struct acpi_namespace_node *node =
|
||||||
|
ACPI_CAST_PTR(struct acpi_namespace_node, device);
|
||||||
union acpi_operand_object *obj_desc;
|
union acpi_operand_object *obj_desc;
|
||||||
struct acpi_namespace_node *node;
|
union acpi_operand_object *handler_obj;
|
||||||
|
union acpi_operand_object *previous_handler_obj;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(acpi_remove_notify_handler);
|
ACPI_FUNCTION_TRACE(acpi_remove_notify_handler);
|
||||||
|
|
||||||
/* Parameter validation */
|
/* Parameter validation */
|
||||||
|
|
||||||
if ((!device) ||
|
if ((!device) || (!handler) || (!handler_type) ||
|
||||||
(!handler) || (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
|
(handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
|
||||||
status = AE_BAD_PARAMETER;
|
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Make sure all deferred tasks are completed */
|
/* Make sure all deferred tasks are completed */
|
||||||
|
|
||||||
acpi_os_wait_events_complete(NULL);
|
acpi_os_wait_events_complete(NULL);
|
||||||
|
|
||||||
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
goto exit;
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert and validate the device handle */
|
/* Root Object. Global handlers are removed here */
|
||||||
|
|
||||||
|
if (device == ACPI_ROOT_OBJECT) {
|
||||||
|
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
|
||||||
|
if (handler_type & (i + 1)) {
|
||||||
|
if (!acpi_gbl_global_notify[i].handler ||
|
||||||
|
(acpi_gbl_global_notify[i].handler !=
|
||||||
|
handler)) {
|
||||||
|
status = AE_NOT_EXIST;
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||||
|
"Removing global notify handler\n"));
|
||||||
|
|
||||||
|
acpi_gbl_global_notify[i].handler = NULL;
|
||||||
|
acpi_gbl_global_notify[i].context = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
node = acpi_ns_validate_handle(device);
|
|
||||||
if (!node) {
|
|
||||||
status = AE_BAD_PARAMETER;
|
|
||||||
goto unlock_and_exit;
|
goto unlock_and_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Root Object */
|
/* All other objects: Are Notifies allowed on this object? */
|
||||||
|
|
||||||
if (device == ACPI_ROOT_OBJECT) {
|
if (!acpi_ev_is_notify_object(node)) {
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
status = AE_TYPE;
|
||||||
"Removing notify handler for namespace root object\n"));
|
goto unlock_and_exit;
|
||||||
|
|
||||||
if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
|
|
||||||
!acpi_gbl_system_notify.handler) ||
|
|
||||||
((handler_type & ACPI_DEVICE_NOTIFY) &&
|
|
||||||
!acpi_gbl_device_notify.handler)) {
|
|
||||||
status = AE_NOT_EXIST;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler_type & ACPI_SYSTEM_NOTIFY) {
|
|
||||||
acpi_gbl_system_notify.node = NULL;
|
|
||||||
acpi_gbl_system_notify.handler = NULL;
|
|
||||||
acpi_gbl_system_notify.context = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler_type & ACPI_DEVICE_NOTIFY) {
|
|
||||||
acpi_gbl_device_notify.node = NULL;
|
|
||||||
acpi_gbl_device_notify.handler = NULL;
|
|
||||||
acpi_gbl_device_notify.context = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All Other Objects */
|
/* Must have an existing internal object */
|
||||||
|
|
||||||
else {
|
obj_desc = acpi_ns_get_attached_object(node);
|
||||||
/* Notifies allowed on this object? */
|
if (!obj_desc) {
|
||||||
|
status = AE_NOT_EXIST;
|
||||||
|
goto unlock_and_exit;
|
||||||
|
}
|
||||||
|
|
||||||
if (!acpi_ev_is_notify_object(node)) {
|
/* Internal object exists. Find the handler and remove it */
|
||||||
status = AE_TYPE;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for an existing internal object */
|
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
|
||||||
|
if (handler_type & (i + 1)) {
|
||||||
|
handler_obj = obj_desc->common_notify.notify_list[i];
|
||||||
|
previous_handler_obj = NULL;
|
||||||
|
|
||||||
obj_desc = acpi_ns_get_attached_object(node);
|
/* Attempt to find the handler in the handler list */
|
||||||
if (!obj_desc) {
|
|
||||||
status = AE_NOT_EXIST;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Object exists - make sure there's an existing handler */
|
while (handler_obj &&
|
||||||
|
(handler_obj->notify.handler != handler)) {
|
||||||
|
previous_handler_obj = handler_obj;
|
||||||
|
handler_obj = handler_obj->notify.next[i];
|
||||||
|
}
|
||||||
|
|
||||||
if (handler_type & ACPI_SYSTEM_NOTIFY) {
|
if (!handler_obj) {
|
||||||
struct acpi_object_notify_handler *handler_obj;
|
|
||||||
struct acpi_object_notify_handler *parent_obj;
|
|
||||||
|
|
||||||
notify_obj = obj_desc->common_notify.system_notify;
|
|
||||||
if (!notify_obj) {
|
|
||||||
status = AE_NOT_EXIST;
|
status = AE_NOT_EXIST;
|
||||||
goto unlock_and_exit;
|
goto unlock_and_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
handler_obj = ¬ify_obj->notify;
|
/* Remove the handler object from the list */
|
||||||
parent_obj = NULL;
|
|
||||||
while (handler_obj->handler != handler) {
|
if (previous_handler_obj) { /* Handler is not at the list head */
|
||||||
if (handler_obj->next) {
|
previous_handler_obj->notify.next[i] =
|
||||||
parent_obj = handler_obj;
|
handler_obj->notify.next[i];
|
||||||
handler_obj = handler_obj->next;
|
} else { /* Handler is at the list head */
|
||||||
} else {
|
|
||||||
break;
|
obj_desc->common_notify.notify_list[i] =
|
||||||
}
|
handler_obj->notify.next[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handler_obj->handler != handler) {
|
acpi_ut_remove_reference(handler_obj);
|
||||||
status = AE_BAD_PARAMETER;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove the handler. There are three possible cases.
|
|
||||||
* First, we may need to remove a non-embedded object.
|
|
||||||
* Second, we may need to remove the embedded object's
|
|
||||||
* handler data, while non-embedded objects exist.
|
|
||||||
* Finally, we may need to remove the embedded object
|
|
||||||
* entirely along with its container.
|
|
||||||
*/
|
|
||||||
if (parent_obj) {
|
|
||||||
/* Non-embedded object is being removed. */
|
|
||||||
parent_obj->next = handler_obj->next;
|
|
||||||
ACPI_FREE(handler_obj);
|
|
||||||
} else if (notify_obj->notify.next) {
|
|
||||||
/*
|
|
||||||
* The handler matches the embedded object, but
|
|
||||||
* there are more handler objects in the list.
|
|
||||||
* Replace the embedded object's data with the
|
|
||||||
* first next object's data and remove that
|
|
||||||
* object.
|
|
||||||
*/
|
|
||||||
parent_obj = ¬ify_obj->notify;
|
|
||||||
handler_obj = notify_obj->notify.next;
|
|
||||||
*parent_obj = *handler_obj;
|
|
||||||
ACPI_FREE(handler_obj);
|
|
||||||
} else {
|
|
||||||
/* No more handler objects in the list. */
|
|
||||||
obj_desc->common_notify.system_notify = NULL;
|
|
||||||
acpi_ut_remove_reference(notify_obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler_type & ACPI_DEVICE_NOTIFY) {
|
|
||||||
notify_obj = obj_desc->common_notify.device_notify;
|
|
||||||
if (!notify_obj) {
|
|
||||||
status = AE_NOT_EXIST;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notify_obj->notify.handler != handler) {
|
|
||||||
status = AE_BAD_PARAMETER;
|
|
||||||
goto unlock_and_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the handler */
|
|
||||||
obj_desc->common_notify.device_notify = NULL;
|
|
||||||
acpi_ut_remove_reference(notify_obj);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_and_exit:
|
unlock_and_exit:
|
||||||
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||||
exit:
|
|
||||||
if (ACPI_FAILURE(status))
|
|
||||||
ACPI_EXCEPTION((AE_INFO, status, "Removing notify handler"));
|
|
||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,9 +109,9 @@ static struct acpi_exdump_info acpi_ex_dump_package[5] = {
|
||||||
static struct acpi_exdump_info acpi_ex_dump_device[4] = {
|
static struct acpi_exdump_info acpi_ex_dump_device[4] = {
|
||||||
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_device), NULL},
|
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_device), NULL},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.handler), "Handler"},
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.handler), "Handler"},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.system_notify),
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.notify_list[0]),
|
||||||
"System Notify"},
|
"System Notify"},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.device_notify),
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.notify_list[1]),
|
||||||
"Device Notify"}
|
"Device Notify"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -158,9 +158,9 @@ static struct acpi_exdump_info acpi_ex_dump_power[5] = {
|
||||||
"System Level"},
|
"System Level"},
|
||||||
{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.resource_order),
|
{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.resource_order),
|
||||||
"Resource Order"},
|
"Resource Order"},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.system_notify),
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.notify_list[0]),
|
||||||
"System Notify"},
|
"System Notify"},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.device_notify),
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.notify_list[1]),
|
||||||
"Device Notify"}
|
"Device Notify"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -169,18 +169,18 @@ static struct acpi_exdump_info acpi_ex_dump_processor[7] = {
|
||||||
{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"},
|
{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"},
|
||||||
{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.length), "Length"},
|
{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.length), "Length"},
|
||||||
{ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"},
|
{ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.system_notify),
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.notify_list[0]),
|
||||||
"System Notify"},
|
"System Notify"},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.device_notify),
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.notify_list[1]),
|
||||||
"Device Notify"},
|
"Device Notify"},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.handler), "Handler"}
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.handler), "Handler"}
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct acpi_exdump_info acpi_ex_dump_thermal[4] = {
|
static struct acpi_exdump_info acpi_ex_dump_thermal[4] = {
|
||||||
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_thermal), NULL},
|
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_thermal), NULL},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.system_notify),
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.notify_list[0]),
|
||||||
"System Notify"},
|
"System Notify"},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.device_notify),
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.notify_list[1]),
|
||||||
"Device Notify"},
|
"Device Notify"},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.handler), "Handler"}
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.handler), "Handler"}
|
||||||
};
|
};
|
||||||
|
@ -241,10 +241,15 @@ static struct acpi_exdump_info acpi_ex_dump_address_handler[6] = {
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.context), "Context"}
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.context), "Context"}
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct acpi_exdump_info acpi_ex_dump_notify[3] = {
|
static struct acpi_exdump_info acpi_ex_dump_notify[7] = {
|
||||||
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_notify), NULL},
|
{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_notify), NULL},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.node), "Node"},
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.node), "Node"},
|
||||||
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.context), "Context"}
|
{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(notify.handler_type), "Handler Type"},
|
||||||
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.handler), "Handler"},
|
||||||
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.context), "Context"},
|
||||||
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.next[0]),
|
||||||
|
"Next System Notify"},
|
||||||
|
{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.next[1]), "Next Device Notify"}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Miscellaneous tables */
|
/* Miscellaneous tables */
|
||||||
|
|
|
@ -152,7 +152,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
|
||||||
case ACPI_TYPE_PROCESSOR:
|
case ACPI_TYPE_PROCESSOR:
|
||||||
case ACPI_TYPE_THERMAL:
|
case ACPI_TYPE_THERMAL:
|
||||||
|
|
||||||
/* Walk the notify handler list for this object */
|
/* Walk the address handler list for this object */
|
||||||
|
|
||||||
handler_desc = object->common_notify.handler;
|
handler_desc = object->common_notify.handler;
|
||||||
while (handler_desc) {
|
while (handler_desc) {
|
||||||
|
@ -480,6 +480,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
|
||||||
acpi_status status = AE_OK;
|
acpi_status status = AE_OK;
|
||||||
union acpi_generic_state *state_list = NULL;
|
union acpi_generic_state *state_list = NULL;
|
||||||
union acpi_operand_object *next_object = NULL;
|
union acpi_operand_object *next_object = NULL;
|
||||||
|
union acpi_operand_object *prev_object;
|
||||||
union acpi_generic_state *state;
|
union acpi_generic_state *state;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
|
@ -505,12 +506,21 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
|
||||||
case ACPI_TYPE_POWER:
|
case ACPI_TYPE_POWER:
|
||||||
case ACPI_TYPE_THERMAL:
|
case ACPI_TYPE_THERMAL:
|
||||||
|
|
||||||
/* Update the notify objects for these types (if present) */
|
/*
|
||||||
|
* Update the notify objects for these types (if present)
|
||||||
acpi_ut_update_ref_count(object->common_notify.
|
* Two lists, system and device notify handlers.
|
||||||
system_notify, action);
|
*/
|
||||||
acpi_ut_update_ref_count(object->common_notify.
|
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
|
||||||
device_notify, action);
|
prev_object =
|
||||||
|
object->common_notify.notify_list[i];
|
||||||
|
while (prev_object) {
|
||||||
|
next_object =
|
||||||
|
prev_object->notify.next[i];
|
||||||
|
acpi_ut_update_ref_count(prev_object,
|
||||||
|
action);
|
||||||
|
prev_object = next_object;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACPI_TYPE_PACKAGE:
|
case ACPI_TYPE_PACKAGE:
|
||||||
|
|
|
@ -304,8 +304,8 @@ acpi_status acpi_ut_init_globals(void)
|
||||||
|
|
||||||
/* Global handlers */
|
/* Global handlers */
|
||||||
|
|
||||||
acpi_gbl_system_notify.handler = NULL;
|
acpi_gbl_global_notify[0].handler = NULL;
|
||||||
acpi_gbl_device_notify.handler = NULL;
|
acpi_gbl_global_notify[1].handler = NULL;
|
||||||
acpi_gbl_exception_handler = NULL;
|
acpi_gbl_exception_handler = NULL;
|
||||||
acpi_gbl_init_handler = NULL;
|
acpi_gbl_init_handler = NULL;
|
||||||
acpi_gbl_table_handler = NULL;
|
acpi_gbl_table_handler = NULL;
|
||||||
|
|
|
@ -706,10 +706,14 @@ typedef u32 acpi_event_status;
|
||||||
#define ACPI_DEVICE_NOTIFY 0x2
|
#define ACPI_DEVICE_NOTIFY 0x2
|
||||||
#define ACPI_ALL_NOTIFY (ACPI_SYSTEM_NOTIFY | ACPI_DEVICE_NOTIFY)
|
#define ACPI_ALL_NOTIFY (ACPI_SYSTEM_NOTIFY | ACPI_DEVICE_NOTIFY)
|
||||||
#define ACPI_MAX_NOTIFY_HANDLER_TYPE 0x3
|
#define ACPI_MAX_NOTIFY_HANDLER_TYPE 0x3
|
||||||
|
#define ACPI_NUM_NOTIFY_TYPES 2
|
||||||
|
|
||||||
#define ACPI_MAX_SYS_NOTIFY 0x7F
|
#define ACPI_MAX_SYS_NOTIFY 0x7F
|
||||||
#define ACPI_MAX_DEVICE_SPECIFIC_NOTIFY 0xBF
|
#define ACPI_MAX_DEVICE_SPECIFIC_NOTIFY 0xBF
|
||||||
|
|
||||||
|
#define ACPI_SYSTEM_HANDLER_LIST 0 /* Used as index, must be SYSTEM_NOTIFY -1 */
|
||||||
|
#define ACPI_DEVICE_HANDLER_LIST 1 /* Used as index, must be DEVICE_NOTIFY -1 */
|
||||||
|
|
||||||
/* Address Space (Operation Region) Types */
|
/* Address Space (Operation Region) Types */
|
||||||
|
|
||||||
typedef u8 acpi_adr_space_type;
|
typedef u8 acpi_adr_space_type;
|
||||||
|
|
Loading…
Reference in a new issue