:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / bus / acpi / executer / amsystem.c
1
2 /******************************************************************************
3  *
4  * Module Name: amsystem - Interface to OS services
5  *              $Revision$
6  *
7  *****************************************************************************/
8
9 /*
10  *  Copyright (C) 2000, 2001 R. Byron Moore
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  */
26
27
28 #include "acpi.h"
29 #include "acinterp.h"
30 #include "acnamesp.h"
31 #include "achware.h"
32 #include "acevents.h"
33
34 #define _COMPONENT          ACPI_EXECUTER
35          MODULE_NAME         ("amsystem")
36
37
38 /*******************************************************************************
39  *
40  * FUNCTION:    Acpi_aml_system_wait_semaphore
41  *
42  * PARAMETERS:  Semaphore           - OSD semaphore to wait on
43  *              Timeout             - Max time to wait
44  *
45  * RETURN:      Status
46  *
47  * DESCRIPTION: Implements a semaphore wait with a check to see if the
48  *              semaphore is available immediately.  If it is not, the
49  *              interpreter is released.
50  *
51  ******************************************************************************/
52
53 ACPI_STATUS
54 acpi_aml_system_wait_semaphore (
55         ACPI_HANDLE             semaphore,
56         u32                     timeout)
57 {
58         ACPI_STATUS             status;
59
60
61         status = acpi_os_wait_semaphore (semaphore, 1, 0);
62         if (ACPI_SUCCESS (status)) {
63                 return (status);
64         }
65
66         if (status == AE_TIME) {
67                 /* We must wait, so unlock the interpreter */
68
69                 acpi_aml_exit_interpreter ();
70
71                 status = acpi_os_wait_semaphore (semaphore, 1, timeout);
72
73                 /* Reacquire the interpreter */
74
75                 status = acpi_aml_enter_interpreter ();
76                 if (ACPI_SUCCESS (status)) {
77                         /* Restore the timeout exception */
78
79                         status = AE_TIME;
80                 }
81         }
82
83         return (status);
84 }
85
86
87 /*******************************************************************************
88  *
89  * FUNCTION:    Acpi_aml_system_do_stall
90  *
91  * PARAMETERS:  How_long            - The amount of time to stall
92  *
93  * RETURN:      None
94  *
95  * DESCRIPTION: Suspend running thread for specified amount of time.
96  *
97  ******************************************************************************/
98
99 void
100 acpi_aml_system_do_stall (
101         u32                     how_long)
102 {
103
104         if (how_long > 1000) /* 1 millisecond */ {
105                 /* Since this thread will sleep, we must release the interpreter */
106
107                 acpi_aml_exit_interpreter ();
108
109                 acpi_os_sleep_usec (how_long);
110
111                 /* And now we must get the interpreter again */
112
113                 acpi_aml_enter_interpreter ();
114         }
115
116         else {
117                 acpi_os_sleep_usec (how_long);
118         }
119 }
120
121
122 /*******************************************************************************
123  *
124  * FUNCTION:    Acpi_aml_system_do_suspend
125  *
126  * PARAMETERS:  How_long            - The amount of time to suspend
127  *
128  * RETURN:      None
129  *
130  * DESCRIPTION: Suspend running thread for specified amount of time.
131  *
132  ******************************************************************************/
133
134 void
135 acpi_aml_system_do_suspend (
136         u32                     how_long)
137 {
138         /* Since this thread will sleep, we must release the interpreter */
139
140         acpi_aml_exit_interpreter ();
141
142         acpi_os_sleep ((u16) (how_long / (u32) 1000),
143                           (u16) (how_long % (u32) 1000));
144
145         /* And now we must get the interpreter again */
146
147         acpi_aml_enter_interpreter ();
148 }
149
150
151 /*******************************************************************************
152  *
153  * FUNCTION:    Acpi_aml_system_acquire_mutex
154  *
155  * PARAMETERS:  *Time_desc          - The 'time to delay' object descriptor
156  *              *Obj_desc           - The object descriptor for this op
157  *
158  * RETURN:      Status
159  *
160  * DESCRIPTION: Provides an access point to perform synchronization operations
161  *              within the AML.  This function will cause a lock to be generated
162  *              for the Mutex pointed to by Obj_desc.
163  *
164  ******************************************************************************/
165
166 ACPI_STATUS
167 acpi_aml_system_acquire_mutex (
168         ACPI_OPERAND_OBJECT     *time_desc,
169         ACPI_OPERAND_OBJECT     *obj_desc)
170 {
171         ACPI_STATUS             status = AE_OK;
172
173
174         if (!obj_desc) {
175                 return (AE_BAD_PARAMETER);
176         }
177
178         /*
179          * Support for the _GL_ Mutex object -- go get the global lock
180          */
181
182         if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
183                 status = acpi_ev_acquire_global_lock ();
184                 return (status);
185         }
186
187         status = acpi_aml_system_wait_semaphore (obj_desc->mutex.semaphore,
188                           (u32) time_desc->integer.value);
189         return (status);
190 }
191
192
193 /*******************************************************************************
194  *
195  * FUNCTION:    Acpi_aml_system_release_mutex
196  *
197  * PARAMETERS:  *Obj_desc           - The object descriptor for this op
198  *
199  * RETURN:      Status
200  *
201  * DESCRIPTION: Provides an access point to perform synchronization operations
202  *              within the AML.  This operation is a request to release a
203  *              previously acquired Mutex.  If the Mutex variable is set then
204  *              it will be decremented.
205  *
206  ******************************************************************************/
207
208 ACPI_STATUS
209 acpi_aml_system_release_mutex (
210         ACPI_OPERAND_OBJECT     *obj_desc)
211 {
212         ACPI_STATUS             status = AE_OK;
213
214
215         if (!obj_desc) {
216                 return (AE_BAD_PARAMETER);
217         }
218
219         /*
220          * Support for the _GL_ Mutex object -- release the global lock
221          */
222         if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
223                 acpi_ev_release_global_lock ();
224                 return (AE_OK);
225         }
226
227         status = acpi_os_signal_semaphore (obj_desc->mutex.semaphore, 1);
228         return (status);
229 }
230
231
232 /*******************************************************************************
233  *
234  * FUNCTION:    Acpi_aml_system_signal_event
235  *
236  * PARAMETERS:  *Obj_desc           - The object descriptor for this op
237  *
238  * RETURN:      AE_OK
239  *
240  * DESCRIPTION: Provides an access point to perform synchronization operations
241  *              within the AML.
242  *
243  ******************************************************************************/
244
245 ACPI_STATUS
246 acpi_aml_system_signal_event (
247         ACPI_OPERAND_OBJECT     *obj_desc)
248 {
249         ACPI_STATUS             status = AE_OK;
250
251
252         if (obj_desc) {
253                 status = acpi_os_signal_semaphore (obj_desc->event.semaphore, 1);
254         }
255
256         return (status);
257 }
258
259
260 /*******************************************************************************
261  *
262  * FUNCTION:    Acpi_aml_system_wait_event
263  *
264  * PARAMETERS:  *Time_desc          - The 'time to delay' object descriptor
265  *              *Obj_desc           - The object descriptor for this op
266  *
267  * RETURN:      Status
268  *
269  * DESCRIPTION: Provides an access point to perform synchronization operations
270  *              within the AML.  This operation is a request to wait for an
271  *              event.
272  *
273  ******************************************************************************/
274
275 ACPI_STATUS
276 acpi_aml_system_wait_event (
277         ACPI_OPERAND_OBJECT     *time_desc,
278         ACPI_OPERAND_OBJECT     *obj_desc)
279 {
280         ACPI_STATUS             status = AE_OK;
281
282
283         if (obj_desc) {
284                 status = acpi_aml_system_wait_semaphore (obj_desc->event.semaphore,
285                                   (u32) time_desc->integer.value);
286         }
287
288
289         return (status);
290 }
291
292
293 /*******************************************************************************
294  *
295  * FUNCTION:    Acpi_aml_system_reset_event
296  *
297  * PARAMETERS:  *Obj_desc           - The object descriptor for this op
298  *
299  * RETURN:      Status
300  *
301  * DESCRIPTION: Reset an event to a known state.
302  *
303  ******************************************************************************/
304
305 ACPI_STATUS
306 acpi_aml_system_reset_event (
307         ACPI_OPERAND_OBJECT     *obj_desc)
308 {
309         ACPI_STATUS             status = AE_OK;
310         void                    *temp_semaphore;
311
312
313         /*
314          * We are going to simply delete the existing semaphore and
315          * create a new one!
316          */
317
318         status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
319         if (ACPI_SUCCESS (status)) {
320                 acpi_os_delete_semaphore (obj_desc->event.semaphore);
321                 obj_desc->event.semaphore = temp_semaphore;
322         }
323
324         return (status);
325 }
326