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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [acpi/] [dispatcher/] [dswstate.c] - Blame information for rev 67

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

Line No. Rev Author Line
1 62 marcus.erl
/******************************************************************************
2
 *
3
 * Module Name: dswstate - Dispatcher parse tree walk management routines
4
 *
5
 *****************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2007, 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
#include <acpi/acpi.h>
45
#include <acpi/acparser.h>
46
#include <acpi/acdispat.h>
47
#include <acpi/acnamesp.h>
48
 
49
#define _COMPONENT          ACPI_DISPATCHER
50
ACPI_MODULE_NAME("dswstate")
51
 
52
/* Local prototypes */
53
#ifdef ACPI_OBSOLETE_FUNCTIONS
54
acpi_status
55
acpi_ds_result_insert(void *object,
56
                      u32 index, struct acpi_walk_state *walk_state);
57
 
58
acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state *walk_state);
59
 
60
acpi_status
61
acpi_ds_obj_stack_pop_object(union acpi_operand_object **object,
62
                             struct acpi_walk_state *walk_state);
63
 
64
void *acpi_ds_obj_stack_get_value(u32 index,
65
                                  struct acpi_walk_state *walk_state);
66
#endif
67
 
68
#ifdef ACPI_FUTURE_USAGE
69
/*******************************************************************************
70
 *
71
 * FUNCTION:    acpi_ds_result_remove
72
 *
73
 * PARAMETERS:  Object              - Where to return the popped object
74
 *              Index               - Where to extract the object
75
 *              walk_state          - Current Walk state
76
 *
77
 * RETURN:      Status
78
 *
79
 * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
80
 *              other words, this is a FIFO.
81
 *
82
 ******************************************************************************/
83
 
84
acpi_status
85
acpi_ds_result_remove(union acpi_operand_object **object,
86
                      u32 index, struct acpi_walk_state *walk_state)
87
{
88
        union acpi_generic_state *state;
89
 
90
        ACPI_FUNCTION_NAME(ds_result_remove);
91
 
92
        state = walk_state->results;
93
        if (!state) {
94
                ACPI_ERROR((AE_INFO, "No result object pushed! State=%p",
95
                            walk_state));
96
                return (AE_NOT_EXIST);
97
        }
98
 
99
        if (index >= ACPI_OBJ_MAX_OPERAND) {
100
                ACPI_ERROR((AE_INFO,
101
                            "Index out of range: %X State=%p Num=%X",
102
                            index, walk_state, state->results.num_results));
103
        }
104
 
105
        /* Check for a valid result object */
106
 
107
        if (!state->results.obj_desc[index]) {
108
                ACPI_ERROR((AE_INFO,
109
                            "Null operand! State=%p #Ops=%X, Index=%X",
110
                            walk_state, state->results.num_results, index));
111
                return (AE_AML_NO_RETURN_VALUE);
112
        }
113
 
114
        /* Remove the object */
115
 
116
        state->results.num_results--;
117
 
118
        *object = state->results.obj_desc[index];
119
        state->results.obj_desc[index] = NULL;
120
 
121
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
122
                          "Obj=%p [%s] Index=%X State=%p Num=%X\n",
123
                          *object,
124
                          (*object) ? acpi_ut_get_object_type_name(*object) :
125
                          "NULL", index, walk_state,
126
                          state->results.num_results));
127
 
128
        return (AE_OK);
129
}
130
#endif                          /*  ACPI_FUTURE_USAGE  */
131
 
132
/*******************************************************************************
133
 *
134
 * FUNCTION:    acpi_ds_result_pop
135
 *
136
 * PARAMETERS:  Object              - Where to return the popped object
137
 *              walk_state          - Current Walk state
138
 *
139
 * RETURN:      Status
140
 *
141
 * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
142
 *              other words, this is a FIFO.
143
 *
144
 ******************************************************************************/
145
 
146
acpi_status
147
acpi_ds_result_pop(union acpi_operand_object ** object,
148
                   struct acpi_walk_state * walk_state)
