summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher/dswscope.c
blob: 11b6a6cb96dceccf0103d1fe65175054b62c5e3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/******************************************************************************
 *
 * Module Name: dswscope - Scope stack manipulation
 *              $Revision: 40 $
 *
 *****************************************************************************/

/*
 *  Copyright (C) 2000 R. Byron Moore
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


#include "acpi.h"
#include "acinterp.h"
#include "acdispat.h"


#define _COMPONENT          NAMESPACE
	 MODULE_NAME         ("dswscope")


#define STACK_POP(head) head


/****************************************************************************
 *
 * FUNCTION:    Acpi_ds_scope_stack_clear
 *
 * PARAMETERS:  None
 *
 * DESCRIPTION: Pop (and free) everything on the scope stack except the
 *              root scope object (which remains at the stack top.)
 *
 ***************************************************************************/

void
acpi_ds_scope_stack_clear (
	ACPI_WALK_STATE         *walk_state)
{
	ACPI_GENERIC_STATE      *scope_info;


	while (walk_state->scope_info) {
		/* Pop a scope off the stack */

		scope_info = walk_state->scope_info;
		walk_state->scope_info = scope_info->scope.next;

		acpi_cm_delete_generic_state (scope_info);
	}
}


/****************************************************************************
 *
 * FUNCTION:    Acpi_ds_scope_stack_push
 *
 * PARAMETERS:  *Node,              - Name to be made current
 *              Type,               - Type of frame being pushed
 *
 * DESCRIPTION: Push the current scope on the scope stack, and make the
 *              passed Node current.
 *
 ***************************************************************************/

ACPI_STATUS
acpi_ds_scope_stack_push (
	ACPI_NAMESPACE_NODE     *node,
	OBJECT_TYPE_INTERNAL    type,
	ACPI_WALK_STATE         *walk_state)
{
	ACPI_GENERIC_STATE      *scope_info;


	if (!node) {
		/*  invalid scope   */

		REPORT_ERROR (("Ds_scope_stack_push: null scope passed\n"));
		return (AE_BAD_PARAMETER);
	}

	/* Make sure object type is valid */

	if (!acpi_aml_validate_object_type (type)) {
		REPORT_WARNING (("Ds_scope_stack_push: type code out of range\n"));
	}


	/* Allocate a new scope object */

	scope_info = acpi_cm_create_generic_state ();
	if (!scope_info) {
		return (AE_NO_MEMORY);
	}

	/* Init new scope object */

	scope_info->scope.node = node;
	scope_info->common.value = (u16) type;

	/* Push new scope object onto stack */

	acpi_cm_push_generic_state (&walk_state->scope_info, scope_info);

	return (AE_OK);
}


/****************************************************************************
 *
 * FUNCTION:    Acpi_ds_scope_stack_pop
 *
 * PARAMETERS:  Type                - The type of frame to be found
 *
 * DESCRIPTION: Pop the scope stack until a frame of the requested type
 *              is found.
 *
 * RETURN:      Count of frames popped.  If no frame of the requested type
 *              was found, the count is returned as a negative number and
 *              the scope stack is emptied (which sets the current scope
 *              to the root).  If the scope stack was empty at entry, the
 *              function is a no-op and returns 0.
 *
 ***************************************************************************/

ACPI_STATUS
acpi_ds_scope_stack_pop (
	ACPI_WALK_STATE         *walk_state)
{
	ACPI_GENERIC_STATE      *scope_info;


	/*
	 * Pop scope info object off the stack.
	 */

	scope_info = acpi_cm_pop_generic_state (&walk_state->scope_info);
	if (!scope_info) {
		return (AE_STACK_UNDERFLOW);
	}

	acpi_cm_delete_generic_state (scope_info);

	return (AE_OK);
}