0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <acpi/acpi.h>
0010 #include "accommon.h"
0011 #include "acnamesp.h"
0012
0013 #define _COMPONENT ACPI_NAMESPACE
0014 ACPI_MODULE_NAME("nsobject")
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 acpi_status
0037 acpi_ns_attach_object(struct acpi_namespace_node *node,
0038 union acpi_operand_object *object, acpi_object_type type)
0039 {
0040 union acpi_operand_object *obj_desc;
0041 union acpi_operand_object *last_obj_desc;
0042 acpi_object_type object_type = ACPI_TYPE_ANY;
0043
0044 ACPI_FUNCTION_TRACE(ns_attach_object);
0045
0046
0047
0048
0049 if (!node) {
0050
0051
0052
0053 ACPI_ERROR((AE_INFO, "Null NamedObj handle"));
0054 return_ACPI_STATUS(AE_BAD_PARAMETER);
0055 }
0056
0057 if (!object && (ACPI_TYPE_ANY != type)) {
0058
0059
0060
0061 ACPI_ERROR((AE_INFO,
0062 "Null object, but type not ACPI_TYPE_ANY"));
0063 return_ACPI_STATUS(AE_BAD_PARAMETER);
0064 }
0065
0066 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
0067
0068
0069
0070 ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]",
0071 node, acpi_ut_get_descriptor_name(node)));
0072 return_ACPI_STATUS(AE_BAD_PARAMETER);
0073 }
0074
0075
0076
0077 if (node->object == object) {
0078 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0079 "Obj %p already installed in NameObj %p\n",
0080 object, node));
0081
0082 return_ACPI_STATUS(AE_OK);
0083 }
0084
0085
0086
0087 if (!object) {
0088 obj_desc = NULL;
0089 object_type = ACPI_TYPE_ANY;
0090 }
0091
0092
0093
0094
0095
0096 else if ((ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) &&
0097 ((struct acpi_namespace_node *)object)->object) {
0098
0099
0100
0101
0102 obj_desc = ((struct acpi_namespace_node *)object)->object;
0103 object_type = ((struct acpi_namespace_node *)object)->type;
0104 }
0105
0106
0107
0108
0109
0110 else {
0111 obj_desc = (union acpi_operand_object *)object;
0112
0113
0114
0115 object_type = type;
0116 }
0117
0118 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
0119 obj_desc, node, acpi_ut_get_node_name(node)));
0120
0121
0122
0123 if (node->object) {
0124 acpi_ns_detach_object(node);
0125 }
0126
0127 if (obj_desc) {
0128
0129
0130
0131
0132 acpi_ut_add_reference(obj_desc);
0133
0134
0135
0136
0137
0138 last_obj_desc = obj_desc;
0139 while (last_obj_desc->common.next_object) {
0140 last_obj_desc = last_obj_desc->common.next_object;
0141 }
0142
0143
0144
0145 last_obj_desc->common.next_object = node->object;
0146 }
0147
0148 node->type = (u8) object_type;
0149 node->object = obj_desc;
0150
0151 return_ACPI_STATUS(AE_OK);
0152 }
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 void acpi_ns_detach_object(struct acpi_namespace_node *node)
0169 {
0170 union acpi_operand_object *obj_desc;
0171
0172 ACPI_FUNCTION_TRACE(ns_detach_object);
0173
0174 obj_desc = node->object;
0175
0176 if (!obj_desc || (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
0177 return_VOID;
0178 }
0179
0180 if (node->flags & ANOBJ_ALLOCATED_BUFFER) {
0181
0182
0183
0184 if (obj_desc->common.type == ACPI_TYPE_METHOD) {
0185 ACPI_FREE(obj_desc->method.aml_start);
0186 }
0187 }
0188
0189 if (obj_desc->common.type == ACPI_TYPE_REGION) {
0190 acpi_ut_remove_address_range(obj_desc->region.space_id, node);
0191 }
0192
0193
0194
0195 node->object = NULL;
0196 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
0197
0198
0199
0200 node->object = obj_desc->common.next_object;
0201
0202
0203
0204 if (node->object &&
0205 (node->object->common.type != ACPI_TYPE_LOCAL_DATA)) {
0206 node->object = node->object->common.next_object;
0207 }
0208
0209
0210
0211
0212
0213 if (obj_desc->common.next_object &&
0214 ((obj_desc->common.next_object)->common.type ==
0215 ACPI_TYPE_LOCAL_DATA)) {
0216 obj_desc->common.next_object = NULL;
0217 }
0218 }
0219
0220
0221
0222 node->type = ACPI_TYPE_ANY;
0223
0224 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
0225 node, acpi_ut_get_node_name(node), obj_desc));
0226
0227
0228
0229 acpi_ut_remove_reference(obj_desc);
0230 return_VOID;
0231 }
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 union acpi_operand_object *acpi_ns_get_attached_object(struct
0247 acpi_namespace_node
0248 *node)
0249 {
0250 ACPI_FUNCTION_TRACE_PTR(ns_get_attached_object, node);
0251
0252 if (!node) {
0253 ACPI_WARNING((AE_INFO, "Null Node ptr"));
0254 return_PTR(NULL);
0255 }
0256
0257 if (!node->object ||
0258 ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
0259 && (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
0260 ACPI_DESC_TYPE_NAMED))
0261 || ((node->object)->common.type == ACPI_TYPE_LOCAL_DATA)) {
0262 return_PTR(NULL);
0263 }
0264
0265 return_PTR(node->object);
0266 }
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281 union acpi_operand_object *acpi_ns_get_secondary_object(union
0282 acpi_operand_object
0283 *obj_desc)
0284 {
0285 ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc);
0286
0287 if ((!obj_desc) ||
0288 (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) ||
0289 (!obj_desc->common.next_object) ||
0290 ((obj_desc->common.next_object)->common.type ==
0291 ACPI_TYPE_LOCAL_DATA)) {
0292 return_PTR(NULL);
0293 }
0294
0295 return_PTR(obj_desc->common.next_object);
0296 }
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312 acpi_status
0313 acpi_ns_attach_data(struct acpi_namespace_node *node,
0314 acpi_object_handler handler, void *data)
0315 {
0316 union acpi_operand_object *prev_obj_desc;
0317 union acpi_operand_object *obj_desc;
0318 union acpi_operand_object *data_desc;
0319
0320
0321
0322 prev_obj_desc = NULL;
0323 obj_desc = node->object;
0324 while (obj_desc) {
0325 if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
0326 (obj_desc->data.handler == handler)) {
0327 return (AE_ALREADY_EXISTS);
0328 }
0329
0330 prev_obj_desc = obj_desc;
0331 obj_desc = obj_desc->common.next_object;
0332 }
0333
0334
0335
0336 data_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_DATA);
0337 if (!data_desc) {
0338 return (AE_NO_MEMORY);
0339 }
0340
0341 data_desc->data.handler = handler;
0342 data_desc->data.pointer = data;
0343
0344
0345
0346 if (prev_obj_desc) {
0347 prev_obj_desc->common.next_object = data_desc;
0348 } else {
0349 node->object = data_desc;
0350 }
0351
0352 return (AE_OK);
0353 }
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369 acpi_status
0370 acpi_ns_detach_data(struct acpi_namespace_node *node,
0371 acpi_object_handler handler)
0372 {
0373 union acpi_operand_object *obj_desc;
0374 union acpi_operand_object *prev_obj_desc;
0375
0376 prev_obj_desc = NULL;
0377 obj_desc = node->object;
0378 while (obj_desc) {
0379 if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
0380 (obj_desc->data.handler == handler)) {
0381 if (prev_obj_desc) {
0382 prev_obj_desc->common.next_object =
0383 obj_desc->common.next_object;
0384 } else {
0385 node->object = obj_desc->common.next_object;
0386 }
0387
0388 acpi_ut_remove_reference(obj_desc);
0389 return (AE_OK);
0390 }
0391
0392 prev_obj_desc = obj_desc;
0393 obj_desc = obj_desc->common.next_object;
0394 }
0395
0396 return (AE_NOT_FOUND);
0397 }
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414 acpi_status
0415 acpi_ns_get_attached_data(struct acpi_namespace_node *node,
0416 acpi_object_handler handler, void **data)
0417 {
0418 union acpi_operand_object *obj_desc;
0419
0420 obj_desc = node->object;
0421 while (obj_desc) {
0422 if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
0423 (obj_desc->data.handler == handler)) {
0424 *data = obj_desc->data.pointer;
0425 return (AE_OK);
0426 }
0427
0428 obj_desc = obj_desc->common.next_object;
0429 }
0430
0431 return (AE_NOT_FOUND);
0432 }