149
{
150
        acpi_native_uint index;
151
        union acpi_generic_state *state;
152
 
153
        ACPI_FUNCTION_NAME(ds_result_pop);
154
 
155
        state = walk_state->results;
156
        if (!state) {
157
                return (AE_OK);
158
        }
159
 
160
        if (!state->results.num_results) {
161
                ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p",
162
                            walk_state));
163
                return (AE_AML_NO_RETURN_VALUE);
164
        }
165
 
166
        /* Remove top element */
167
 
168
        state->results.num_results--;
169
 
170
        for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) {
171
 
172
                /* Check for a valid result object */
173
 
174
                if (state->results.obj_desc[index - 1]) {
175
                        *object = state->results.obj_desc[index - 1];
176
                        state->results.obj_desc[index - 1] = NULL;
177
 
178
                        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
179
                                          "Obj=%p [%s] Index=%X State=%p Num=%X\n",
180
                                          *object,
181
                                          (*object) ?
182
                                          acpi_ut_get_object_type_name(*object)
183
                                          : "NULL", (u32) index - 1, walk_state,
184
                                          state->results.num_results));
185
 
186
                        return (AE_OK);
187
                }
188
        }
189
 
190
        ACPI_ERROR((AE_INFO, "No result objects! State=%p", walk_state));
191
        return (AE_AML_NO_RETURN_VALUE);
192
}
193
 
194
/*******************************************************************************
195
 *
196
 * FUNCTION:    acpi_ds_result_pop_from_bottom
197
 *
198
 * PARAMETERS:  Object              - Where to return the popped object
199
 *              walk_state          - Current Walk state
200
 *
201
 * RETURN:      Status
202
 *
203
 * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
204
 *              other words, this is a FIFO.
205
 *
206
 ******************************************************************************/
207
 
208
acpi_status
209
acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object,
210
                               struct acpi_walk_state * walk_state)
211
{
212
        acpi_native_uint index;
213
        union acpi_generic_state *state;
214
 
215
        ACPI_FUNCTION_NAME(ds_result_pop_from_bottom);
216
 
217
        state = walk_state->results;
218
        if (!state) {
219
                ACPI_ERROR((AE_INFO,
220
                            "No result object pushed! State=%p", walk_state));
221
                return (AE_NOT_EXIST);
222
        }
223
 
224
        if (!state->results.num_results) {
225
                ACPI_ERROR((AE_INFO, "No result objects! State=%p",
226
                            walk_state));
227
                return (AE_AML_NO_RETURN_VALUE);
228
        }
229
 
230
        /* Remove Bottom element */
231
 
232
        *object = state->results.obj_desc[0];
233
 
234
        /* Push entire stack down one element */
235
 
236
        for (index = 0; index < state->results.num_results; index++) {
237
                state->results.obj_desc[index] =
238
                    state->results.obj_desc[index + 1];
239
        }
240
 
241
        state->results.num_results--;
242
 
243
        /* Check for a valid result object */
244
 
245
        if (!*object) {
246
                ACPI_ERROR((AE_INFO,
247
                            "Null operand! State=%p #Ops=%X Index=%X",
248
                            walk_state, state->results.num_results,
249
                            (u32) index));
250
                return (AE_AML_NO_RETURN_VALUE);
251
        }
252
 
253
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] Results=%p State=%p\n",
254
                          *object,
255
                          (*object) ? acpi_ut_get_object_type_name(*object) :
256
                          "NULL", state, walk_state));
257
 
258
        return (AE_OK);
259
}
260
 
261
/*******************************************************************************
262
 *
263
 * FUNCTION:    acpi_ds_result_push
264
 *
265
 * PARAMETERS:  Object              - Where to return the popped object
266
 *              walk_state          - Current Walk state
267
 *
268
 * RETURN:      Status
269
 *
270
 * DESCRIPTION: Push an object onto the current result stack
271
 *
272
 ******************************************************************************/
273
 
274
acpi_status
275
acpi_ds_result_push(union acpi_operand_object * object,
276
                    struct acpi_walk_state * walk_state)
