OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acpi/] [namespace/] [nseval.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*******************************************************************************
2
 *
3
 * Module Name: nseval - Object evaluation interfaces -- includes control
4
 *                       method lookup and execution.
5
 *
6
 ******************************************************************************/
7
 
8
/*
9
 * Copyright (C) 2000 - 2004, 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
 
46
#include <acpi/acpi.h>
47
#include <acpi/acparser.h>
48
#include <acpi/acinterp.h>
49
#include <acpi/acnamesp.h>
50
 
51
 
52
#define _COMPONENT          ACPI_NAMESPACE
53
         ACPI_MODULE_NAME    ("nseval")
54
 
55
 
56
/*******************************************************************************
57
 *
58
 * FUNCTION:    acpi_ns_evaluate_relative
59
 *
60
 * PARAMETERS:  Handle              - The relative containing object
61
 *              Pathname            - Name of method to execute, If NULL, the
62
 *                                    handle is the object to execute
63
 *              Params              - List of parameters to pass to the method,
64
 *                                    terminated by NULL.  Params itself may be
65
 *                                    NULL if no parameters are being passed.
66
 *              return_object       - Where to put method's return value (if
67
 *                                    any).  If NULL, no value is returned.
68
 *
69
 * RETURN:      Status
70
 *
71
 * DESCRIPTION: Find and execute the requested method using the handle as a
72
 *              scope
73
 *
74
 * MUTEX:       Locks Namespace
75
 *
76
 ******************************************************************************/
77
 
78
acpi_status
79
acpi_ns_evaluate_relative (
80
        struct acpi_namespace_node      *handle,
81
        char                            *pathname,
82
        union acpi_operand_object       **params,
83
        union acpi_operand_object       **return_object)
84
{
85
        acpi_status                     status;
86
        struct acpi_namespace_node      *prefix_node;
87
        struct acpi_namespace_node      *node = NULL;
88
        union acpi_generic_state        *scope_info;
89
        char                            *internal_path = NULL;
90
 
91
 
92
        ACPI_FUNCTION_TRACE ("ns_evaluate_relative");
93
 
94
 
95
        /*
96
         * Must have a valid object handle
97
         */
98
        if (!handle) {
99
                return_ACPI_STATUS (AE_BAD_PARAMETER);
100
        }
101
 
102
        /* Build an internal name string for the method */
103
 
104
        status = acpi_ns_internalize_name (pathname, &internal_path);
105
        if (ACPI_FAILURE (status)) {
106
                return_ACPI_STATUS (status);
107
        }
108
 
109
        scope_info = acpi_ut_create_generic_state ();
110
        if (!scope_info) {
111
                goto cleanup1;
112
        }
113
 
114
        /* Get the prefix handle and Node */
115
 
116
        status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
117
        if (ACPI_FAILURE (status)) {
118
                goto cleanup;
119
        }
120
 
121
        prefix_node = acpi_ns_map_handle_to_node (handle);
122
        if (!prefix_node) {
123
                (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
124
                status = AE_BAD_PARAMETER;
125
                goto cleanup;
126
        }
127
 
128
        /* Lookup the name in the namespace */
129
 
130
        scope_info->scope.node = prefix_node;
131
        status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY,
132
                         ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
133
                         &node);
134
 
135
        (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
136
 
137
        if (ACPI_FAILURE (status)) {
138
                ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object [%s] not found [%s]\n",
139
                        pathname, acpi_format_exception (status)));
140
                goto cleanup;
141
        }
142
 
143
        /*
144
         * Now that we have a handle to the object, we can attempt
145
         * to evaluate it.
146
         */
147
        ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
148
                pathname, node, acpi_ns_get_attached_object (node)));
149
 
150
        status = acpi_ns_evaluate_by_handle (node, params, return_object);
151
 
152
        ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
153
                pathname));
154
 
155
cleanup:
156
        acpi_ut_delete_generic_state (scope_info);
157
 
158
cleanup1:
159
        ACPI_MEM_FREE (internal_path);
160
        return_ACPI_STATUS (status);
