File: /usr/src/linux/drivers/acpi/namespace/nsaccess.c
1 /*******************************************************************************
2 *
3 * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
4 * $Revision: 133 $
5 *
6 ******************************************************************************/
7
8 /*
9 * Copyright (C) 2000, 2001 R. Byron Moore
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26
27 #include "acpi.h"
28 #include "amlcode.h"
29 #include "acinterp.h"
30 #include "acnamesp.h"
31 #include "acdispat.h"
32
33
34 #define _COMPONENT ACPI_NAMESPACE
35 MODULE_NAME ("nsaccess")
36
37
38 /*******************************************************************************
39 *
40 * FUNCTION: Acpi_ns_root_initialize
41 *
42 * PARAMETERS: None
43 *
44 * RETURN: Status
45 *
46 * DESCRIPTION: Allocate and initialize the default root named objects
47 *
48 * MUTEX: Locks namespace for entire execution
49 *
50 ******************************************************************************/
51
52 acpi_status
53 acpi_ns_root_initialize (void)
54 {
55 acpi_status status = AE_OK;
56 const predefined_names *init_val = NULL;
57 acpi_namespace_node *new_node;
58 acpi_operand_object *obj_desc;
59
60
61 FUNCTION_TRACE ("Ns_root_initialize");
62
63
64 acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
65
66 /*
67 * The global root ptr is initially NULL, so a non-NULL value indicates
68 * that Acpi_ns_root_initialize() has already been called; just return.
69 */
70 if (acpi_gbl_root_node) {
71 status = AE_OK;
72 goto unlock_and_exit;
73 }
74
75
76 /*
77 * Tell the rest of the subsystem that the root is initialized
78 * (This is OK because the namespace is locked)
79 */
80 acpi_gbl_root_node = &acpi_gbl_root_node_struct;
81
82
83 /* Enter the pre-defined names in the name table */
84
85 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Entering predefined entries into namespace\n"));
86
87 for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
88 status = acpi_ns_lookup (NULL, init_val->name, init_val->type,
89 IMODE_LOAD_PASS2, NS_NO_UPSEARCH,
90 NULL, &new_node);
91
92 if (ACPI_FAILURE (status) || (!new_node)) /* Must be on same line for code converter */ {
93 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
94 "Could not create predefined name %s, %s\n",
95 init_val->name, acpi_format_exception (status)));
96 }
97
98 /*
99 * Name entered successfully.
100 * If entry in Pre_defined_names[] specifies an
101 * initial value, create the initial value.
102 */
103 if (init_val->val) {
104 /*
105 * Entry requests an initial value, allocate a
106 * descriptor for it.
107 */
108 obj_desc = acpi_ut_create_internal_object (init_val->type);
109 if (!obj_desc) {
110 status = AE_NO_MEMORY;
111 goto unlock_and_exit;
112 }
113
114 /*
115 * Convert value string from table entry to
116 * internal representation. Only types actually
117 * used for initial values are implemented here.
118 */
119
120 switch (init_val->type) {
121
122 case ACPI_TYPE_INTEGER:
123
124 obj_desc->integer.value =
125 (acpi_integer) STRTOUL (init_val->val, NULL, 10);
126 break;
127
128
129 case ACPI_TYPE_STRING:
130
131 /*
132 * Build an object around the static string
133 */
134 obj_desc->string.length = STRLEN (init_val->val);
135 obj_desc->string.pointer = init_val->val;
136 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
137 break;
138
139
140 case ACPI_TYPE_MUTEX:
141
142 obj_desc->mutex.sync_level =
143 (u16) STRTOUL (init_val->val, NULL, 10);
144
145 if (STRCMP (init_val->name, "_GL_") == 0) {
146 /*
147 * Create a counting semaphore for the
148 * global lock
149 */
150 status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT,
151 1, &obj_desc->mutex.semaphore);
152
153 if (ACPI_FAILURE (status)) {
154 goto unlock_and_exit;
155 }
156
157 /*
158 * We just created the mutex for the
159 * global lock, save it
160 */
161 acpi_gbl_global_lock_semaphore = obj_desc->mutex.semaphore;
162 }
163
164 else {
165 /* Create a mutex */
166
167 status = acpi_os_create_semaphore (1, 1,
168 &obj_desc->mutex.semaphore);
169
170 if (ACPI_FAILURE (status)) {
171 goto unlock_and_exit;
172 }
173 }
174 break;
175
176
177 default:
178 REPORT_ERROR (("Unsupported initial type value %X\n",
179 init_val->type));
180 acpi_ut_remove_reference (obj_desc);
181 obj_desc = NULL;
182 continue;
183 }
184
185 /* Store pointer to value descriptor in the Node */
186
187 acpi_ns_attach_object (new_node, obj_desc, obj_desc->common.type);
188 }
189 }
190
191
192 unlock_and_exit:
193 acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
194 return_ACPI_STATUS (status);
195 }
196
197
198 /*******************************************************************************
199 *
200 * FUNCTION: Acpi_ns_lookup
201 *
202 * PARAMETERS: Prefix_node - Search scope if name is not fully qualified
203 * Pathname - Search pathname, in internal format
204 * (as represented in the AML stream)
205 * Type - Type associated with name
206 * Interpreter_mode - IMODE_LOAD_PASS2 => add name if not found
207 * Flags - Flags describing the search restrictions
208 * Walk_state - Current state of the walk
209 * Return_node - Where the Node is placed (if found
210 * or created successfully)
211 *
212 * RETURN: Status
213 *
214 * DESCRIPTION: Find or enter the passed name in the name space.
215 * Log an error if name not found in Exec mode.
216 *
217 * MUTEX: Assumes namespace is locked.
218 *
219 ******************************************************************************/
220
221 acpi_status
222 acpi_ns_lookup (
223 acpi_generic_state *scope_info,
224 NATIVE_CHAR *pathname,
225 acpi_object_type8 type,
226 operating_mode interpreter_mode,
227 u32 flags,
228 acpi_walk_state *walk_state,
229 acpi_namespace_node **return_node)
230 {
231 acpi_status status;
232 acpi_namespace_node *prefix_node;
233 acpi_namespace_node *current_node = NULL;
234 acpi_namespace_node *scope_to_push = NULL;
235 acpi_namespace_node *this_node = NULL;
236 u32 num_segments;
237 acpi_name simple_name;
238 u8 null_name_path = FALSE;
239 acpi_object_type8 type_to_check_for;
240 acpi_object_type8 this_search_type;
241 u32 local_flags = flags & ~NS_ERROR_IF_FOUND;
242
243 DEBUG_EXEC (u32 i;)
244
245
246 FUNCTION_TRACE ("Ns_lookup");
247
248
249 if (!return_node) {
250 return_ACPI_STATUS (AE_BAD_PARAMETER);
251 }
252
253
254 acpi_gbl_ns_lookup_count++;
255
256 *return_node = ENTRY_NOT_FOUND;
257
258
259 if (!acpi_gbl_root_node) {
260 return (AE_NO_NAMESPACE);
261 }
262
263 /*
264 * Get the prefix scope.
265 * A null scope means use the root scope
266 */
267 if ((!scope_info) ||
268 (!scope_info->scope.node)) {
269 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Null scope prefix, using root node (%p)\n",
270 acpi_gbl_root_node));
271
272 prefix_node = acpi_gbl_root_node;
273 }
274 else {
275 prefix_node = scope_info->scope.node;
276 }
277
278
279 /*
280 * This check is explicitly split to relax the Type_to_check_for
281 * conditions for Bank_field_defn. Originally, both Bank_field_defn and
282 * Def_field_defn caused Type_to_check_for to be set to ACPI_TYPE_REGION,
283 * but the Bank_field_defn may also check for a Field definition as well
284 * as an Operation_region.
285 */
286 if (INTERNAL_TYPE_FIELD_DEFN == type) {
287 /* Def_field_defn defines fields in a Region */
288
289 type_to_check_for = ACPI_TYPE_REGION;
290 }
291
292 else if (INTERNAL_TYPE_BANK_FIELD_DEFN == type) {
293 /* Bank_field_defn defines data fields in a Field Object */
294
295 type_to_check_for = ACPI_TYPE_ANY;
296 }
297
298 else {
299 type_to_check_for = type;
300 }
301
302
303 /* TBD: [Restructure] - Move the pathname stuff into a new procedure */
304
305 /* Examine the name pointer */
306
307 if (!pathname) {
308 /* 8-12-98 ASL Grammar Update supports null Name_path */
309
310 null_name_path = TRUE;
311 num_segments = 0;
312 this_node = acpi_gbl_root_node;
313
314 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
315 "Null Pathname (Zero segments), Flags=%x\n", flags));
316 }
317
318 else {
319 /*
320 * Valid name pointer (Internal name format)
321 *
322 * Check for prefixes. As represented in the AML stream, a
323 * Pathname consists of an optional scope prefix followed by
324 * a segment part.
325 *
326 * If present, the scope prefix is either a Root_prefix (in
327 * which case the name is fully qualified), or zero or more
328 * Parent_prefixes (in which case the name's scope is relative
329 * to the current scope).
330 *
331 * The segment part consists of either:
332 * - A single 4-byte name segment, or
333 * - A Dual_name_prefix followed by two 4-byte name segments, or
334 * - A Multi_name_prefix_op, followed by a byte indicating the
335 * number of segments and the segments themselves.
336 */
337 if (*pathname == AML_ROOT_PREFIX) {
338 /* Pathname is fully qualified, look in root name table */
339
340 current_node = acpi_gbl_root_node;
341
342 /* point to segment part */
343
344 pathname++;
345
346 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching from root [%p]\n",
347 current_node));
348
349 /* Direct reference to root, "\" */
350
351 if (!(*pathname)) {
352 this_node = acpi_gbl_root_node;
353 goto check_for_new_scope_and_exit;
354 }
355 }
356
357 else {
358 /* Pathname is relative to current scope, start there */
359
360 current_node = prefix_node;
361
362 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Searching relative to pfx scope [%p]\n",
363 prefix_node));
364
365 /*
366 * Handle up-prefix (carat). More than one prefix
367 * is supported
368 */
369 while (*pathname == AML_PARENT_PREFIX) {
370 /* Point to segment part or next Parent_prefix */
371
372 pathname++;
373
374 /* Backup to the parent's scope */
375
376 this_node = acpi_ns_get_parent_object (current_node);
377 if (!this_node) {
378 /* Current scope has no parent scope */
379
380 REPORT_ERROR (
381 ("Too many parent prefixes (^) - reached root\n"));
382 return_ACPI_STATUS (AE_NOT_FOUND);
383 }
384
385 current_node = this_node;
386 }
387 }
388
389
390 /*
391 * Examine the name prefix opcode, if any,
392 * to determine the number of segments
393 */
394 if (*pathname == AML_DUAL_NAME_PREFIX) {
395 num_segments = 2;
396
397 /* point to first segment */
398
399 pathname++;
400
401 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
402 "Dual Pathname (2 segments, Flags=%X)\n", flags));
403 }
404
405 else if (*pathname == AML_MULTI_NAME_PREFIX_OP) {
406 num_segments = (u32)* (u8 *) ++pathname;
407
408 /* point to first segment */
409
410 pathname++;
411
412 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
413 "Multi Pathname (%d Segments, Flags=%X) \n",
414 num_segments, flags));
415 }
416
417 else {
418 /*
419 * No Dual or Multi prefix, hence there is only one
420 * segment and Pathname is already pointing to it.
421 */
422 num_segments = 1;
423
424 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
425 "Simple Pathname (1 segment, Flags=%X)\n", flags));
426 }
427
428 #ifdef ACPI_DEBUG
429
430 /* TBD: [Restructure] Make this a procedure */
431
432 /* Debug only: print the entire name that we are about to lookup */
433
434 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "["));
435
436 for (i = 0; i < num_segments; i++) {
437 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, "%4.4s/", &pathname[i * 4]));
438 }
439 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, "]\n"));
440 #endif
441 }
442
443
444 /*
445 * Search namespace for each segment of the name.
446 * Loop through and verify/add each name segment.
447 */
448 while (num_segments-- && current_node) {
449 /*
450 * Search for the current name segment under the current
451 * named object. The Type is significant only at the last (topmost)
452 * level. (We don't care about the types along the path, only
453 * the type of the final target object.)
454 */
455 this_search_type = ACPI_TYPE_ANY;
456 if (!num_segments) {
457 this_search_type = type;
458 local_flags = flags;
459 }
460
461 /* Pluck one ACPI name from the front of the pathname */
462
463 MOVE_UNALIGNED32_TO_32 (&simple_name, pathname);
464
465 /* Try to find the ACPI name */
466
467 status = acpi_ns_search_and_enter (simple_name, walk_state,
468 current_node, interpreter_mode,
469 this_search_type, local_flags,
470 &this_node);
471
472 if (ACPI_FAILURE (status)) {
473 if (status == AE_NOT_FOUND) {
474 /* Name not found in ACPI namespace */
475
476 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
477 "Name [%4.4s] not found in scope %X\n",
478 &simple_name, current_node));
479 }
480
481 return_ACPI_STATUS (status);
482 }
483
484
485 /*
486 * If 1) This is the last segment (Num_segments == 0)
487 * 2) and looking for a specific type
488 * (Not checking for TYPE_ANY)
489 * 3) Which is not an alias
490 * 4) which is not a local type (TYPE_DEF_ANY)
491 * 5) which is not a local type (TYPE_SCOPE)
492 * 6) which is not a local type (TYPE_INDEX_FIELD_DEFN)
493 * 7) and type of object is known (not TYPE_ANY)
494 * 8) and object does not match request
495 *
496 * Then we have a type mismatch. Just warn and ignore it.
497 */
498 if ((num_segments == 0) &&
499 (type_to_check_for != ACPI_TYPE_ANY) &&
500 (type_to_check_for != INTERNAL_TYPE_ALIAS) &&
501 (type_to_check_for != INTERNAL_TYPE_DEF_ANY) &&
502 (type_to_check_for != INTERNAL_TYPE_SCOPE) &&
503 (type_to_check_for != INTERNAL_TYPE_INDEX_FIELD_DEFN) &&
504 (this_node->type != ACPI_TYPE_ANY) &&
505 (this_node->type != type_to_check_for)) {
506 /* Complain about a type mismatch */
507
508 REPORT_WARNING (
509 ("Ns_lookup: %4.4s, type %X, checking for type %X\n",
510 &simple_name, this_node->type, type_to_check_for));
511 }
512
513 /*
514 * If this is the last name segment and we are not looking for a
515 * specific type, but the type of found object is known, use that type
516 * to see if it opens a scope.
517 */
518 if ((0 == num_segments) && (ACPI_TYPE_ANY == type)) {
519 type = this_node->type;
520 }
521
522 if ((num_segments || acpi_ns_opens_scope (type)) &&
523 (this_node->child == NULL)) {
524 /*
525 * More segments or the type implies enclosed scope,
526 * and the next scope has not been allocated.
527 */
528 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Load mode=%X This_node=%X\n",
529 interpreter_mode, this_node));
530 }
531
532 current_node = this_node;
533
534 /* point to next name segment */
535
536 pathname += ACPI_NAME_SIZE;
537 }
538
539
540 /*
541 * Always check if we need to open a new scope
542 */
543 check_for_new_scope_and_exit:
544
545 if (!(flags & NS_DONT_OPEN_SCOPE) && (walk_state)) {
546 /*
547 * If entry is a type which opens a scope,
548 * push the new scope on the scope stack.
549 */
550 if (acpi_ns_opens_scope (type_to_check_for)) {
551 /* 8-12-98 ASL Grammar Update supports null Name_path */
552
553 if (null_name_path) {
554 /* TBD: [Investigate] - is this the correct thing to do? */
555
556 scope_to_push = NULL;
557 }
558 else {
559 scope_to_push = this_node;
560 }
561
562 status = acpi_ds_scope_stack_push (scope_to_push, type,
563 walk_state);
564 if (ACPI_FAILURE (status)) {
565 return_ACPI_STATUS (status);
566 }
567
568 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Set global scope to %p\n", scope_to_push));
569 }
570 }
571
572 *return_node = this_node;
573 return_ACPI_STATUS (AE_OK);
574 }
575
576