277
{
278
        union acpi_generic_state *state;
279
 
280
        ACPI_FUNCTION_NAME(ds_result_push);
281
 
282
        state = walk_state->results;
283
        if (!state) {
284
                ACPI_ERROR((AE_INFO, "No result stack frame during push"));
285
                return (AE_AML_INTERNAL);
286
        }
287
 
288
        if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) {
289
                ACPI_ERROR((AE_INFO,
290
                            "Result stack overflow: Obj=%p State=%p Num=%X",
291
                            object, walk_state, state->results.num_results));
292
                return (AE_STACK_OVERFLOW);
293
        }
294
 
295
        if (!object) {
296
                ACPI_ERROR((AE_INFO,
297
                            "Null Object! Obj=%p State=%p Num=%X",
298
                            object, walk_state, state->results.num_results));
299
                return (AE_BAD_PARAMETER);
300
        }
301
 
302
        state->results.obj_desc[state->results.num_results] = object;
303
        state->results.num_results++;
304
 
305
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
306
                          object,
307
                          object ?
308
                          acpi_ut_get_object_type_name((union
309
                                                        acpi_operand_object *)
310
                                                       object) : "NULL",
311
                          walk_state, state->results.num_results,
312
                          walk_state->current_result));
313
 
314
        return (AE_OK);
315
}
316
 
317
/*******************************************************************************
318
 *
319
 * FUNCTION:    acpi_ds_result_stack_push
320
 *
321
 * PARAMETERS:  walk_state          - Current Walk state
322
 *
323
 * RETURN:      Status
324
 *
325
 * DESCRIPTION: Push an object onto the walk_state result stack.
326
 *
327
 ******************************************************************************/
328
 
329
acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state)
330
{
331
        union acpi_generic_state *state;
332
 
333
        ACPI_FUNCTION_NAME(ds_result_stack_push);
334
 
335
        state = acpi_ut_create_generic_state();
336
        if (!state) {
337
                return (AE_NO_MEMORY);
338
        }
339
 
340
        state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT;
341
        acpi_ut_push_generic_state(&walk_state->results, state);
342
 
343
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n",
344
                          state, walk_state));
345
 
346
        return (AE_OK);
347
}
348
 
349
/*******************************************************************************
350
 *
351
 * FUNCTION:    acpi_ds_result_stack_pop
352
 *
353
 * PARAMETERS:  walk_state          - Current Walk state
354
 *
355
 * RETURN:      Status
356
 *
357
 * DESCRIPTION: Pop an object off of the walk_state result stack.
358
 *
359
 ******************************************************************************/
360
 
361
acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state)
362
{
363
        union acpi_generic_state *state;
364
 
365
        ACPI_FUNCTION_NAME(ds_result_stack_pop);
366
 
367
        /* Check for stack underflow */
368
 
369
        if (walk_state->results == NULL) {
370
                ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Underflow - State=%p\n",
371
                                  walk_state));
372
                return (AE_AML_NO_OPERAND);
373
        }
374
 
375
        state = acpi_ut_pop_generic_state(&walk_state->results);
376
 
377
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
378
                          "Result=%p RemainingResults=%X State=%p\n",
379
                          state, state->results.num_results, walk_state));
380
 
381
        acpi_ut_delete_generic_state(state);
382
 
383
        return (AE_OK);
384
}
385
 
386
/*******************************************************************************
387
 *
388
 * FUNCTION:    acpi_ds_obj_stack_push
389
 *
390
 * PARAMETERS:  Object              - Object to push
391
 *              walk_state          - Current Walk state
392
 *
393
 * RETURN:      Status
394
 *
395
 * DESCRIPTION: Push an object onto this walk's object/operand stack
396
 *
397
 ******************************************************************************/
398
 
399
acpi_status
400
acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state)
401
{
402
        ACPI_FUNCTION_NAME(ds_obj_stack_push);
403
 
404
        /* Check for stack overflow */
405
 
406
        if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
407
                ACPI_ERROR((AE_INFO,
408
                            "Object stack overflow! Obj=%p State=%p #Ops=%X",
409
                            object, walk_state, walk_state->num_operands));
410
                return (AE_STACK_OVERFLOW);
411
        }
412
 
413
        /* Put the object onto the stack */
414
 
415
        walk_state->operands[walk_state->num_operands] = object;
416
        walk_state->num_operands++;
417
 
418
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
419
                          object,
