Merge master.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild
[linux-2.6] / drivers / acpi / namespace / nsinit.c
1 /******************************************************************************
2  *
3  * Module Name: nsinit - namespace initialization
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2005, R. Byron Moore
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
45 #include <acpi/acpi.h>
46 #include <acpi/acnamesp.h>
47 #include <acpi/acdispat.h>
48 #include <acpi/acinterp.h>
49
50 #define _COMPONENT          ACPI_NAMESPACE
51          ACPI_MODULE_NAME    ("nsinit")
52
53 /* Local prototypes */
54
55 static acpi_status
56 acpi_ns_init_one_object (
57         acpi_handle                     obj_handle,
58         u32                             level,
59         void                            *context,
60         void                            **return_value);
61
62 static acpi_status
63 acpi_ns_init_one_device (
64         acpi_handle                     obj_handle,
65         u32                             nesting_level,
66         void                            *context,
67         void                            **return_value);
68
69
70 /*******************************************************************************
71  *
72  * FUNCTION:    acpi_ns_initialize_objects
73  *
74  * PARAMETERS:  None
75  *
76  * RETURN:      Status
77  *
78  * DESCRIPTION: Walk the entire namespace and perform any necessary
79  *              initialization on the objects found therein
80  *
81  ******************************************************************************/
82
83 acpi_status
84 acpi_ns_initialize_objects (
85         void)
86 {
87         acpi_status                     status;
88         struct acpi_init_walk_info      info;
89
90
91         ACPI_FUNCTION_TRACE ("ns_initialize_objects");
92
93
94         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
95                 "**** Starting initialization of namespace objects ****\n"));
96         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
97                 "Completing Region/Field/Buffer/Package initialization:"));
98
99         /* Set all init info to zero */
100
101         ACPI_MEMSET (&info, 0, sizeof (struct acpi_init_walk_info));
102
103         /* Walk entire namespace from the supplied root */
104
105         status = acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
106                           ACPI_UINT32_MAX, acpi_ns_init_one_object,
107                           &info, NULL);
108         if (ACPI_FAILURE (status)) {
109                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
110                         acpi_format_exception (status)));
111         }
112
113         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
114                 "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",
115                 info.op_region_init, info.op_region_count,
116                 info.field_init,    info.field_count,
117                 info.buffer_init,   info.buffer_count,
118                 info.package_init,  info.package_count, info.object_count));
119
120         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
121                 "%hd Control Methods found\n", info.method_count));
122         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
123                 "%hd Op Regions found\n", info.op_region_count));
124
125         return_ACPI_STATUS (AE_OK);
126 }
127
128
129 /*******************************************************************************
130  *
131  * FUNCTION:    acpi_ns_initialize_devices
132  *
133  * PARAMETERS:  None
134  *
135  * RETURN:      acpi_status
136  *
137  * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.
138  *              This means running _INI on all present devices.
139  *
140  *              Note: We install PCI config space handler on region access,
141  *              not here.
142  *
143  ******************************************************************************/
144
145 acpi_status
146 acpi_ns_initialize_devices (
147         void)
148 {
149         acpi_status                     status;
150         struct acpi_device_walk_info    info;
151
152
153         ACPI_FUNCTION_TRACE ("ns_initialize_devices");
154
155
156         /* Init counters */
157
158         info.device_count = 0;
159         info.num_STA = 0;
160         info.num_INI = 0;
161
162         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
163                 "Executing all Device _STA and_INI methods:"));
164
165         status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
166         if (ACPI_FAILURE (status)) {
167                 return_ACPI_STATUS (status);
168         }
169
170         /* Walk namespace for all objects */
171
172         status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
173                           ACPI_UINT32_MAX, TRUE, acpi_ns_init_one_device, &info, NULL);
174
175         (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
176
177         if (ACPI_FAILURE (status)) {
178                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
179                         acpi_format_exception (status)));
180         }
181
182         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
183                 "\n%hd Devices found containing: %hd _STA, %hd _INI methods\n",
184                 info.device_count, info.num_STA, info.num_INI));
185
186         return_ACPI_STATUS (status);
187 }
188
189
190 /*******************************************************************************
191  *
192  * FUNCTION:    acpi_ns_init_one_object
193  *
194  * PARAMETERS:  obj_handle      - Node
195  *              Level           - Current nesting level
196  *              Context         - Points to a init info struct
197  *              return_value    - Not used
198  *
199  * RETURN:      Status
200  *
201  * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object
202  *              within the  namespace.
203  *
204  *              Currently, the only objects that require initialization are:
205  *              1) Methods
206  *              2) Op Regions
207  *
208  ******************************************************************************/
209
210 static acpi_status
211 acpi_ns_init_one_object (
212         acpi_handle                     obj_handle,
213         u32                             level,
214         void                            *context,
215         void                            **return_value)
216 {
217         acpi_object_type                type;
218         acpi_status                     status;
219         struct acpi_init_walk_info      *info = (struct acpi_init_walk_info *) context;
220         struct acpi_namespace_node      *node = (struct acpi_namespace_node *) obj_handle;
221         union acpi_operand_object       *obj_desc;
222
223
224         ACPI_FUNCTION_NAME ("ns_init_one_object");
225
226
227         info->object_count++;
228
229         /* And even then, we are only interested in a few object types */
230
231         type = acpi_ns_get_type (obj_handle);
232         obj_desc = acpi_ns_get_attached_object (node);
233         if (!obj_desc) {
234                 return (AE_OK);
235         }
236
237         /* Increment counters for object types we are looking for */
238
239         switch (type) {
240         case ACPI_TYPE_REGION:
241                 info->op_region_count++;
242                 break;
243
244         case ACPI_TYPE_BUFFER_FIELD:
245                 info->field_count++;
246                 break;
247
248         case ACPI_TYPE_BUFFER:
249                 info->buffer_count++;
250                 break;
251
252         case ACPI_TYPE_PACKAGE:
253                 info->package_count++;
254                 break;
255
256         default:
257
258                 /* No init required, just exit now */
259                 return (AE_OK);
260         }
261
262         /*
263          * If the object is already initialized, nothing else to do
264          */
265         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
266                 return (AE_OK);
267         }
268
269         /*
270          * Must lock the interpreter before executing AML code
271          */
272         status = acpi_ex_enter_interpreter ();
273         if (ACPI_FAILURE (status)) {
274                 return (status);
275         }
276
277         /*
278          * Each of these types can contain executable AML code within the
279          * declaration.
280          */
281         switch (type) {
282         case ACPI_TYPE_REGION:
283
284                 info->op_region_init++;
285                 status = acpi_ds_get_region_arguments (obj_desc);
286                 break;
287
288         case ACPI_TYPE_BUFFER_FIELD:
289
290                 info->field_init++;
291                 status = acpi_ds_get_buffer_field_arguments (obj_desc);
292                 break;
293
294         case ACPI_TYPE_BUFFER:
295
296                 info->buffer_init++;
297                 status = acpi_ds_get_buffer_arguments (obj_desc);
298                 break;
299
300         case ACPI_TYPE_PACKAGE:
301
302                 info->package_init++;
303                 status = acpi_ds_get_package_arguments (obj_desc);
304                 break;
305
306         default:
307                 /* No other types can get here */
308                 break;
309         }
310
311         if (ACPI_FAILURE (status)) {
312                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "\n"));
313                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
314                                 "Could not execute arguments for [%4.4s] (%s), %s\n",
315                                 acpi_ut_get_node_name (node), acpi_ut_get_type_name (type),
316                                 acpi_format_exception (status)));
317         }
318
319         /*
320          * Print a dot for each object unless we are going to print the entire
321          * pathname
322          */
323         if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
324                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
325         }
326
327         /*
328          * We ignore errors from above, and always return OK, since we don't want
329          * to abort the walk on any single error.
330          */
331         acpi_ex_exit_interpreter ();
332         return (AE_OK);
333 }
334
335
336 /*******************************************************************************
337  *
338  * FUNCTION:    acpi_ns_init_one_device
339  *
340  * PARAMETERS:  acpi_walk_callback
341  *
342  * RETURN:      acpi_status
343  *
344  * DESCRIPTION: This is called once per device soon after ACPI is enabled
345  *              to initialize each device. It determines if the device is
346  *              present, and if so, calls _INI.
347  *
348  ******************************************************************************/
349
350 static acpi_status
351 acpi_ns_init_one_device (
352         acpi_handle                     obj_handle,
353         u32                             nesting_level,
354         void                            *context,
355         void                            **return_value)
356 {
357         struct acpi_device_walk_info   *info = (struct acpi_device_walk_info *) context;
358         struct acpi_parameter_info      pinfo;
359         u32                             flags;
360         acpi_status                     status;
361
362
363         ACPI_FUNCTION_TRACE ("ns_init_one_device");
364
365
366         pinfo.parameters = NULL;
367         pinfo.parameter_type = ACPI_PARAM_ARGS;
368
369         pinfo.node = acpi_ns_map_handle_to_node (obj_handle);
370         if (!pinfo.node) {
371                 return_ACPI_STATUS (AE_BAD_PARAMETER);
372         }
373
374         /*
375          * We will run _STA/_INI on Devices, Processors and thermal_zones only
376          */
377         if ((pinfo.node->type != ACPI_TYPE_DEVICE)      &&
378                 (pinfo.node->type != ACPI_TYPE_PROCESSOR)   &&
379                 (pinfo.node->type != ACPI_TYPE_THERMAL)) {
380                 return_ACPI_STATUS (AE_OK);
381         }
382
383         if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) &&
384                 (!(acpi_dbg_level & ACPI_LV_INFO))) {
385                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
386         }
387
388         info->device_count++;
389
390         /*
391          * Run _STA to determine if we can run _INI on the device.
392          */
393         ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD,
394                            pinfo.node, METHOD_NAME__STA));
395         status = acpi_ut_execute_STA (pinfo.node, &flags);
396
397         if (ACPI_FAILURE (status)) {
398                 if (pinfo.node->type == ACPI_TYPE_DEVICE) {
399                         /* Ignore error and move on to next device */
400
401                         return_ACPI_STATUS (AE_OK);
402                 }
403
404                 /* _STA is not required for Processor or thermal_zone objects */
405         }
406         else {
407                 info->num_STA++;
408
409                 if (!(flags & 0x01)) {
410                         /* Don't look at children of a not present device */
411
412                         return_ACPI_STATUS(AE_CTRL_DEPTH);
413                 }
414         }
415
416         /*
417          * The device is present. Run _INI.
418          */
419         ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD,
420                            pinfo.node, METHOD_NAME__INI));
421         status = acpi_ns_evaluate_relative (METHOD_NAME__INI, &pinfo);
422         if (ACPI_FAILURE (status)) {
423                 /* No _INI (AE_NOT_FOUND) means device requires no initialization */
424
425                 if (status != AE_NOT_FOUND) {
426                         /* Ignore error and move on to next device */
427
428 #ifdef ACPI_DEBUG_OUTPUT
429                         char                *scope_name = acpi_ns_get_external_pathname (pinfo.node);
430
431                         ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%s._INI failed: %s\n",
432                                         scope_name, acpi_format_exception (status)));
433
434                         ACPI_MEM_FREE (scope_name);
435 #endif
436                 }
437
438                 status = AE_OK;
439         }
440         else {
441                 /* Delete any return object (especially if implicit_return is enabled) */
442
443                 if (pinfo.return_object) {
444                         acpi_ut_remove_reference (pinfo.return_object);
445                 }
446
447                 /* Count of successful INIs */
448
449                 info->num_INI++;
450         }
451
452         if (acpi_gbl_init_handler) {
453                 /* External initialization handler is present, call it */
454
455                 status = acpi_gbl_init_handler (pinfo.node, ACPI_INIT_DEVICE_INI);
456         }
457
458         return_ACPI_STATUS (status);
459 }