File: /usr/src/linux/drivers/acpi/executer/exdyadic.c
1 /******************************************************************************
2 *
3 * Module Name: exdyadic - ACPI AML execution for dyadic (2-operand) operators
4 * $Revision: 88 $
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000, 2001 R. Byron Moore
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26
27 #include "acpi.h"
28 #include "acparser.h"
29 #include "acnamesp.h"
30 #include "acinterp.h"
31 #include "acevents.h"
32 #include "amlcode.h"
33 #include "acdispat.h"
34
35
36 #define _COMPONENT ACPI_EXECUTER
37 MODULE_NAME ("exdyadic")
38
39
40 /*******************************************************************************
41 *
42 * FUNCTION: Acpi_ex_do_concatenate
43 *
44 * PARAMETERS: *Obj_desc - Object to be converted. Must be an
45 * Integer, Buffer, or String
46 * Walk_state - Current walk state
47 *
48 * RETURN: Status
49 *
50 * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
51 *
52 ******************************************************************************/
53
54 acpi_status
55 acpi_ex_do_concatenate (
56 acpi_operand_object *obj_desc,
57 acpi_operand_object *obj_desc2,
58 acpi_operand_object **actual_ret_desc,
59 acpi_walk_state *walk_state)
60 {
61 acpi_status status;
62 u32 i;
63 acpi_integer this_integer;
64 acpi_operand_object *ret_desc;
65 NATIVE_CHAR *new_buf;
66 u32 integer_size = sizeof (acpi_integer);
67
68
69 FUNCTION_ENTRY ();
70
71
72 /*
73 * There are three cases to handle:
74 * 1) Two Integers concatenated to produce a buffer
75 * 2) Two Strings concatenated to produce a string
76 * 3) Two Buffers concatenated to produce a buffer
77 */
78 switch (obj_desc->common.type) {
79 case ACPI_TYPE_INTEGER:
80
81 /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */
82
83 if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) {
84 /*
85 * We are running a method that exists in a 32-bit ACPI table.
86 * Truncate the value to 32 bits by zeroing out the upper
87 * 32-bit field
88 */
89 integer_size = sizeof (u32);
90 }
91
92 /* Result of two integers is a buffer */
93
94 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
95 if (!ret_desc) {
96 return (AE_NO_MEMORY);
97 }
98
99 /* Need enough space for two integers */
100
101 ret_desc->buffer.length = integer_size * 2;
102 new_buf = ACPI_MEM_CALLOCATE (ret_desc->buffer.length);
103 if (!new_buf) {
104 REPORT_ERROR
105 (("Ex_do_concatenate: Buffer allocation failure\n"));
106 status = AE_NO_MEMORY;
107 goto cleanup;
108 }
109
110 ret_desc->buffer.pointer = (u8 *) new_buf;
111
112 /* Convert the first integer */
113
114 this_integer = obj_desc->integer.value;
115 for (i = 0; i < integer_size; i++) {
116 new_buf[i] = (u8) this_integer;
117 this_integer >>= 8;
118 }
119
120 /* Convert the second integer */
121
122 this_integer = obj_desc2->integer.value;
123 for (; i < (integer_size * 2); i++) {
124 new_buf[i] = (u8) this_integer;
125 this_integer >>= 8;
126 }
127
128 break;
129
130
131 case ACPI_TYPE_STRING:
132
133 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
134 if (!ret_desc) {
135 return (AE_NO_MEMORY);
136 }
137
138 /* Operand1 is string */
139
140 new_buf = ACPI_MEM_ALLOCATE (obj_desc->string.length +
141 obj_desc2->string.length + 1);
142 if (!new_buf) {
143 REPORT_ERROR
144 (("Ex_do_concatenate: String allocation failure\n"));
145 status = AE_NO_MEMORY;
146 goto cleanup;
147 }
148
149 STRCPY (new_buf, obj_desc->string.pointer);
150 STRCPY (new_buf + obj_desc->string.length,
151 obj_desc2->string.pointer);
152
153 /* Point the return object to the new string */
154
155 ret_desc->string.pointer = new_buf;
156 ret_desc->string.length = obj_desc->string.length +=
157 obj_desc2->string.length;
158 break;
159
160
161 case ACPI_TYPE_BUFFER:
162
163 /* Operand1 is a buffer */
164
165 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
166 if (!ret_desc) {
167 return (AE_NO_MEMORY);
168 }
169
170 new_buf = ACPI_MEM_ALLOCATE (obj_desc->buffer.length +
171 obj_desc2->buffer.length);
172 if (!new_buf) {
173 REPORT_ERROR
174 (("Ex_do_concatenate: Buffer allocation failure\n"));
175 status = AE_NO_MEMORY;
176 goto cleanup;
177 }
178
179 MEMCPY (new_buf, obj_desc->buffer.pointer,
180 obj_desc->buffer.length);
181 MEMCPY (new_buf + obj_desc->buffer.length, obj_desc2->buffer.pointer,
182 obj_desc2->buffer.length);
183
184 /*
185 * Point the return object to the new buffer
186 */
187
188 ret_desc->buffer.pointer = (u8 *) new_buf;
189 ret_desc->buffer.length = obj_desc->buffer.length +
190 obj_desc2->buffer.length;
191 break;
192
193 default:
194 status = AE_AML_INTERNAL;
195 ret_desc = NULL;
196 }
197
198
199 *actual_ret_desc = ret_desc;
200 return (AE_OK);
201
202
203 cleanup:
204
205 acpi_ut_remove_reference (ret_desc);
206 return (status);
207 }
208
209
210 /*******************************************************************************
211 *
212 * FUNCTION: Acpi_ex_dyadic1
213 *
214 * PARAMETERS: Opcode - The opcode to be executed
215 * Walk_state - Current walk state
216 *
217 * RETURN: Status
218 *
219 * DESCRIPTION: Execute Type 1 dyadic operator with numeric operands:
220 * Notify_op
221 *
222 * ALLOCATION: Deletes both operands
223 *
224 ******************************************************************************/
225
226 acpi_status
227 acpi_ex_dyadic1 (
228 u16 opcode,
229 acpi_walk_state *walk_state)
230 {
231 acpi_operand_object **operand = &walk_state->operands[0];
232 acpi_namespace_node *node;
233 acpi_status status = AE_OK;
234
235
236 FUNCTION_TRACE_PTR ("Ex_dyadic1", WALK_OPERANDS);
237
238
239 /* Examine the opcode */
240
241 switch (opcode) {
242
243 /* Def_notify := Notify_op (0)Notify_object (1)Notify_value */
244
245 case AML_NOTIFY_OP:
246
247 /* The Obj_desc is actually an Node */
248
249 node = (acpi_namespace_node *) operand[0];
250 operand[0] = NULL;
251
252 /* Object must be a device or thermal zone */
253
254 if (node && operand[1]) {
255 switch (node->type) {
256 case ACPI_TYPE_DEVICE:
257 case ACPI_TYPE_THERMAL:
258
259 /*
260 * Dispatch the notify to the appropriate handler
261 * NOTE: the request is queued for execution after this method
262 * completes. The notify handlers are NOT invoked synchronously
263 * from this thread -- because handlers may in turn run other
264 * control methods.
265 */
266 status = acpi_ev_queue_notify_request (node,
267 (u32) operand[1]->integer.value);
268 break;
269
270 default:
271 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unexpected notify object type %X\n",
272 operand[0]->common.type));
273
274 status = AE_AML_OPERAND_TYPE;
275 break;
276 }
277 }
278 break;
279
280 default:
281
282 REPORT_ERROR (("Acpi_ex_dyadic1: Unknown dyadic opcode %X\n", opcode));
283 status = AE_AML_BAD_OPCODE;
284 }
285
286
287 /* Always delete both operands */
288
289 acpi_ut_remove_reference (operand[1]);
290 acpi_ut_remove_reference (operand[0]);
291
292
293 return_ACPI_STATUS (status);
294 }
295
296
297 /*******************************************************************************
298 *
299 * FUNCTION: Acpi_ex_dyadic2_r
300 *
301 * PARAMETERS: Opcode - The opcode to be executed
302 * Walk_state - Current walk state
303 * Return_desc - Where to store the return object
304 *
305 * RETURN: Status
306 *
307 * DESCRIPTION: Execute Type 2 dyadic operator with numeric operands and
308 * one or two result operands.
309 *
310 * ALLOCATION: Deletes one operand descriptor -- other remains on stack
311 *
312 ******************************************************************************/
313
314 acpi_status
315 acpi_ex_dyadic2_r (
316 u16 opcode,
317 acpi_walk_state *walk_state,
318 acpi_operand_object **return_desc)
319 {
320 acpi_operand_object **operand = &walk_state->operands[0];
321 acpi_operand_object *ret_desc = NULL;
322 acpi_operand_object *ret_desc2 = NULL;
323 acpi_status status = AE_OK;
324
325
326 FUNCTION_TRACE_U32 ("Ex_dyadic2_r", opcode);
327
328
329 /* Create an internal return object if necessary */
330
331 switch (opcode) {
332 case AML_ADD_OP:
333 case AML_BIT_AND_OP:
334 case AML_BIT_NAND_OP:
335 case AML_BIT_OR_OP:
336 case AML_BIT_NOR_OP:
337 case AML_BIT_XOR_OP:
338 case AML_DIVIDE_OP:
339 case AML_MOD_OP:
340 case AML_MULTIPLY_OP:
341 case AML_SHIFT_LEFT_OP:
342 case AML_SHIFT_RIGHT_OP:
343 case AML_SUBTRACT_OP:
344
345 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
346 if (!ret_desc) {
347 status = AE_NO_MEMORY;
348 goto cleanup;
349 }
350
351 break;
352 }
353
354
355 /*
356 * Execute the opcode
357 */
358 switch (opcode) {
359
360 /* Def_add := Add_op Operand1 Operand2 Result */
361
362 case AML_ADD_OP:
363
364 ret_desc->integer.value = operand[0]->integer.value +
365 operand[1]->integer.value;
366 break;
367
368
369 /* Def_and := And_op Operand1 Operand2 Result */
370
371 case AML_BIT_AND_OP:
372
373 ret_desc->integer.value = operand[0]->integer.value &
374 operand[1]->integer.value;
375 break;
376
377
378 /* Def_nAnd := NAnd_op Operand1 Operand2 Result */
379
380 case AML_BIT_NAND_OP:
381
382 ret_desc->integer.value = ~(operand[0]->integer.value &
383 operand[1]->integer.value);
384 break;
385
386
387 /* Def_or := Or_op Operand1 Operand2 Result */
388
389 case AML_BIT_OR_OP:
390
391 ret_desc->integer.value = operand[0]->integer.value |
392 operand[1]->integer.value;
393 break;
394
395
396 /* Def_nOr := NOr_op Operand1 Operand2 Result */
397
398 case AML_BIT_NOR_OP:
399
400 ret_desc->integer.value = ~(operand[0]->integer.value |
401 operand[1]->integer.value);
402 break;
403
404
405 /* Def_xOr := XOr_op Operand1 Operand2 Result */
406
407 case AML_BIT_XOR_OP:
408
409 ret_desc->integer.value = operand[0]->integer.value ^
410 operand[1]->integer.value;
411 break;
412
413
414 /* Def_divide := Divide_op Dividend Divisor Remainder Quotient */
415
416 case AML_DIVIDE_OP:
417
418 if (!operand[1]->integer.value) {
419 REPORT_ERROR
420 (("Divide_op: Divide by zero\n"));
421
422 status = AE_AML_DIVIDE_BY_ZERO;
423 goto cleanup;
424 }
425
426 ret_desc2 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
427 if (!ret_desc2) {
428 status = AE_NO_MEMORY;
429 goto cleanup;
430 }
431
432 /* Remainder (modulo) */
433
434 ret_desc->integer.value = ACPI_MODULO (operand[0]->integer.value,
435 operand[1]->integer.value);
436
437 /* Result (what we used to call the quotient) */
438
439 ret_desc2->integer.value = ACPI_DIVIDE (operand[0]->integer.value,
440 operand[1]->integer.value);
441 break;
442
443
444 /* Def_mod := Mod_op Dividend Divisor Remainder */
445
446 case AML_MOD_OP: /* ACPI 2.0 */
447
448 if (!operand[1]->integer.value) {
449 REPORT_ERROR
450 (("Mod_op: Divide by zero\n"));
451
452 status = AE_AML_DIVIDE_BY_ZERO;
453 goto cleanup;
454 }
455
456 /* Remainder (modulo) */
457
458 ret_desc->integer.value = ACPI_MODULO (operand[0]->integer.value,
459 operand[1]->integer.value);
460 break;
461
462
463 /* Def_multiply := Multiply_op Operand1 Operand2 Result */
464
465 case AML_MULTIPLY_OP:
466
467 ret_desc->integer.value = operand[0]->integer.value *
468 operand[1]->integer.value;
469 break;
470
471
472 /* Def_shift_left := Shift_left_op Operand Shift_count Result */
473
474 case AML_SHIFT_LEFT_OP:
475
476 ret_desc->integer.value = operand[0]->integer.value <<
477 operand[1]->integer.value;
478 break;
479
480
481 /* Def_shift_right := Shift_right_op Operand Shift_count Result */
482
483 case AML_SHIFT_RIGHT_OP:
484
485 ret_desc->integer.value = operand[0]->integer.value >>
486 operand[1]->integer.value;
487 break;
488
489
490 /* Def_subtract := Subtract_op Operand1 Operand2 Result */
491
492 case AML_SUBTRACT_OP:
493
494 ret_desc->integer.value = operand[0]->integer.value -
495 operand[1]->integer.value;
496 break;
497
498
499 /* Def_concat := Concat_op Data1 Data2 Result */
500
501 case AML_CONCAT_OP:
502
503 /*
504 * Convert the second operand if necessary. The first operand
505 * determines the type of the second operand, (See the Data Types
506 * section of the ACPI specification.) Both object types are
507 * guaranteed to be either Integer/String/Buffer by the operand
508 * resolution mechanism above.
509 */
510 switch (operand[0]->common.type) {
511 case ACPI_TYPE_INTEGER:
512 status = acpi_ex_convert_to_integer (operand[1], &operand[1], walk_state);
513 break;
514
515 case ACPI_TYPE_STRING:
516 status = acpi_ex_convert_to_string (operand[1], &operand[1], 16, ACPI_UINT32_MAX, walk_state);
517 break;
518
519 case ACPI_TYPE_BUFFER:
520 status = acpi_ex_convert_to_buffer (operand[1], &operand[1], walk_state);
521 break;
522
523 default:
524 status = AE_AML_INTERNAL;
525 }
526
527 if (ACPI_FAILURE (status)) {
528 goto cleanup;
529 }
530
531
532 /*
533 * Both operands are now known to be the same object type
534 * (Both are Integer, String, or Buffer), and we can now perform the
535 * concatenation.
536 */
537 status = acpi_ex_do_concatenate (operand[0], operand[1], &ret_desc, walk_state);
538 if (ACPI_FAILURE (status)) {
539 goto cleanup;
540 }
541 break;
542
543
544 /* Def_to_string := Buffer, Length, Result */
545
546 case AML_TO_STRING_OP: /* ACPI 2.0 */
547
548 status = acpi_ex_convert_to_string (operand[0], &ret_desc, 16,
549 (u32) operand[1]->integer.value, walk_state);
550 break;
551
552
553 /* Def_concat_res := Buffer, Buffer, Result */
554
555 case AML_CONCAT_RES_OP: /* ACPI 2.0 */
556
557 status = AE_NOT_IMPLEMENTED;
558 goto cleanup;
559 break;
560
561
562 default:
563
564 REPORT_ERROR (("Acpi_ex_dyadic2_r: Unknown dyadic opcode %X\n",
565 opcode));
566 status = AE_AML_BAD_OPCODE;
567 goto cleanup;
568 }
569
570
571 /*
572 * Store the result of the operation (which is now in Operand[0]) into
573 * the result descriptor, or the location pointed to by the result
574 * descriptor (Operand[2]).
575 */
576 status = acpi_ex_store (ret_desc, operand[2], walk_state);
577 if (ACPI_FAILURE (status)) {
578 goto cleanup;
579 }
580
581 if (AML_DIVIDE_OP == opcode) {
582 status = acpi_ex_store (ret_desc2, operand[3], walk_state);
583
584 /*
585 * Since the remainder is not returned, remove a reference to
586 * the object we created earlier
587 */
588 acpi_ut_remove_reference (ret_desc);
589 *return_desc = ret_desc2;
590 }
591
592 else {
593 *return_desc = ret_desc;
594 }
595
596
597 cleanup:
598
599 /* Always delete the operands */
600
601 acpi_ut_remove_reference (operand[0]);
602 acpi_ut_remove_reference (operand[1]);
603
604
605 /* Delete return object on error */
606
607 if (ACPI_FAILURE (status)) {
608 /* On failure, delete the result ops */
609
610 acpi_ut_remove_reference (operand[2]);
611 acpi_ut_remove_reference (operand[3]);
612
613 if (ret_desc) {
614 /* And delete the internal return object */
615
616 acpi_ut_remove_reference (ret_desc);
617 ret_desc = NULL;
618 }
619 }
620
621 /* Set the return object and exit */
622
623 return_ACPI_STATUS (status);
624 }
625
626
627 /*******************************************************************************
628 *
629 * FUNCTION: Acpi_ex_dyadic2_s
630 *
631 * PARAMETERS: Opcode - The opcode to be executed
632 * Walk_state - Current walk state
633 * Return_desc - Where to store the return object
634 *
635 * RETURN: Status
636 *
637 * DESCRIPTION: Execute Type 2 dyadic synchronization operator
638 *
639 * ALLOCATION: Deletes one operand descriptor -- other remains on stack
640 *
641 ******************************************************************************/
642
643 acpi_status
644 acpi_ex_dyadic2_s (
645 u16 opcode,
646 acpi_walk_state *walk_state,
647 acpi_operand_object **return_desc)
648 {
649 acpi_operand_object **operand = &walk_state->operands[0];
650 acpi_operand_object *ret_desc = NULL;
651 acpi_status status;
652
653
654 FUNCTION_TRACE_PTR ("Ex_dyadic2_s", WALK_OPERANDS);
655
656
657 /* Create the internal return object */
658
659 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
660 if (!ret_desc) {
661 status = AE_NO_MEMORY;
662 goto cleanup;
663 }
664
665 /* Default return value is FALSE, operation did not time out */
666
667 ret_desc->integer.value = 0;
668
669
670 /* Examine the opcode */
671
672 switch (opcode) {
673
674 /* Def_acquire := Acquire_op Mutex_object Timeout */
675
676 case AML_ACQUIRE_OP:
677
678 status = acpi_ex_acquire_mutex (operand[1], operand[0], walk_state);
679 break;
680
681
682 /* Def_wait := Wait_op Acpi_event_object Timeout */
683
684 case AML_WAIT_OP:
685
686 status = acpi_ex_system_wait_event (operand[1], operand[0]);
687 break;
688
689
690 default:
691
692 REPORT_ERROR (("Acpi_ex_dyadic2_s: Unknown dyadic synchronization opcode %X\n", opcode));
693 status = AE_AML_BAD_OPCODE;
694 goto cleanup;
695 }
696
697
698 /*
699 * Return a boolean indicating if operation timed out
700 * (TRUE) or not (FALSE)
701 */
702 if (status == AE_TIME) {
703 ret_desc->integer.value = ACPI_INTEGER_MAX; /* TRUE, op timed out */
704 status = AE_OK;
705 }
706
707
708 cleanup:
709
710 /* Delete params */
711
712 acpi_ut_remove_reference (operand[1]);
713 acpi_ut_remove_reference (operand[0]);
714
715 /* Delete return object on error */
716
717 if (ACPI_FAILURE (status) &&
718 (ret_desc)) {
719 acpi_ut_remove_reference (ret_desc);
720 ret_desc = NULL;
721 }
722
723
724 /* Set the return object and exit */
725
726 *return_desc = ret_desc;
727 return_ACPI_STATUS (status);
728 }
729
730
731 /*******************************************************************************
732 *
733 * FUNCTION: Acpi_ex_dyadic2
734 *
735 * PARAMETERS: Opcode - The opcode to be executed
736 * Walk_state - Current walk state
737 * Return_desc - Where to store the return object
738 *
739 * RETURN: Status
740 *
741 * DESCRIPTION: Execute Type 2 dyadic operator with numeric operands and
742 * no result operands
743 *
744 * ALLOCATION: Deletes one operand descriptor -- other remains on stack
745 * containing result value
746 *
747 ******************************************************************************/
748
749 acpi_status
750 acpi_ex_dyadic2 (
751 u16 opcode,
752 acpi_walk_state *walk_state,
753 acpi_operand_object **return_desc)
754 {
755 acpi_operand_object **operand = &walk_state->operands[0];
756 acpi_operand_object *ret_desc = NULL;
757 acpi_status status = AE_OK;
758 u8 lboolean;
759
760
761 FUNCTION_TRACE_PTR ("Ex_dyadic2", WALK_OPERANDS);
762
763
764 /* Create the internal return object */
765
766 ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
767 if (!ret_desc) {
768 status = AE_NO_MEMORY;
769 goto cleanup;
770 }
771
772 /*
773 * Execute the Opcode
774 */
775 lboolean = FALSE;
776 switch (opcode) {
777
778 /* Def_lAnd := LAnd_op Operand1 Operand2 */
779
780 case AML_LAND_OP:
781
782 lboolean = (u8) (operand[0]->integer.value &&
783 operand[1]->integer.value);
784 break;
785
786
787 /* Def_lEqual := LEqual_op Operand1 Operand2 */
788
789 case AML_LEQUAL_OP:
790
791 lboolean = (u8) (operand[0]->integer.value ==
792 operand[1]->integer.value);
793 break;
794
795
796 /* Def_lGreater := LGreater_op Operand1 Operand2 */
797
798 case AML_LGREATER_OP:
799
800 lboolean = (u8) (operand[0]->integer.value >
801 operand[1]->integer.value);
802 break;
803
804
805 /* Def_lLess := LLess_op Operand1 Operand2 */
806
807 case AML_LLESS_OP:
808
809 lboolean = (u8) (operand[0]->integer.value <
810 operand[1]->integer.value);
811 break;
812
813
814 /* Def_lOr := LOr_op Operand1 Operand2 */
815
816 case AML_LOR_OP:
817
818 lboolean = (u8) (operand[0]->integer.value ||
819 operand[1]->integer.value);
820 break;
821
822
823 /* Def_copy := Source, Destination */
824
825 case AML_COPY_OP: /* ACPI 2.0 */
826
827 status = AE_NOT_IMPLEMENTED;
828 goto cleanup;
829 break;
830
831
832 default:
833
834 REPORT_ERROR (("Acpi_ex_dyadic2: Unknown dyadic opcode %X\n", opcode));
835 status = AE_AML_BAD_OPCODE;
836 goto cleanup;
837 break;
838 }
839
840
841 /* Set return value to logical TRUE (all ones) or FALSE (zero) */
842
843 if (lboolean) {
844 ret_desc->integer.value = ACPI_INTEGER_MAX;
845 }
846 else {
847 ret_desc->integer.value = 0;
848 }
849
850
851 cleanup:
852
853 /* Always delete operands */
854
855 acpi_ut_remove_reference (operand[0]);
856 acpi_ut_remove_reference (operand[1]);
857
858
859 /* Delete return object on error */
860
861 if (ACPI_FAILURE (status) &&
862 (ret_desc)) {
863 acpi_ut_remove_reference (ret_desc);
864 ret_desc = NULL;
865 }
866
867
868 /* Set the return object and exit */
869
870 *return_desc = ret_desc;
871 return_ACPI_STATUS (status);
872 }
873
874
875