420
                          acpi_ut_get_object_type_name((union
421
                                                        acpi_operand_object *)
422
                                                       object), walk_state,
423
                          walk_state->num_operands));
424
 
425
        return (AE_OK);
426
}
427
 
428
/*******************************************************************************
429
 *
430
 * FUNCTION:    acpi_ds_obj_stack_pop
431
 *
432
 * PARAMETERS:  pop_count           - Number of objects/entries to pop
433
 *              walk_state          - Current Walk state
434
 *
435
 * RETURN:      Status
436
 *
437
 * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
438
 *              deleted by this routine.
439
 *
440
 ******************************************************************************/
441
 
442
acpi_status
443
acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state)
444
{
445
        u32 i;
446
 
447
        ACPI_FUNCTION_NAME(ds_obj_stack_pop);
448
 
449
        for (i = 0; i < pop_count; i++) {
450
 
451
                /* Check for stack underflow */
452
 
453
                if (walk_state->num_operands == 0) {
454
                        ACPI_ERROR((AE_INFO,
455
                                    "Object stack underflow! Count=%X State=%p #Ops=%X",
456
                                    pop_count, walk_state,
457
                                    walk_state->num_operands));
458
                        return (AE_STACK_UNDERFLOW);
459
                }
460
 
461
                /* Just set the stack entry to null */
462
 
463
                walk_state->num_operands--;
464
                walk_state->operands[walk_state->num_operands] = NULL;
465
        }
466
 
467
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
468
                          pop_count, walk_state, walk_state->num_operands));
469
 
470
        return (AE_OK);
471
}
472
 
473
/*******************************************************************************
474
 *
475
 * FUNCTION:    acpi_ds_obj_stack_pop_and_delete
476
 *
477
 * PARAMETERS:  pop_count           - Number of objects/entries to pop
478
 *              walk_state          - Current Walk state
479
 *
480
 * RETURN:      Status
481
 *
482
 * DESCRIPTION: Pop this walk's object stack and delete each object that is
483
 *              popped off.
484
 *
485
 ******************************************************************************/
486
 
487
acpi_status
488
acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
489
                                 struct acpi_walk_state * walk_state)
490
{
491
        u32 i;
492
        union acpi_operand_object *obj_desc;
493
 
494
        ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete);
495
 
496
        for (i = 0; i < pop_count; i++) {
497
 
498
                /* Check for stack underflow */
499
 
500
                if (walk_state->num_operands == 0) {
501
                        ACPI_ERROR((AE_INFO,
502
                                    "Object stack underflow! Count=%X State=%p #Ops=%X",
503
                                    pop_count, walk_state,
504
                                    walk_state->num_operands));
505
                        return (AE_STACK_UNDERFLOW);
506
                }
507
 
508
                /* Pop the stack and delete an object if present in this stack entry */
509
 
510
                walk_state->num_operands--;
511
                obj_desc = walk_state->operands[walk_state->num_operands];
512
                if (obj_desc) {
513
                        acpi_ut_remove_reference(walk_state->
514
                                                 operands[walk_state->
515
                                                          num_operands]);
516
                        walk_state->operands[walk_state->num_operands] = NULL;
517
                }
518
        }
519
 
520
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
521
                          pop_count, walk_state, walk_state->num_operands));
522
 
523
        return (AE_OK);
524
}
525
 
526
/*******************************************************************************
527
 *
528
 * FUNCTION:    acpi_ds_get_current_walk_state
529
 *
530
 * PARAMETERS:  Thread          - Get current active state for this Thread
531
 *
532
 * RETURN:      Pointer to the current walk state
533
 *
534
 * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
535
 *              walk state.)
536
 *
537
 ******************************************************************************/
538
 
539
struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state
540
                                                       *thread)
541
{
542
        ACPI_FUNCTION_NAME(ds_get_current_walk_state);
543
 
544
        if (!thread) {
545
                return (NULL);
546
        }
547
 
548
        ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Current WalkState %p\n",
549
                          thread->walk_state_list));
550
 
551
        return (thread->walk_state_list);
552
}
553
 
