| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /****************************************************************************** | 
|  | 2 | * | 
|  | 3 | * Module Name: dswstate - Dispatcher parse tree walk management routines | 
|  | 4 | * | 
|  | 5 | *****************************************************************************/ | 
|  | 6 |  | 
|  | 7 | /* | 
| Len Brown | 75a44ce | 2008-04-23 23:00:13 -0400 | [diff] [blame] | 8 | * Copyright (C) 2000 - 2008, Intel Corp. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 50 | ACPI_MODULE_NAME("dswstate") | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 51 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 52 | /* Local prototypes */ | 
|  | 53 | static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *ws); | 
|  | 54 | static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *ws); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 55 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 56 | /******************************************************************************* | 
|  | 57 | * | 
|  | 58 | * FUNCTION:    acpi_ds_result_pop | 
|  | 59 | * | 
|  | 60 | * PARAMETERS:  Object              - Where to return the popped object | 
|  | 61 | *              walk_state          - Current Walk state | 
|  | 62 | * | 
|  | 63 | * RETURN:      Status | 
|  | 64 | * | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 65 | * DESCRIPTION: Pop an object off the top of this walk's result stack | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 66 | * | 
|  | 67 | ******************************************************************************/ | 
|  | 68 |  | 
|  | 69 | acpi_status | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 70 | acpi_ds_result_pop(union acpi_operand_object **object, | 
|  | 71 | struct acpi_walk_state *walk_state) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 72 | { | 
| Bob Moore | 67a119f | 2008-06-10 13:42:13 +0800 | [diff] [blame] | 73 | u32 index; | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 74 | union acpi_generic_state *state; | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 75 | acpi_status status; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 76 |  | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 77 | ACPI_FUNCTION_NAME(ds_result_pop); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 78 |  | 
|  | 79 | state = walk_state->results; | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 80 |  | 
|  | 81 | /* Incorrect state of result stack */ | 
|  | 82 |  | 
|  | 83 | if (state && !walk_state->result_count) { | 
|  | 84 | ACPI_ERROR((AE_INFO, "No results on result stack")); | 
|  | 85 | return (AE_AML_INTERNAL); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 86 | } | 
|  | 87 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 88 | if (!state && walk_state->result_count) { | 
|  | 89 | ACPI_ERROR((AE_INFO, "No result state for result stack")); | 
|  | 90 | return (AE_AML_INTERNAL); | 
|  | 91 | } | 
|  | 92 |  | 
|  | 93 | /* Empty result stack */ | 
|  | 94 |  | 
|  | 95 | if (!state) { | 
| Bob Moore | b8e4d89 | 2006-01-27 16:43:00 -0500 | [diff] [blame] | 96 | ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p", | 
|  | 97 | walk_state)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 98 | return (AE_AML_NO_RETURN_VALUE); | 
|  | 99 | } | 
|  | 100 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 101 | /* Return object of the top element and clean that top element result stack */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 102 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 103 | walk_state->result_count--; | 
|  | 104 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 105 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 106 | *object = state->results.obj_desc[index]; | 
|  | 107 | if (!*object) { | 
| Bob Moore | b8e4d89 | 2006-01-27 16:43:00 -0500 | [diff] [blame] | 108 | ACPI_ERROR((AE_INFO, | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 109 | "No result objects on result stack, State=%p", | 
| Bob Moore | b8e4d89 | 2006-01-27 16:43:00 -0500 | [diff] [blame] | 110 | walk_state)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 111 | return (AE_AML_NO_RETURN_VALUE); | 
|  | 112 | } | 
|  | 113 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 114 | state->results.obj_desc[index] = NULL; | 
|  | 115 | if (index == 0) { | 
|  | 116 | status = acpi_ds_result_stack_pop(walk_state); | 
|  | 117 | if (ACPI_FAILURE(status)) { | 
|  | 118 | return (status); | 
|  | 119 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 120 | } | 
|  | 121 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 122 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 
|  | 123 | "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object, | 
|  | 124 | acpi_ut_get_object_type_name(*object), | 
| Bob Moore | 67a119f | 2008-06-10 13:42:13 +0800 | [diff] [blame] | 125 | index, walk_state, walk_state->result_count)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 126 |  | 
|  | 127 | return (AE_OK); | 
|  | 128 | } | 
|  | 129 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 130 | /******************************************************************************* | 
|  | 131 | * | 
|  | 132 | * FUNCTION:    acpi_ds_result_push | 
|  | 133 | * | 
|  | 134 | * PARAMETERS:  Object              - Where to return the popped object | 
|  | 135 | *              walk_state          - Current Walk state | 
|  | 136 | * | 
|  | 137 | * RETURN:      Status | 
|  | 138 | * | 
|  | 139 | * DESCRIPTION: Push an object onto the current result stack | 
|  | 140 | * | 
|  | 141 | ******************************************************************************/ | 
|  | 142 |  | 
|  | 143 | acpi_status | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 144 | acpi_ds_result_push(union acpi_operand_object * object, | 
|  | 145 | struct acpi_walk_state * walk_state) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 146 | { | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 147 | union acpi_generic_state *state; | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 148 | acpi_status status; | 
| Bob Moore | 67a119f | 2008-06-10 13:42:13 +0800 | [diff] [blame] | 149 | u32 index; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 150 |  | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 151 | ACPI_FUNCTION_NAME(ds_result_push); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 152 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 153 | if (walk_state->result_count > walk_state->result_size) { | 
|  | 154 | ACPI_ERROR((AE_INFO, "Result stack is full")); | 
|  | 155 | return (AE_AML_INTERNAL); | 
|  | 156 | } else if (walk_state->result_count == walk_state->result_size) { | 
|  | 157 |  | 
|  | 158 | /* Extend the result stack */ | 
|  | 159 |  | 
|  | 160 | status = acpi_ds_result_stack_push(walk_state); | 
|  | 161 | if (ACPI_FAILURE(status)) { | 
|  | 162 | ACPI_ERROR((AE_INFO, | 
|  | 163 | "Failed to extend the result stack")); | 
|  | 164 | return (status); | 
|  | 165 | } | 
|  | 166 | } | 
|  | 167 |  | 
|  | 168 | if (!(walk_state->result_count < walk_state->result_size)) { | 
|  | 169 | ACPI_ERROR((AE_INFO, "No free elements in result stack")); | 
|  | 170 | return (AE_AML_INTERNAL); | 
|  | 171 | } | 
|  | 172 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 173 | state = walk_state->results; | 
|  | 174 | if (!state) { | 
| Bob Moore | b8e4d89 | 2006-01-27 16:43:00 -0500 | [diff] [blame] | 175 | ACPI_ERROR((AE_INFO, "No result stack frame during push")); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 176 | return (AE_AML_INTERNAL); | 
|  | 177 | } | 
|  | 178 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 179 | if (!object) { | 
| Bob Moore | b8e4d89 | 2006-01-27 16:43:00 -0500 | [diff] [blame] | 180 | ACPI_ERROR((AE_INFO, | 
|  | 181 | "Null Object! Obj=%p State=%p Num=%X", | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 182 | object, walk_state, walk_state->result_count)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 183 | return (AE_BAD_PARAMETER); | 
|  | 184 | } | 
|  | 185 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 186 | /* Assign the address of object to the top free element of result stack */ | 
|  | 187 |  | 
|  | 188 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | 
|  | 189 | state->results.obj_desc[index] = object; | 
|  | 190 | walk_state->result_count++; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 191 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 192 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", | 
|  | 193 | object, | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 194 | acpi_ut_get_object_type_name((union | 
|  | 195 | acpi_operand_object *) | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 196 | object), walk_state, | 
|  | 197 | walk_state->result_count, | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 198 | walk_state->current_result)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 199 |  | 
|  | 200 | return (AE_OK); | 
|  | 201 | } | 
|  | 202 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 203 | /******************************************************************************* | 
|  | 204 | * | 
|  | 205 | * FUNCTION:    acpi_ds_result_stack_push | 
|  | 206 | * | 
|  | 207 | * PARAMETERS:  walk_state          - Current Walk state | 
|  | 208 | * | 
|  | 209 | * RETURN:      Status | 
|  | 210 | * | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 211 | * DESCRIPTION: Push an object onto the walk_state result stack | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 212 | * | 
|  | 213 | ******************************************************************************/ | 
|  | 214 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 215 | static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 216 | { | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 217 | union acpi_generic_state *state; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 218 |  | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 219 | ACPI_FUNCTION_NAME(ds_result_stack_push); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 220 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 221 | /* Check for stack overflow */ | 
|  | 222 |  | 
| Bob Moore | b7f9f04 | 2008-04-10 19:06:40 +0400 | [diff] [blame] | 223 | if (((u32) walk_state->result_size + ACPI_RESULTS_FRAME_OBJ_NUM) > | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 224 | ACPI_RESULTS_OBJ_NUM_MAX) { | 
|  | 225 | ACPI_ERROR((AE_INFO, "Result stack overflow: State=%p Num=%X", | 
|  | 226 | walk_state, walk_state->result_size)); | 
|  | 227 | return (AE_STACK_OVERFLOW); | 
|  | 228 | } | 
|  | 229 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 230 | state = acpi_ut_create_generic_state(); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 231 | if (!state) { | 
|  | 232 | return (AE_NO_MEMORY); | 
|  | 233 | } | 
|  | 234 |  | 
| Bob Moore | 61686124 | 2006-03-17 16:44:00 -0500 | [diff] [blame] | 235 | state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT; | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 236 | acpi_ut_push_generic_state(&walk_state->results, state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 237 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 238 | /* Increase the length of the result stack by the length of frame */ | 
|  | 239 |  | 
|  | 240 | walk_state->result_size += ACPI_RESULTS_FRAME_OBJ_NUM; | 
|  | 241 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 242 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n", | 
|  | 243 | state, walk_state)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 244 |  | 
|  | 245 | return (AE_OK); | 
|  | 246 | } | 
|  | 247 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 248 | /******************************************************************************* | 
|  | 249 | * | 
|  | 250 | * FUNCTION:    acpi_ds_result_stack_pop | 
|  | 251 | * | 
|  | 252 | * PARAMETERS:  walk_state          - Current Walk state | 
|  | 253 | * | 
|  | 254 | * RETURN:      Status | 
|  | 255 | * | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 256 | * DESCRIPTION: Pop an object off of the walk_state result stack | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 257 | * | 
|  | 258 | ******************************************************************************/ | 
|  | 259 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 260 | static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 261 | { | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 262 | union acpi_generic_state *state; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 263 |  | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 264 | ACPI_FUNCTION_NAME(ds_result_stack_pop); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 265 |  | 
|  | 266 | /* Check for stack underflow */ | 
|  | 267 |  | 
|  | 268 | if (walk_state->results == NULL) { | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 269 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 
|  | 270 | "Result stack underflow - State=%p\n", | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 271 | walk_state)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 272 | return (AE_AML_NO_OPERAND); | 
|  | 273 | } | 
|  | 274 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 275 | if (walk_state->result_size < ACPI_RESULTS_FRAME_OBJ_NUM) { | 
|  | 276 | ACPI_ERROR((AE_INFO, "Insufficient result stack size")); | 
|  | 277 | return (AE_AML_INTERNAL); | 
|  | 278 | } | 
|  | 279 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 280 | state = acpi_ut_pop_generic_state(&walk_state->results); | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 281 | acpi_ut_delete_generic_state(state); | 
|  | 282 |  | 
|  | 283 | /* Decrease the length of result stack by the length of frame */ | 
|  | 284 |  | 
|  | 285 | walk_state->result_size -= ACPI_RESULTS_FRAME_OBJ_NUM; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 286 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 287 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 288 | "Result=%p RemainingResults=%X State=%p\n", | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 289 | state, walk_state->result_count, walk_state)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 290 |  | 
|  | 291 | return (AE_OK); | 
|  | 292 | } | 
|  | 293 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 294 | /******************************************************************************* | 
|  | 295 | * | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 296 | * FUNCTION:    acpi_ds_obj_stack_push | 
|  | 297 | * | 
|  | 298 | * PARAMETERS:  Object              - Object to push | 
|  | 299 | *              walk_state          - Current Walk state | 
|  | 300 | * | 
|  | 301 | * RETURN:      Status | 
|  | 302 | * | 
|  | 303 | * DESCRIPTION: Push an object onto this walk's object/operand stack | 
|  | 304 | * | 
|  | 305 | ******************************************************************************/ | 
|  | 306 |  | 
|  | 307 | acpi_status | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 308 | acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 309 | { | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 310 | ACPI_FUNCTION_NAME(ds_obj_stack_push); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 311 |  | 
|  | 312 | /* Check for stack overflow */ | 
|  | 313 |  | 
|  | 314 | if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) { | 
| Bob Moore | b8e4d89 | 2006-01-27 16:43:00 -0500 | [diff] [blame] | 315 | ACPI_ERROR((AE_INFO, | 
|  | 316 | "Object stack overflow! Obj=%p State=%p #Ops=%X", | 
|  | 317 | object, walk_state, walk_state->num_operands)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 318 | return (AE_STACK_OVERFLOW); | 
|  | 319 | } | 
|  | 320 |  | 
|  | 321 | /* Put the object onto the stack */ | 
|  | 322 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 323 | walk_state->operands[walk_state->operand_index] = object; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 324 | walk_state->num_operands++; | 
|  | 325 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 326 | /* For the usual order of filling the operand stack */ | 
|  | 327 |  | 
|  | 328 | walk_state->operand_index++; | 
|  | 329 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 330 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", | 
|  | 331 | object, | 
|  | 332 | acpi_ut_get_object_type_name((union | 
|  | 333 | acpi_operand_object *) | 
|  | 334 | object), walk_state, | 
|  | 335 | walk_state->num_operands)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 336 |  | 
|  | 337 | return (AE_OK); | 
|  | 338 | } | 
|  | 339 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 340 | /******************************************************************************* | 
|  | 341 | * | 
|  | 342 | * FUNCTION:    acpi_ds_obj_stack_pop | 
|  | 343 | * | 
|  | 344 | * PARAMETERS:  pop_count           - Number of objects/entries to pop | 
|  | 345 | *              walk_state          - Current Walk state | 
|  | 346 | * | 
|  | 347 | * RETURN:      Status | 
|  | 348 | * | 
|  | 349 | * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT | 
|  | 350 | *              deleted by this routine. | 
|  | 351 | * | 
|  | 352 | ******************************************************************************/ | 
|  | 353 |  | 
|  | 354 | acpi_status | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 355 | acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 356 | { | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 357 | u32 i; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 358 |  | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 359 | ACPI_FUNCTION_NAME(ds_obj_stack_pop); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 360 |  | 
|  | 361 | for (i = 0; i < pop_count; i++) { | 
| Bob Moore | 52fc0b0 | 2006-10-02 00:00:00 -0400 | [diff] [blame] | 362 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 363 | /* Check for stack underflow */ | 
|  | 364 |  | 
|  | 365 | if (walk_state->num_operands == 0) { | 
| Bob Moore | b8e4d89 | 2006-01-27 16:43:00 -0500 | [diff] [blame] | 366 | ACPI_ERROR((AE_INFO, | 
|  | 367 | "Object stack underflow! Count=%X State=%p #Ops=%X", | 
|  | 368 | pop_count, walk_state, | 
|  | 369 | walk_state->num_operands)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 370 | return (AE_STACK_UNDERFLOW); | 
|  | 371 | } | 
|  | 372 |  | 
|  | 373 | /* Just set the stack entry to null */ | 
|  | 374 |  | 
|  | 375 | walk_state->num_operands--; | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 376 | walk_state->operands[walk_state->num_operands] = NULL; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 377 | } | 
|  | 378 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 379 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 380 | pop_count, walk_state, walk_state->num_operands)); | 
|  | 381 |  | 
|  | 382 | return (AE_OK); | 
|  | 383 | } | 
|  | 384 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 385 | /******************************************************************************* | 
|  | 386 | * | 
|  | 387 | * FUNCTION:    acpi_ds_obj_stack_pop_and_delete | 
|  | 388 | * | 
|  | 389 | * PARAMETERS:  pop_count           - Number of objects/entries to pop | 
|  | 390 | *              walk_state          - Current Walk state | 
|  | 391 | * | 
|  | 392 | * RETURN:      Status | 
|  | 393 | * | 
|  | 394 | * DESCRIPTION: Pop this walk's object stack and delete each object that is | 
|  | 395 | *              popped off. | 
|  | 396 | * | 
|  | 397 | ******************************************************************************/ | 
|  | 398 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 399 | void | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 400 | acpi_ds_obj_stack_pop_and_delete(u32 pop_count, | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 401 | struct acpi_walk_state *walk_state) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 402 | { | 
| Bob Moore | 67a119f | 2008-06-10 13:42:13 +0800 | [diff] [blame] | 403 | s32 i; | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 404 | union acpi_operand_object *obj_desc; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 405 |  | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 406 | ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 407 |  | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 408 | if (pop_count == 0) { | 
|  | 409 | return; | 
|  | 410 | } | 
| Bob Moore | 52fc0b0 | 2006-10-02 00:00:00 -0400 | [diff] [blame] | 411 |  | 
| Bob Moore | 67a119f | 2008-06-10 13:42:13 +0800 | [diff] [blame] | 412 | for (i = (s32) pop_count - 1; i >= 0; i--) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 413 | if (walk_state->num_operands == 0) { | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 414 | return; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 415 | } | 
|  | 416 |  | 
|  | 417 | /* Pop the stack and delete an object if present in this stack entry */ | 
|  | 418 |  | 
|  | 419 | walk_state->num_operands--; | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 420 | obj_desc = walk_state->operands[i]; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 421 | if (obj_desc) { | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 422 | acpi_ut_remove_reference(walk_state->operands[i]); | 
|  | 423 | walk_state->operands[i] = NULL; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 424 | } | 
|  | 425 | } | 
|  | 426 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 427 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 428 | pop_count, walk_state, walk_state->num_operands)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 429 | } | 
|  | 430 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 431 | /******************************************************************************* | 
|  | 432 | * | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 433 | * FUNCTION:    acpi_ds_get_current_walk_state | 
|  | 434 | * | 
|  | 435 | * PARAMETERS:  Thread          - Get current active state for this Thread | 
|  | 436 | * | 
|  | 437 | * RETURN:      Pointer to the current walk state | 
|  | 438 | * | 
|  | 439 | * DESCRIPTION: Get the walk state that is at the head of the list (the "current" | 
|  | 440 | *              walk state.) | 
|  | 441 | * | 
|  | 442 | ******************************************************************************/ | 
|  | 443 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 444 | struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state | 
|  | 445 | *thread) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 446 | { | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 447 | ACPI_FUNCTION_NAME(ds_get_current_walk_state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 448 |  | 
|  | 449 | if (!thread) { | 
|  | 450 | return (NULL); | 
|  | 451 | } | 
|  | 452 |  | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 453 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Current WalkState %p\n", | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 454 | thread->walk_state_list)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 455 |  | 
|  | 456 | return (thread->walk_state_list); | 
|  | 457 | } | 
|  | 458 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 459 | /******************************************************************************* | 
|  | 460 | * | 
|  | 461 | * FUNCTION:    acpi_ds_push_walk_state | 
|  | 462 | * | 
|  | 463 | * PARAMETERS:  walk_state      - State to push | 
| Robert Moore | 44f6c01 | 2005-04-18 22:49:35 -0400 | [diff] [blame] | 464 | *              Thread          - Thread state object | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 465 | * | 
|  | 466 | * RETURN:      None | 
|  | 467 | * | 
| Bob Moore | 773069d | 2008-04-10 19:06:36 +0400 | [diff] [blame] | 468 | * DESCRIPTION: Place the Thread state at the head of the state list | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 469 | * | 
|  | 470 | ******************************************************************************/ | 
|  | 471 |  | 
|  | 472 | void | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 473 | acpi_ds_push_walk_state(struct acpi_walk_state *walk_state, | 
|  | 474 | struct acpi_thread_state *thread) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 475 | { | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 476 | ACPI_FUNCTION_TRACE(ds_push_walk_state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 477 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 478 | walk_state->next = thread->walk_state_list; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 479 | thread->walk_state_list = walk_state; | 
|  | 480 |  | 
|  | 481 | return_VOID; | 
|  | 482 | } | 
|  | 483 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 484 | /******************************************************************************* | 
|  | 485 | * | 
|  | 486 | * FUNCTION:    acpi_ds_pop_walk_state | 
|  | 487 | * | 
| Robert Moore | 44f6c01 | 2005-04-18 22:49:35 -0400 | [diff] [blame] | 488 | * PARAMETERS:  Thread      - Current thread state | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 489 | * | 
| Robert Moore | 44f6c01 | 2005-04-18 22:49:35 -0400 | [diff] [blame] | 490 | * RETURN:      A walk_state object popped from the thread's stack | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 491 | * | 
|  | 492 | * DESCRIPTION: Remove and return the walkstate object that is at the head of | 
|  | 493 | *              the walk stack for the given walk list.  NULL indicates that | 
|  | 494 | *              the list is empty. | 
|  | 495 | * | 
|  | 496 | ******************************************************************************/ | 
|  | 497 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 498 | struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 499 | { | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 500 | struct acpi_walk_state *walk_state; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 501 |  | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 502 | ACPI_FUNCTION_TRACE(ds_pop_walk_state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 503 |  | 
|  | 504 | walk_state = thread->walk_state_list; | 
|  | 505 |  | 
|  | 506 | if (walk_state) { | 
| Bob Moore | 52fc0b0 | 2006-10-02 00:00:00 -0400 | [diff] [blame] | 507 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 508 | /* Next walk state becomes the current walk state */ | 
|  | 509 |  | 
|  | 510 | thread->walk_state_list = walk_state->next; | 
|  | 511 |  | 
|  | 512 | /* | 
|  | 513 | * Don't clear the NEXT field, this serves as an indicator | 
|  | 514 | * that there is a parent WALK STATE | 
| Robert Moore | 44f6c01 | 2005-04-18 22:49:35 -0400 | [diff] [blame] | 515 | * Do Not: walk_state->Next = NULL; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 516 | */ | 
|  | 517 | } | 
|  | 518 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 519 | return_PTR(walk_state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 520 | } | 
|  | 521 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 522 | /******************************************************************************* | 
|  | 523 | * | 
|  | 524 | * FUNCTION:    acpi_ds_create_walk_state | 
|  | 525 | * | 
| Robert Moore | 44f6c01 | 2005-04-18 22:49:35 -0400 | [diff] [blame] | 526 | * PARAMETERS:  owner_id        - ID for object creation | 
|  | 527 | *              Origin          - Starting point for this walk | 
| Bob Moore | 61686124 | 2006-03-17 16:44:00 -0500 | [diff] [blame] | 528 | *              method_desc     - Method object | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 529 | *              Thread          - Current thread state | 
|  | 530 | * | 
|  | 531 | * RETURN:      Pointer to the new walk state. | 
|  | 532 | * | 
|  | 533 | * DESCRIPTION: Allocate and initialize a new walk state.  The current walk | 
|  | 534 | *              state is set to this new state. | 
|  | 535 | * | 
|  | 536 | ******************************************************************************/ | 
|  | 537 |  | 
| Len Brown | fd35094 | 2007-05-09 23:34:35 -0400 | [diff] [blame] | 538 | struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union acpi_parse_object | 
|  | 539 | *origin, union acpi_operand_object | 
|  | 540 | *method_desc, struct acpi_thread_state | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 541 | *thread) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 542 | { | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 543 | struct acpi_walk_state *walk_state; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 544 |  | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 545 | ACPI_FUNCTION_TRACE(ds_create_walk_state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 546 |  | 
| Bob Moore | 8313524 | 2006-10-03 00:00:00 -0400 | [diff] [blame] | 547 | walk_state = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_walk_state)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 548 | if (!walk_state) { | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 549 | return_PTR(NULL); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 550 | } | 
|  | 551 |  | 
| Bob Moore | 61686124 | 2006-03-17 16:44:00 -0500 | [diff] [blame] | 552 | walk_state->descriptor_type = ACPI_DESC_TYPE_WALK; | 
|  | 553 | walk_state->method_desc = method_desc; | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 554 | walk_state->owner_id = owner_id; | 
|  | 555 | walk_state->origin = origin; | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 556 | walk_state->thread = thread; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 557 |  | 
|  | 558 | walk_state->parser_state.start_op = origin; | 
|  | 559 |  | 
|  | 560 | /* Init the method args/local */ | 
|  | 561 |  | 
|  | 562 | #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 563 | acpi_ds_method_data_init(walk_state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 564 | #endif | 
|  | 565 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 566 | /* Put the new state at the head of the walk list */ | 
|  | 567 |  | 
|  | 568 | if (thread) { | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 569 | acpi_ds_push_walk_state(walk_state, thread); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 570 | } | 
|  | 571 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 572 | return_PTR(walk_state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 573 | } | 
|  | 574 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 575 | /******************************************************************************* | 
|  | 576 | * | 
|  | 577 | * FUNCTION:    acpi_ds_init_aml_walk | 
|  | 578 | * | 
|  | 579 | * PARAMETERS:  walk_state      - New state to be initialized | 
|  | 580 | *              Op              - Current parse op | 
|  | 581 | *              method_node     - Control method NS node, if any | 
|  | 582 | *              aml_start       - Start of AML | 
|  | 583 | *              aml_length      - Length of AML | 
| Robert Moore | 44f6c01 | 2005-04-18 22:49:35 -0400 | [diff] [blame] | 584 | *              Info            - Method info block (params, etc.) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 585 | *              pass_number     - 1, 2, or 3 | 
|  | 586 | * | 
|  | 587 | * RETURN:      Status | 
|  | 588 | * | 
|  | 589 | * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk | 
|  | 590 | * | 
|  | 591 | ******************************************************************************/ | 
|  | 592 |  | 
|  | 593 | acpi_status | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 594 | acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state, | 
|  | 595 | union acpi_parse_object *op, | 
|  | 596 | struct acpi_namespace_node *method_node, | 
|  | 597 | u8 * aml_start, | 
|  | 598 | u32 aml_length, | 
| Bob Moore | 4119532 | 2006-05-26 16:36:00 -0400 | [diff] [blame] | 599 | struct acpi_evaluate_info *info, u8 pass_number) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 600 | { | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 601 | acpi_status status; | 
|  | 602 | struct acpi_parse_state *parser_state = &walk_state->parser_state; | 
|  | 603 | union acpi_parse_object *extra_op; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 604 |  | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 605 | ACPI_FUNCTION_TRACE(ds_init_aml_walk); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 606 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 607 | walk_state->parser_state.aml = | 
|  | 608 | walk_state->parser_state.aml_start = aml_start; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 609 | walk_state->parser_state.aml_end = | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 610 | walk_state->parser_state.pkg_end = aml_start + aml_length; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 611 |  | 
|  | 612 | /* The next_op of the next_walk will be the beginning of the method */ | 
|  | 613 |  | 
| Robert Moore | 44f6c01 | 2005-04-18 22:49:35 -0400 | [diff] [blame] | 614 | walk_state->next_op = NULL; | 
| Robert Moore | 0c9938c | 2005-07-29 15:15:00 -0700 | [diff] [blame] | 615 | walk_state->pass_number = pass_number; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 616 |  | 
|  | 617 | if (info) { | 
| Bob Moore | c91d924 | 2008-06-10 12:38:10 +0800 | [diff] [blame] | 618 | walk_state->params = info->parameters; | 
|  | 619 | walk_state->caller_return_desc = &info->return_object; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 620 | } | 
|  | 621 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 622 | status = acpi_ps_init_scope(&walk_state->parser_state, op); | 
|  | 623 | if (ACPI_FAILURE(status)) { | 
|  | 624 | return_ACPI_STATUS(status); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 625 | } | 
|  | 626 |  | 
|  | 627 | if (method_node) { | 
|  | 628 | walk_state->parser_state.start_node = method_node; | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 629 | walk_state->walk_type = ACPI_WALK_METHOD; | 
|  | 630 | walk_state->method_node = method_node; | 
|  | 631 | walk_state->method_desc = | 
|  | 632 | acpi_ns_get_attached_object(method_node); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 633 |  | 
|  | 634 | /* Push start scope on scope stack and make it current  */ | 
|  | 635 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 636 | status = | 
|  | 637 | acpi_ds_scope_stack_push(method_node, ACPI_TYPE_METHOD, | 
|  | 638 | walk_state); | 
|  | 639 | if (ACPI_FAILURE(status)) { | 
|  | 640 | return_ACPI_STATUS(status); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 641 | } | 
|  | 642 |  | 
|  | 643 | /* Init the method arguments */ | 
|  | 644 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 645 | status = acpi_ds_method_data_init_args(walk_state->params, | 
|  | 646 | ACPI_METHOD_NUM_ARGS, | 
|  | 647 | walk_state); | 
|  | 648 | if (ACPI_FAILURE(status)) { | 
|  | 649 | return_ACPI_STATUS(status); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 650 | } | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 651 | } else { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 652 | /* | 
|  | 653 | * Setup the current scope. | 
|  | 654 | * Find a Named Op that has a namespace node associated with it. | 
|  | 655 | * search upwards from this Op.  Current scope is the first | 
|  | 656 | * Op with a namespace node. | 
|  | 657 | */ | 
|  | 658 | extra_op = parser_state->start_op; | 
|  | 659 | while (extra_op && !extra_op->common.node) { | 
|  | 660 | extra_op = extra_op->common.parent; | 
|  | 661 | } | 
|  | 662 |  | 
|  | 663 | if (!extra_op) { | 
|  | 664 | parser_state->start_node = NULL; | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 665 | } else { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 666 | parser_state->start_node = extra_op->common.node; | 
|  | 667 | } | 
|  | 668 |  | 
|  | 669 | if (parser_state->start_node) { | 
| Bob Moore | 52fc0b0 | 2006-10-02 00:00:00 -0400 | [diff] [blame] | 670 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 671 | /* Push start scope on scope stack and make it current  */ | 
|  | 672 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 673 | status = | 
|  | 674 | acpi_ds_scope_stack_push(parser_state->start_node, | 
|  | 675 | parser_state->start_node-> | 
|  | 676 | type, walk_state); | 
|  | 677 | if (ACPI_FAILURE(status)) { | 
|  | 678 | return_ACPI_STATUS(status); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 679 | } | 
|  | 680 | } | 
|  | 681 | } | 
|  | 682 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 683 | status = acpi_ds_init_callbacks(walk_state, pass_number); | 
|  | 684 | return_ACPI_STATUS(status); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 685 | } | 
|  | 686 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 687 | /******************************************************************************* | 
|  | 688 | * | 
|  | 689 | * FUNCTION:    acpi_ds_delete_walk_state | 
|  | 690 | * | 
|  | 691 | * PARAMETERS:  walk_state      - State to delete | 
|  | 692 | * | 
|  | 693 | * RETURN:      Status | 
|  | 694 | * | 
|  | 695 | * DESCRIPTION: Delete a walk state including all internal data structures | 
|  | 696 | * | 
|  | 697 | ******************************************************************************/ | 
|  | 698 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 699 | void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 700 | { | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 701 | union acpi_generic_state *state; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 702 |  | 
| Bob Moore | b229cf9 | 2006-04-21 17:15:00 -0400 | [diff] [blame] | 703 | ACPI_FUNCTION_TRACE_PTR(ds_delete_walk_state, walk_state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 704 |  | 
|  | 705 | if (!walk_state) { | 
|  | 706 | return; | 
|  | 707 | } | 
|  | 708 |  | 
| Bob Moore | 61686124 | 2006-03-17 16:44:00 -0500 | [diff] [blame] | 709 | if (walk_state->descriptor_type != ACPI_DESC_TYPE_WALK) { | 
| Bob Moore | b8e4d89 | 2006-01-27 16:43:00 -0500 | [diff] [blame] | 710 | ACPI_ERROR((AE_INFO, "%p is not a valid walk state", | 
|  | 711 | walk_state)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 712 | return; | 
|  | 713 | } | 
|  | 714 |  | 
| Bob Moore | 4119532 | 2006-05-26 16:36:00 -0400 | [diff] [blame] | 715 | /* There should not be any open scopes */ | 
|  | 716 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 717 | if (walk_state->parser_state.scope) { | 
| Bob Moore | b8e4d89 | 2006-01-27 16:43:00 -0500 | [diff] [blame] | 718 | ACPI_ERROR((AE_INFO, "%p walk still has a scope list", | 
|  | 719 | walk_state)); | 
| Bob Moore | 4119532 | 2006-05-26 16:36:00 -0400 | [diff] [blame] | 720 | acpi_ps_cleanup_scope(&walk_state->parser_state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 721 | } | 
|  | 722 |  | 
|  | 723 | /* Always must free any linked control states */ | 
|  | 724 |  | 
|  | 725 | while (walk_state->control_state) { | 
|  | 726 | state = walk_state->control_state; | 
|  | 727 | walk_state->control_state = state->common.next; | 
|  | 728 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 729 | acpi_ut_delete_generic_state(state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 730 | } | 
|  | 731 |  | 
|  | 732 | /* Always must free any linked parse states */ | 
|  | 733 |  | 
|  | 734 | while (walk_state->scope_info) { | 
|  | 735 | state = walk_state->scope_info; | 
|  | 736 | walk_state->scope_info = state->common.next; | 
|  | 737 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 738 | acpi_ut_delete_generic_state(state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 739 | } | 
|  | 740 |  | 
|  | 741 | /* Always must free any stacked result states */ | 
|  | 742 |  | 
|  | 743 | while (walk_state->results) { | 
|  | 744 | state = walk_state->results; | 
|  | 745 | walk_state->results = state->common.next; | 
|  | 746 |  | 
| Len Brown | 4be44fc | 2005-08-05 00:44:28 -0400 | [diff] [blame] | 747 | acpi_ut_delete_generic_state(state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 748 | } | 
|  | 749 |  | 
| Bob Moore | 8313524 | 2006-10-03 00:00:00 -0400 | [diff] [blame] | 750 | ACPI_FREE(walk_state); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 751 | return_VOID; | 
|  | 752 | } |