Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dswload2.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Module Name: dswload2 - Dispatcher second pass namespace load callbacks
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2012, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  * notice, this list of conditions, and the following disclaimer,
16  * without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  * substantially similar to the "NO WARRANTY" disclaimer below
19  * ("Disclaimer") and any redistribution must be conditioned upon
20  * including a substantially similar Disclaimer requirement for further
21  * binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  * of any contributors may be used to endorse or promote products derived
24  * from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46 #include "acparser.h"
47 #include "amlcode.h"
48 #include "acdispat.h"
49 #include "acinterp.h"
50 #include "acnamesp.h"
51 #include "acevents.h"
52 
53 #define _COMPONENT ACPI_DISPATCHER
54 ACPI_MODULE_NAME("dswload2")
55 
56 /*******************************************************************************
57  *
58  * FUNCTION: acpi_ds_load2_begin_op
59  *
60  * PARAMETERS: walk_state - Current state of the parse tree walk
61  * out_op - Wher to return op if a new one is created
62  *
63  * RETURN: Status
64  *
65  * DESCRIPTION: Descending callback used during the loading of ACPI tables.
66  *
67  ******************************************************************************/
70  union acpi_parse_object **out_op)
71 {
72  union acpi_parse_object *op;
73  struct acpi_namespace_node *node;
76  char *buffer_ptr;
77  u32 flags;
78 
79  ACPI_FUNCTION_TRACE(ds_load2_begin_op);
80 
81  op = walk_state->op;
82  ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
83  walk_state));
84 
85  if (op) {
86  if ((walk_state->control_state) &&
87  (walk_state->control_state->common.state ==
89 
90  /* We are executing a while loop outside of a method */
91 
92  status = acpi_ds_exec_begin_op(walk_state, out_op);
93  return_ACPI_STATUS(status);
94  }
95 
96  /* We only care about Namespace opcodes here */
97 
98  if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
99  (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
100  (!(walk_state->op_info->flags & AML_NAMED))) {
102  }
103 
104  /* Get the name we are going to enter or lookup in the namespace */
105 
106  if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
107 
108  /* For Namepath op, get the path string */
109 
110  buffer_ptr = op->common.value.string;
111  if (!buffer_ptr) {
112 
113  /* No name, just exit */
114 
116  }
117  } else {
118  /* Get name from the op */
119 
120  buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);
121  }
122  } else {
123  /* Get the namestring from the raw AML */
124 
125  buffer_ptr =
126  acpi_ps_get_next_namestring(&walk_state->parser_state);
127  }
128 
129  /* Map the opcode into an internal object type */
130 
131  object_type = walk_state->op_info->object_type;
132 
134  "State=%p Op=%p Type=%X\n", walk_state, op,
135  object_type));
136 
137  switch (walk_state->opcode) {
138  case AML_FIELD_OP:
139  case AML_BANK_FIELD_OP:
140  case AML_INDEX_FIELD_OP:
141 
142  node = NULL;
143  status = AE_OK;
144  break;
145 
146  case AML_INT_NAMEPATH_OP:
147  /*
148  * The name_path is an object reference to an existing object.
149  * Don't enter the name into the namespace, but look it up
150  * for use later.
151  */
152  status =
153  acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
154  object_type, ACPI_IMODE_EXECUTE,
155  ACPI_NS_SEARCH_PARENT, walk_state, &(node));
156  break;
157 
158  case AML_SCOPE_OP:
159 
160  /* Special case for Scope(\) -> refers to the Root node */
161 
162  if (op && (op->named.node == acpi_gbl_root_node)) {
163  node = op->named.node;
164 
165  status =
166  acpi_ds_scope_stack_push(node, object_type,
167  walk_state);
168  if (ACPI_FAILURE(status)) {
169  return_ACPI_STATUS(status);
170  }
171  } else {
172  /*
173  * The Path is an object reference to an existing object.
174  * Don't enter the name into the namespace, but look it up
175  * for use later.
176  */
177  status =
178  acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
179  object_type, ACPI_IMODE_EXECUTE,
180  ACPI_NS_SEARCH_PARENT, walk_state,
181  &(node));
182  if (ACPI_FAILURE(status)) {
183 #ifdef ACPI_ASL_COMPILER
184  if (status == AE_NOT_FOUND) {
185  status = AE_OK;
186  } else {
187  ACPI_ERROR_NAMESPACE(buffer_ptr,
188  status);
189  }
190 #else
191  ACPI_ERROR_NAMESPACE(buffer_ptr, status);
192 #endif
193  return_ACPI_STATUS(status);
194  }
195  }
196 
197  /*
198  * We must check to make sure that the target is
199  * one of the opcodes that actually opens a scope
200  */
201  switch (node->type) {
202  case ACPI_TYPE_ANY:
203  case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
204  case ACPI_TYPE_DEVICE:
205  case ACPI_TYPE_POWER:
206  case ACPI_TYPE_PROCESSOR:
207  case ACPI_TYPE_THERMAL:
208 
209  /* These are acceptable types */
210  break;
211 
212  case ACPI_TYPE_INTEGER:
213  case ACPI_TYPE_STRING:
214  case ACPI_TYPE_BUFFER:
215 
216  /*
217  * These types we will allow, but we will change the type.
218  * This enables some existing code of the form:
219  *
220  * Name (DEB, 0)
221  * Scope (DEB) { ... }
222  */
224  "Type override - [%4.4s] had invalid type (%s) "
225  "for Scope operator, changed to type ANY\n",
226  acpi_ut_get_node_name(node),
227  acpi_ut_get_type_name(node->type)));
228 
229  node->type = ACPI_TYPE_ANY;
230  walk_state->scope_info->common.value = ACPI_TYPE_ANY;
231  break;
232 
233  case ACPI_TYPE_METHOD:
234 
235  /*
236  * Allow scope change to root during execution of module-level
237  * code. Root is typed METHOD during this time.
238  */
239  if ((node == acpi_gbl_root_node) &&
240  (walk_state->
241  parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
242  break;
243  }
244 
245  /*lint -fallthrough */
246 
247  default:
248 
249  /* All other types are an error */
250 
252  "Invalid type (%s) for target of "
253  "Scope operator [%4.4s] (Cannot override)",
255  acpi_ut_get_node_name(node)));
256 
257  return (AE_AML_OPERAND_TYPE);
258  }
259  break;
260 
261  default:
262 
263  /* All other opcodes */
264 
265  if (op && op->common.node) {
266 
267  /* This op/node was previously entered into the namespace */
268 
269  node = op->common.node;
270 
271  if (acpi_ns_opens_scope(object_type)) {
272  status =
273  acpi_ds_scope_stack_push(node, object_type,
274  walk_state);
275  if (ACPI_FAILURE(status)) {
276  return_ACPI_STATUS(status);
277  }
278  }
279 
281  }
282 
283  /*
284  * Enter the named type into the internal namespace. We enter the name
285  * as we go downward in the parse tree. Any necessary subobjects that
286  * involve arguments to the opcode must be created as we go back up the
287  * parse tree later.
288  *
289  * Note: Name may already exist if we are executing a deferred opcode.
290  */
291  if (walk_state->deferred_node) {
292 
293  /* This name is already in the namespace, get the node */
294 
295  node = walk_state->deferred_node;
296  status = AE_OK;
297  break;
298  }
299 
300  flags = ACPI_NS_NO_UPSEARCH;
301  if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
302 
303  /* Execution mode, node cannot already exist, node is temporary */
304 
305  flags |= ACPI_NS_ERROR_IF_FOUND;
306 
307  if (!
308  (walk_state->
309  parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
310  flags |= ACPI_NS_TEMPORARY;
311  }
312  }
313 
314  /* Add new entry or lookup existing entry */
315 
316  status =
317  acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
318  object_type, ACPI_IMODE_LOAD_PASS2, flags,
319  walk_state, &node);
320 
321  if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
323  "***New Node [%4.4s] %p is temporary\n",
324  acpi_ut_get_node_name(node), node));
325  }
326  break;
327  }
328 
329  if (ACPI_FAILURE(status)) {
330  ACPI_ERROR_NAMESPACE(buffer_ptr, status);
331  return_ACPI_STATUS(status);
332  }
333 
334  if (!op) {
335 
336  /* Create a new op */
337 
338  op = acpi_ps_alloc_op(walk_state->opcode);
339  if (!op) {
341  }
342 
343  /* Initialize the new op */
344 
345  if (node) {
346  op->named.name = node->name.integer;
347  }
348  *out_op = op;
349  }
350 
351  /*
352  * Put the Node in the "op" object that the parser uses, so we
353  * can get it again quickly when this scope is closed
354  */
355  op->common.node = node;
356  return_ACPI_STATUS(status);
357 }
358 
359 /*******************************************************************************
360  *
361  * FUNCTION: acpi_ds_load2_end_op
362  *
363  * PARAMETERS: walk_state - Current state of the parse tree walk
364  *
365  * RETURN: Status
366  *
367  * DESCRIPTION: Ascending callback used during the loading of the namespace,
368  * both control methods and everything else.
369  *
370  ******************************************************************************/
371 
373 {
374  union acpi_parse_object *op;
377  struct acpi_namespace_node *node;
378  union acpi_parse_object *arg;
379  struct acpi_namespace_node *new_node;
380 #ifndef ACPI_NO_METHOD_EXECUTION
381  u32 i;
382  u8 region_space;
383 #endif
384 
385  ACPI_FUNCTION_TRACE(ds_load2_end_op);
386 
387  op = walk_state->op;
388  ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
389  walk_state->op_info->name, op, walk_state));
390 
391  /* Check if opcode had an associated namespace object */
392 
393  if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
395  }
396 
397  if (op->common.aml_opcode == AML_SCOPE_OP) {
399  "Ending scope Op=%p State=%p\n", op,
400  walk_state));
401  }
402 
403  object_type = walk_state->op_info->object_type;
404 
405  /*
406  * Get the Node/name from the earlier lookup
407  * (It was saved in the *op structure)
408  */
409  node = op->common.node;
410 
411  /*
412  * Put the Node on the object stack (Contains the ACPI Name of
413  * this object)
414  */
415  walk_state->operands[0] = (void *)node;
416  walk_state->num_operands = 1;
417 
418  /* Pop the scope stack */
419 
420  if (acpi_ns_opens_scope(object_type) &&
421  (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
423  "(%s) Popping scope for Op %p\n",
424  acpi_ut_get_type_name(object_type), op));
425 
426  status = acpi_ds_scope_stack_pop(walk_state);
427  if (ACPI_FAILURE(status)) {
428  goto cleanup;
429  }
430  }
431 
432  /*
433  * Named operations are as follows:
434  *
435  * AML_ALIAS
436  * AML_BANKFIELD
437  * AML_CREATEBITFIELD
438  * AML_CREATEBYTEFIELD
439  * AML_CREATEDWORDFIELD
440  * AML_CREATEFIELD
441  * AML_CREATEQWORDFIELD
442  * AML_CREATEWORDFIELD
443  * AML_DATA_REGION
444  * AML_DEVICE
445  * AML_EVENT
446  * AML_FIELD
447  * AML_INDEXFIELD
448  * AML_METHOD
449  * AML_METHODCALL
450  * AML_MUTEX
451  * AML_NAME
452  * AML_NAMEDFIELD
453  * AML_OPREGION
454  * AML_POWERRES
455  * AML_PROCESSOR
456  * AML_SCOPE
457  * AML_THERMALZONE
458  */
459 
461  "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
462  acpi_ps_get_opcode_name(op->common.aml_opcode),
463  walk_state, op, node));
464 
465  /* Decode the opcode */
466 
467  arg = op->common.value.arg;
468 
469  switch (walk_state->op_info->type) {
470 #ifndef ACPI_NO_METHOD_EXECUTION
471 
473  /*
474  * Create the field object, but the field buffer and index must
475  * be evaluated later during the execution phase
476  */
477  status = acpi_ds_create_buffer_field(op, walk_state);
478  break;
479 
481  /*
482  * If we are executing a method, initialize the field
483  */
484  if (walk_state->method_node) {
485  status = acpi_ds_init_field_objects(op, walk_state);
486  }
487 
488  switch (op->common.aml_opcode) {
489  case AML_INDEX_FIELD_OP:
490 
491  status =
493  (acpi_handle) arg->
494  common.node, walk_state);
495  break;
496 
497  case AML_BANK_FIELD_OP:
498 
499  status =
500  acpi_ds_create_bank_field(op, arg->common.node,
501  walk_state);
502  break;
503 
504  case AML_FIELD_OP:
505 
506  status =
507  acpi_ds_create_field(op, arg->common.node,
508  walk_state);
509  break;
510 
511  default:
512  /* All NAMED_FIELD opcodes must be handled above */
513  break;
514  }
515  break;
516 
518 
519  status = acpi_ds_create_operands(walk_state, arg);
520  if (ACPI_FAILURE(status)) {
521  goto cleanup;
522  }
523 
524  switch (op->common.aml_opcode) {
525  case AML_PROCESSOR_OP:
526 
527  status = acpi_ex_create_processor(walk_state);
528  break;
529 
530  case AML_POWER_RES_OP:
531 
532  status = acpi_ex_create_power_resource(walk_state);
533  break;
534 
535  case AML_MUTEX_OP:
536 
537  status = acpi_ex_create_mutex(walk_state);
538  break;
539 
540  case AML_EVENT_OP:
541 
542  status = acpi_ex_create_event(walk_state);
543  break;
544 
545  case AML_ALIAS_OP:
546 
547  status = acpi_ex_create_alias(walk_state);
548  break;
549 
550  default:
551  /* Unknown opcode */
552 
553  status = AE_OK;
554  goto cleanup;
555  }
556 
557  /* Delete operands */
558 
559  for (i = 1; i < walk_state->num_operands; i++) {
560  acpi_ut_remove_reference(walk_state->operands[i]);
561  walk_state->operands[i] = NULL;
562  }
563 
564  break;
565 #endif /* ACPI_NO_METHOD_EXECUTION */
566 
568 
569  switch (op->common.aml_opcode) {
570 #ifndef ACPI_NO_METHOD_EXECUTION
571  case AML_REGION_OP:
572  case AML_DATA_REGION_OP:
573 
574  if (op->common.aml_opcode == AML_REGION_OP) {
575  region_space = (acpi_adr_space_type)
576  ((op->common.value.arg)->common.value.
577  integer);
578  } else {
579  region_space = ACPI_ADR_SPACE_DATA_TABLE;
580  }
581 
582  /*
583  * The op_region is not fully parsed at this time. The only valid
584  * argument is the space_id. (We must save the address of the
585  * AML of the address and length operands)
586  *
587  * If we have a valid region, initialize it. The namespace is
588  * unlocked at this point.
589  *
590  * Need to unlock interpreter if it is locked (if we are running
591  * a control method), in order to allow _REG methods to be run
592  * during acpi_ev_initialize_region.
593  */
594  if (walk_state->method_node) {
595  /*
596  * Executing a method: initialize the region and unlock
597  * the interpreter
598  */
599  status =
600  acpi_ex_create_region(op->named.data,
601  op->named.length,
602  region_space,
603  walk_state);
604  if (ACPI_FAILURE(status)) {
605  return (status);
606  }
607 
609  }
610 
611  status =
614  if (walk_state->method_node) {
616  }
617 
618  if (ACPI_FAILURE(status)) {
619  /*
620  * If AE_NOT_EXIST is returned, it is not fatal
621  * because many regions get created before a handler
622  * is installed for said region.
623  */
624  if (AE_NOT_EXIST == status) {
625  status = AE_OK;
626  }
627  }
628  break;
629 
630  case AML_NAME_OP:
631 
632  status = acpi_ds_create_node(walk_state, node, op);
633  break;
634 
635  case AML_METHOD_OP:
636  /*
637  * method_op pkg_length name_string method_flags term_list
638  *
639  * Note: We must create the method node/object pair as soon as we
640  * see the method declaration. This allows later pass1 parsing
641  * of invocations of the method (need to know the number of
642  * arguments.)
643  */
645  "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
646  walk_state, op, op->named.node));
647 
648  if (!acpi_ns_get_attached_object(op->named.node)) {
649  walk_state->operands[0] =
650  ACPI_CAST_PTR(void, op->named.node);
651  walk_state->num_operands = 1;
652 
653  status =
654  acpi_ds_create_operands(walk_state,
655  op->common.value.
656  arg);
657  if (ACPI_SUCCESS(status)) {
658  status =
660  data,
661  op->named.
662  length,
663  walk_state);
664  }
665  walk_state->operands[0] = NULL;
666  walk_state->num_operands = 0;
667 
668  if (ACPI_FAILURE(status)) {
669  return_ACPI_STATUS(status);
670  }
671  }
672  break;
673 
674 #endif /* ACPI_NO_METHOD_EXECUTION */
675 
676  default:
677  /* All NAMED_COMPLEX opcodes must be handled above */
678  break;
679  }
680  break;
681 
682  case AML_CLASS_INTERNAL:
683 
684  /* case AML_INT_NAMEPATH_OP: */
685  break;
686 
688 
690  "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
691  walk_state, op, node));
692 
693  /*
694  * Lookup the method name and save the Node
695  */
696  status =
697  acpi_ns_lookup(walk_state->scope_info,
698  arg->common.value.string, ACPI_TYPE_ANY,
701  ACPI_NS_DONT_OPEN_SCOPE, walk_state,
702  &(new_node));
703  if (ACPI_SUCCESS(status)) {
704  /*
705  * Make sure that what we found is indeed a method
706  * We didn't search for a method on purpose, to see if the name
707  * would resolve
708  */
709  if (new_node->type != ACPI_TYPE_METHOD) {
710  status = AE_AML_OPERAND_TYPE;
711  }
712 
713  /* We could put the returned object (Node) on the object stack for
714  * later, but for now, we will put it in the "op" object that the
715  * parser uses, so we can get it again at the end of this scope
716  */
717  op->common.node = new_node;
718  } else {
719  ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
720  }
721  break;
722 
723  default:
724  break;
725  }
726 
727  cleanup:
728 
729  /* Remove the Node pushed at the very beginning */
730 
731  walk_state->operands[0] = NULL;
732  walk_state->num_operands = 0;
733  return_ACPI_STATUS(status);
734 }