554
/*******************************************************************************
555
 *
556
 * FUNCTION:    acpi_ds_push_walk_state
557
 *
558
 * PARAMETERS:  walk_state      - State to push
559
 *              Thread          - Thread state object
560
 *
561
 * RETURN:      None
562
 *
563
 * DESCRIPTION: Place the Thread state at the head of the state list.
564
 *
565
 ******************************************************************************/
566
 
567
void
568
acpi_ds_push_walk_state(struct acpi_walk_state *walk_state,
569
                        struct acpi_thread_state *thread)
570
{
571
        ACPI_FUNCTION_TRACE(ds_push_walk_state);
572
 
573
        walk_state->next = thread->walk_state_list;
574
        thread->walk_state_list = walk_state;
575
 
576
        return_VOID;
577
}
578
 
579
/*******************************************************************************
580
 *
581
 * FUNCTION:    acpi_ds_pop_walk_state
582
 *
583
 * PARAMETERS:  Thread      - Current thread state
584
 *
585
 * RETURN:      A walk_state object popped from the thread's stack
586
 *
587
 * DESCRIPTION: Remove and return the walkstate object that is at the head of
588
 *              the walk stack for the given walk list.  NULL indicates that
589
 *              the list is empty.
590
 *
591
 ******************************************************************************/
592
 
593
struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread)
594
{
595
        struct acpi_walk_state *walk_state;
596
 
597
        ACPI_FUNCTION_TRACE(ds_pop_walk_state);
598
 
599
        walk_state = thread->walk_state_list;
600
 
601
        if (walk_state) {
602
 
603
                /* Next walk state becomes the current walk state */
604
 
605
                thread->walk_state_list = walk_state->next;
606
 
607
                /*
608
                 * Don't clear the NEXT field, this serves as an indicator
609
                 * that there is a parent WALK STATE
610
                 * Do Not: walk_state->Next = NULL;
611
                 */
612
        }
613
 
614
        return_PTR(walk_state);
615
}
616
 
617
/*******************************************************************************
618
 *
619
 * FUNCTION:    acpi_ds_create_walk_state
620
 *
621
 * PARAMETERS:  owner_id        - ID for object creation
622
 *              Origin          - Starting point for this walk
623
 *              method_desc     - Method object
624
 *              Thread          - Current thread state
625
 *
626
 * RETURN:      Pointer to the new walk state.
627
 *
628
 * DESCRIPTION: Allocate and initialize a new walk state.  The current walk
629
 *              state is set to this new state.
630
 *
631
 ******************************************************************************/
632
 
633
struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union acpi_parse_object
634
                                                  *origin, union acpi_operand_object
635
                                                  *method_desc, struct acpi_thread_state
636
                                                  *thread)
637
{
638
        struct acpi_walk_state *walk_state;
639
        acpi_status status;
640
 
641
        ACPI_FUNCTION_TRACE(ds_create_walk_state);
642
 
643
        walk_state = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_walk_state));
644
        if (!walk_state) {
645
                return_PTR(NULL);
646
        }
647
 
648
        walk_state->descriptor_type = ACPI_DESC_TYPE_WALK;
649
        walk_state->method_desc = method_desc;
650
        walk_state->owner_id = owner_id;
651
        walk_state->origin = origin;
652
        walk_state->thread = thread;
653
 
654
        walk_state->parser_state.start_op = origin;
655
 
656
        /* Init the method args/local */
657
 
658
#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
659
        acpi_ds_method_data_init(walk_state);
660
#endif
661
 
662
        /* Create an initial result stack entry */
663
 
664
        status = acpi_ds_result_stack_push(walk_state);
665
        if (ACPI_FAILURE(status)) {
666
                ACPI_FREE(walk_state);
667
                return_PTR(NULL);
668
        }
669
 
670
        /* Put the new state at the head of the walk list */
671
 
672
        if (thread) {
673
                acpi_ds_push_walk_state(walk_state, thread);
674
        }
675
 
676
        return_PTR(walk_state);
677
}
678
 