161
}
162
 
163
 
164
/*******************************************************************************
165
 *
166
 * FUNCTION:    acpi_ns_evaluate_by_name
167
 *
168
 * PARAMETERS:  Pathname            - Fully qualified pathname to the object
169
 *              return_object       - Where to put method's return value (if
170
 *                                    any).  If NULL, no value is returned.
171
 *              Params              - List of parameters to pass to the method,
172
 *                                    terminated by NULL.  Params itself may be
173
 *                                    NULL if no parameters are being passed.
174
 *
175
 * RETURN:      Status
176
 *
177
 * DESCRIPTION: Find and execute the requested method passing the given
178
 *              parameters
179
 *
180
 * MUTEX:       Locks Namespace
181
 *
182
 ******************************************************************************/
183
 
184
acpi_status
185
acpi_ns_evaluate_by_name (
186
        char                            *pathname,
187
        union acpi_operand_object       **params,
188
        union acpi_operand_object       **return_object)
189
{
190
        acpi_status                     status;
191
        struct acpi_namespace_node      *node = NULL;
192
        char                            *internal_path = NULL;
193
 
194
 
195
        ACPI_FUNCTION_TRACE ("ns_evaluate_by_name");
196
 
197
 
198
        /* Build an internal name string for the method */
199
 
200
        status = acpi_ns_internalize_name (pathname, &internal_path);
201
        if (ACPI_FAILURE (status)) {
202
                return_ACPI_STATUS (status);
203
        }
204
 
205
        status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
206
        if (ACPI_FAILURE (status)) {
207
                goto cleanup;
208
        }
209
 
210
        /* Lookup the name in the namespace */
211
 
212
        status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY,
213
                         ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
214
                         &node);
215
 
216
        (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
217
 
218
        if (ACPI_FAILURE (status)) {
219
                ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object at [%s] was not found, status=%.4X\n",
220
                        pathname, status));
221
                goto cleanup;
222
        }
223
 
224
        /*
225
         * Now that we have a handle to the object, we can attempt
226
         * to evaluate it.
227
         */
228
        ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
229
                pathname, node, acpi_ns_get_attached_object (node)));
230
 
231
        status = acpi_ns_evaluate_by_handle (node, params, return_object);
232
 
233
        ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
234
                pathname));
235
 
236
 
237
cleanup:
238
 
239
        /* Cleanup */
240
 
241
        if (internal_path) {
242
                ACPI_MEM_FREE (internal_path);
243
        }
244
 
245
        return_ACPI_STATUS (status);
246
}
247
 
248
 
249
/*******************************************************************************
250
 *
251
 * FUNCTION:    acpi_ns_evaluate_by_handle
252
 *
253
 * PARAMETERS:  Handle              - Method Node to execute
254
 *              Params              - List of parameters to pass to the method,
255
 *                                    terminated by NULL.  Params itself may be
256
 *                                    NULL if no parameters are being passed.
257
 *              return_object       - Where to put method's return value (if
258
 *                                    any).  If NULL, no value is returned.
259
 *
260
 * RETURN:      Status
261
 *
262
 * DESCRIPTION: Execute the requested method passing the given parameters
263
 *
264
 * MUTEX:       Locks Namespace
265
 *
266
 ******************************************************************************/
267
 
268
acpi_status
269
acpi_ns_evaluate_by_handle (
270
        struct acpi_namespace_node      *handle,
271
        union acpi_operand_object       **params,
272
        union acpi_operand_object       **return_object)
