Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.24-rc2 440 lines 13 kB view raw
1/******************************************************************************* 2 * 3 * Module Name: nsobject - Utilities for objects attached to namespace 4 * table entries 5 * 6 ******************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2007, R. Byron Moore 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45#include <acpi/acpi.h> 46#include <acpi/acnamesp.h> 47 48#define _COMPONENT ACPI_NAMESPACE 49ACPI_MODULE_NAME("nsobject") 50 51/******************************************************************************* 52 * 53 * FUNCTION: acpi_ns_attach_object 54 * 55 * PARAMETERS: Node - Parent Node 56 * Object - Object to be attached 57 * Type - Type of object, or ACPI_TYPE_ANY if not 58 * known 59 * 60 * RETURN: Status 61 * 62 * DESCRIPTION: Record the given object as the value associated with the 63 * name whose acpi_handle is passed. If Object is NULL 64 * and Type is ACPI_TYPE_ANY, set the name as having no value. 65 * Note: Future may require that the Node->Flags field be passed 66 * as a parameter. 67 * 68 * MUTEX: Assumes namespace is locked 69 * 70 ******************************************************************************/ 71acpi_status 72acpi_ns_attach_object(struct acpi_namespace_node *node, 73 union acpi_operand_object *object, acpi_object_type type) 74{ 75 union acpi_operand_object *obj_desc; 76 union acpi_operand_object *last_obj_desc; 77 acpi_object_type object_type = ACPI_TYPE_ANY; 78 79 ACPI_FUNCTION_TRACE(ns_attach_object); 80 81 /* 82 * Parameter validation 83 */ 84 if (!node) { 85 86 /* Invalid handle */ 87 88 ACPI_ERROR((AE_INFO, "Null NamedObj handle")); 89 return_ACPI_STATUS(AE_BAD_PARAMETER); 90 } 91 92 if (!object && (ACPI_TYPE_ANY != type)) { 93 94 /* Null object */ 95 96 ACPI_ERROR((AE_INFO, 97 "Null object, but type not ACPI_TYPE_ANY")); 98 return_ACPI_STATUS(AE_BAD_PARAMETER); 99 } 100 101 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { 102 103 /* Not a name handle */ 104 105 ACPI_ERROR((AE_INFO, "Invalid handle %p [%s]", 106 node, acpi_ut_get_descriptor_name(node))); 107 return_ACPI_STATUS(AE_BAD_PARAMETER); 108 } 109 110 /* Check if this object is already attached */ 111 112 if (node->object == object) { 113 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 114 "Obj %p already installed in NameObj %p\n", 115 object, node)); 116 117 return_ACPI_STATUS(AE_OK); 118 } 119 120 /* If null object, we will just install it */ 121 122 if (!object) { 123 obj_desc = NULL; 124 object_type = ACPI_TYPE_ANY; 125 } 126 127 /* 128 * If the source object is a namespace Node with an attached object, 129 * we will use that (attached) object 130 */ 131 else if ((ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED) && 132 ((struct acpi_namespace_node *)object)->object) { 133 /* 134 * Value passed is a name handle and that name has a 135 * non-null value. Use that name's value and type. 136 */ 137 obj_desc = ((struct acpi_namespace_node *)object)->object; 138 object_type = ((struct acpi_namespace_node *)object)->type; 139 } 140 141 /* 142 * Otherwise, we will use the parameter object, but we must type 143 * it first 144 */ 145 else { 146 obj_desc = (union acpi_operand_object *)object; 147 148 /* Use the given type */ 149 150 object_type = type; 151 } 152 153 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n", 154 obj_desc, node, acpi_ut_get_node_name(node))); 155 156 /* Detach an existing attached object if present */ 157 158 if (node->object) { 159 acpi_ns_detach_object(node); 160 } 161 162 if (obj_desc) { 163 /* 164 * Must increment the new value's reference count 165 * (if it is an internal object) 166 */ 167 acpi_ut_add_reference(obj_desc); 168 169 /* 170 * Handle objects with multiple descriptors - walk 171 * to the end of the descriptor list 172 */ 173 last_obj_desc = obj_desc; 174 while (last_obj_desc->common.next_object) { 175 last_obj_desc = last_obj_desc->common.next_object; 176 } 177 178 /* Install the object at the front of the object list */ 179 180 last_obj_desc->common.next_object = node->object; 181 } 182 183 node->type = (u8) object_type; 184 node->object = obj_desc; 185 186 return_ACPI_STATUS(AE_OK); 187} 188 189/******************************************************************************* 190 * 191 * FUNCTION: acpi_ns_detach_object 192 * 193 * PARAMETERS: Node - A Namespace node whose object will be detached 194 * 195 * RETURN: None. 196 * 197 * DESCRIPTION: Detach/delete an object associated with a namespace node. 198 * if the object is an allocated object, it is freed. 199 * Otherwise, the field is simply cleared. 200 * 201 ******************************************************************************/ 202 203void acpi_ns_detach_object(struct acpi_namespace_node *node) 204{ 205 union acpi_operand_object *obj_desc; 206 207 ACPI_FUNCTION_TRACE(ns_detach_object); 208 209 obj_desc = node->object; 210 211 if (!obj_desc || 212 (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA)) { 213 return_VOID; 214 } 215 216 /* Clear the entry in all cases */ 217 218 node->object = NULL; 219 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) { 220 node->object = obj_desc->common.next_object; 221 if (node->object && 222 (ACPI_GET_OBJECT_TYPE(node->object) != 223 ACPI_TYPE_LOCAL_DATA)) { 224 node->object = node->object->common.next_object; 225 } 226 } 227 228 /* Reset the node type to untyped */ 229 230 node->type = ACPI_TYPE_ANY; 231 232 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n", 233 node, acpi_ut_get_node_name(node), obj_desc)); 234 235 /* Remove one reference on the object (and all subobjects) */ 236 237 acpi_ut_remove_reference(obj_desc); 238 return_VOID; 239} 240 241/******************************************************************************* 242 * 243 * FUNCTION: acpi_ns_get_attached_object 244 * 245 * PARAMETERS: Node - Namespace node 246 * 247 * RETURN: Current value of the object field from the Node whose 248 * handle is passed 249 * 250 * DESCRIPTION: Obtain the object attached to a namespace node. 251 * 252 ******************************************************************************/ 253 254union acpi_operand_object *acpi_ns_get_attached_object(struct 255 acpi_namespace_node 256 *node) 257{ 258 ACPI_FUNCTION_TRACE_PTR(ns_get_attached_object, node); 259 260 if (!node) { 261 ACPI_WARNING((AE_INFO, "Null Node ptr")); 262 return_PTR(NULL); 263 } 264 265 if (!node->object || 266 ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND) 267 && (ACPI_GET_DESCRIPTOR_TYPE(node->object) != 268 ACPI_DESC_TYPE_NAMED)) 269 || (ACPI_GET_OBJECT_TYPE(node->object) == ACPI_TYPE_LOCAL_DATA)) { 270 return_PTR(NULL); 271 } 272 273 return_PTR(node->object); 274} 275 276/******************************************************************************* 277 * 278 * FUNCTION: acpi_ns_get_secondary_object 279 * 280 * PARAMETERS: Node - Namespace node 281 * 282 * RETURN: Current value of the object field from the Node whose 283 * handle is passed. 284 * 285 * DESCRIPTION: Obtain a secondary object associated with a namespace node. 286 * 287 ******************************************************************************/ 288 289union acpi_operand_object *acpi_ns_get_secondary_object(union 290 acpi_operand_object 291 *obj_desc) 292{ 293 ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc); 294 295 if ((!obj_desc) || 296 (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) || 297 (!obj_desc->common.next_object) || 298 (ACPI_GET_OBJECT_TYPE(obj_desc->common.next_object) == 299 ACPI_TYPE_LOCAL_DATA)) { 300 return_PTR(NULL); 301 } 302 303 return_PTR(obj_desc->common.next_object); 304} 305 306/******************************************************************************* 307 * 308 * FUNCTION: acpi_ns_attach_data 309 * 310 * PARAMETERS: Node - Namespace node 311 * Handler - Handler to be associated with the data 312 * Data - Data to be attached 313 * 314 * RETURN: Status 315 * 316 * DESCRIPTION: Low-level attach data. Create and attach a Data object. 317 * 318 ******************************************************************************/ 319 320acpi_status 321acpi_ns_attach_data(struct acpi_namespace_node *node, 322 acpi_object_handler handler, void *data) 323{ 324 union acpi_operand_object *prev_obj_desc; 325 union acpi_operand_object *obj_desc; 326 union acpi_operand_object *data_desc; 327 328 /* We only allow one attachment per handler */ 329 330 prev_obj_desc = NULL; 331 obj_desc = node->object; 332 while (obj_desc) { 333 if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) && 334 (obj_desc->data.handler == handler)) { 335 return (AE_ALREADY_EXISTS); 336 } 337 338 prev_obj_desc = obj_desc; 339 obj_desc = obj_desc->common.next_object; 340 } 341 342 /* Create an internal object for the data */ 343 344 data_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_DATA); 345 if (!data_desc) { 346 return (AE_NO_MEMORY); 347 } 348 349 data_desc->data.handler = handler; 350 data_desc->data.pointer = data; 351 352 /* Install the data object */ 353 354 if (prev_obj_desc) { 355 prev_obj_desc->common.next_object = data_desc; 356 } else { 357 node->object = data_desc; 358 } 359 360 return (AE_OK); 361} 362 363/******************************************************************************* 364 * 365 * FUNCTION: acpi_ns_detach_data 366 * 367 * PARAMETERS: Node - Namespace node 368 * Handler - Handler associated with the data 369 * 370 * RETURN: Status 371 * 372 * DESCRIPTION: Low-level detach data. Delete the data node, but the caller 373 * is responsible for the actual data. 374 * 375 ******************************************************************************/ 376 377acpi_status 378acpi_ns_detach_data(struct acpi_namespace_node * node, 379 acpi_object_handler handler) 380{ 381 union acpi_operand_object *obj_desc; 382 union acpi_operand_object *prev_obj_desc; 383 384 prev_obj_desc = NULL; 385 obj_desc = node->object; 386 while (obj_desc) { 387 if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) && 388 (obj_desc->data.handler == handler)) { 389 if (prev_obj_desc) { 390 prev_obj_desc->common.next_object = 391 obj_desc->common.next_object; 392 } else { 393 node->object = obj_desc->common.next_object; 394 } 395 396 acpi_ut_remove_reference(obj_desc); 397 return (AE_OK); 398 } 399 400 prev_obj_desc = obj_desc; 401 obj_desc = obj_desc->common.next_object; 402 } 403 404 return (AE_NOT_FOUND); 405} 406 407/******************************************************************************* 408 * 409 * FUNCTION: acpi_ns_get_attached_data 410 * 411 * PARAMETERS: Node - Namespace node 412 * Handler - Handler associated with the data 413 * Data - Where the data is returned 414 * 415 * RETURN: Status 416 * 417 * DESCRIPTION: Low level interface to obtain data previously associated with 418 * a namespace node. 419 * 420 ******************************************************************************/ 421 422acpi_status 423acpi_ns_get_attached_data(struct acpi_namespace_node * node, 424 acpi_object_handler handler, void **data) 425{ 426 union acpi_operand_object *obj_desc; 427 428 obj_desc = node->object; 429 while (obj_desc) { 430 if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) && 431 (obj_desc->data.handler == handler)) { 432 *data = obj_desc->data.pointer; 433 return (AE_OK); 434 } 435 436 obj_desc = obj_desc->common.next_object; 437 } 438 439 return (AE_NOT_FOUND); 440}