exoparg2.c 16.1 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7
/******************************************************************************
 *
 * Module Name: exoparg2 - AML execution - opcodes with 2 arguments
 *
 *****************************************************************************/

/*
L
Len Brown 已提交
8
 * Copyright (C) 2000 - 2008, Intel Corp.
L
Linus Torvalds 已提交
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

#include <acpi/acpi.h>
45
#include <acpi/accommon.h>
L
Linus Torvalds 已提交
46 47 48 49 50 51
#include <acpi/acparser.h>
#include <acpi/acinterp.h>
#include <acpi/acevents.h>
#include <acpi/amlcode.h>

#define _COMPONENT          ACPI_EXECUTER
L
Len Brown 已提交
52
ACPI_MODULE_NAME("exoparg2")
L
Linus Torvalds 已提交
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

/*!
 * Naming convention for AML interpreter execution routines.
 *
 * The routines that begin execution of AML opcodes are named with a common
 * convention based upon the number of arguments, the number of target operands,
 * and whether or not a value is returned:
 *
 *      AcpiExOpcode_xA_yT_zR
 *
 * Where:
 *
 * xA - ARGUMENTS:    The number of arguments (input operands) that are
 *                    required for this opcode type (1 through 6 args).
 * yT - TARGETS:      The number of targets (output operands) that are required
 *                    for this opcode type (0, 1, or 2 targets).
 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
 *                    as the function return (0 or 1).
 *
 * The AcpiExOpcode* functions are called via the Dispatcher component with
 * fully resolved operands.
!*/
/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_opcode_2A_0T_0R
 *
 * PARAMETERS:  walk_state          - Current walk state
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Execute opcode with two arguments, no target, and no return
 *              value.
 *
 * ALLOCATION:  Deletes both operands
 *
 ******************************************************************************/
L
Len Brown 已提交
89
acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state)
L
Linus Torvalds 已提交
90
{
L
Len Brown 已提交
91 92 93 94
	union acpi_operand_object **operand = &walk_state->operands[0];
	struct acpi_namespace_node *node;
	u32 value;
	acpi_status status = AE_OK;
L
Linus Torvalds 已提交
95

B
Bob Moore 已提交
96
	ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_0T_0R,
L
Len Brown 已提交
97
				acpi_ps_get_opcode_name(walk_state->opcode));
L
Linus Torvalds 已提交
98 99 100 101

	/* Examine the opcode */

	switch (walk_state->opcode) {
L
Len Brown 已提交
102
	case AML_NOTIFY_OP:	/* Notify (notify_object, notify_value) */
L
Linus Torvalds 已提交
103 104 105

		/* The first operand is a namespace node */

L
Len Brown 已提交
106
		node = (struct acpi_namespace_node *)operand[0];
L
Linus Torvalds 已提交
107 108 109 110 111

		/* Second value is the notify value */

		value = (u32) operand[1]->integer.value;

R
Robert Moore 已提交
112
		/* Are notifies allowed on this object? */
L
Linus Torvalds 已提交
113

L
Len Brown 已提交
114
		if (!acpi_ev_is_notify_object(node)) {
B
Bob Moore 已提交
115 116 117
			ACPI_ERROR((AE_INFO,
				    "Unexpected notify object type [%s]",
				    acpi_ut_get_type_name(node->type)));
L
Linus Torvalds 已提交
118 119 120 121 122 123 124

			status = AE_AML_OPERAND_TYPE;
			break;
		}
#ifdef ACPI_GPE_NOTIFY_CHECK
		/*
		 * GPE method wake/notify check.  Here, we want to ensure that we
B
Bob Moore 已提交
125
		 * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx
L
Linus Torvalds 已提交
126 127 128 129 130 131 132 133 134 135 136
		 * GPE method during system runtime.  If we do, the GPE is marked
		 * as "wake-only" and disabled.
		 *
		 * 1) Is the Notify() value == device_wake?
		 * 2) Is this a GPE deferred method?  (An _Lxx or _Exx method)
		 * 3) Did the original GPE happen at system runtime?
		 *    (versus during wake)
		 *
		 * If all three cases are true, this is a wake-only GPE that should
		 * be disabled at runtime.
		 */
L
Len Brown 已提交
137 138 139 140 141
		if (value == 2) {	/* device_wake */
			status =
			    acpi_ev_check_for_wake_only_gpe(walk_state->
							    gpe_event_info);
			if (ACPI_FAILURE(status)) {
B
Bob Moore 已提交
142

L
Linus Torvalds 已提交
143 144
				/* AE_WAKE_ONLY_GPE only error, means ignore this notify */

L
Len Brown 已提交
145
				return_ACPI_STATUS(AE_OK)
L
Linus Torvalds 已提交
146 147 148 149 150 151 152 153 154 155 156
			}
		}
#endif

		/*
		 * Dispatch the notify to the appropriate handler
		 * NOTE: the request is queued for execution after this method
		 * completes.  The notify handlers are NOT invoked synchronously
		 * from this thread -- because handlers may in turn run other
		 * control methods.
		 */
L
Len Brown 已提交
157
		status = acpi_ev_queue_notify_request(node, value);
L
Linus Torvalds 已提交
158 159 160 161
		break;

	default:

B
Bob Moore 已提交
162 163
		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
			    walk_state->opcode));
