Merge master.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-2.6
[linux-2.6] / 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       - 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,
94                         "*** Thread awake after blocking, %s\n",
95                         acpi_format_exception (status)));
96
97                 /* Reacquire the interpreter */
98
99                 status2 = acpi_ex_enter_interpreter ();
100                 if (ACPI_FAILURE (status2)) {
101                         /* Report fatal error, could not acquire interpreter */
102
103                         return_ACPI_STATUS (status2);
104                 }
105         }
106
107         return_ACPI_STATUS (status);
108 }
109
110
111 /*******************************************************************************
112  *
113  * FUNCTION:    acpi_ex_system_do_stall
114  *
115  * PARAMETERS:  how_long        - The amount of time to stall,
116  *                                in microseconds
117  *
118  * RETURN:      Status
119  *
120  * DESCRIPTION: Suspend running thread for specified amount of time.
121  *              Note: ACPI specification requires that Stall() does not
122  *              relinquish the processor, and delays longer than 100 usec
123  *              should use Sleep() instead.  We allow stalls up to 255 usec
124  *              for compatibility with other interpreters and existing BIOSs.
125  *
126  ******************************************************************************/
127
128 acpi_status
129 acpi_ex_system_do_stall (
130         u32                             how_long)
131 {
132         acpi_status                     status = AE_OK;
133
134
135         ACPI_FUNCTION_ENTRY ();
136
137
138         if (how_long > 255) /* 255 microseconds */ {
139                 /*
140                  * Longer than 255 usec, this is an error
141                  *
142                  * (ACPI specifies 100 usec as max, but this gives some slack in
143                  * order to support existing BIOSs)
144                  */
145                 ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n",
146                         how_long));
147                 status = AE_AML_OPERAND_VALUE;
148         }
149         else {
150                 acpi_os_stall (how_long);
151         }
152
153         return (status);
154 }
155
156
157 /*******************************************************************************
158  *
159  * FUNCTION:    acpi_ex_system_do_suspend
160  *
161  * PARAMETERS:  how_long        - The amount of time to suspend,
162  *                                in milliseconds
163  *
164  * RETURN:      None
165  *
166  * DESCRIPTION: Suspend running thread for specified amount of time.
167  *
168  ******************************************************************************/
169
170 acpi_status
171 acpi_ex_system_do_suspend (
172         acpi_integer                    how_long)
173 {
174         acpi_status                     status;
175
176
177         ACPI_FUNCTION_ENTRY ();
178
179
180         /* Since this thread will sleep, we must release the interpreter */
181
182         acpi_ex_exit_interpreter ();
183
184         acpi_os_sleep (how_long);
185
186         /* And now we must get the interpreter again */
187
188         status = acpi_ex_enter_interpreter ();
189         return (status);
190 }
191
192
193 /*******************************************************************************
194  *
195  * FUNCTION:    acpi_ex_system_acquire_mutex
196  *
197  * PARAMETERS:  time_desc       - The 'time to delay' object descriptor
198  *              obj_desc        - The object descriptor for this op
199  *
200  * RETURN:      Status
201  *
202  * DESCRIPTION: Provides an access point to perform synchronization operations
203  *              within the AML.  This function will cause a lock to be generated
204  *              for the Mutex pointed to by obj_desc.
205  *
206  ******************************************************************************/
207
208 acpi_status
209 acpi_ex_system_acquire_mutex (
210         union acpi_operand_object       *time_desc,
211         union acpi_operand_object       *obj_desc)
212 {
213         acpi_status                     status = AE_OK;
214
215
216         ACPI_FUNCTION_TRACE_PTR ("ex_system_acquire_mutex", obj_desc);
217
218
219         if (!obj_desc) {
220                 return_ACPI_STATUS (AE_BAD_PARAMETER);
221         }
222
223         /* Support for the _GL_ Mutex object -- go get the global lock */
224
225         if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
226                 status = acpi_ev_acquire_global_lock ((u16) time_desc->integer.value);
227                 return_ACPI_STATUS (status);
228         }
229
230         status = acpi_ex_system_wait_semaphore (obj_desc->mutex.semaphore,
231                          (u16) time_desc->integer.value);
232         return_ACPI_STATUS (status);
233 }
234
235
236 /*******************************************************************************
237  *
238  * FUNCTION:    acpi_ex_system_release_mutex
239  *
240  * PARAMETERS:  obj_desc        - The object descriptor for this op
241  *
242  * RETURN:      Status
243  *
244  * DESCRIPTION: Provides an access point to perform synchronization operations
245  *              within the AML.  This operation is a request to release a
246  *              previously acquired Mutex.  If the Mutex variable is set then
247  *              it will be decremented.
248  *
249  ******************************************************************************/
250
251 acpi_status
252 acpi_ex_system_release_mutex (
253         union acpi_operand_object       *obj_desc)
254 {
255         acpi_status                     status = AE_OK;
256
257
258         ACPI_FUNCTION_TRACE ("ex_system_release_mutex");
259
260
261         if (!obj_desc) {
262                 return_ACPI_STATUS (AE_BAD_PARAMETER);
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:      Status
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