File: /usr/src/linux/drivers/acpi/dispatcher/dsmthdat.c

1     /*******************************************************************************
2      *
3      * Module Name: dsmthdat - control method arguments and local variables
4      *              $Revision: 49 $
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 "acdispat.h"
30     #include "acinterp.h"
31     #include "amlcode.h"
32     #include "acnamesp.h"
33     
34     
35     #define _COMPONENT          ACPI_DISPATCHER
36     	 MODULE_NAME         ("dsmthdat")
37     
38     
39     /*******************************************************************************
40      *
41      * FUNCTION:    Acpi_ds_method_data_init
42      *
43      * PARAMETERS:  Walk_state          - Current walk state object
44      *
45      * RETURN:      Status
46      *
47      * DESCRIPTION: Initialize the data structures that hold the method's arguments
48      *              and locals.  The data struct is an array of NTEs for each.
49      *              This allows Ref_of and De_ref_of to work properly for these
50      *              special data types.
51      *
52      ******************************************************************************/
53     
54     acpi_status
55     acpi_ds_method_data_init (
56     	acpi_walk_state         *walk_state)
57     {
58     	u32                     i;
59     
60     
61     	FUNCTION_TRACE ("Ds_method_data_init");
62     
63     	/*
64     	 * Walk_state fields are initialized to zero by the
65     	 * ACPI_MEM_CALLOCATE().
66     	 *
67     	 * An Node is assigned to each argument and local so
68     	 * that Ref_of() can return a pointer to the Node.
69     	 */
70     
71     	/* Init the method arguments */
72     
73     	for (i = 0; i < MTH_NUM_ARGS; i++) {
74     		MOVE_UNALIGNED32_TO_32 (&walk_state->arguments[i].name,
75     				 NAMEOF_ARG_NTE);
76     		walk_state->arguments[i].name      |= (i << 24);
77     		walk_state->arguments[i].data_type  = ACPI_DESC_TYPE_NAMED;
78     		walk_state->arguments[i].type       = ACPI_TYPE_ANY;
79     		walk_state->arguments[i].flags      = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
80     	}
81     
82     	/* Init the method locals */
83     
84     	for (i = 0; i < MTH_NUM_LOCALS; i++) {
85     		MOVE_UNALIGNED32_TO_32 (&walk_state->local_variables[i].name,
86     				 NAMEOF_LOCAL_NTE);
87     
88     		walk_state->local_variables[i].name  |= (i << 24);
89     		walk_state->local_variables[i].data_type = ACPI_DESC_TYPE_NAMED;
90     		walk_state->local_variables[i].type   = ACPI_TYPE_ANY;
91     		walk_state->local_variables[i].flags  = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
92     	}
93     
94     	return_ACPI_STATUS (AE_OK);
95     }
96     
97     
98     /*******************************************************************************
99      *
100      * FUNCTION:    Acpi_ds_method_data_delete_all
101      *
102      * PARAMETERS:  Walk_state          - Current walk state object
103      *
104      * RETURN:      Status
105      *
106      * DESCRIPTION: Delete method locals and arguments.  Arguments are only
107      *              deleted if this method was called from another method.
108      *
109      ******************************************************************************/
110     
111     acpi_status
112     acpi_ds_method_data_delete_all (
113     	acpi_walk_state         *walk_state)
114     {
115     	u32                     index;
116     	acpi_operand_object     *object;
117     
118     
119     	FUNCTION_TRACE ("Ds_method_data_delete_all");
120     
121     
122     	/* Delete the locals */
123     
124     	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting local variables in %p\n", walk_state));
125     
126     	for (index = 0; index < MTH_NUM_LOCALS; index++) {
127     		object = walk_state->local_variables[index].object;
128     		if (object) {
129     			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n", index, object));
130     
131     			/* Remove first */
132     
133     			walk_state->local_variables[index].object = NULL;
134     
135     			/* Was given a ref when stored */
136     
137     			acpi_ut_remove_reference (object);
138     	   }
139     	}
140     
141     
142     	/* Delete the arguments */
143     
144     	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting arguments in %p\n", walk_state));
145     
146     	for (index = 0; index < MTH_NUM_ARGS; index++) {
147     		object = walk_state->arguments[index].object;
148     		if (object) {
149     			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n", index, object));
150     
151     			/* Remove first */
152     
153     			walk_state->arguments[index].object = NULL;
154     
155     			 /* Was given a ref when stored */
156     
157     			acpi_ut_remove_reference (object);
158     		}
159     	}
160     
161     	return_ACPI_STATUS (AE_OK);
162     }
163     
164     
165     /*******************************************************************************
166      *
167      * FUNCTION:    Acpi_ds_method_data_init_args
168      *
169      * PARAMETERS:  *Params         - Pointer to a parameter list for the method
170      *              Max_param_count - The arg count for this method
171      *              Walk_state      - Current walk state object
172      *
173      * RETURN:      Status
174      *
175      * DESCRIPTION: Initialize arguments for a method
176      *
177      ******************************************************************************/
178     
179     acpi_status
180     acpi_ds_method_data_init_args (
181     	acpi_operand_object     **params,
182     	u32                     max_param_count,
183     	acpi_walk_state         *walk_state)
184     {
185     	acpi_status             status;
186     	u32                     mindex;
187     	u32                     pindex;
188     
189     
190     	FUNCTION_TRACE_PTR ("Ds_method_data_init_args", params);
191     
192     
193     	if (!params) {
194     		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
195     		return_ACPI_STATUS (AE_OK);
196     	}
197     
198     	/* Copy passed parameters into the new method stack frame  */
199     
200     	for (pindex = mindex = 0;
201     		(mindex < MTH_NUM_ARGS) && (pindex < max_param_count);
202     		mindex++) {
203     		if (params[pindex]) {
204     			/*
205     			 * A valid parameter.
206     			 * Set the current method argument to the
207     			 * Params[Pindex++] argument object descriptor
208     			 */
209     			status = acpi_ds_store_object_to_local (AML_ARG_OP, mindex,
210     					  params[pindex], walk_state);
211     			if (ACPI_FAILURE (status)) {
212     				break;
213     			}
214     
215     			pindex++;
216     		}
217     
218     		else {
219     			break;
220     		}
221     	}
222     
223     	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", pindex));
224     	return_ACPI_STATUS (AE_OK);
225     }
226     
227     
228     /*******************************************************************************
229      *
230      * FUNCTION:    Acpi_ds_method_data_get_entry
231      *
232      * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
233      *              Index               - Which local_var or argument to get
234      *              Entry               - Pointer to where a pointer to the stack
235      *                                    entry is returned.
236      *              Walk_state          - Current walk state object
237      *
238      * RETURN:      Status
239      *
240      * DESCRIPTION: Get the address of the object entry given by Opcode:Index
241      *
242      ******************************************************************************/
243     
244     acpi_status
245     acpi_ds_method_data_get_entry (
246     	u16                     opcode,
247     	u32                     index,
248     	acpi_walk_state         *walk_state,
249     	acpi_operand_object     ***entry)
250     {
251     
252     	FUNCTION_TRACE_U32 ("Ds_method_data_get_entry", index);
253     
254     
255     	/*
256     	 * Get the requested object.
257     	 * The stack "Opcode" is either a Local_variable or an Argument
258     	 */
259     	switch (opcode) {
260     
261     	case AML_LOCAL_OP:
262     
263     		if (index > MTH_MAX_LOCAL) {
264     			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local_var index %d is invalid (max %d)\n",
265     				index, MTH_MAX_LOCAL));
266     			return_ACPI_STATUS (AE_BAD_PARAMETER);
267     		}
268     
269     		*entry = (acpi_operand_object  **)
270     				 &walk_state->local_variables[index].object;
271     		break;
272     
273     
274     	case AML_ARG_OP:
275     
276     		if (index > MTH_MAX_ARG) {
277     			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)\n",
278     				index, MTH_MAX_ARG));
279     			return_ACPI_STATUS (AE_BAD_PARAMETER);
280     		}
281     
282     		*entry = (acpi_operand_object  **)
283     				 &walk_state->arguments[index].object;
284     		break;
285     
286     
287     	default:
288     		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Opcode %d is invalid\n", opcode));
289     		return_ACPI_STATUS (AE_BAD_PARAMETER);
290     	}
291     
292     
293     	return_ACPI_STATUS (AE_OK);
294     }
295     
296     
297     /*******************************************************************************
298      *
299      * FUNCTION:    Acpi_ds_method_data_set_entry
300      *
301      * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
302      *              Index               - Which local_var or argument to get
303      *              Object              - Object to be inserted into the stack entry
304      *              Walk_state          - Current walk state object
305      *
306      * RETURN:      Status
307      *
308      * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
309      *
310      ******************************************************************************/
311     
312     acpi_status
313     acpi_ds_method_data_set_entry (
314     	u16                     opcode,
315     	u32                     index,
316     	acpi_operand_object     *object,
317     	acpi_walk_state         *walk_state)
318     {
319     	acpi_status             status;
320     	acpi_operand_object     **entry;
321     
322     
323     	FUNCTION_TRACE ("Ds_method_data_set_entry");
324     
325     
326     	/* Get a pointer to the stack entry to set */
327     
328     	status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
329     	if (ACPI_FAILURE (status)) {
330     		return_ACPI_STATUS (status);
331     	}
332     
333     	/* Increment ref count so object can't be deleted while installed */
334     
335     	acpi_ut_add_reference (object);
336     
337     	/* Install the object into the stack entry */
338     
339     	*entry = object;
340     
341     	return_ACPI_STATUS (AE_OK);
342     }
343     
344     
345     /*******************************************************************************
346      *
347      * FUNCTION:    Acpi_ds_method_data_get_type
348      *
349      * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
350      *              Index               - Which local_var or argument whose type
351      *                                      to get
352      *              Walk_state          - Current walk state object
353      *
354      * RETURN:      Data type of selected Arg or Local
355      *              Used only in Exec_monadic2()/Type_op.
356      *
357      ******************************************************************************/
358     
359     acpi_object_type8
360     acpi_ds_method_data_get_type (
361     	u16                     opcode,
362     	u32                     index,
363     	acpi_walk_state         *walk_state)
364     {
365     	acpi_status             status;
366     	acpi_operand_object     **entry;
367     	acpi_operand_object     *object;
368     
369     
370     	FUNCTION_TRACE ("Ds_method_data_get_type");
371     
372     
373     	/* Get a pointer to the requested stack entry */
374     
375     	status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
376     	if (ACPI_FAILURE (status)) {
377     		return_VALUE ((ACPI_TYPE_NOT_FOUND));
378     	}
379     
380     	/* Get the object from the method stack */
381     
382     	object = *entry;
383     
384     	/* Get the object type */
385     
386     	if (!object) {
387     		/* Any == 0 => "uninitialized" -- see spec 15.2.3.5.2.28 */
388     		return_VALUE (ACPI_TYPE_ANY);
389     	}
390     
391     	return_VALUE (object->common.type);
392     }
393     
394     
395     /*******************************************************************************
396      *
397      * FUNCTION:    Acpi_ds_method_data_get_node
398      *
399      * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
400      *              Index               - Which local_var or argument whose type
401      *                                      to get
402      *              Walk_state          - Current walk state object
403      *
404      * RETURN:      Get the Node associated with a local or arg.
405      *
406      ******************************************************************************/
407     
408     acpi_namespace_node *
409     acpi_ds_method_data_get_node (
410     	u16                     opcode,
411     	u32                     index,
412     	acpi_walk_state         *walk_state)
413     {
414     	acpi_namespace_node     *node = NULL;
415     
416     
417     	FUNCTION_TRACE ("Ds_method_data_get_node");
418     
419     
420     	switch (opcode) {
421     
422     	case AML_LOCAL_OP:
423     
424     		if (index > MTH_MAX_LOCAL) {
425     			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local index %d is invalid (max %d)\n",
426     				index, MTH_MAX_LOCAL));
427     			return_PTR (node);
428     		}
429     
430     		node =  &walk_state->local_variables[index];
431     		break;
432     
433     
434     	case AML_ARG_OP:
435     
436     		if (index > MTH_MAX_ARG) {
437     			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)\n",
438     				index, MTH_MAX_ARG));
439     			return_PTR (node);
440     		}
441     
442     		node = &walk_state->arguments[index];
443     		break;
444     
445     
446     	default:
447     		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Opcode %d is invalid\n", opcode));
448     		break;
449     	}
450     
451     
452     	return_PTR (node);
453     }
454     
455     
456     /*******************************************************************************
457      *
458      * FUNCTION:    Acpi_ds_method_data_get_value
459      *
460      * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
461      *              Index               - Which local_var or argument to get
462      *              Walk_state          - Current walk state object
463      *              *Dest_desc          - Ptr to Descriptor into which selected Arg
464      *                                    or Local value should be copied
465      *
466      * RETURN:      Status
467      *
468      * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
469      *              at the current top of the method stack.
470      *              Used only in Acpi_ex_resolve_to_value().
471      *
472      ******************************************************************************/
473     
474     acpi_status
475     acpi_ds_method_data_get_value (
476     	u16                     opcode,
477     	u32                     index,
478     	acpi_walk_state         *walk_state,
479     	acpi_operand_object     **dest_desc)
480     {
481     	acpi_status             status;
482     	acpi_operand_object     **entry;
483     	acpi_operand_object     *object;
484     
485     
486     	FUNCTION_TRACE ("Ds_method_data_get_value");
487     
488     
489     	/* Validate the object descriptor */
490     
491     	if (!dest_desc) {
492     		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null object descriptor pointer\n"));
493     		return_ACPI_STATUS (AE_BAD_PARAMETER);
494     	}
495     
496     
497     	/* Get a pointer to the requested method stack entry */
498     
499     	status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
500     	if (ACPI_FAILURE (status)) {
501     		return_ACPI_STATUS (status);
502     	}
503     
504     	/* Get the object from the method stack */
505     
506     	object = *entry;
507     
508     
509     	/* Examine the returned object, it must be valid. */
510     
511     	if (!object) {
512     		/*
513     		 * Index points to uninitialized object stack value.
514     		 * This means that either 1) The expected argument was
515     		 * not passed to the method, or 2) A local variable
516     		 * was referenced by the method (via the ASL)
517     		 * before it was initialized.  Either case is an error.
518     		 */
519     		switch (opcode) {
520     		case AML_ARG_OP:
521     
522     			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at entry %p\n",
523     				index, entry));
524     
525     			return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
526     			break;
527     
528     		case AML_LOCAL_OP:
529     
530     			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Local[%d] at entry %p\n",
531     				index, entry));
532     
533     			return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
534     			break;
535     		}
536     	}
537     
538     
539     	/*
540     	 * Index points to initialized and valid object stack value.
541     	 * Return an additional reference to the object
542     	 */
543     	*dest_desc = object;
544     	acpi_ut_add_reference (object);
545     
546     	return_ACPI_STATUS (AE_OK);
547     }
548     
549     
550     /*******************************************************************************
551      *
552      * FUNCTION:    Acpi_ds_method_data_delete_value
553      *
554      * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
555      *              Index               - Which local_var or argument to delete
556      *              Walk_state          - Current walk state object
557      *
558      * RETURN:      Status
559      *
560      * DESCRIPTION: Delete the entry at Opcode:Index on the method stack.  Inserts
561      *              a null into the stack slot after the object is deleted.
562      *
563      ******************************************************************************/
564     
565     acpi_status
566     acpi_ds_method_data_delete_value (
567     	u16                     opcode,
568     	u32                     index,
569     	acpi_walk_state         *walk_state)
570     {
571     	acpi_status             status;
572     	acpi_operand_object     **entry;
573     	acpi_operand_object     *object;
574     
575     
576     	FUNCTION_TRACE ("Ds_method_data_delete_value");
577     
578     
579     	/* Get a pointer to the requested entry */
580     
581     	status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
582     	if (ACPI_FAILURE (status)) {
583     		return_ACPI_STATUS (status);
584     	}
585     
586     	/* Get the current entry in this slot k */
587     
588     	object = *entry;
589     
590     	/*
591     	 * Undefine the Arg or Local by setting its descriptor
592     	 * pointer to NULL. Locals/Args can contain both
593     	 * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
594     	 */
595     	*entry = NULL;
596     
597     	if ((object) &&
598     		(VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL))) {
599     		/*
600     		 * There is a valid object in this slot
601     		 * Decrement the reference count by one to balance the
602     		 * increment when the object was stored in the slot.
603     		 */
604     		acpi_ut_remove_reference (object);
605     	}
606     
607     	return_ACPI_STATUS (AE_OK);
608     }
609     
610     
611     /*******************************************************************************
612      *
613      * FUNCTION:    Acpi_ds_store_object_to_local
614      *
615      * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
616      *              Index               - Which local_var or argument to set
617      *              Src_desc            - Value to be stored
618      *              Walk_state          - Current walk state
619      *
620      * RETURN:      Status
621      *
622      * DESCRIPTION: Store a value in an Arg or Local.  The Src_desc is installed
623      *              as the new value for the Arg or Local and the reference count
624      *              for Src_desc is incremented.
625      *
626      ******************************************************************************/
627     
628     acpi_status
629     acpi_ds_store_object_to_local (
630     	u16                     opcode,
631     	u32                     index,
632     	acpi_operand_object     *src_desc,
633     	acpi_walk_state         *walk_state)
634     {
635     	acpi_status             status;
636     	acpi_operand_object     **entry;
637     
638     
639     	FUNCTION_TRACE ("Ds_method_data_set_value");
640     	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n",
641     		opcode, index, src_desc));
642     
643     
644     	/* Parameter validation */
645     
646     	if (!src_desc) {
647     		return_ACPI_STATUS (AE_BAD_PARAMETER);
648     	}
649     
650     
651     	/* Get a pointer to the requested method stack entry */
652     
653     	status = acpi_ds_method_data_get_entry (opcode, index, walk_state, &entry);
654     	if (ACPI_FAILURE (status)) {
655     		goto cleanup;
656     	}
657     
658     	if (*entry == src_desc) {
659     		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n", src_desc));
660     		goto cleanup;
661     	}
662     
663     
664     	/*
665     	 * If there is an object already in this slot, we either
666     	 * have to delete it, or if this is an argument and there
667     	 * is an object reference stored there, we have to do
668     	 * an indirect store!
669     	 */
670     	if (*entry) {
671     		/*
672     		 * Check for an indirect store if an argument
673     		 * contains an object reference (stored as an Node).
674     		 * We don't allow this automatic dereferencing for
675     		 * locals, since a store to a local should overwrite
676     		 * anything there, including an object reference.
677     		 *
678     		 * If both Arg0 and Local0 contain Ref_of (Local4):
679     		 *
680     		 * Store (1, Arg0)             - Causes indirect store to local4
681     		 * Store (1, Local0)           - Stores 1 in local0, overwriting
682     		 *                                  the reference to local4
683     		 * Store (1, De_refof (Local0)) - Causes indirect store to local4
684     		 *
685     		 * Weird, but true.
686     		 */
687     		if ((opcode == AML_ARG_OP) &&
688     			(VALID_DESCRIPTOR_TYPE (*entry, ACPI_DESC_TYPE_NAMED))) {
689     			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
690     				"Arg (%p) is an Obj_ref(Node), storing in %p\n",
691     				src_desc, *entry));
692     
693     			/* Detach an existing object from the Node */
694     
695     			acpi_ns_detach_object ((acpi_namespace_node *) *entry);
696     
697     			/*
698     			 * Store this object into the Node
699     			 * (do the indirect store)
700     			 */
701     			status = acpi_ns_attach_object ((acpi_namespace_node *) *entry, src_desc,
702     					   src_desc->common.type);
703     			return_ACPI_STATUS (status);
704     		}
705     
706     
707     #ifdef ACPI_ENABLE_IMPLICIT_CONVERSION
708     		/*
709     		 * Perform "Implicit conversion" of the new object to the type of the
710     		 * existing object
711     		 */
712     		status = acpi_ex_convert_to_target_type ((*entry)->common.type, &src_desc, walk_state);
713     		if (ACPI_FAILURE (status)) {
714     			goto cleanup;
715     		}
716     #endif
717     
718     		/*
719     		 * Delete the existing object
720     		 * before storing the new one
721     		 */
722     		acpi_ds_method_data_delete_value (opcode, index, walk_state);
723     	}
724     
725     
726     	/*
727     	 * Install the Obj_stack descriptor (*Src_desc) into
728     	 * the descriptor for the Arg or Local.
729     	 * Install the new object in the stack entry
730     	 * (increments the object reference count by one)
731     	 */
732     	status = acpi_ds_method_data_set_entry (opcode, index, src_desc, walk_state);
733     	if (ACPI_FAILURE (status)) {
734     		goto cleanup;
735     	}
736     
737     	/* Normal exit */
738     
739     	return_ACPI_STATUS (AE_OK);
740     
741     
742     	/* Error exit */
743     
744     cleanup:
745     
746     	return_ACPI_STATUS (status);
747     }
748     
749