L
Linus Torvalds 已提交
164 165 166
		status = AE_AML_BAD_OPCODE;
	}

L
Len Brown 已提交
167
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_opcode_2A_2T_1R
 *
 * PARAMETERS:  walk_state          - Current walk state
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Execute a dyadic operator (2 operands) with 2 output targets
 *              and one implicit return value.
 *
 ******************************************************************************/

L
Len Brown 已提交
183
acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state)
L
Linus Torvalds 已提交
184
{
L
Len Brown 已提交
185 186 187 188
	union acpi_operand_object **operand = &walk_state->operands[0];
	union acpi_operand_object *return_desc1 = NULL;
	union acpi_operand_object *return_desc2 = NULL;
	acpi_status status;
L
Linus Torvalds 已提交
189

B
Bob Moore 已提交
190
	ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_2T_1R,
L
Len Brown 已提交
191
				acpi_ps_get_opcode_name(walk_state->opcode));
L
Linus Torvalds 已提交
192

R
Robert Moore 已提交
193 194
	/* Execute the opcode */

L
Linus Torvalds 已提交
195
	switch (walk_state->opcode) {
R
Robert Moore 已提交
196 197 198
	case AML_DIVIDE_OP:

		/* Divide (Dividend, Divisor, remainder_result quotient_result) */
L
Linus Torvalds 已提交
199

L
Len Brown 已提交
200 201
		return_desc1 =
		    acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
L
Linus Torvalds 已提交
202 203 204 205 206
		if (!return_desc1) {
			status = AE_NO_MEMORY;
			goto cleanup;
		}

L
Len Brown 已提交
207 208
		return_desc2 =
		    acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
L
Linus Torvalds 已提交
209 210 211 212 213 214 215
		if (!return_desc2) {
			status = AE_NO_MEMORY;
			goto cleanup;
		}

		/* Quotient to return_desc1, remainder to return_desc2 */

L
Len Brown 已提交
216 217 218 219 220
		status = acpi_ut_divide(operand[0]->integer.value,
					operand[1]->integer.value,
					&return_desc1->integer.value,
					&return_desc2->integer.value);
		if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
221 222 223 224 225 226
			goto cleanup;
		}
		break;

	default:

B
Bob Moore 已提交
227 228
		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
			    walk_state->opcode));
L
Linus Torvalds 已提交
229 230 231 232 233 234
		status = AE_AML_BAD_OPCODE;
		goto cleanup;
	}

	/* Store the results to the target reference operands */

L
Len Brown 已提交
235 236
	status = acpi_ex_store(return_desc2, operand[2], walk_state);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
237 238 239
		goto cleanup;
	}

L
Len Brown 已提交
240 241
	status = acpi_ex_store(return_desc1, operand[3], walk_state);
	if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
242 243 244
		goto cleanup;
	}

L
Len Brown 已提交
245
      cleanup:
L
Linus Torvalds 已提交
246 247 248 249
	/*
	 * Since the remainder is not returned indirectly, remove a reference to
	 * it. Only the quotient is returned indirectly.
	 */
L
Len Brown 已提交
250
	acpi_ut_remove_reference(return_desc2);
L
Linus Torvalds 已提交
251

L
Len Brown 已提交
252
	if (ACPI_FAILURE(status)) {
B
Bob Moore 已提交
253

L
Linus Torvalds 已提交
254 255
		/* Delete the return object */

L
Len Brown 已提交
256
		acpi_ut_remove_reference(return_desc1);
L
Linus Torvalds 已提交
257 258
	}

259 260 261 262 263 264
	/* Save return object (the remainder) on success */

	else {
		walk_state->result_obj = return_desc1;
	}

L
Len Brown 已提交
265
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_opcode_2A_1T_1R
 *
 * PARAMETERS:  walk_state          - Current walk state
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Execute opcode with two arguments, one target, and a return
 *              value.
 *
 ******************************************************************************/

