0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #define EXPORT_ACPI_INTERFACES
0012
0013 #include <acpi/acpi.h>
0014 #include "accommon.h"
0015 #include "acnamesp.h"
0016 #include "acevents.h"
0017
0018 #define _COMPONENT ACPI_EVENTS
0019 ACPI_MODULE_NAME("evxfregn")
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 acpi_status
0043 acpi_install_address_space_handler(acpi_handle device,
0044 acpi_adr_space_type space_id,
0045 acpi_adr_space_handler handler,
0046 acpi_adr_space_setup setup, void *context)
0047 {
0048 struct acpi_namespace_node *node;
0049 acpi_status status;
0050
0051 ACPI_FUNCTION_TRACE(acpi_install_address_space_handler);
0052
0053
0054
0055 if (!device) {
0056 return_ACPI_STATUS(AE_BAD_PARAMETER);
0057 }
0058
0059 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
0060 if (ACPI_FAILURE(status)) {
0061 return_ACPI_STATUS(status);
0062 }
0063
0064
0065
0066 node = acpi_ns_validate_handle(device);
0067 if (!node) {
0068 status = AE_BAD_PARAMETER;
0069 goto unlock_and_exit;
0070 }
0071
0072
0073
0074 status =
0075 acpi_ev_install_space_handler(node, space_id, handler, setup,
0076 context);
0077 if (ACPI_FAILURE(status)) {
0078 goto unlock_and_exit;
0079 }
0080
0081
0082
0083 acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
0084
0085 unlock_and_exit:
0086 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
0087 return_ACPI_STATUS(status);
0088 }
0089
0090 ACPI_EXPORT_SYMBOL(acpi_install_address_space_handler)
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 acpi_status
0106 acpi_remove_address_space_handler(acpi_handle device,
0107 acpi_adr_space_type space_id,
0108 acpi_adr_space_handler handler)
0109 {
0110 union acpi_operand_object *obj_desc;
0111 union acpi_operand_object *handler_obj;
0112 union acpi_operand_object *region_obj;
0113 union acpi_operand_object **last_obj_ptr;
0114 struct acpi_namespace_node *node;
0115 acpi_status status;
0116
0117 ACPI_FUNCTION_TRACE(acpi_remove_address_space_handler);
0118
0119
0120
0121 if (!device) {
0122 return_ACPI_STATUS(AE_BAD_PARAMETER);
0123 }
0124
0125 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
0126 if (ACPI_FAILURE(status)) {
0127 return_ACPI_STATUS(status);
0128 }
0129
0130
0131
0132 node = acpi_ns_validate_handle(device);
0133 if (!node ||
0134 ((node->type != ACPI_TYPE_DEVICE) &&
0135 (node->type != ACPI_TYPE_PROCESSOR) &&
0136 (node->type != ACPI_TYPE_THERMAL) &&
0137 (node != acpi_gbl_root_node))) {
0138 status = AE_BAD_PARAMETER;
0139 goto unlock_and_exit;
0140 }
0141
0142
0143
0144 obj_desc = acpi_ns_get_attached_object(node);
0145 if (!obj_desc) {
0146 status = AE_NOT_EXIST;
0147 goto unlock_and_exit;
0148 }
0149
0150
0151
0152 handler_obj = obj_desc->common_notify.handler;
0153 last_obj_ptr = &obj_desc->common_notify.handler;
0154 while (handler_obj) {
0155
0156
0157
0158 if (handler_obj->address_space.space_id == space_id) {
0159
0160
0161
0162 if (handler_obj->address_space.handler != handler) {
0163 status = AE_BAD_PARAMETER;
0164 goto unlock_and_exit;
0165 }
0166
0167
0168
0169 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
0170 "Removing address handler %p(%p) for region %s "
0171 "on Device %p(%p)\n",
0172 handler_obj, handler,
0173 acpi_ut_get_region_name(space_id),
0174 node, obj_desc));
0175
0176 region_obj = handler_obj->address_space.region_list;
0177
0178
0179
0180 while (region_obj) {
0181
0182
0183
0184
0185
0186
0187
0188 acpi_ev_detach_region(region_obj, TRUE);
0189
0190
0191
0192
0193
0194 region_obj =
0195 handler_obj->address_space.region_list;
0196 }
0197
0198
0199
0200 *last_obj_ptr = handler_obj->address_space.next;
0201
0202
0203
0204 acpi_os_release_mutex(handler_obj->address_space.
0205 context_mutex);
0206 acpi_ut_remove_reference(handler_obj);
0207 goto unlock_and_exit;
0208 }
0209
0210
0211
0212 last_obj_ptr = &handler_obj->address_space.next;
0213 handler_obj = handler_obj->address_space.next;
0214 }
0215
0216
0217
0218 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
0219 "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n",
0220 handler, acpi_ut_get_region_name(space_id), space_id,
0221 node, obj_desc));
0222
0223 status = AE_NOT_EXIST;
0224
0225 unlock_and_exit:
0226 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
0227 return_ACPI_STATUS(status);
0228 }
0229
0230 ACPI_EXPORT_SYMBOL(acpi_remove_address_space_handler)