/drivers/acpi/dispatcher/dswstate.c

https://bitbucket.org/evzijst/gittest · C · 1100 lines · 513 code · 248 blank · 339 comment · 65 complexity · 2d3ae675920818f6e99835c44c34e97b MD5 · raw file

  1. /******************************************************************************
  2. *
  3. * Module Name: dswstate - Dispatcher parse tree walk management routines
  4. *
  5. *****************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2005, R. Byron Moore
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions, and the following disclaimer,
  15. * without modification.
  16. * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  17. * substantially similar to the "NO WARRANTY" disclaimer below
  18. * ("Disclaimer") and any redistribution must be conditioned upon
  19. * including a substantially similar Disclaimer requirement for further
  20. * binary redistribution.
  21. * 3. Neither the names of the above-listed copyright holders nor the names
  22. * of any contributors may be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * Alternatively, this software may be distributed under the terms of the
  26. * GNU General Public License ("GPL") version 2 as published by the Free
  27. * Software Foundation.
  28. *
  29. * NO WARRANTY
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  33. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  34. * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  38. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  39. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGES.
  41. */
  42. #include <acpi/acpi.h>
  43. #include <acpi/acparser.h>
  44. #include <acpi/acdispat.h>
  45. #include <acpi/acnamesp.h>
  46. #define _COMPONENT ACPI_DISPATCHER
  47. ACPI_MODULE_NAME ("dswstate")
  48. #ifdef ACPI_FUTURE_USAGE
  49. /*******************************************************************************
  50. *
  51. * FUNCTION: acpi_ds_result_insert
  52. *
  53. * PARAMETERS: Object - Object to push
  54. * Index - Where to insert the object
  55. * walk_state - Current Walk state
  56. *
  57. * RETURN: Status
  58. *
  59. * DESCRIPTION: Insert an object onto this walk's result stack
  60. *
  61. ******************************************************************************/
  62. acpi_status
  63. acpi_ds_result_insert (
  64. void *object,
  65. u32 index,
  66. struct acpi_walk_state *walk_state)
  67. {
  68. union acpi_generic_state *state;
  69. ACPI_FUNCTION_NAME ("ds_result_insert");
  70. state = walk_state->results;
  71. if (!state) {
  72. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
  73. walk_state));
  74. return (AE_NOT_EXIST);
  75. }
  76. if (index >= ACPI_OBJ_NUM_OPERANDS) {
  77. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  78. "Index out of range: %X Obj=%p State=%p Num=%X\n",
  79. index, object, walk_state, state->results.num_results));
  80. return (AE_BAD_PARAMETER);
  81. }
  82. if (!object) {
  83. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  84. "Null Object! Index=%X Obj=%p State=%p Num=%X\n",
  85. index, object, walk_state, state->results.num_results));
  86. return (AE_BAD_PARAMETER);
  87. }
  88. state->results.obj_desc [index] = object;
  89. state->results.num_results++;
  90. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
  91. "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
  92. object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
  93. walk_state, state->results.num_results, walk_state->current_result));
  94. return (AE_OK);
  95. }
  96. /*******************************************************************************
  97. *
  98. * FUNCTION: acpi_ds_result_remove
  99. *
  100. * PARAMETERS: Object - Where to return the popped object
  101. * Index - Where to extract the object
  102. * walk_state - Current Walk state
  103. *
  104. * RETURN: Status
  105. *
  106. * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
  107. * other words, this is a FIFO.
  108. *
  109. ******************************************************************************/
  110. acpi_status
  111. acpi_ds_result_remove (
  112. union acpi_operand_object **object,
  113. u32 index,
  114. struct acpi_walk_state *walk_state)
  115. {
  116. union acpi_generic_state *state;
  117. ACPI_FUNCTION_NAME ("ds_result_remove");
  118. state = walk_state->results;
  119. if (!state) {
  120. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
  121. walk_state));
  122. return (AE_NOT_EXIST);
  123. }
  124. if (index >= ACPI_OBJ_MAX_OPERAND) {
  125. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  126. "Index out of range: %X State=%p Num=%X\n",
  127. index, walk_state, state->results.num_results));
  128. }
  129. /* Check for a valid result object */
  130. if (!state->results.obj_desc [index]) {
  131. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  132. "Null operand! State=%p #Ops=%X, Index=%X\n",
  133. walk_state, state->results.num_results, index));
  134. return (AE_AML_NO_RETURN_VALUE);
  135. }
  136. /* Remove the object */
  137. state->results.num_results--;
  138. *object = state->results.obj_desc [index];
  139. state->results.obj_desc [index] = NULL;
  140. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
  141. "Obj=%p [%s] Index=%X State=%p Num=%X\n",
  142. *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
  143. index, walk_state, state->results.num_results));
  144. return (AE_OK);
  145. }
  146. #endif /* ACPI_FUTURE_USAGE */
  147. /*******************************************************************************
  148. *
  149. * FUNCTION: acpi_ds_result_pop
  150. *
  151. * PARAMETERS: Object - Where to return the popped object
  152. * walk_state - Current Walk state
  153. *
  154. * RETURN: Status
  155. *
  156. * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
  157. * other words, this is a FIFO.
  158. *
  159. ******************************************************************************/
  160. acpi_status
  161. acpi_ds_result_pop (
  162. union acpi_operand_object **object,
  163. struct acpi_walk_state *walk_state)
  164. {
  165. acpi_native_uint index;
  166. union acpi_generic_state *state;
  167. ACPI_FUNCTION_NAME ("ds_result_pop");
  168. state = walk_state->results;
  169. if (!state) {
  170. return (AE_OK);
  171. }
  172. if (!state->results.num_results) {
  173. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Result stack is empty! State=%p\n",
  174. walk_state));
  175. return (AE_AML_NO_RETURN_VALUE);
  176. }
  177. /* Remove top element */
  178. state->results.num_results--;
  179. for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) {
  180. /* Check for a valid result object */
  181. if (state->results.obj_desc [index -1]) {
  182. *object = state->results.obj_desc [index -1];
  183. state->results.obj_desc [index -1] = NULL;
  184. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%X\n",
  185. *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
  186. (u32) index -1, walk_state, state->results.num_results));
  187. return (AE_OK);
  188. }
  189. }
  190. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
  191. return (AE_AML_NO_RETURN_VALUE);
  192. }
  193. /*******************************************************************************
  194. *
  195. * FUNCTION: acpi_ds_result_pop_from_bottom
  196. *
  197. * PARAMETERS: Object - Where to return the popped object
  198. * walk_state - Current Walk state
  199. *
  200. * RETURN: Status
  201. *
  202. * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
  203. * other words, this is a FIFO.
  204. *
  205. ******************************************************************************/
  206. acpi_status
  207. acpi_ds_result_pop_from_bottom (
  208. union acpi_operand_object **object,
  209. struct acpi_walk_state *walk_state)
  210. {
  211. acpi_native_uint index;
  212. union acpi_generic_state *state;
  213. ACPI_FUNCTION_NAME ("ds_result_pop_from_bottom");
  214. state = walk_state->results;
  215. if (!state) {
  216. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  217. "Warning: No result object pushed! State=%p\n", walk_state));
  218. return (AE_NOT_EXIST);
  219. }
  220. if (!state->results.num_results) {
  221. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
  222. return (AE_AML_NO_RETURN_VALUE);
  223. }
  224. /* Remove Bottom element */
  225. *object = state->results.obj_desc [0];
  226. /* Push entire stack down one element */
  227. for (index = 0; index < state->results.num_results; index++) {
  228. state->results.obj_desc [index] = state->results.obj_desc [index + 1];
  229. }
  230. state->results.num_results--;
  231. /* Check for a valid result object */
  232. if (!*object) {
  233. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null operand! State=%p #Ops=%X, Index=%X\n",
  234. walk_state, state->results.num_results, (u32) index));
  235. return (AE_AML_NO_RETURN_VALUE);
  236. }
  237. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s], Results=%p State=%p\n",
  238. *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
  239. state, walk_state));
  240. return (AE_OK);
  241. }
  242. /*******************************************************************************
  243. *
  244. * FUNCTION: acpi_ds_result_push
  245. *
  246. * PARAMETERS: Object - Where to return the popped object
  247. * walk_state - Current Walk state
  248. *
  249. * RETURN: Status
  250. *
  251. * DESCRIPTION: Push an object onto the current result stack
  252. *
  253. ******************************************************************************/
  254. acpi_status
  255. acpi_ds_result_push (
  256. union acpi_operand_object *object,
  257. struct acpi_walk_state *walk_state)
  258. {
  259. union acpi_generic_state *state;
  260. ACPI_FUNCTION_NAME ("ds_result_push");
  261. state = walk_state->results;
  262. if (!state) {
  263. ACPI_REPORT_ERROR (("No result stack frame during push\n"));
  264. return (AE_AML_INTERNAL);
  265. }
  266. if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) {
  267. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  268. "Result stack overflow: Obj=%p State=%p Num=%X\n",
  269. object, walk_state, state->results.num_results));
  270. return (AE_STACK_OVERFLOW);
  271. }
  272. if (!object) {
  273. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Object! Obj=%p State=%p Num=%X\n",
  274. object, walk_state, state->results.num_results));
  275. return (AE_BAD_PARAMETER);
  276. }
  277. state->results.obj_desc [state->results.num_results] = object;
  278. state->results.num_results++;
  279. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
  280. object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
  281. walk_state, state->results.num_results, walk_state->current_result));
  282. return (AE_OK);
  283. }
  284. /*******************************************************************************
  285. *
  286. * FUNCTION: acpi_ds_result_stack_push
  287. *
  288. * PARAMETERS: walk_state - Current Walk state
  289. *
  290. * RETURN: Status
  291. *
  292. * DESCRIPTION: Push an object onto the walk_state result stack.
  293. *
  294. ******************************************************************************/
  295. acpi_status
  296. acpi_ds_result_stack_push (
  297. struct acpi_walk_state *walk_state)
  298. {
  299. union acpi_generic_state *state;
  300. ACPI_FUNCTION_NAME ("ds_result_stack_push");
  301. state = acpi_ut_create_generic_state ();
  302. if (!state) {
  303. return (AE_NO_MEMORY);
  304. }
  305. state->common.data_type = ACPI_DESC_TYPE_STATE_RESULT;
  306. acpi_ut_push_generic_state (&walk_state->results, state);
  307. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
  308. state, walk_state));
  309. return (AE_OK);
  310. }
  311. /*******************************************************************************
  312. *
  313. * FUNCTION: acpi_ds_result_stack_pop
  314. *
  315. * PARAMETERS: walk_state - Current Walk state
  316. *
  317. * RETURN: Status
  318. *
  319. * DESCRIPTION: Pop an object off of the walk_state result stack.
  320. *
  321. ******************************************************************************/
  322. acpi_status
  323. acpi_ds_result_stack_pop (
  324. struct acpi_walk_state *walk_state)
  325. {
  326. union acpi_generic_state *state;
  327. ACPI_FUNCTION_NAME ("ds_result_stack_pop");
  328. /* Check for stack underflow */
  329. if (walk_state->results == NULL) {
  330. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Underflow - State=%p\n",
  331. walk_state));
  332. return (AE_AML_NO_OPERAND);
  333. }
  334. state = acpi_ut_pop_generic_state (&walk_state->results);
  335. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
  336. "Result=%p remaining_results=%X State=%p\n",
  337. state, state->results.num_results, walk_state));
  338. acpi_ut_delete_generic_state (state);
  339. return (AE_OK);
  340. }
  341. /*******************************************************************************
  342. *
  343. * FUNCTION: acpi_ds_obj_stack_delete_all
  344. *
  345. * PARAMETERS: walk_state - Current Walk state
  346. *
  347. * RETURN: Status
  348. *
  349. * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
  350. * Should be used with great care, if at all!
  351. *
  352. ******************************************************************************/
  353. #ifdef ACPI_FUTURE_USAGE
  354. acpi_status
  355. acpi_ds_obj_stack_delete_all (
  356. struct acpi_walk_state *walk_state)
  357. {
  358. u32 i;
  359. ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_delete_all", walk_state);
  360. /* The stack size is configurable, but fixed */
  361. for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
  362. if (walk_state->operands[i]) {
  363. acpi_ut_remove_reference (walk_state->operands[i]);
  364. walk_state->operands[i] = NULL;
  365. }
  366. }
  367. return_ACPI_STATUS (AE_OK);
  368. }
  369. #endif /* ACPI_FUTURE_USAGE */
  370. /*******************************************************************************
  371. *
  372. * FUNCTION: acpi_ds_obj_stack_push
  373. *
  374. * PARAMETERS: Object - Object to push
  375. * walk_state - Current Walk state
  376. *
  377. * RETURN: Status
  378. *
  379. * DESCRIPTION: Push an object onto this walk's object/operand stack
  380. *
  381. ******************************************************************************/
  382. acpi_status
  383. acpi_ds_obj_stack_push (
  384. void *object,
  385. struct acpi_walk_state *walk_state)
  386. {
  387. ACPI_FUNCTION_NAME ("ds_obj_stack_push");
  388. /* Check for stack overflow */
  389. if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
  390. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  391. "overflow! Obj=%p State=%p #Ops=%X\n",
  392. object, walk_state, walk_state->num_operands));
  393. return (AE_STACK_OVERFLOW);
  394. }
  395. /* Put the object onto the stack */
  396. walk_state->operands [walk_state->num_operands] = object;
  397. walk_state->num_operands++;
  398. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
  399. object, acpi_ut_get_object_type_name ((union acpi_operand_object *) object),
  400. walk_state, walk_state->num_operands));
  401. return (AE_OK);
  402. }
  403. #if 0
  404. /*******************************************************************************
  405. *
  406. * FUNCTION: acpi_ds_obj_stack_pop_object
  407. *
  408. * PARAMETERS: pop_count - Number of objects/entries to pop
  409. * walk_state - Current Walk state
  410. *
  411. * RETURN: Status
  412. *
  413. * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
  414. * deleted by this routine.
  415. *
  416. ******************************************************************************/
  417. acpi_status
  418. acpi_ds_obj_stack_pop_object (
  419. union acpi_operand_object **object,
  420. struct acpi_walk_state *walk_state)
  421. {
  422. ACPI_FUNCTION_NAME ("ds_obj_stack_pop_object");
  423. /* Check for stack underflow */
  424. if (walk_state->num_operands == 0) {
  425. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  426. "Missing operand/stack empty! State=%p #Ops=%X\n",
  427. walk_state, walk_state->num_operands));
  428. *object = NULL;
  429. return (AE_AML_NO_OPERAND);
  430. }
  431. /* Pop the stack */
  432. walk_state->num_operands--;
  433. /* Check for a valid operand */
  434. if (!walk_state->operands [walk_state->num_operands]) {
  435. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  436. "Null operand! State=%p #Ops=%X\n",
  437. walk_state, walk_state->num_operands));
  438. *object = NULL;
  439. return (AE_AML_NO_OPERAND);
  440. }
  441. /* Get operand and set stack entry to null */
  442. *object = walk_state->operands [walk_state->num_operands];
  443. walk_state->operands [walk_state->num_operands] = NULL;
  444. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
  445. *object, acpi_ut_get_object_type_name (*object),
  446. walk_state, walk_state->num_operands));
  447. return (AE_OK);
  448. }
  449. #endif
  450. /*******************************************************************************
  451. *
  452. * FUNCTION: acpi_ds_obj_stack_pop
  453. *
  454. * PARAMETERS: pop_count - Number of objects/entries to pop
  455. * walk_state - Current Walk state
  456. *
  457. * RETURN: Status
  458. *
  459. * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
  460. * deleted by this routine.
  461. *
  462. ******************************************************************************/
  463. acpi_status
  464. acpi_ds_obj_stack_pop (
  465. u32 pop_count,
  466. struct acpi_walk_state *walk_state)
  467. {
  468. u32 i;
  469. ACPI_FUNCTION_NAME ("ds_obj_stack_pop");
  470. for (i = 0; i < pop_count; i++) {
  471. /* Check for stack underflow */
  472. if (walk_state->num_operands == 0) {
  473. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  474. "Underflow! Count=%X State=%p #Ops=%X\n",
  475. pop_count, walk_state, walk_state->num_operands));
  476. return (AE_STACK_UNDERFLOW);
  477. }
  478. /* Just set the stack entry to null */
  479. walk_state->num_operands--;
  480. walk_state->operands [walk_state->num_operands] = NULL;
  481. }
  482. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
  483. pop_count, walk_state, walk_state->num_operands));
  484. return (AE_OK);
  485. }
  486. /*******************************************************************************
  487. *
  488. * FUNCTION: acpi_ds_obj_stack_pop_and_delete
  489. *
  490. * PARAMETERS: pop_count - Number of objects/entries to pop
  491. * walk_state - Current Walk state
  492. *
  493. * RETURN: Status
  494. *
  495. * DESCRIPTION: Pop this walk's object stack and delete each object that is
  496. * popped off.
  497. *
  498. ******************************************************************************/
  499. acpi_status
  500. acpi_ds_obj_stack_pop_and_delete (
  501. u32 pop_count,
  502. struct acpi_walk_state *walk_state)
  503. {
  504. u32 i;
  505. union acpi_operand_object *obj_desc;
  506. ACPI_FUNCTION_NAME ("ds_obj_stack_pop_and_delete");
  507. for (i = 0; i < pop_count; i++) {
  508. /* Check for stack underflow */
  509. if (walk_state->num_operands == 0) {
  510. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  511. "Underflow! Count=%X State=%p #Ops=%X\n",
  512. pop_count, walk_state, walk_state->num_operands));
  513. return (AE_STACK_UNDERFLOW);
  514. }
  515. /* Pop the stack and delete an object if present in this stack entry */
  516. walk_state->num_operands--;
  517. obj_desc = walk_state->operands [walk_state->num_operands];
  518. if (obj_desc) {
  519. acpi_ut_remove_reference (walk_state->operands [walk_state->num_operands]);
  520. walk_state->operands [walk_state->num_operands] = NULL;
  521. }
  522. }
  523. ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
  524. pop_count, walk_state, walk_state->num_operands));
  525. return (AE_OK);
  526. }
  527. /*******************************************************************************
  528. *
  529. * FUNCTION: acpi_ds_obj_stack_get_value
  530. *
  531. * PARAMETERS: Index - Stack index whose value is desired. Based
  532. * on the top of the stack (index=0 == top)
  533. * walk_state - Current Walk state
  534. *
  535. * RETURN: Status
  536. *
  537. * DESCRIPTION: Retrieve an object from this walk's object stack. Index must
  538. * be within the range of the current stack pointer.
  539. *
  540. ******************************************************************************/
  541. #ifdef ACPI_FUTURE_USAGE
  542. void *
  543. acpi_ds_obj_stack_get_value (
  544. u32 index,
  545. struct acpi_walk_state *walk_state)
  546. {
  547. ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_get_value", walk_state);
  548. /* Can't do it if the stack is empty */
  549. if (walk_state->num_operands == 0) {
  550. return_PTR (NULL);
  551. }
  552. /* or if the index is past the top of the stack */
  553. if (index > (walk_state->num_operands - (u32) 1)) {
  554. return_PTR (NULL);
  555. }
  556. return_PTR (walk_state->operands[(acpi_native_uint)(walk_state->num_operands - 1) -
  557. index]);
  558. }
  559. #endif /* ACPI_FUTURE_USAGE */
  560. /*******************************************************************************
  561. *
  562. * FUNCTION: acpi_ds_get_current_walk_state
  563. *
  564. * PARAMETERS: Thread - Get current active state for this Thread
  565. *
  566. * RETURN: Pointer to the current walk state
  567. *
  568. * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
  569. * walk state.)
  570. *
  571. ******************************************************************************/
  572. struct acpi_walk_state *
  573. acpi_ds_get_current_walk_state (
  574. struct acpi_thread_state *thread)
  575. {
  576. ACPI_FUNCTION_NAME ("ds_get_current_walk_state");
  577. if (!thread) {
  578. return (NULL);
  579. }
  580. ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current walk_state %p\n",
  581. thread->walk_state_list));
  582. return (thread->walk_state_list);
  583. }
  584. /*******************************************************************************
  585. *
  586. * FUNCTION: acpi_ds_push_walk_state
  587. *
  588. * PARAMETERS: walk_state - State to push
  589. * walk_list - The list that owns the walk stack
  590. *
  591. * RETURN: None
  592. *
  593. * DESCRIPTION: Place the walk_state at the head of the state list.
  594. *
  595. ******************************************************************************/
  596. void
  597. acpi_ds_push_walk_state (
  598. struct acpi_walk_state *walk_state,
  599. struct acpi_thread_state *thread)
  600. {
  601. ACPI_FUNCTION_TRACE ("ds_push_walk_state");
  602. walk_state->next = thread->walk_state_list;
  603. thread->walk_state_list = walk_state;
  604. return_VOID;
  605. }
  606. /*******************************************************************************
  607. *
  608. * FUNCTION: acpi_ds_pop_walk_state
  609. *
  610. * PARAMETERS: walk_list - The list that owns the walk stack
  611. *
  612. * RETURN: A walk_state object popped from the stack
  613. *
  614. * DESCRIPTION: Remove and return the walkstate object that is at the head of
  615. * the walk stack for the given walk list. NULL indicates that
  616. * the list is empty.
  617. *
  618. ******************************************************************************/
  619. struct acpi_walk_state *
  620. acpi_ds_pop_walk_state (
  621. struct acpi_thread_state *thread)
  622. {
  623. struct acpi_walk_state *walk_state;
  624. ACPI_FUNCTION_TRACE ("ds_pop_walk_state");
  625. walk_state = thread->walk_state_list;
  626. if (walk_state) {
  627. /* Next walk state becomes the current walk state */
  628. thread->walk_state_list = walk_state->next;
  629. /*
  630. * Don't clear the NEXT field, this serves as an indicator
  631. * that there is a parent WALK STATE
  632. * NO: walk_state->Next = NULL;
  633. */
  634. }
  635. return_PTR (walk_state);
  636. }
  637. /*******************************************************************************
  638. *
  639. * FUNCTION: acpi_ds_create_walk_state
  640. *
  641. * PARAMETERS: Origin - Starting point for this walk
  642. * Thread - Current thread state
  643. *
  644. * RETURN: Pointer to the new walk state.
  645. *
  646. * DESCRIPTION: Allocate and initialize a new walk state. The current walk
  647. * state is set to this new state.
  648. *
  649. ******************************************************************************/
  650. struct acpi_walk_state *
  651. acpi_ds_create_walk_state (
  652. acpi_owner_id owner_id,
  653. union acpi_parse_object *origin,
  654. union acpi_operand_object *mth_desc,
  655. struct acpi_thread_state *thread)
  656. {
  657. struct acpi_walk_state *walk_state;
  658. acpi_status status;
  659. ACPI_FUNCTION_TRACE ("ds_create_walk_state");
  660. walk_state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_WALK);
  661. if (!walk_state) {
  662. return_PTR (NULL);
  663. }
  664. walk_state->data_type = ACPI_DESC_TYPE_WALK;
  665. walk_state->owner_id = owner_id;
  666. walk_state->origin = origin;
  667. walk_state->method_desc = mth_desc;
  668. walk_state->thread = thread;
  669. walk_state->parser_state.start_op = origin;
  670. /* Init the method args/local */
  671. #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
  672. acpi_ds_method_data_init (walk_state);
  673. #endif
  674. /* Create an initial result stack entry */
  675. status = acpi_ds_result_stack_push (walk_state);
  676. if (ACPI_FAILURE (status)) {
  677. acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
  678. return_PTR (NULL);
  679. }
  680. /* Put the new state at the head of the walk list */
  681. if (thread) {
  682. acpi_ds_push_walk_state (walk_state, thread);
  683. }
  684. return_PTR (walk_state);
  685. }
  686. /*******************************************************************************
  687. *
  688. * FUNCTION: acpi_ds_init_aml_walk
  689. *
  690. * PARAMETERS: walk_state - New state to be initialized
  691. * Op - Current parse op
  692. * method_node - Control method NS node, if any
  693. * aml_start - Start of AML
  694. * aml_length - Length of AML
  695. * Params - Method args, if any
  696. * return_obj_desc - Where to store a return object, if any
  697. * pass_number - 1, 2, or 3
  698. *
  699. * RETURN: Status
  700. *
  701. * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
  702. *
  703. ******************************************************************************/
  704. acpi_status
  705. acpi_ds_init_aml_walk (
  706. struct acpi_walk_state *walk_state,
  707. union acpi_parse_object *op,
  708. struct acpi_namespace_node *method_node,
  709. u8 *aml_start,
  710. u32 aml_length,
  711. struct acpi_parameter_info *info,
  712. u32 pass_number)
  713. {
  714. acpi_status status;
  715. struct acpi_parse_state *parser_state = &walk_state->parser_state;
  716. union acpi_parse_object *extra_op;
  717. ACPI_FUNCTION_TRACE ("ds_init_aml_walk");
  718. walk_state->parser_state.aml =
  719. walk_state->parser_state.aml_start = aml_start;
  720. walk_state->parser_state.aml_end =
  721. walk_state->parser_state.pkg_end = aml_start + aml_length;
  722. /* The next_op of the next_walk will be the beginning of the method */
  723. walk_state->next_op = NULL;
  724. if (info) {
  725. if (info->parameter_type == ACPI_PARAM_GPE) {
  726. walk_state->gpe_event_info = ACPI_CAST_PTR (struct acpi_gpe_event_info,
  727. info->parameters);
  728. }
  729. else {
  730. walk_state->params = info->parameters;
  731. walk_state->caller_return_desc = &info->return_object;
  732. }
  733. }
  734. status = acpi_ps_init_scope (&walk_state->parser_state, op);
  735. if (ACPI_FAILURE (status)) {
  736. return_ACPI_STATUS (status);
  737. }
  738. if (method_node) {
  739. walk_state->parser_state.start_node = method_node;
  740. walk_state->walk_type = ACPI_WALK_METHOD;
  741. walk_state->method_node = method_node;
  742. walk_state->method_desc = acpi_ns_get_attached_object (method_node);
  743. /* Push start scope on scope stack and make it current */
  744. status = acpi_ds_scope_stack_push (method_node, ACPI_TYPE_METHOD, walk_state);
  745. if (ACPI_FAILURE (status)) {
  746. return_ACPI_STATUS (status);
  747. }
  748. /* Init the method arguments */
  749. status = acpi_ds_method_data_init_args (walk_state->params, ACPI_METHOD_NUM_ARGS, walk_state);
  750. if (ACPI_FAILURE (status)) {
  751. return_ACPI_STATUS (status);
  752. }
  753. }
  754. else {
  755. /*
  756. * Setup the current scope.
  757. * Find a Named Op that has a namespace node associated with it.
  758. * search upwards from this Op. Current scope is the first
  759. * Op with a namespace node.
  760. */
  761. extra_op = parser_state->start_op;
  762. while (extra_op && !extra_op->common.node) {
  763. extra_op = extra_op->common.parent;
  764. }
  765. if (!extra_op) {
  766. parser_state->start_node = NULL;
  767. }
  768. else {
  769. parser_state->start_node = extra_op->common.node;
  770. }
  771. if (parser_state->start_node) {
  772. /* Push start scope on scope stack and make it current */
  773. status = acpi_ds_scope_stack_push (parser_state->start_node,
  774. parser_state->start_node->type, walk_state);
  775. if (ACPI_FAILURE (status)) {
  776. return_ACPI_STATUS (status);
  777. }
  778. }
  779. }
  780. status = acpi_ds_init_callbacks (walk_state, pass_number);
  781. return_ACPI_STATUS (status);
  782. }
  783. /*******************************************************************************
  784. *
  785. * FUNCTION: acpi_ds_delete_walk_state
  786. *
  787. * PARAMETERS: walk_state - State to delete
  788. *
  789. * RETURN: Status
  790. *
  791. * DESCRIPTION: Delete a walk state including all internal data structures
  792. *
  793. ******************************************************************************/
  794. void
  795. acpi_ds_delete_walk_state (
  796. struct acpi_walk_state *walk_state)
  797. {
  798. union acpi_generic_state *state;
  799. ACPI_FUNCTION_TRACE_PTR ("ds_delete_walk_state", walk_state);
  800. if (!walk_state) {
  801. return;
  802. }
  803. if (walk_state->data_type != ACPI_DESC_TYPE_WALK) {
  804. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p is not a valid walk state\n", walk_state));
  805. return;
  806. }
  807. if (walk_state->parser_state.scope) {
  808. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n", walk_state));
  809. }
  810. /* Always must free any linked control states */
  811. while (walk_state->control_state) {
  812. state = walk_state->control_state;
  813. walk_state->control_state = state->common.next;
  814. acpi_ut_delete_generic_state (state);
  815. }
  816. /* Always must free any linked parse states */
  817. while (walk_state->scope_info) {
  818. state = walk_state->scope_info;
  819. walk_state->scope_info = state->common.next;
  820. acpi_ut_delete_generic_state (state);
  821. }
  822. /* Always must free any stacked result states */
  823. while (walk_state->results) {
  824. state = walk_state->results;
  825. walk_state->results = state->common.next;
  826. acpi_ut_delete_generic_state (state);
  827. }
  828. acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
  829. return_VOID;
  830. }
  831. #ifdef ACPI_ENABLE_OBJECT_CACHE
  832. /******************************************************************************
  833. *
  834. * FUNCTION: acpi_ds_delete_walk_state_cache
  835. *
  836. * PARAMETERS: None
  837. *
  838. * RETURN: Status
  839. *
  840. * DESCRIPTION: Purge the global state object cache. Used during subsystem
  841. * termination.
  842. *
  843. ******************************************************************************/
  844. void
  845. acpi_ds_delete_walk_state_cache (
  846. void)
  847. {
  848. ACPI_FUNCTION_TRACE ("ds_delete_walk_state_cache");
  849. acpi_ut_delete_generic_cache (ACPI_MEM_LIST_WALK);
  850. return_VOID;
  851. }
  852. #endif