L
Len Brown 已提交
281
acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
L
Linus Torvalds 已提交
282
{
L
Len Brown 已提交
283 284 285 286 287
	union acpi_operand_object **operand = &walk_state->operands[0];
	union acpi_operand_object *return_desc = NULL;
	acpi_integer index;
	acpi_status status = AE_OK;
	acpi_size length;
L
Linus Torvalds 已提交
288

B
Bob Moore 已提交
289
	ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_1T_1R,
L
Len Brown 已提交
290
				acpi_ps_get_opcode_name(walk_state->opcode));
L
Linus Torvalds 已提交
291

R
Robert Moore 已提交
292 293
	/* Execute the opcode */

L
Linus Torvalds 已提交
294
	if (walk_state->op_info->flags & AML_MATH) {
B
Bob Moore 已提交
295

L
Linus Torvalds 已提交
296 297
		/* All simple math opcodes (add, etc.) */

L
Len Brown 已提交
298
		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
L
Linus Torvalds 已提交
299 300 301 302 303
		if (!return_desc) {
			status = AE_NO_MEMORY;
			goto cleanup;
		}

L
Len Brown 已提交
304 305 306 307
		return_desc->integer.value =
		    acpi_ex_do_math_op(walk_state->opcode,
				       operand[0]->integer.value,
				       operand[1]->integer.value);
L
Linus Torvalds 已提交
308 309 310 311
		goto store_result_to_target;
	}

	switch (walk_state->opcode) {
L
Len Brown 已提交
312
	case AML_MOD_OP:	/* Mod (Dividend, Divisor, remainder_result (ACPI 2.0) */
L
Linus Torvalds 已提交
313

L
Len Brown 已提交
314
		return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
L
Linus Torvalds 已提交
315 316 317 318 319 320 321
		if (!return_desc) {
			status = AE_NO_MEMORY;
			goto cleanup;
		}

		/* return_desc will contain the remainder */

L
Len Brown 已提交
322 323 324
		status = acpi_ut_divide(operand[0]->integer.value,
					operand[1]->integer.value,
					NULL, &return_desc->integer.value);
L
Linus Torvalds 已提交
325 326
		break;

L
Len Brown 已提交
327
	case AML_CONCAT_OP:	/* Concatenate (Data1, Data2, Result) */
L
Linus Torvalds 已提交
328

L
Len Brown 已提交
329 330
		status = acpi_ex_do_concatenate(operand[0], operand[1],
						&return_desc, walk_state);
L
Linus Torvalds 已提交
331 332
		break;

L
Len Brown 已提交
333
	case AML_TO_STRING_OP:	/* to_string (Buffer, Length, Result) (ACPI 2.0) */
L
Linus Torvalds 已提交
334 335 336

		/*
		 * Input object is guaranteed to be a buffer at this point (it may have
R
Robert Moore 已提交
337 338
		 * been converted.)  Copy the raw buffer data to a new object of
		 * type String.
L
Linus Torvalds 已提交
339 340 341 342 343 344 345 346 347 348 349 350 351
		 */

		/*
		 * Get the length of the new string. It is the smallest of:
		 * 1) Length of the input buffer
		 * 2) Max length as specified in the to_string operator
		 * 3) Length of input buffer up to a zero byte (null terminator)
		 *
		 * NOTE: A length of zero is ok, and will create a zero-length, null
		 *       terminated string.
		 */
		length = 0;
		while ((length < operand[0]->buffer.length) &&
L
Len Brown 已提交
352 353
		       (length < operand[1]->integer.value) &&
		       (operand[0]->buffer.pointer[length])) {
L
Linus Torvalds 已提交
354 355 356 357 358
			length++;
		}

		/* Allocate a new string object */

L
Len Brown 已提交
359
		return_desc = acpi_ut_create_string_object(length);
L
Linus Torvalds 已提交
360 361 362 363 364
		if (!return_desc) {
			status = AE_NO_MEMORY;
			goto cleanup;
		}

B
Bob Moore 已提交
365 366 367 368
		/*
		 * Copy the raw buffer data with no transform.
		 * (NULL terminated already)
		 */
L
Len Brown 已提交
369 370
		ACPI_MEMCPY(return_desc->string.pointer,
			    operand[0]->buffer.pointer, length);
L
Linus Torvalds 已提交
371 372
		break;

R
Robert Moore 已提交
373 374 375
	case AML_CONCAT_RES_OP:

		/* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */
L
Linus Torvalds 已提交
376

L
Len Brown 已提交
377 378
		status = acpi_ex_concat_template(operand[0], operand[1],
						 &return_desc, walk_state);
L
Linus Torvalds 已提交
379 380
		break;

L
Len Brown 已提交
381
	case AML_INDEX_OP:	/* Index (Source Index Result) */
L
Linus Torvalds 已提交
382 383 384

		/* Create the internal return object */

L
Len Brown 已提交
385 386
		return_desc =
		    acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
L
Linus Torvalds 已提交
387 388 389 390 391
		if (!return_desc) {
			status = AE_NO_MEMORY;
			goto cleanup;
		}

B
Bob Moore 已提交
392 393
		/* Initialize the Index reference object */

R
Robert Moore 已提交
394
		index = operand[1]->integer.value;
395 396
		return_desc->reference.value = (u32) index;
		return_desc->reference.class = ACPI_REFCLASS_INDEX;
R
Robert Moore 已提交
397

B
Bob Moore 已提交
398 399 400 401 402 403
		/*
		 * At this point, the Source operand is a String, Buffer, or Package.
		 * Verify that the index is within range.
		 */
		switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
		case ACPI_TYPE_STRING:
L
Linus Torvalds 已提交
404

B
Bob Moore 已提交
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
			if (index >= operand[0]->string.length) {
				status = AE_AML_STRING_LIMIT;
			}

			return_desc->reference.target_type =
			    ACPI_TYPE_BUFFER_FIELD;
			break;

		case ACPI_TYPE_BUFFER:

			if (index >= operand[0]->buffer.length) {
				status = AE_AML_BUFFER_LIMIT;
			}

			return_desc->reference.target_type =
			    ACPI_TYPE_BUFFER_FIELD;
			break;

		case ACPI_TYPE_PACKAGE:
L
Linus Torvalds 已提交
424 425 426 427 428 429

			if (index >= operand[0]->package.count) {
				status = AE_AML_PACKAGE_LIMIT;
			}

			return_desc->reference.target_type = ACPI_TYPE_PACKAGE;
L
Len Brown 已提交
430 431
			return_desc->reference.where =
			    &operand[0]->package.elements[index];
B
Bob Moore 已提交
432
			break;
L
Linus Torvalds 已提交
433

B
Bob Moore 已提交
434
		default:
L
Linus Torvalds 已提交
435

B
Bob Moore 已提交
436 437 438 439 440 441 442 443 444 445 446
			status = AE_AML_INTERNAL;
			goto cleanup;
		}

		/* Failure means that the Index was beyond the end of the object */

		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"Index (%X%8.8X) is beyond end of object",
					ACPI_FORMAT_UINT64(index)));
			goto cleanup;