679
/*******************************************************************************
680
 *
681
 * FUNCTION:    acpi_ds_init_aml_walk
682
 *
683
 * PARAMETERS:  walk_state      - New state to be initialized
684
 *              Op              - Current parse op
685
 *              method_node     - Control method NS node, if any
686
 *              aml_start       - Start of AML
687
 *              aml_length      - Length of AML
688
 *              Info            - Method info block (params, etc.)
689
 *              pass_number     - 1, 2, or 3
690
 *
691
 * RETURN:      Status
692
 *
693
 * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
694
 *
695
 ******************************************************************************/
696
 
697
acpi_status
698
acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
699
                      union acpi_parse_object *op,
700
                      struct acpi_namespace_node *method_node,
701
                      u8 * aml_start,
702
                      u32 aml_length,
703
                      struct acpi_evaluate_info *info, u8 pass_number)
704
{
705
        acpi_status status;
706
        struct acpi_parse_state *parser_state = &walk_state->parser_state;
707
        union acpi_parse_object *extra_op;
708
 
709
        ACPI_FUNCTION_TRACE(ds_init_aml_walk);
710
 
711
        walk_state->parser_state.aml =
712
            walk_state->parser_state.aml_start = aml_start;
713
        walk_state->parser_state.aml_end =
714
            walk_state->parser_state.pkg_end = aml_start + aml_length;
715
 
716
        /* The next_op of the next_walk will be the beginning of the method */
717
 
718
        walk_state->next_op = NULL;
719
        walk_state->pass_number = pass_number;
720
 
721
        if (info) {
722
                if (info->parameter_type == ACPI_PARAM_GPE) {
723
                        walk_state->gpe_event_info =
724
                            ACPI_CAST_PTR(struct acpi_gpe_event_info,
725
                                          info->parameters);
726
                } else {
727
                        walk_state->params = info->parameters;
728
                        walk_state->caller_return_desc = &info->return_object;
729
                }
730
        }
731
 
732
        status = acpi_ps_init_scope(&walk_state->parser_state, op);
733
        if (ACPI_FAILURE(status)) {
734
                return_ACPI_STATUS(status);
735
        }
736
 
737
        if (method_node) {
738
                walk_state->parser_state.start_node = method_node;
739
                walk_state->walk_type = ACPI_WALK_METHOD;
740
                walk_state->method_node = method_node;
741
                walk_state->method_desc =
742
                    acpi_ns_get_attached_object(method_node);
743
 
744
                /* Push start scope on scope stack and make it current  */
745
 
746
                status =
747
                    acpi_ds_scope_stack_push(method_node, ACPI_TYPE_METHOD,
748
                                             walk_state);
749
                if (ACPI_FAILURE(status)) {
750
                        return_ACPI_STATUS(status);
751
                }
752
 
753
                /* Init the method arguments */
754
 
755
                status = acpi_ds_method_data_init_args(walk_state->params,
756
                                                       ACPI_METHOD_NUM_ARGS,
757
                                                       walk_state);
758
                if (ACPI_FAILURE(status)) {
759
                        return_ACPI_STATUS(status);
760
                }
761
        } else {
762
                /*
763
                 * Setup the current scope.
764
                 * Find a Named Op that has a namespace node associated with it.
765
                 * search upwards from this Op.  Current scope is the first
766
                 * Op with a namespace node.
767
                 */
768
                extra_op = parser_state->start_op;
769
                while (extra_op && !extra_op->common.node) {
770
                        extra_op = extra_op->common.parent;
771
                }
772
 
773
                if (!extra_op) {
774
                        parser_state->start_node = NULL;
775
                } else {
776
                        parser_state->start_node = extra_op->common.node;
777
                }
778
 
779
                if (parser_state->start_node) {
780
 
781
                        /* Push start scope on scope stack and make it current  */
782
 
783
                        status =
784
                            acpi_ds_scope_stack_push(parser_state->start_node,
785
                                                     parser_state->start_node->
786
                                                     type, walk_state);
787
                        if (ACPI_FAILURE(status)) {
788
                                return_ACPI_STATUS(status);
789
                        }
790
                }
791
        }
792
 
793
        status = acpi_ds_init_callbacks(walk_state, pass_number);
794
        return_ACPI_STATUS(status);
795
}
796
 
