PageRenderTime 80ms CodeModel.GetById 16ms app.highlight 56ms RepoModel.GetById 2ms app.codeStats 0ms

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