L
Linus Torvalds 已提交
447 448 449
		}

		/*
B
Bob Moore 已提交
450
		 * Save the target object and add a reference to it for the life
B
Bob Moore 已提交
451
		 * of the index
L
Linus Torvalds 已提交
452
		 */
B
Bob Moore 已提交
453
		return_desc->reference.object = operand[0];
L
Len Brown 已提交
454
		acpi_ut_add_reference(operand[0]);
L
Linus Torvalds 已提交
455 456 457

		/* Store the reference to the Target */

L
Len Brown 已提交
458
		status = acpi_ex_store(return_desc, operand[2], walk_state);
L
Linus Torvalds 已提交
459 460 461 462 463 464 465 466

		/* Return the reference */

		walk_state->result_obj = return_desc;
		goto cleanup;

	default:

B
Bob Moore 已提交
467 468
		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
			    walk_state->opcode));
L
Linus Torvalds 已提交
469 470 471 472
		status = AE_AML_BAD_OPCODE;
		break;
	}

L
Len Brown 已提交
473
      store_result_to_target:
L
Linus Torvalds 已提交
474

L
Len Brown 已提交
475
	if (ACPI_SUCCESS(status)) {
L
Linus Torvalds 已提交
476 477 478 479
		/*
		 * Store the result of the operation (which is now in return_desc) into
		 * the Target descriptor.
		 */
L
Len Brown 已提交
480 481
		status = acpi_ex_store(return_desc, operand[2], walk_state);
		if (ACPI_FAILURE(status)) {
L
Linus Torvalds 已提交
482 483 484 485 486 487 488 489
			goto cleanup;
		}

		if (!walk_state->result_obj) {
			walk_state->result_obj = return_desc;
		}
	}

L
Len Brown 已提交
490
      cleanup:
L
Linus Torvalds 已提交
491 492 493

	/* Delete return object on error */