797
/*******************************************************************************
798
 *
799
 * FUNCTION:    acpi_ds_delete_walk_state
800
 *
801
 * PARAMETERS:  walk_state      - State to delete
802
 *
803
 * RETURN:      Status
804
 *
805
 * DESCRIPTION: Delete a walk state including all internal data structures
806
 *
807
 ******************************************************************************/
808
 
809
void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state)
810
{
811
        union acpi_generic_state *state;
812
 
813
        ACPI_FUNCTION_TRACE_PTR(ds_delete_walk_state, walk_state);
814
 
815
        if (!walk_state) {
816
                return;
817
        }
818
 
819
        if (walk_state->descriptor_type != ACPI_DESC_TYPE_WALK) {
820
                ACPI_ERROR((AE_INFO, "%p is not a valid walk state",
821
                            walk_state));
822
                return;
823
        }
824
 
825
        /* There should not be any open scopes */
826
 
827
        if (walk_state->parser_state.scope) {
828
                ACPI_ERROR((AE_INFO, "%p walk still has a scope list",
829
                            walk_state));
830
                acpi_ps_cleanup_scope(&walk_state->parser_state);
831
        }
832
 
833
        /* Always must free any linked control states */
834
 
835
        while (walk_state->control_state) {
836
                state = walk_state->control_state;
837
                walk_state->control_state = state->common.next;
838
 
839
                acpi_ut_delete_generic_state(state);
840
        }
841
 
842
        /* Always must free any linked parse states */
843
 
844
        while (walk_state->scope_info) {
845
                state = walk_state->scope_info;
846
                walk_state->scope_info = state->common.next;
847
 
848
                acpi_ut_delete_generic_state(state);
849
        }
850
 
851
        /* Always must free any stacked result states */
852
 
853
        while (walk_state->results) {
854
                state = walk_state->results;
855
                walk_state->results = state->common.next;
856
 
857
                acpi_ut_delete_generic_state(state);
858
        }
859
 
860
        ACPI_FREE(walk_state);
861
        return_VOID;
862
}
863
 
864
#ifdef ACPI_OBSOLETE_FUNCTIONS
865
/*******************************************************************************
866
 *
867
 * FUNCTION:    acpi_ds_result_insert
868
 *
869
 * PARAMETERS:  Object              - Object to push
870
 *              Index               - Where to insert the object
871
 *              walk_state          - Current Walk state
872
 *
873
 * RETURN:      Status
874
 *
875
 * DESCRIPTION: Insert an object onto this walk's result stack
876
 *
877
 ******************************************************************************/
878
 
879
acpi_status
880
acpi_ds_result_insert(void *object,
881
                      u32 index, struct acpi_walk_state *walk_state)
882
{
883
        union acpi_generic_state *state;
884
 
885
        ACPI_FUNCTION_NAME(ds_result_insert);
886
 
887
        state = walk_state->results;
888
        if (!state) {
889
                ACPI_ERROR((AE_INFO, "No result object pushed! State=%p",
890
                            walk_state));
891
                return (AE_NOT_EXIST);
892
        }
893
 
894
        if (index >= ACPI_OBJ_NUM_OPERANDS) {
895
                ACPI_ERROR((AE_INFO,
896
                            "Index out of range: %X Obj=%p State=%p Num=%X",
897
                            index, object, walk_state,
898
                            state->results.num_results));
899
                return (AE_BAD_PARAMETER);
900
        }
901
 
902
        if (!object) {
903
                ACPI_ERROR((AE_INFO,
904
                            "Null Object! Index=%X Obj=%p State=%p Num=%X",
905
                            index, object, walk_state,
906
                            state->results.num_results));
907
                return (AE_BAD_PARAMETER);
908
        }
909
 
910
        state->results.obj_desc[index] = object;
911
        state->results.num_results++;
912
 
913
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
914
                          "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
915
                          object,
916
                          object ?
917
                          acpi_ut_get_object_type_name((union
918
                                                        acpi_operand_object *)
919
                                                       object) : "NULL",
920
                          walk_state, state->results.num_results,
921
                          walk_state->current_result));
922
 
923
        return (AE_OK);
924
}
925
 
