vserver 1.9.5.x5
[linux-2.6.git] / drivers / acpi / executer / exsystem.c
1
2 /******************************************************************************
3  *
4  * Module Name: exsystem - Interface to OS services
5  *
6  *****************************************************************************/
7
8 /*
9  * Copyright (C) 2000 - 2005, R. Byron Moore
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44
45
46 #include <acpi/acpi.h>
47 #include <acpi/acinterp.h>
48 #include <acpi/acevents.h>
49
50 #define _COMPONENT          ACPI_EXECUTER
51          ACPI_MODULE_NAME    ("exsystem")
52
53
54 /*******************************************************************************
55  *
56  * FUNCTION:    acpi_ex_system_wait_semaphore
57  *
58  * PARAMETERS:  Semaphore           - OSD semaphore to wait on
59  *              Timeout             - Max time to wait
60  *
61  * RETURN:      Status
62  *
63  * DESCRIPTION: Implements a semaphore wait with a check to see if the
64  *              semaphore is available immediately.  If it is not, the
65  *              interpreter is released.
66  *
67  ******************************************************************************/
68
69 acpi_status
70 acpi_ex_system_wait_semaphore (
71         acpi_handle                     semaphore,
72         u16                             timeout)
73 {
74         acpi_status                     status;
75         acpi_status                     status2;
76
77
78         ACPI_FUNCTION_TRACE ("ex_system_wait_semaphore");
79
80
81         status = acpi_os_wait_semaphore (semaphore, 1, 0);
82         if (ACPI_SUCCESS (status)) {
83                 return_ACPI_STATUS (status);
84         }
85
86         if (status == AE_TIME) {
87                 /* We must wait, so unlock the interpreter */
88
89                 acpi_ex_exit_interpreter ();
90
91                 status = acpi_os_wait_semaphore (semaphore, 1, timeout);
92
93                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*** Thread awake after blocking, %s\n",
94                         acpi_format_exception (status)));
95
96                 /* Reacquire the interpreter */
97
98                 status2 = acpi_ex_enter_interpreter ();
99                 if (ACPI_FAILURE (status2)) {
100                         /* Report fatal error, could not acquire interpreter */
101
102                         return_ACPI_STATUS (status2);
103                 }
104         }
105
106         return_ACPI_STATUS (status);
107 }
108
109
110 /*******************************************************************************
111  *
112  * FUNCTION:    acpi_ex_system_do_stall
113  *
114  * PARAMETERS:  how_long            - The amount of time to stall,
115  *                                    in microseconds
116  *
117  * RETURN:      Status
118  *
119  * DESCRIPTION: Suspend running thread for specified amount of time.
120  *              Note: ACPI specification requires that Stall() does not
121  *              relinquish the processor, and delays longer than 100 usec
122  *              should use Sleep() instead.  We allow stalls up to 255 usec
123  *              for compatibility with other interpreters and existing BIOSs.
124  *
125  ******************************************************************************/
126
127 acpi_status
128 acpi_ex_system_do_stall (
129         u32                             how_long)
130 {
131         acpi_status                     status = AE_OK;
132
133
134         ACPI_FUNCTION_ENTRY ();
135
136
137         if (how_long > 255) /* 255 microseconds */ {
138                 /*
139                  * Longer than 255 usec, this is an error
140                  *
141                  * (ACPI specifies 100 usec as max, but this gives some slack in
142                  * order to support existing BIOSs)
143                  */
144                 ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n", how_long));
145                 status = AE_AML_OPERAND_VALUE;
146         }
147         else {
148                 acpi_os_stall (how_long);
149         }
150
151         return (status);
152 }
153
154
155 /*******************************************************************************
156  *
157  * FUNCTION:    acpi_ex_system_do_suspend
158  *
159  * PARAMETERS:  how_long            - The amount of time to suspend,
160  *                                    in milliseconds
161  *
162  * RETURN:      None
163  *
164  * DESCRIPTION: Suspend running thread for specified amount of time.
165  *
166  ******************************************************************************/
167
168 acpi_status
169 acpi_ex_system_do_suspend (
170         acpi_integer                    how_long)
171 {
172         acpi_status                     status;
173
174
175         ACPI_FUNCTION_ENTRY ();
176
177
178         /* Since this thread will sleep, we must release the interpreter */
179
180         acpi_ex_exit_interpreter ();
181
182         acpi_os_sleep (how_long);
183
184         /* And now we must get the interpreter again */
185
186         status = acpi_ex_enter_interpreter ();
187         return (status);
188 }
189
190
191 /*******************************************************************************
192  *
193  * FUNCTION:    acpi_ex_system_acquire_mutex
194  *
195  * PARAMETERS:  *time_desc          - The 'time to delay' object descriptor
196  *              *obj_desc           - The object descriptor for this op
197  *
198  * RETURN:      Status
199  *
200  * DESCRIPTION: Provides an access point to perform synchronization operations
201  *              within the AML.  This function will cause a lock to be generated
202  *              for the Mutex pointed to by obj_desc.
203  *
204  ******************************************************************************/
205
206 acpi_status
207 acpi_ex_system_acquire_mutex (
208         union acpi_operand_object       *time_desc,
209         union acpi_operand_object       *obj_desc)
210 {
211         acpi_status                     status = AE_OK;
212
213
214         ACPI_FUNCTION_TRACE_PTR ("ex_system_acquire_mutex", obj_desc);
215
216
217         if (!obj_desc) {
218                 return_ACPI_STATUS (AE_BAD_PARAMETER);
219         }
220
221         /*
222          * Support for the _GL_ Mutex object -- go get the global lock
223          */
224         if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
225                 status = acpi_ev_acquire_global_lock ((u16) time_desc->integer.value);
226                 return_ACPI_STATUS (status);
227         }
228
229         status = acpi_ex_system_wait_semaphore (obj_desc->mutex.semaphore,
230                           (u16) time_desc->integer.value);
231         return_ACPI_STATUS (status);
232 }
233
234
235 /*******************************************************************************
236  *
237  * FUNCTION:    acpi_ex_system_release_mutex
238  *
239  * PARAMETERS:  *obj_desc           - The object descriptor for this op
240  *
241  * RETURN:      Status
242  *
243  * DESCRIPTION: Provides an access point to perform synchronization operations
244  *              within the AML.  This operation is a request to release a
245  *              previously acquired Mutex.  If the Mutex variable is set then
246  *              it will be decremented.
247  *
248  ******************************************************************************/
249
250 acpi_status
251 acpi_ex_system_release_mutex (
252         union acpi_operand_object       *obj_desc)
253 {
254         acpi_status                     status = AE_OK;
255
256
257         ACPI_FUNCTION_TRACE ("ex_system_release_mutex");
258
259
260         if (!obj_desc) {
261                 return_ACPI_STATUS (AE_BAD_PARAMETER);
262         }
263
264         /*
265          * Support for the _GL_ Mutex object -- release the global lock
266          */
267         if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
268                 status = acpi_ev_release_global_lock ();
269                 return_ACPI_STATUS (status);
270         }
271
272         status = acpi_os_signal_semaphore (obj_desc->mutex.semaphore, 1);
273         return_ACPI_STATUS (status);
274 }
275
276
277 /*******************************************************************************
278  *
279  * FUNCTION:    acpi_ex_system_signal_event
280  *
281  * PARAMETERS:  *obj_desc           - The object descriptor for this op
282  *
283  * RETURN:      AE_OK
284  *
285  * DESCRIPTION: Provides an access point to perform synchronization operations
286  *              within the AML.
287  *
288  ******************************************************************************/
289
290 acpi_status
291 acpi_ex_system_signal_event (
292         union acpi_operand_object       *obj_desc)
293 {
294         acpi_status                     status = AE_OK;
295
296
297         ACPI_FUNCTION_TRACE ("ex_system_signal_event");
298
299
300         if (obj_desc) {
301                 status = acpi_os_signal_semaphore (obj_desc->event.semaphore, 1);
302         }
303
304         return_ACPI_STATUS (status);
305 }
306
307
308 /*******************************************************************************
309  *
310  * FUNCTION:    acpi_ex_system_wait_event
311  *
312  * PARAMETERS:  *time_desc          - The 'time to delay' object descriptor
313  *              *obj_desc           - The object descriptor for this op
314  *
315  * RETURN:      Status
316  *
317  * DESCRIPTION: Provides an access point to perform synchronization operations
318  *              within the AML.  This operation is a request to wait for an
319  *              event.
320  *
321  ******************************************************************************/
322
323 acpi_status
324 acpi_ex_system_wait_event (
325         union acpi_operand_object       *time_desc,
326         union acpi_operand_object       *obj_desc)
327 {
328         acpi_status                     status = AE_OK;
329
330
331         ACPI_FUNCTION_TRACE ("ex_system_wait_event");
332
333
334         if (obj_desc) {
335                 status = acpi_ex_system_wait_semaphore (obj_desc->event.semaphore,
336                                   (u16) time_desc->integer.value);
337         }
338
339         return_ACPI_STATUS (status);
340 }
341
342
343 /*******************************************************************************
344  *
345  * FUNCTION:    acpi_ex_system_reset_event
346  *
347  * PARAMETERS:  *obj_desc           - The object descriptor for this op
348  *
349  * RETURN:      Status
350  *
351  * DESCRIPTION: Reset an event to a known state.
352  *
353  ******************************************************************************/
354
355 acpi_status
356 acpi_ex_system_reset_event (
357         union acpi_operand_object       *obj_desc)
358 {
359         acpi_status                     status = AE_OK;
360         void                            *temp_semaphore;
361
362
363         ACPI_FUNCTION_ENTRY ();
364
365
366         /*
367          * We are going to simply delete the existing semaphore and
368          * create a new one!
369          */
370         status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
371         if (ACPI_SUCCESS (status)) {
372                 (void) acpi_os_delete_semaphore (obj_desc->event.semaphore);
373                 obj_desc->event.semaphore = temp_semaphore;
374         }
375
376         return (status);
377 }
378