L
Len Brown 已提交
494 495
	if (ACPI_FAILURE(status)) {
		acpi_ut_remove_reference(return_desc);
496
		walk_state->result_obj = NULL;
L
Linus Torvalds 已提交
497 498
	}

L
Len Brown 已提交
499
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
500 501 502 503 504 505 506 507 508 509 510 511 512 513
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_opcode_2A_0T_1R
 *
 * PARAMETERS:  walk_state          - Current walk state
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Execute opcode with 2 arguments, no target, and a return value
 *
 ******************************************************************************/

L
Len Brown 已提交
514
acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state)
L
Linus Torvalds 已提交
515
{
L
Len Brown 已提交
516 517 518 519
	union acpi_operand_object **operand = &walk_state->operands[0];
	union acpi_operand_object *return_desc = NULL;
	acpi_status status = AE_OK;
	u8 logical_result = FALSE;
L
Linus Torvalds 已提交
520

B
Bob Moore 已提交
521
	ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_0T_1R,
L
Len Brown 已提交
522
				acpi_ps_get_opcode_name(walk_state->opcode));
L
Linus Torvalds 已提交
523 524 525

	/* Create the internal return object */

L
Len Brown 已提交
526
	return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
L
Linus Torvalds 已提交
527 528 529 530 531
	if (!return_desc) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

R
Robert Moore 已提交
532 533 534
	/* Execute the Opcode */

	if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) {
B
Bob Moore 已提交
535

R
Robert Moore 已提交
536 537
		/* logical_op (Operand0, Operand1) */

L
Len Brown 已提交
538 539 540 541 542
		status = acpi_ex_do_logical_numeric_op(walk_state->opcode,
						       operand[0]->integer.
						       value,
						       operand[1]->integer.
						       value, &logical_result);
L
Linus Torvalds 已提交
543
		goto store_logical_result;
L
Len Brown 已提交
544
	} else if (walk_state->op_info->flags & AML_LOGICAL) {
B
Bob Moore 已提交
545

R
Robert Moore 已提交
546 547
		/* logical_op (Operand0, Operand1) */

L
Len Brown 已提交
548 549
		status = acpi_ex_do_logical_op(walk_state->opcode, operand[0],
					       operand[1], &logical_result);
L
Linus Torvalds 已提交
550 551 552 553
		goto store_logical_result;
	}

	switch (walk_state->opcode) {
L
Len Brown 已提交
554
	case AML_ACQUIRE_OP:	/* Acquire (mutex_object, Timeout) */
L
Linus Torvalds 已提交
555

L
Len Brown 已提交
556 557
		status =
		    acpi_ex_acquire_mutex(operand[1], operand[0], walk_state);
L
Linus Torvalds 已提交
558
		if (status == AE_TIME) {
L
Len Brown 已提交
559
			logical_result = TRUE;	/* TRUE = Acquire timed out */
L
Linus Torvalds 已提交
560 561 562 563
			status = AE_OK;
		}
		break;

L
Len Brown 已提交
564
	case AML_WAIT_OP:	/* Wait (event_object, Timeout) */
L
Linus Torvalds 已提交
565

L
Len Brown 已提交
566
		status = acpi_ex_system_wait_event(operand[1], operand[0]);
L
Linus Torvalds 已提交
567
		if (status == AE_TIME) {
L
Len Brown 已提交
568
			logical_result = TRUE;	/* TRUE, Wait timed out */
L
Linus Torvalds 已提交
569 570 571 572 573 574
			status = AE_OK;
		}
		break;

	default:

B
Bob Moore 已提交
575 576
		ACPI_ERROR((AE_INFO, "Unknown AML opcode %X",
			    walk_state->opcode));
L
Linus Torvalds 已提交
577 578 579 580
		status = AE_AML_BAD_OPCODE;
		goto cleanup;
	}

L
Len Brown 已提交
581
      store_logical_result:
L
Linus Torvalds 已提交
582 583 584 585 586 587 588 589
	/*
	 * Set return value to according to logical_result. logical TRUE (all ones)
	 * Default is FALSE (zero)
	 */
	if (logical_result) {
		return_desc->integer.value = ACPI_INTEGER_MAX;
	}

L
Len Brown 已提交
590
      cleanup:
L
Linus Torvalds 已提交
591 592 593

	/* Delete return object on error */

L
Len Brown 已提交
594 595
	if (ACPI_FAILURE(status)) {
		acpi_ut_remove_reference(return_desc);
L
Linus Torvalds 已提交
596 597
	}

598 599 600 601 602 603
	/* Save return object on success */

	else {
		walk_state->result_obj = return_desc;
	}

L
Len Brown 已提交
604
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
605
}