926
/*******************************************************************************
927
 *
928
 * FUNCTION:    acpi_ds_obj_stack_delete_all
929
 *
930
 * PARAMETERS:  walk_state          - Current Walk state
931
 *
932
 * RETURN:      Status
933
 *
934
 * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
935
 *              Should be used with great care, if at all!
936
 *
937
 ******************************************************************************/
938
 
939
acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state * walk_state)
940
{
941
        u32 i;
942
 
943
        ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_delete_all, walk_state);
944
 
945
        /* The stack size is configurable, but fixed */
946
 
947
        for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
948
                if (walk_state->operands[i]) {
949
                        acpi_ut_remove_reference(walk_state->operands[i]);
950
                        walk_state->operands[i] = NULL;
951
                }
952
        }
953
 
954
        return_ACPI_STATUS(AE_OK);
955
}
956
 
957
/*******************************************************************************
958
 *
959
 * FUNCTION:    acpi_ds_obj_stack_pop_object
960
 *
961
 * PARAMETERS:  Object              - Where to return the popped object
962
 *              walk_state          - Current Walk state
963
 *
964
 * RETURN:      Status
965
 *
966
 * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
967
 *              deleted by this routine.
968
 *
969
 ******************************************************************************/
970
 
971
acpi_status
972
acpi_ds_obj_stack_pop_object(union acpi_operand_object **object,
973
                             struct acpi_walk_state *walk_state)
974
{
975
        ACPI_FUNCTION_NAME(ds_obj_stack_pop_object);
976
 
977
        /* Check for stack underflow */
978
 
979
        if (walk_state->num_operands == 0) {
980
                ACPI_ERROR((AE_INFO,
981
                            "Missing operand/stack empty! State=%p #Ops=%X",
982
                            walk_state, walk_state->num_operands));
983
                *object = NULL;
984
                return (AE_AML_NO_OPERAND);
985
        }
986
 
987
        /* Pop the stack */
988
 
989
        walk_state->num_operands--;
990
 
991
        /* Check for a valid operand */
992
 
993
        if (!walk_state->operands[walk_state->num_operands]) {
994
                ACPI_ERROR((AE_INFO,
995
                            "Null operand! State=%p #Ops=%X",
996
                            walk_state, walk_state->num_operands));
997
                *object = NULL;
998
                return (AE_AML_NO_OPERAND);
999
        }
1000
 
1001
        /* Get operand and set stack entry to null */
1002
 
1003
        *object = walk_state->operands[walk_state->num_operands];
1004
        walk_state->operands[walk_state->num_operands] = NULL;
1005
 
1006
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
1007
                          *object, acpi_ut_get_object_type_name(*object),
1008
                          walk_state, walk_state->num_operands));
1009
 
1010
        return (AE_OK);
1011
}
1012
 
1013
/*******************************************************************************
1014
 *
1015
 * FUNCTION:    acpi_ds_obj_stack_get_value
1016
 *
1017
 * PARAMETERS:  Index               - Stack index whose value is desired.  Based
1018
 *                                    on the top of the stack (index=0 == top)
1019
 *              walk_state          - Current Walk state
1020
 *
1021
 * RETURN:      Pointer to the requested operand
1022
 *
1023
 * DESCRIPTION: Retrieve an object from this walk's operand stack.  Index must
1024
 *              be within the range of the current stack pointer.
1025
 *
1026
 ******************************************************************************/
1027
 
1028
void *acpi_ds_obj_stack_get_value(u32 index, struct acpi_walk_state *walk_state)
1029
{
1030
 
1031
        ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_get_value, walk_state);
1032
 
1033
        /* Can't do it if the stack is empty */
1034
 
1035
        if (walk_state->num_operands == 0) {
1036
                return_PTR(NULL);
1037
        }
1038
 
1039
        /* or if the index is past the top of the stack */
1040
 
1041
        if (index > (walk_state->num_operands - (u32) 1)) {
1042
                return_PTR(NULL);
1043
        }
1044
 
1045
        return_PTR(walk_state->
1046
                   operands[(acpi_native_uint) (walk_state->num_operands - 1) -
1047
                            index]);
1048
}
1049
#endif

powered by: WebSVN 2.1.0

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