dswstate.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:27k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: dswstate - Dispatcher parse tree walk management routines
  4.  *              $Revision: 54 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include "acpi.h"
  25. #include "amlcode.h"
  26. #include "acparser.h"
  27. #include "acdispat.h"
  28. #include "acnamesp.h"
  29. #include "acinterp.h"
  30. #define _COMPONENT          ACPI_DISPATCHER
  31.  MODULE_NAME         ("dswstate")
  32. /*******************************************************************************
  33.  *
  34.  * FUNCTION:    Acpi_ds_result_insert
  35.  *
  36.  * PARAMETERS:  Object              - Object to push
  37.  *              Walk_state          - Current Walk state
  38.  *
  39.  * RETURN:      Status
  40.  *
  41.  * DESCRIPTION: Push an object onto this walk's result stack
  42.  *
  43.  ******************************************************************************/
  44. acpi_status
  45. acpi_ds_result_insert (
  46. void                    *object,
  47. u32                     index,
  48. acpi_walk_state         *walk_state)
  49. {
  50. acpi_generic_state      *state;
  51. PROC_NAME ("Ds_result_insert");
  52. state = walk_state->results;
  53. if (!state) {
  54. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%pn",
  55. walk_state));
  56. return (AE_NOT_EXIST);
  57. }
  58. if (index >= OBJ_NUM_OPERANDS) {
  59. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  60. "Index out of range: %X Obj=%p State=%p Num=%Xn",
  61. index, object, walk_state, state->results.num_results));
  62. return (AE_BAD_PARAMETER);
  63. }
  64. if (!object) {
  65. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  66. "Null Object! Index=%X Obj=%p State=%p Num=%Xn",
  67. index, object, walk_state, state->results.num_results));
  68. return (AE_BAD_PARAMETER);
  69. }
  70. state->results.obj_desc [index] = object;
  71. state->results.num_results++;
  72. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
  73. "Obj=%p [%s] State=%p Num=%X Cur=%Xn",
  74. object, object ? acpi_ut_get_type_name (((acpi_operand_object *) object)->common.type) : "NULL",
  75. walk_state, state->results.num_results, walk_state->current_result));
  76. return (AE_OK);
  77. }
  78. /*******************************************************************************
  79.  *
  80.  * FUNCTION:    Acpi_ds_result_remove
  81.  *
  82.  * PARAMETERS:  Object              - Where to return the popped object
  83.  *              Walk_state          - Current Walk state
  84.  *
  85.  * RETURN:      Status
  86.  *
  87.  * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
  88.  *              other words, this is a FIFO.
  89.  *
  90.  ******************************************************************************/
  91. acpi_status
  92. acpi_ds_result_remove (
  93. acpi_operand_object     **object,
  94. u32                     index,
  95. acpi_walk_state         *walk_state)
  96. {
  97. acpi_generic_state      *state;
  98. PROC_NAME ("Ds_result_remove");
  99. state = walk_state->results;
  100. if (!state) {
  101. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%pn",
  102. walk_state));
  103. return (AE_NOT_EXIST);
  104. }
  105. if (index >= OBJ_NUM_OPERANDS) {
  106. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  107. "Index out of range: %X State=%p Num=%Xn",
  108. index, walk_state, state->results.num_results));
  109. }
  110. /* Check for a valid result object */
  111. if (!state->results.obj_desc [index]) {
  112. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  113. "Null operand! State=%p #Ops=%X, Index=%Xn",
  114. walk_state, state->results.num_results, index));
  115. return (AE_AML_NO_RETURN_VALUE);
  116. }
  117. /* Remove the object */
  118. state->results.num_results--;
  119. *object = state->results.obj_desc [index];
  120. state->results.obj_desc [index] = NULL;
  121. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
  122. "Obj=%p [%s] Index=%X State=%p Num=%Xn",
  123. *object, (*object) ? acpi_ut_get_type_name ((*object)->common.type) : "NULL",
  124. index, walk_state, state->results.num_results));
  125. return (AE_OK);
  126. }
  127. /*******************************************************************************
  128.  *
  129.  * FUNCTION:    Acpi_ds_result_pop
  130.  *
  131.  * PARAMETERS:  Object              - Where to return the popped object
  132.  *              Walk_state          - Current Walk state
  133.  *
  134.  * RETURN:      Status
  135.  *
  136.  * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
  137.  *              other words, this is a FIFO.
  138.  *
  139.  ******************************************************************************/
  140. acpi_status
  141. acpi_ds_result_pop (
  142. acpi_operand_object     **object,
  143. acpi_walk_state         *walk_state)
  144. {
  145. u32                     index;
  146. acpi_generic_state      *state;
  147. PROC_NAME ("Ds_result_pop");
  148. state = walk_state->results;
  149. if (!state) {
  150. return (AE_OK);
  151. }
  152. if (!state->results.num_results) {
  153. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Result stack is empty! State=%pn",
  154. walk_state));
  155. return (AE_AML_NO_RETURN_VALUE);
  156. }
  157. /* Remove top element */
  158. state->results.num_results--;
  159. for (index = OBJ_NUM_OPERANDS; index; index--) {
  160. /* Check for a valid result object */
  161. if (state->results.obj_desc [index -1]) {
  162. *object = state->results.obj_desc [index -1];
  163. state->results.obj_desc [index -1] = NULL;
  164. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%Xn",
  165. *object, (*object) ? acpi_ut_get_type_name ((*object)->common.type) : "NULL",
  166. index -1, walk_state, state->results.num_results));
  167. return (AE_OK);
  168. }
  169. }
  170. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%pn", walk_state));
  171. return (AE_AML_NO_RETURN_VALUE);
  172. }
  173. /*******************************************************************************
  174.  *
  175.  * FUNCTION:    Acpi_ds_result_pop_from_bottom
  176.  *
  177.  * PARAMETERS:  Object              - Where to return the popped object
  178.  *              Walk_state          - Current Walk state
  179.  *
  180.  * RETURN:      Status
  181.  *
  182.  * DESCRIPTION: Pop an object off the bottom of this walk's result stack.  In
  183.  *              other words, this is a FIFO.
  184.  *
  185.  ******************************************************************************/
  186. acpi_status
  187. acpi_ds_result_pop_from_bottom (
  188. acpi_operand_object     **object,
  189. acpi_walk_state         *walk_state)
  190. {
  191. u32                     index;
  192. acpi_generic_state      *state;
  193. PROC_NAME ("Ds_result_pop_from_bottom");
  194. state = walk_state->results;
  195. if (!state) {
  196. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  197. "Warning: No result object pushed! State=%pn", walk_state));
  198. return (AE_NOT_EXIST);
  199. }
  200. if (!state->results.num_results) {
  201. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%pn", walk_state));
  202. return (AE_AML_NO_RETURN_VALUE);
  203. }
  204. /* Remove Bottom element */
  205. *object = state->results.obj_desc [0];
  206. /* Push entire stack down one element */
  207. for (index = 0; index < state->results.num_results; index++) {
  208. state->results.obj_desc [index] = state->results.obj_desc [index + 1];
  209. }
  210. state->results.num_results--;
  211. /* Check for a valid result object */
  212. if (!*object) {
  213. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null operand! State=%p #Ops=%X, Index=%Xn",
  214. walk_state, state->results.num_results, index));
  215. return (AE_AML_NO_RETURN_VALUE);
  216. }
  217. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s], Results=%p State=%pn",
  218. *object, (*object) ? acpi_ut_get_type_name ((*object)->common.type) : "NULL",
  219. state, walk_state));
  220. return (AE_OK);
  221. }
  222. /*******************************************************************************
  223.  *
  224.  * FUNCTION:    Acpi_ds_result_push
  225.  *
  226.  * PARAMETERS:  Object              - Where to return the popped object
  227.  *              Walk_state          - Current Walk state
  228.  *
  229.  * RETURN:      Status
  230.  *
  231.  * DESCRIPTION: Push an object onto the current result stack
  232.  *
  233.  ******************************************************************************/
  234. acpi_status
  235. acpi_ds_result_push (
  236. acpi_operand_object     *object,
  237. acpi_walk_state         *walk_state)
  238. {
  239. acpi_generic_state      *state;
  240. PROC_NAME ("Ds_result_push");
  241. state = walk_state->results;
  242. if (!state) {
  243. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result stack framen"));
  244. return (AE_AML_INTERNAL);
  245. }
  246. if (state->results.num_results == OBJ_NUM_OPERANDS) {
  247. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  248. "Result stack overflow: Obj=%p State=%p Num=%Xn",
  249. object, walk_state, state->results.num_results));
  250. return (AE_STACK_OVERFLOW);
  251. }
  252. if (!object) {
  253. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Object! Obj=%p State=%p Num=%Xn",
  254. object, walk_state, state->results.num_results));
  255. return (AE_BAD_PARAMETER);
  256. }
  257. state->results.obj_desc [state->results.num_results] = object;
  258. state->results.num_results++;
  259. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%Xn",
  260. object, object ? acpi_ut_get_type_name (((acpi_operand_object *) object)->common.type) : "NULL",
  261. walk_state, state->results.num_results, walk_state->current_result));
  262. return (AE_OK);
  263. }
  264. /*******************************************************************************
  265.  *
  266.  * FUNCTION:    Acpi_ds_result_stack_push
  267.  *
  268.  * PARAMETERS:  Object              - Object to push
  269.  *              Walk_state          - Current Walk state
  270.  *
  271.  * RETURN:      Status
  272.  *
  273.  * DESCRIPTION:
  274.  *
  275.  ******************************************************************************/
  276. acpi_status
  277. acpi_ds_result_stack_push (
  278. acpi_walk_state         *walk_state)
  279. {
  280. acpi_generic_state      *state;
  281. PROC_NAME ("Ds_result_stack_push");
  282. state = acpi_ut_create_generic_state ();
  283. if (!state) {
  284. return (AE_NO_MEMORY);
  285. }
  286. state->common.data_type = ACPI_DESC_TYPE_STATE_RESULT;
  287. acpi_ut_push_generic_state (&walk_state->results, state);
  288. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%pn",
  289. state, walk_state));
  290. return (AE_OK);
  291. }
  292. /*******************************************************************************
  293.  *
  294.  * FUNCTION:    Acpi_ds_result_stack_pop
  295.  *
  296.  * PARAMETERS:  Walk_state          - Current Walk state
  297.  *
  298.  * RETURN:      Status
  299.  *
  300.  * DESCRIPTION:
  301.  *
  302.  ******************************************************************************/
  303. acpi_status
  304. acpi_ds_result_stack_pop (
  305. acpi_walk_state         *walk_state)
  306. {
  307. acpi_generic_state      *state;
  308. PROC_NAME ("Ds_result_stack_pop");
  309. /* Check for stack underflow */
  310. if (walk_state->results == NULL) {
  311. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Underflow - State=%pn",
  312. walk_state));
  313. return (AE_AML_NO_OPERAND);
  314. }
  315. state = acpi_ut_pop_generic_state (&walk_state->results);
  316. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
  317. "Result=%p Remaining_results=%X State=%pn",
  318. state, state->results.num_results, walk_state));
  319. acpi_ut_delete_generic_state (state);
  320. return (AE_OK);
  321. }
  322. /*******************************************************************************
  323.  *
  324.  * FUNCTION:    Acpi_ds_obj_stack_delete_all
  325.  *
  326.  * PARAMETERS:  Walk_state          - Current Walk state
  327.  *
  328.  * RETURN:      Status
  329.  *
  330.  * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
  331.  *              Should be used with great care, if at all!
  332.  *
  333.  ******************************************************************************/
  334. acpi_status
  335. acpi_ds_obj_stack_delete_all (
  336. acpi_walk_state         *walk_state)
  337. {
  338. u32                     i;
  339. FUNCTION_TRACE_PTR ("Ds_obj_stack_delete_all", walk_state);
  340. /* The stack size is configurable, but fixed */
  341. for (i = 0; i < OBJ_NUM_OPERANDS; i++) {
  342. if (walk_state->operands[i]) {
  343. acpi_ut_remove_reference (walk_state->operands[i]);
  344. walk_state->operands[i] = NULL;
  345. }
  346. }
  347. return_ACPI_STATUS (AE_OK);
  348. }
  349. /*******************************************************************************
  350.  *
  351.  * FUNCTION:    Acpi_ds_obj_stack_push
  352.  *
  353.  * PARAMETERS:  Object              - Object to push
  354.  *              Walk_state          - Current Walk state
  355.  *
  356.  * RETURN:      Status
  357.  *
  358.  * DESCRIPTION: Push an object onto this walk's object/operand stack
  359.  *
  360.  ******************************************************************************/
  361. acpi_status
  362. acpi_ds_obj_stack_push (
  363. void                    *object,
  364. acpi_walk_state         *walk_state)
  365. {
  366. PROC_NAME ("Ds_obj_stack_push");
  367. /* Check for stack overflow */
  368. if (walk_state->num_operands >= OBJ_NUM_OPERANDS) {
  369. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  370. "overflow! Obj=%p State=%p #Ops=%Xn",
  371. object, walk_state, walk_state->num_operands));
  372. return (AE_STACK_OVERFLOW);
  373. }
  374. /* Put the object onto the stack */
  375. walk_state->operands [walk_state->num_operands] = object;
  376. walk_state->num_operands++;
  377. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%Xn",
  378.   object, acpi_ut_get_type_name (((acpi_operand_object *) object)->common.type),
  379.   walk_state, walk_state->num_operands));
  380. return (AE_OK);
  381. }
  382. #if 0
  383. /*******************************************************************************
  384.  *
  385.  * FUNCTION:    Acpi_ds_obj_stack_pop_object
  386.  *
  387.  * PARAMETERS:  Pop_count           - Number of objects/entries to pop
  388.  *              Walk_state          - Current Walk state
  389.  *
  390.  * RETURN:      Status
  391.  *
  392.  * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
  393.  *              deleted by this routine.
  394.  *
  395.  ******************************************************************************/
  396. acpi_status
  397. acpi_ds_obj_stack_pop_object (
  398. acpi_operand_object     **object,
  399. acpi_walk_state         *walk_state)
  400. {
  401. PROC_NAME ("Ds_obj_stack_pop_object");
  402. /* Check for stack underflow */
  403. if (walk_state->num_operands == 0) {
  404. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  405. "Missing operand/stack empty! State=%p #Ops=%Xn",
  406. walk_state, walk_state->num_operands));
  407. *object = NULL;
  408. return (AE_AML_NO_OPERAND);
  409. }
  410. /* Pop the stack */
  411. walk_state->num_operands--;
  412. /* Check for a valid operand */
  413. if (!walk_state->operands [walk_state->num_operands]) {
  414. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  415. "Null operand! State=%p #Ops=%Xn",
  416. walk_state, walk_state->num_operands));
  417. *object = NULL;
  418. return (AE_AML_NO_OPERAND);
  419. }
  420. /* Get operand and set stack entry to null */
  421. *object = walk_state->operands [walk_state->num_operands];
  422. walk_state->operands [walk_state->num_operands] = NULL;
  423. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%Xn",
  424.   *object, acpi_ut_get_type_name ((*object)->common.type),
  425.   walk_state, walk_state->num_operands));
  426. return (AE_OK);
  427. }
  428. #endif
  429. /*******************************************************************************
  430.  *
  431.  * FUNCTION:    Acpi_ds_obj_stack_pop
  432.  *
  433.  * PARAMETERS:  Pop_count           - Number of objects/entries to pop
  434.  *              Walk_state          - Current Walk state
  435.  *
  436.  * RETURN:      Status
  437.  *
  438.  * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
  439.  *              deleted by this routine.
  440.  *
  441.  ******************************************************************************/
  442. acpi_status
  443. acpi_ds_obj_stack_pop (
  444. u32                     pop_count,
  445. acpi_walk_state         *walk_state)
  446. {
  447. u32                     i;
  448. PROC_NAME ("Ds_obj_stack_pop");
  449. for (i = 0; i < pop_count; i++) {
  450. /* Check for stack underflow */
  451. if (walk_state->num_operands == 0) {
  452. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  453. "Underflow! Count=%X State=%p #Ops=%Xn",
  454. pop_count, walk_state, walk_state->num_operands));
  455. return (AE_STACK_UNDERFLOW);
  456. }
  457. /* Just set the stack entry to null */
  458. walk_state->num_operands--;
  459. walk_state->operands [walk_state->num_operands] = NULL;
  460. }
  461. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%Xn",
  462.   pop_count, walk_state, walk_state->num_operands));
  463. return (AE_OK);
  464. }
  465. /*******************************************************************************
  466.  *
  467.  * FUNCTION:    Acpi_ds_obj_stack_pop_and_delete
  468.  *
  469.  * PARAMETERS:  Pop_count           - Number of objects/entries to pop
  470.  *              Walk_state          - Current Walk state
  471.  *
  472.  * RETURN:      Status
  473.  *
  474.  * DESCRIPTION: Pop this walk's object stack and delete each object that is
  475.  *              popped off.
  476.  *
  477.  ******************************************************************************/
  478. acpi_status
  479. acpi_ds_obj_stack_pop_and_delete (
  480. u32                     pop_count,
  481. acpi_walk_state         *walk_state)
  482. {
  483. u32                     i;
  484. acpi_operand_object     *obj_desc;
  485. PROC_NAME ("Ds_obj_stack_pop_and_delete");
  486. for (i = 0; i < pop_count; i++) {
  487. /* Check for stack underflow */
  488. if (walk_state->num_operands == 0) {
  489. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  490. "Underflow! Count=%X State=%p #Ops=%Xn",
  491. pop_count, walk_state, walk_state->num_operands));
  492. return (AE_STACK_UNDERFLOW);
  493. }
  494. /* Pop the stack and delete an object if present in this stack entry */
  495. walk_state->num_operands--;
  496. obj_desc = walk_state->operands [walk_state->num_operands];
  497. if (obj_desc) {
  498. acpi_ut_remove_reference (walk_state->operands [walk_state->num_operands]);
  499. walk_state->operands [walk_state->num_operands] = NULL;
  500. }
  501. }
  502. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%Xn",
  503.   pop_count, walk_state, walk_state->num_operands));
  504. return (AE_OK);
  505. }
  506. /*******************************************************************************
  507.  *
  508.  * FUNCTION:    Acpi_ds_obj_stack_get_value
  509.  *
  510.  * PARAMETERS:  Index               - Stack index whose value is desired.  Based
  511.  *                                    on the top of the stack (index=0 == top)
  512.  *              Walk_state          - Current Walk state
  513.  *
  514.  * RETURN:      Status
  515.  *
  516.  * DESCRIPTION: Retrieve an object from this walk's object stack.  Index must
  517.  *              be within the range of the current stack pointer.
  518.  *
  519.  ******************************************************************************/
  520. void *
  521. acpi_ds_obj_stack_get_value (
  522. u32                     index,
  523. acpi_walk_state         *walk_state)
  524. {
  525. FUNCTION_TRACE_PTR ("Ds_obj_stack_get_value", walk_state);
  526. /* Can't do it if the stack is empty */
  527. if (walk_state->num_operands == 0) {
  528. return_PTR (NULL);
  529. }
  530. /* or if the index is past the top of the stack */
  531. if (index > (walk_state->num_operands - (u32) 1)) {
  532. return_PTR (NULL);
  533. }
  534. return_PTR (walk_state->operands[(NATIVE_UINT)(walk_state->num_operands - 1) -
  535.   index]);
  536. }
  537. /*******************************************************************************
  538.  *
  539.  * FUNCTION:    Acpi_ds_get_current_walk_state
  540.  *
  541.  * PARAMETERS:  Walk_list       - Get current active state for this walk list
  542.  *
  543.  * RETURN:      Pointer to the current walk state
  544.  *
  545.  * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
  546.  *              walk state.
  547.  *
  548.  ******************************************************************************/
  549. acpi_walk_state *
  550. acpi_ds_get_current_walk_state (
  551. acpi_walk_list          *walk_list)
  552. {
  553. PROC_NAME ("Ds_get_current_walk_state");
  554. ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Ds_get_current_walk_state, =%pn",
  555. walk_list->walk_state));
  556. if (!walk_list) {
  557. return (NULL);
  558. }
  559. return (walk_list->walk_state);
  560. }
  561. /*******************************************************************************
  562.  *
  563.  * FUNCTION:    Acpi_ds_push_walk_state
  564.  *
  565.  * PARAMETERS:  Walk_state      - State to push
  566.  *              Walk_list       - The list that owns the walk stack
  567.  *
  568.  * RETURN:      None
  569.  *
  570.  * DESCRIPTION: Place the Walk_state at the head of the state list.
  571.  *
  572.  ******************************************************************************/
  573. void
  574. acpi_ds_push_walk_state (
  575. acpi_walk_state         *walk_state,
  576. acpi_walk_list          *walk_list)
  577. {
  578. FUNCTION_TRACE ("Ds_push_walk_state");
  579. walk_state->next    = walk_list->walk_state;
  580. walk_list->walk_state = walk_state;
  581. return_VOID;
  582. }
  583. /*******************************************************************************
  584.  *
  585.  * FUNCTION:    Acpi_ds_pop_walk_state
  586.  *
  587.  * PARAMETERS:  Walk_list       - The list that owns the walk stack
  588.  *
  589.  * RETURN:      A Walk_state object popped from the stack
  590.  *
  591.  * DESCRIPTION: Remove and return the walkstate object that is at the head of
  592.  *              the walk stack for the given walk list.  NULL indicates that
  593.  *              the list is empty.
  594.  *
  595.  ******************************************************************************/
  596. acpi_walk_state *
  597. acpi_ds_pop_walk_state (
  598. acpi_walk_list          *walk_list)
  599. {
  600. acpi_walk_state         *walk_state;
  601. FUNCTION_TRACE ("Ds_pop_walk_state");
  602. walk_state = walk_list->walk_state;
  603. if (walk_state) {
  604. /* Next walk state becomes the current walk state */
  605. walk_list->walk_state = walk_state->next;
  606. /*
  607.  * Don't clear the NEXT field, this serves as an indicator
  608.  * that there is a parent WALK STATE
  609.  *     Walk_state->Next = NULL;
  610.  */
  611. }
  612. return_PTR (walk_state);
  613. }
  614. /*******************************************************************************
  615.  *
  616.  * FUNCTION:    Acpi_ds_create_walk_state
  617.  *
  618.  * PARAMETERS:  Origin          - Starting point for this walk
  619.  *              Walk_list       - Owning walk list
  620.  *
  621.  * RETURN:      Pointer to the new walk state.
  622.  *
  623.  * DESCRIPTION: Allocate and initialize a new walk state.  The current walk state
  624.  *              is set to this new state.
  625.  *
  626.  ******************************************************************************/
  627. acpi_walk_state *
  628. acpi_ds_create_walk_state (
  629. acpi_owner_id           owner_id,
  630. acpi_parse_object       *origin,
  631. acpi_operand_object     *mth_desc,
  632. acpi_walk_list          *walk_list)
  633. {
  634. acpi_walk_state         *walk_state;
  635. acpi_status             status;
  636. FUNCTION_TRACE ("Ds_create_walk_state");
  637. walk_state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_WALK);
  638. if (!walk_state) {
  639. return_PTR (NULL);
  640. }
  641. walk_state->data_type       = ACPI_DESC_TYPE_WALK;
  642. walk_state->owner_id        = owner_id;
  643. walk_state->origin          = origin;
  644. walk_state->method_desc     = mth_desc;
  645. walk_state->walk_list       = walk_list;
  646. /* Init the method args/local */
  647. #ifndef _ACPI_ASL_COMPILER
  648. acpi_ds_method_data_init (walk_state);
  649. #endif
  650. /* Create an initial result stack entry */
  651. status = acpi_ds_result_stack_push (walk_state);
  652. if (ACPI_FAILURE (status)) {
  653. return_PTR (NULL);
  654. }
  655. /* Put the new state at the head of the walk list */
  656. if (walk_list) {
  657. acpi_ds_push_walk_state (walk_state, walk_list);
  658. }
  659. return_PTR (walk_state);
  660. }
  661. #ifndef _ACPI_ASL_COMPILER
  662. /*******************************************************************************
  663.  *
  664.  * FUNCTION:    Acpi_ds_init_aml_walk
  665.  *
  666.  * PARAMETERS:  Walk_state      - New state to be initialized
  667.  *
  668.  * RETURN:      None
  669.  *
  670.  * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
  671.  *
  672.  ******************************************************************************/
  673. acpi_status
  674. acpi_ds_init_aml_walk (
  675. acpi_walk_state         *walk_state,
  676. acpi_parse_object       *op,
  677. acpi_namespace_node     *method_node,
  678. u8                      *aml_start,
  679. u32                     aml_length,
  680. acpi_operand_object     **params,
  681. acpi_operand_object     **return_obj_desc,
  682. u32                     pass_number)
  683. {
  684. acpi_status             status;
  685. acpi_parse_state        *parser_state = &walk_state->parser_state;
  686. FUNCTION_TRACE ("Ds_init_aml_walk");
  687. walk_state->parser_state.aml    =
  688. walk_state->parser_state.aml_start = aml_start;
  689. walk_state->parser_state.aml_end =
  690. walk_state->parser_state.pkg_end = aml_start + aml_length;
  691. /* The Next_op of the Next_walk will be the beginning of the method */
  692. /* TBD: [Restructure] -- obsolete? */
  693. walk_state->next_op             = NULL;
  694. walk_state->params              = params;
  695. walk_state->caller_return_desc  = return_obj_desc;
  696. status = acpi_ps_init_scope (&walk_state->parser_state, op);
  697. if (ACPI_FAILURE (status)) {
  698. return_ACPI_STATUS (status);
  699. }
  700. if (method_node) {
  701. walk_state->parser_state.start_node = method_node;
  702. walk_state->walk_type               = WALK_METHOD;
  703. walk_state->method_node             = method_node;
  704. walk_state->method_desc             = acpi_ns_get_attached_object (method_node);
  705. /* Push start scope on scope stack and make it current  */
  706. status = acpi_ds_scope_stack_push (method_node, ACPI_TYPE_METHOD, walk_state);
  707. if (ACPI_FAILURE (status)) {
  708. return_ACPI_STATUS (status);
  709. }
  710. /* Init the method arguments */
  711. acpi_ds_method_data_init_args (params, MTH_NUM_ARGS, walk_state);
  712. }
  713. else {
  714. /* Setup the current scope */
  715. parser_state->start_node = parser_state->start_op->node;
  716. if (parser_state->start_node) {
  717. /* Push start scope on scope stack and make it current  */
  718. status = acpi_ds_scope_stack_push (parser_state->start_node,
  719.   parser_state->start_node->type, walk_state);
  720. if (ACPI_FAILURE (status)) {
  721. return_ACPI_STATUS (status);
  722. }
  723. }
  724. }
  725. acpi_ds_init_callbacks (walk_state, pass_number);
  726. return_ACPI_STATUS (AE_OK);
  727. }
  728. #endif
  729. /*******************************************************************************
  730.  *
  731.  * FUNCTION:    Acpi_ds_delete_walk_state
  732.  *
  733.  * PARAMETERS:  Walk_state      - State to delete
  734.  *
  735.  * RETURN:      Status
  736.  *
  737.  * DESCRIPTION: Delete a walk state including all internal data structures
  738.  *
  739.  ******************************************************************************/
  740. void
  741. acpi_ds_delete_walk_state (
  742. acpi_walk_state         *walk_state)
  743. {
  744. acpi_generic_state      *state;
  745. FUNCTION_TRACE_PTR ("Ds_delete_walk_state", walk_state);
  746. if (!walk_state) {
  747. return;
  748. }
  749. if (walk_state->data_type != ACPI_DESC_TYPE_WALK) {
  750. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p is not a valid walk staten", walk_state));
  751. return;
  752. }
  753. if (walk_state->parser_state.scope) {
  754. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope listn", walk_state));
  755. }
  756.    /* Always must free any linked control states */
  757. while (walk_state->control_state) {
  758. state = walk_state->control_state;
  759. walk_state->control_state = state->common.next;
  760. acpi_ut_delete_generic_state (state);
  761. }
  762. /* Always must free any linked parse states */
  763. while (walk_state->scope_info) {
  764. state = walk_state->scope_info;
  765. walk_state->scope_info = state->common.next;
  766. acpi_ut_delete_generic_state (state);
  767. }
  768. /* Always must free any stacked result states */
  769. while (walk_state->results) {
  770. state = walk_state->results;
  771. walk_state->results = state->common.next;
  772. acpi_ut_delete_generic_state (state);
  773. }
  774. acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
  775. return_VOID;
  776. }
  777. /******************************************************************************
  778.  *
  779.  * FUNCTION:    Acpi_ds_delete_walk_state_cache
  780.  *
  781.  * PARAMETERS:  None
  782.  *
  783.  * RETURN:      Status
  784.  *
  785.  * DESCRIPTION: Purge the global state object cache.  Used during subsystem
  786.  *              termination.
  787.  *
  788.  ******************************************************************************/
  789. void
  790. acpi_ds_delete_walk_state_cache (
  791. void)
  792. {
  793. FUNCTION_TRACE ("Ds_delete_walk_state_cache");
  794. acpi_ut_delete_generic_cache (ACPI_MEM_LIST_WALK);
  795. return_VOID;
  796. }