File: /usr/src/linux/drivers/acpi/ospm/thermal/tz.c

1     /*****************************************************************************
2      *
3      * Module Name: tz.c
4      *   $Revision: 40 $
5      *
6      *****************************************************************************/
7     
8     /*
9      *  Copyright (C) 2000, 2001 Andrew Grover
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      * TBD: 1. Finish /proc interface (threshold values, _SCP changes, etc.)
28      *	2. Update policy for ACPI 2.0 compliance
29      *	3. Check for all required methods prior to enabling a threshold
30      *	4. Support for multiple processors in a zone (passive cooling devices)
31      */
32     
33     #include <acpi.h>
34     #include <bm.h>
35     #include "tz.h"
36     
37     #define _COMPONENT		ACPI_THERMAL
38     	MODULE_NAME		("tz")
39     
40     
41     /****************************************************************************
42      *                            Internal Functions
43      ****************************************************************************/
44     
45     /****************************************************************************
46      *
47      * FUNCTION:    tz_print
48      *
49      * PARAMETERS:
50      *
51      * RETURN:
52      *
53      * DESCRIPTION: Prints out information on a specific thermal zone.
54      *
55      ****************************************************************************/
56     
57     void
58     tz_print (
59     	TZ_CONTEXT		*thermal_zone)
60     {
61     #ifdef ACPI_DEBUG
62     	acpi_buffer		buffer;
63     	u32			i,j = 0;
64     	TZ_THRESHOLD            *threshold = NULL;
65     
66     	PROC_NAME("tz_print");
67     
68     	if (!thermal_zone) {
69     		return;
70     	}
71     
72     	buffer.length = 256;
73     	buffer.pointer = acpi_os_callocate(buffer.length);
74     	if (!buffer.pointer) {
75     		return;
76     	}
77     
78     	/*
79     	 * Get the full pathname for this ACPI object.
80     	 */
81     	acpi_get_name(thermal_zone->acpi_handle, ACPI_FULL_PATHNAME, &buffer);
82     
83     	/*
84     	 * Print out basic thermal zone information.
85     	 */
86     	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n"));
87     	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Thermal_zone[%02x]:[%p] %s\n", thermal_zone->device_handle, thermal_zone->acpi_handle, buffer.pointer));
88     	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "|   temperature[%d] state[%08x]\n", thermal_zone->policy.temperature, thermal_zone->policy.state));
89     	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "|   cooling_mode[%08x] polling_freq[%d]\n", thermal_zone->policy.cooling_mode, thermal_zone->policy.polling_freq));
90     
91     	for (i=0; i<thermal_zone->policy.threshold_list.count; i++) {
92     
93     		threshold = &(thermal_zone->policy.threshold_list.thresholds[i]);
94     
95     		switch (threshold->type) {
96     		case TZ_THRESHOLD_CRITICAL:
97     			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "|   critical[%d]\n", threshold->temperature));
98     			break;
99     		case TZ_THRESHOLD_PASSIVE:
100     			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "|   passive[%d]: tc1[%d] tc2[%d] tsp[%d]\n", threshold->temperature, thermal_zone->policy.passive.tc1, thermal_zone->policy.passive.tc2, thermal_zone->policy.passive.tsp));
101     			break;
102     		case TZ_THRESHOLD_ACTIVE:
103     			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "|   active[%d]: index[%d]\n", threshold->temperature, threshold->index));
104     			break;
105     		default:
106     			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "|   unknown[%d]\n", threshold->temperature));
107     			break;
108     		}
109     
110     		if (threshold->cooling_devices.count > 0) {
111     			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "|     cooling_devices"));
112     			for (j=0; (j<threshold->cooling_devices.count && j<10); j++) {
113     				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "[%02x]", threshold->cooling_devices.handles[j]));
114     			}
115     			
116     			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "\n"));
117     		}
118     	}
119     
120     	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n"));
121     
122     	acpi_os_free(buffer.pointer);
123     #endif /*ACPI_DEBUG*/
124     
125     	return;
126     }
127     
128     
129     /****************************************************************************
130      *
131      * FUNCTION:    tz_get_temperaturee
132      *
133      * PARAMETERS:
134      *
135      * RETURN:
136      *
137      * DESCRIPTION:
138      *
139      ****************************************************************************/
140     
141     acpi_status
142     tz_get_temperature (
143     	TZ_CONTEXT              *thermal_zone,
144     	u32                     *temperature)
145     {
146     	acpi_status             status = AE_OK;
147     
148     	FUNCTION_TRACE("tz_get_temperature");
149     
150     	if (!thermal_zone || !temperature) {
151     		return_ACPI_STATUS(AE_BAD_PARAMETER);
152     	}
153     
154     	/*
155     	 * Evaluate the _TMP driver method to get the current temperature.
156     	 */
157     	status = bm_evaluate_simple_integer(thermal_zone->acpi_handle,
158     		"_TMP", temperature);
159     
160     	return_ACPI_STATUS(status);
161     }
162     
163     
164     /****************************************************************************
165      *
166      * FUNCTION:    tz_set_cooling_preference
167      *
168      * PARAMETERS:
169      *
170      * RETURN:
171      *
172      * DESCRIPTION:
173      *
174      ****************************************************************************/
175     
176     acpi_status
177     tz_set_cooling_preference (
178     	TZ_CONTEXT              *thermal_zone,
179     	TZ_COOLING_MODE         cooling_mode)
180     {
181     	acpi_status             status = AE_OK;
182     	acpi_object_list        arg_list;
183     	acpi_object             arg0;
184     
185     	FUNCTION_TRACE("tz_set_cooling_preference");
186     
187     	if (!thermal_zone || ((cooling_mode != TZ_COOLING_MODE_ACTIVE) &&
188     		(cooling_mode != TZ_COOLING_MODE_PASSIVE))) {
189     		return_ACPI_STATUS(AE_BAD_PARAMETER);
190     	}
191     
192     	/*
193     	 * Build the argument list, which simply consists of the current
194     	 * cooling preference.
195     	 */
196     	MEMSET(&arg_list, 0, sizeof(acpi_object));
197     	arg_list.count = 1;
198     	arg_list.pointer = &arg0;
199     
200     	MEMSET(&arg0, 0, sizeof(acpi_object));
201     	arg0.type = ACPI_TYPE_INTEGER;
202     	arg0.integer.value = cooling_mode;
203     
204     	/*
205     	 * Evaluate "_SCP" - setting the new cooling preference.
206     	 */
207     	status = acpi_evaluate_object(thermal_zone->acpi_handle, "_SCP",
208     		&arg_list, NULL);
209     
210     	return_ACPI_STATUS(status);
211     }
212     
213     
214     /***************************************************************************
215      *
216      * FUNCTION:    tz_get_single_threshold
217      *
218      * PARAMETERS:
219      *
220      * RETURN:
221      *
222      * DESCRIPTION:
223      *
224      ****************************************************************************/
225     
226     acpi_status
227     tz_get_single_threshold (
228     	TZ_CONTEXT              *thermal_zone,
229     	TZ_THRESHOLD            *threshold)
230     {
231     	acpi_status             status = AE_OK;
232     
233     	FUNCTION_TRACE("tz_get_single_threshold");
234     
235     	if (!thermal_zone || !threshold) {
236     		return_ACPI_STATUS(AE_BAD_PARAMETER);
237     	}
238     
239     	switch (threshold->type) {
240     
241     	/*
242     	 * Critical Threshold:
243     	 * -------------------
244     	 */
245     	case TZ_THRESHOLD_CRITICAL:
246     		threshold->index = 0;
247     		threshold->cooling_devices.count = 0;
248     		status = bm_evaluate_simple_integer(
249     			thermal_zone->acpi_handle, "_CRT",
250     			&(threshold->temperature));
251     		break;
252     
253     	/*
254     	 * Passive Threshold:
255     	 * ------------------
256     	 * Evaluate _PSV to get the threshold temperature and _PSL to get
257     	 * references to all passive cooling devices.
258     	 */
259     	case TZ_THRESHOLD_PASSIVE:
260     		threshold->index = 0;
261     		threshold->cooling_devices.count = 0;
262     		status = bm_evaluate_simple_integer(
263     			thermal_zone->acpi_handle, "_PSV",
264     			&(threshold->temperature));
265     		if (ACPI_SUCCESS(status)) {
266     			status = bm_evaluate_reference_list(
267     				thermal_zone->acpi_handle, "_PSL",
268     				&(threshold->cooling_devices));
269     		}
270     
271     		break;
272     
273     	/*
274     	 * Active Thresholds:
275     	 * ------------------
276     	 * Evaluate _ACx to get all threshold temperatures, and _ALx to get
277     	 * references to all passive cooling devices.
278     	 */
279     	case TZ_THRESHOLD_ACTIVE:
280     		 {
281     			char object_name[5] = {'_','A', 'C',
282     				('0'+threshold->index),'\0'};
283     			status = bm_evaluate_simple_integer(
284     				thermal_zone->acpi_handle, object_name,
285     				&(threshold->temperature));
286     			if (ACPI_SUCCESS(status)) {
287     				object_name[2] = 'L';
288     				status = bm_evaluate_reference_list(
289     					thermal_zone->acpi_handle,
290     					object_name,
291     					&(threshold->cooling_devices));
292     			}
293     		}
294     		break;
295     
296     	default:
297     		status = AE_SUPPORT;
298     		break;
299     	}
300     
301     	return_ACPI_STATUS(status);
302     }
303     
304     
305     /****************************************************************************
306      *
307      * FUNCTION:    tz_get_thresholds
308      *
309      * PARAMETERS:  thermal_zone          - Identifies the thermal zone to parse.
310      *              buffer      - Output buffer.
311      *
312      * RETURN:      acpi_status result code.
313      *
314      * DESCRIPTION: Builds a TZ_THRESHOLD_LIST structure containing information
315      *              on all thresholds for a given thermal zone.
316      *
317      * NOTES:       The current design limits the number of cooling devices
318      *              per theshold to the value specified by BM_MAX_HANDLES.
319      *              This simplifies parsing of thresholds by allowing a maximum
320      *              threshold list size to be computed (and enforced) -- which
321      *              allows all thresholds to be parsed in a single pass (since
322      *              memory must be contiguous when returned in the acpi_buffer).
323      *
324      ****************************************************************************/
325     
326     acpi_status
327     tz_get_thresholds (
328     	TZ_CONTEXT              *thermal_zone,
329     	TZ_THRESHOLD_LIST       *threshold_list)
330     {
331     	acpi_status             status = AE_OK;
332     	TZ_THRESHOLD            *threshold = NULL;
333     	u32                     i = 0;
334     
335     	FUNCTION_TRACE("tz_get_thresholds");
336     
337     	if (!thermal_zone || !threshold_list) {
338     		return_ACPI_STATUS(AE_BAD_PARAMETER);
339     	}
340     
341     	threshold_list->count = 0;
342     
343     	/*
344     	 * Critical threshold:
345     	 * -------------------
346     	 * Every thermal zone must have one!
347     	 */
348     	threshold = &(threshold_list->thresholds[threshold_list->count]);
349     	threshold->type = TZ_THRESHOLD_CRITICAL;
350     
351     	status = tz_get_single_threshold(thermal_zone, threshold);
352     	if (ACPI_SUCCESS(status)) {
353     		(threshold_list->count)++;
354     	}
355     	else {
356     		return_ACPI_STATUS(status);
357     	}
358     
359     
360     	/*
361     	 * Passive threshold:
362     	 * ------------------
363     	 */
364     	threshold = &(threshold_list->thresholds[threshold_list->count]);
365     	threshold->type = TZ_THRESHOLD_PASSIVE;
366     
367     	status = tz_get_single_threshold(thermal_zone, threshold);
368     	if (ACPI_SUCCESS(status)) {
369     		(threshold_list->count)++;
370     	}
371     
372     	/*
373     	 * Active threshold:
374     	 * -----------------
375     	 * Note that active thresholds are sorted by index (e.g. _AC0,
376     	 * _AC1, ...), and thus from highest (_AC0) to lowest (_AC9)
377     	 * temperature.
378     	 */
379     	for (i = 0; i < TZ_MAX_ACTIVE_THRESHOLDS; i++) {
380     
381     		threshold = &(threshold_list->thresholds[threshold_list->count]);
382     		threshold->type = TZ_THRESHOLD_ACTIVE;
383     		threshold->index = i;
384     
385     		status = tz_get_single_threshold(thermal_zone, threshold);
386     		if (ACPI_SUCCESS(status)) {
387     			(threshold_list->count)++;
388     		}
389     		else {
390     			threshold->type = TZ_THRESHOLD_UNKNOWN;
391     			threshold->index = 0;
392     			thermal_zone->policy.active.threshold_count = i;
393     			break;
394     		}
395     	}
396     
397     	return_ACPI_STATUS(AE_OK);
398     }
399     
400     
401     /****************************************************************************
402      *
403      * FUNCTION:    tz_add_device
404      *
405      * PARAMETERS:  <none>
406      *
407      * RETURN:	
408      *
409      * DESCRIPTION:
410      *
411      ****************************************************************************/
412     
413     acpi_status
414     tz_add_device (
415     	BM_HANDLE               device_handle,
416     	void                    **context)
417     {
418     	acpi_status             status = AE_OK;
419     	TZ_CONTEXT              *thermal_zone = NULL;
420     	BM_DEVICE		*device = NULL;
421     	acpi_handle             tmp_handle = NULL;
422     	static u32		zone_count = 0;
423     
424     	FUNCTION_TRACE("tz_add_device");
425     
426     	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding thermal zone [%02x].\n", device_handle));
427     
428     	if (!context || *context) {
429     		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Invalid context for device [%02x].\n", device_handle));
430     		return_ACPI_STATUS(AE_BAD_PARAMETER);
431     	}
432     
433     	/*
434     	 * Get information on this device.
435     	 */
436     	status = bm_get_device_info(device_handle, &device);
437     	if (ACPI_FAILURE(status)) {
438     		return_ACPI_STATUS(status);
439     	}
440     
441     	/*
442     	 * Allocate a new Thermal Zone device.
443     	 */
444     	thermal_zone = acpi_os_callocate(sizeof(TZ_CONTEXT));
445     	if (!thermal_zone) {
446     		return AE_NO_MEMORY;
447     	}
448     
449     	thermal_zone->device_handle = device->handle;
450     	thermal_zone->acpi_handle = device->acpi_handle;
451     
452     	/* TBD: How to manage 'uid' when zones are Pn_p? */
453     	sprintf(thermal_zone->uid, "%d", zone_count++);
454     
455     	/*
456     	 * _TMP?
457     	 * -----
458     	 */
459     	status = acpi_get_handle(thermal_zone->acpi_handle, "_TMP",
460     		&tmp_handle);
461     	if (ACPI_FAILURE(status)) {
462     		goto end;
463     	}
464     
465     	/*
466     	 * Initialize Policy:
467     	 * ------------------
468     	 * TBD: Move all thermal zone policy to user-mode daemon...
469     	 */
470     	status = tz_policy_add_device(thermal_zone);
471     	if (ACPI_FAILURE(status)) {
472     		goto end;
473     	}
474     
475     	status = tz_osl_add_device(thermal_zone);
476     	if (ACPI_FAILURE(status)) {
477     		goto end;
478     	}
479     
480     	*context = thermal_zone;
481     
482     	tz_print(thermal_zone);
483     
484     end:
485     	if (ACPI_FAILURE(status)) {
486     		acpi_os_free(thermal_zone);
487     	}
488     
489     	return_ACPI_STATUS(status);
490     }
491     
492     
493     /****************************************************************************
494      *
495      * FUNCTION:    tz_remove_device
496      *
497      * PARAMETERS:  <none>
498      *
499      * RETURN:	
500      *
501      * DESCRIPTION:
502      *
503      ****************************************************************************/
504     
505     acpi_status
506     tz_remove_device (
507     	void			**context)
508     {
509     	acpi_status		status = AE_OK;
510     	TZ_CONTEXT		*thermal_zone = NULL;
511     
512     	FUNCTION_TRACE("tz_remove_device");
513     
514     	if (!context || !*context) {
515     		return_ACPI_STATUS(AE_BAD_PARAMETER);
516     	}
517     
518     	thermal_zone = (TZ_CONTEXT*)(*context);
519     
520     	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing thermal zone [%02x].\n", thermal_zone->device_handle));
521     
522     	status = tz_osl_remove_device(thermal_zone);
523     
524     	/*
525     	 * Remove Policy:
526     	 * --------------
527     	 * TBD: Move all thermal zone policy to user-mode daemon...
528     	 */
529     	status = tz_policy_remove_device(thermal_zone);
530     	if (ACPI_FAILURE(status)) {
531     		return_ACPI_STATUS(status);
532     	}
533     
534     	acpi_os_free(thermal_zone);
535     
536     	return_ACPI_STATUS(status);
537     }
538     
539     
540     /****************************************************************************
541      *                            External Functions
542      ****************************************************************************/
543     
544     /****************************************************************************
545      *
546      * FUNCTION:    tz_initialize
547      *
548      * PARAMETERS:  <none>
549      *
550      * RETURN:	
551      *
552      * DESCRIPTION:
553      *
554      ****************************************************************************/
555     
556     acpi_status
557     tz_initialize (void)
558     {
559     	acpi_status             status = AE_OK;
560     	BM_DEVICE_ID		criteria;
561     	BM_DRIVER		driver;
562     
563     	FUNCTION_TRACE("tz_initialize");
564     
565     	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
566     	MEMSET(&driver, 0, sizeof(BM_DRIVER));
567     
568     	/*
569     	 * Register driver for thermal zone devices.
570     	 */
571     	criteria.type = BM_TYPE_THERMAL_ZONE;
572     
573     	driver.notify = &tz_notify;
574     	driver.request = &tz_request;
575     
576     	status = bm_register_driver(&criteria, &driver);
577     
578     	return_ACPI_STATUS(status);
579     }
580     
581     
582     /****************************************************************************
583      *
584      * FUNCTION:    tz_terminate
585      *
586      * PARAMETERS:  <none>
587      *
588      * RETURN:	
589      *
590      * DESCRIPTION:
591      *
592      ****************************************************************************/
593     
594     acpi_status
595     tz_terminate (void)
596     {
597     	acpi_status             status = AE_OK;
598     	BM_DEVICE_ID		criteria;
599     	BM_DRIVER		driver;
600     
601     	FUNCTION_TRACE("tz_terminate");
602     
603     	MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
604     	MEMSET(&driver, 0, sizeof(BM_DRIVER));
605     
606     	/*
607     	 * Unregister driver for thermal zone devices.
608     	 */
609     	criteria.type = BM_TYPE_THERMAL_ZONE;
610     
611     	driver.notify = &tz_notify;
612     	driver.request = &tz_request;
613     
614     	status = bm_unregister_driver(&criteria, &driver);
615     
616     	return_ACPI_STATUS(status);
617     }
618     
619     
620     /****************************************************************************
621      *
622      * FUNCTION:    tz_notify
623      *
624      * PARAMETERS:  <none>
625      *
626      * RETURN:	
627      *
628      * DESCRIPTION:
629      *
630      ****************************************************************************/
631     acpi_status
632     tz_notify (
633     	BM_NOTIFY               notify_type,
634     	BM_HANDLE               device_handle,
635     	void                    **context)
636     {
637     	acpi_status             status = AE_OK;
638     	TZ_CONTEXT		*thermal_zone = NULL;
639     
640     	FUNCTION_TRACE("tz_notify");
641     
642     	if (!context) {
643     		return_ACPI_STATUS(AE_BAD_PARAMETER);
644     	}
645     
646     	thermal_zone = (TZ_CONTEXT*)*context;
647     
648     	switch (notify_type) {
649     
650     	case BM_NOTIFY_DEVICE_ADDED:
651     		status = tz_add_device(device_handle, context);
652     		break;
653     
654     	case BM_NOTIFY_DEVICE_REMOVED:
655     		status = tz_remove_device(context);
656     		break;
657     
658     	case TZ_NOTIFY_TEMPERATURE_CHANGE:
659     		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Temperature (_TMP) change event detected.\n"));
660     		/* -------------------------------------------- */
661     		/* TBD: Remove when policy moves to user-mode. */
662     		tz_policy_check(*context);
663     		/* -------------------------------------------- */
664     		status = tz_get_temperature(thermal_zone,
665     			&(thermal_zone->policy.temperature));
666     		if (ACPI_SUCCESS(status)) {
667     			status = tz_osl_generate_event(notify_type,
668     				thermal_zone);
669     		}
670     		break;
671     
672     	case TZ_NOTIFY_THRESHOLD_CHANGE:
673     		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Threshold (_SCP) change event detected.\n"));
674     		/* -------------------------------------------- */
675     		/* TBD: Remove when policy moves to user-mode. */
676     		status = tz_policy_remove_device(thermal_zone);
677     		if (ACPI_SUCCESS(status)) {
678     			status = tz_policy_add_device(thermal_zone);
679     		}
680     		/* -------------------------------------------- */
681     		status = tz_osl_generate_event(notify_type, thermal_zone);
682     		break;
683     
684     	case TZ_NOTIFY_DEVICE_LISTS_CHANGE:
685     		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Device lists (_ALx, _PSL, _TZD) change event detected.\n"));
686     		/* -------------------------------------------- */
687     		/* TBD: Remove when policy moves to user-mode. */
688     		status = tz_policy_remove_device(thermal_zone);
689     		if (ACPI_SUCCESS(status)) {
690     			status = tz_policy_add_device(thermal_zone);
691     		}
692     		/* -------------------------------------------- */
693     		status = tz_osl_generate_event(notify_type, thermal_zone);
694     		break;
695     
696     	default:
697     		status = AE_SUPPORT;
698     		break;
699     	}
700     
701     	return_ACPI_STATUS(status);
702     }
703     
704     
705     /****************************************************************************
706      *
707      * FUNCTION:    tz_request
708      *
709      * PARAMETERS:
710      *
711      * RETURN:      Exception code.
712      *
713      * DESCRIPTION:
714      *
715      ****************************************************************************/
716     
717     acpi_status
718     tz_request (
719     	BM_REQUEST		*request,
720     	void                    *context)
721     {
722     	acpi_status             status = AE_OK;
723     	TZ_CONTEXT              *thermal_zone = NULL;
724     
725     	FUNCTION_TRACE("tz_request");
726     
727     	/*
728     	 * Must have a valid request structure and context.
729     	 */
730     	if (!request || !context) {
731     		return_ACPI_STATUS(AE_BAD_PARAMETER);
732     	}
733     
734     	thermal_zone = (TZ_CONTEXT*)context;
735     
736     	/*
737     	 * Handle request:
738     	 * ---------------
739     	 */
740     	switch (request->command) {
741     
742     	default:
743     		status = AE_SUPPORT;
744     		break;
745     	}
746     
747     	request->status = status;
748     
749     	return_ACPI_STATUS(status);
750     }
751