273
{
274
        struct acpi_namespace_node      *node;
275
        acpi_status                     status;
276
        union acpi_operand_object       *local_return_object;
277
 
278
 
279
        ACPI_FUNCTION_TRACE ("ns_evaluate_by_handle");
280
 
281
 
282
        /* Check if namespace has been initialized */
283
 
284
        if (!acpi_gbl_root_node) {
285
                return_ACPI_STATUS (AE_NO_NAMESPACE);
286
        }
287
 
288
        /* Parameter Validation */
289
 
290
        if (!handle) {
291
                return_ACPI_STATUS (AE_BAD_PARAMETER);
292
        }
293
 
294
        if (return_object) {
295
                /* Initialize the return value to an invalid object */
296
 
297
                *return_object = NULL;
298
        }
299
 
300
        /* Get the prefix handle and Node */
301
 
302
        status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
303
        if (ACPI_FAILURE (status)) {
304
                return_ACPI_STATUS (status);
305
        }
306
 
307
        node = acpi_ns_map_handle_to_node (handle);
308
        if (!node) {
309
                (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
310
                return_ACPI_STATUS (AE_BAD_PARAMETER);
311
        }
312
 
313
        /*
314
         * For a method alias, we must grab the actual method node
315
         * so that proper scoping context will be established
316
         * before execution.
317
         */
318
        if (acpi_ns_get_type (node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
319
                node = ACPI_CAST_PTR (struct acpi_namespace_node, node->object);
320
        }
321
 
322
        /*
323
         * Two major cases here:
324
         * 1) The object is an actual control method -- execute it.
325
         * 2) The object is not a method -- just return it's current
326
         *      value
327
         *
328
         * In both cases, the namespace is unlocked by the
329
         *  acpi_ns* procedure
330
         */
331
        if (acpi_ns_get_type (node) == ACPI_TYPE_METHOD) {
332
                /*
333
                 * Case 1) We have an actual control method to execute
334
                 */
335
                status = acpi_ns_execute_control_method (node, params,
336
                                 &local_return_object);
337
        }
338
        else {
339
                /*
340
                 * Case 2) Object is NOT a method, just return its
341
                 * current value
342
                 */
343
                status = acpi_ns_get_object_value (node, &local_return_object);
344
        }
345
 
346
        /*
347
         * Check if there is a return value on the stack that must
348
         * be dealt with
349
         */
350
        if (status == AE_CTRL_RETURN_VALUE) {
351
                /*
352
                 * If the Method returned a value and the caller
353
                 * provided a place to store a returned value, Copy
354
                 * the returned value to the object descriptor provided
355
                 * by the caller.
356
                 */
357
                if (return_object) {
358
                        /*
359
                         * Valid return object, copy the pointer to
360
                         * the returned object
361
                         */
362
                        *return_object = local_return_object;
363
                }
364
 
365
                /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
366
 
367
                status = AE_OK;
368
        }
369
 
370
        /*
371
         * Namespace was unlocked by the handling acpi_ns* function,
372
         * so we just return
373
         */
374
        return_ACPI_STATUS (status);
375
}
376
 
377
 
378
/*******************************************************************************
379
 *
380
 * FUNCTION:    acpi_ns_execute_control_method
381
 *
382
 * PARAMETERS:  method_node         - The method to execute
383
 *              Params              - List of parameters to pass to the method,
384
 *                                    terminated by NULL.  Params itself may be
385
 *                                    NULL if no parameters are being passed.
386
 *              return_obj_desc     - List of result objects to be returned
387
 *                                    from the method.
388
 *
389
 * RETURN:      Status
390
 *
391
 * DESCRIPTION: Execute the requested method passing the given parameters
392
 *
393
 * MUTEX:       Assumes namespace is locked
394
 *
395
 ******************************************************************************/
396
 
397
acpi_status
398
acpi_ns_execute_control_method (
399
        struct acpi_namespace_node      *method_node,
400
        union acpi_operand_object       **params,
401
        union acpi_operand_object       **return_obj_desc)
402
{
403
        acpi_status                     status;
404
        union acpi_operand_object       *obj_desc;
405
 
406
 
407
        ACPI_FUNCTION_TRACE ("ns_execute_control_method");
408
 
409
 
410
        /* Verify that there is a method associated with this object */
411
 
412
        obj_desc = acpi_ns_get_attached_object (method_node);
413
        if (!obj_desc) {
414
                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n"));
415
 
416
                (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
417
                return_ACPI_STATUS (AE_NULL_OBJECT);
418
        }
419
 
420
        ACPI_DUMP_PATHNAME (method_node, "Execute Method:",
421
                ACPI_LV_INFO, _COMPONENT);
422
 
423
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n",
424
                obj_desc->method.aml_start + 1, obj_desc->method.aml_length - 1));
425
 
426
        /*
427
         * Unlock the namespace before execution.  This allows namespace access
428
         * via the external Acpi* interfaces while a method is being executed.
429
         * However, any namespace deletion must acquire both the namespace and
430
         * interpreter locks to ensure that no thread is using the portion of the
431
         * namespace that is being deleted.
432
         */
433
        status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
434
        if (ACPI_FAILURE (status)) {
435
                return_ACPI_STATUS (status);
436
        }
437
 
438
        /*
439
         * Execute the method via the interpreter.  The interpreter is locked
440
         * here before calling into the AML parser
441
         */
442
        status = acpi_ex_enter_interpreter ();
443
        if (ACPI_FAILURE (status)) {
444
                return_ACPI_STATUS (status);
445
        }
446
 
447
        status = acpi_psx_execute (method_node, params, return_obj_desc);
448
        acpi_ex_exit_interpreter ();
449
 
450
        return_ACPI_STATUS (status);
451
}
452
 
453
 
454
/*******************************************************************************
455
 *
456
 * FUNCTION:    acpi_ns_get_object_value
457
 *
458
 * PARAMETERS:  Node                - The object
459
 *              return_obj_desc     - Where the objects value is returned
460
 *
461
 * RETURN:      Status
462
 *
463
 * DESCRIPTION: Return the current value of the object
464
 *
465
 * MUTEX:       Assumes namespace is locked, leaves namespace unlocked
466
 *
467
 ******************************************************************************/
468
 
469
acpi_status
470
acpi_ns_get_object_value (
471
        struct acpi_namespace_node      *node,
472
        union acpi_operand_object       **return_obj_desc)
473
{
474
        acpi_status                     status = AE_OK;
475
        struct acpi_namespace_node      *resolved_node = node;
476
 
477
 
478
        ACPI_FUNCTION_TRACE ("ns_get_object_value");
479
 
480
 
481
        /*
482
         * Objects require additional resolution steps (e.g., the
483
         * Node may be a field that must be read, etc.) -- we can't just grab
484
         * the object out of the node.
485
         */
486
 
487
        /*
488
         * Use resolve_node_to_value() to get the associated value. This call
489
         * always deletes obj_desc (allocated above).
490
         *
491
         * NOTE: we can get away with passing in NULL for a walk state
492
         * because obj_desc is guaranteed to not be a reference to either
493
         * a method local or a method argument (because this interface can only be
494
         * called from the acpi_evaluate external interface, never called from
495
         * a running control method.)
496
         *
497
         * Even though we do not directly invoke the interpreter
498
         * for this, we must enter it because we could access an opregion.
499
         * The opregion access code assumes that the interpreter
500
         * is locked.
501
         *
502
         * We must release the namespace lock before entering the
503
         * intepreter.
504
         */
505
        status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
506
        if (ACPI_FAILURE (status)) {
507
                return_ACPI_STATUS (status);
508
        }
509
 
510
        status = acpi_ex_enter_interpreter ();
511
        if (ACPI_SUCCESS (status)) {
512
                status = acpi_ex_resolve_node_to_value (&resolved_node, NULL);
513
                /*
514
                 * If acpi_ex_resolve_node_to_value() succeeded, the return value was
515
                 * placed in resolved_node.
516
                 */
517
                acpi_ex_exit_interpreter ();
518
 
519
                if (ACPI_SUCCESS (status)) {
520
                        status = AE_CTRL_RETURN_VALUE;
521
                        *return_obj_desc = ACPI_CAST_PTR (union acpi_operand_object, resolved_node);
522
                        ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n",
523
                                *return_obj_desc, acpi_ut_get_object_type_name (*return_obj_desc)));
524
                }
525
        }
526
 
527
        /* Namespace is unlocked */
528
 
529
        return_ACPI_STATUS (status);
530
}
531
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.