Merge trunk HEAD (r46369)
[reactos.git] / reactos / drivers / bus / acpi / utils / cmxface.c
1 /******************************************************************************
2 *
3 * Module Name: cmxface - External interfaces for "global" ACPI functions
4 * $Revision: 1.1 $
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
29 #define _COMPONENT ACPI_UTILITIES
30 MODULE_NAME ("cmxface")
31
32
33 /*******************************************************************************
34 *
35 * FUNCTION: Acpi_initialize_subsystem
36 *
37 * PARAMETERS: None
38 *
39 * RETURN: Status
40 *
41 * DESCRIPTION: Initializes all global variables. This is the first function
42 * called, so any early initialization belongs here.
43 *
44 ******************************************************************************/
45
46 ACPI_STATUS
47 acpi_initialize_subsystem (
48 void)
49 {
50 ACPI_STATUS status;
51
52
53 /* Initialize all globals used by the subsystem */
54
55 acpi_cm_init_globals ();
56
57 /* Initialize the OS-Dependent layer */
58
59 status = acpi_os_initialize ();
60 if (ACPI_FAILURE (status)) {
61 REPORT_ERROR (("OSD failed to initialize, %s\n",
62 acpi_cm_format_exception (status)));
63 return (status);
64 }
65
66 /* Create the default mutex objects */
67
68 status = acpi_cm_mutex_initialize ();
69 if (ACPI_FAILURE (status)) {
70 REPORT_ERROR (("Global mutex creation failure, %s\n",
71 acpi_cm_format_exception (status)));
72 return (status);
73 }
74
75 /*
76 * Initialize the namespace manager and
77 * the root of the namespace tree
78 */
79
80 status = acpi_ns_root_initialize ();
81 if (ACPI_FAILURE (status)) {
82 REPORT_ERROR (("Namespace initialization failure, %s\n",
83 acpi_cm_format_exception (status)));
84 return (status);
85 }
86
87
88 /* If configured, initialize the AML debugger */
89
90 DEBUGGER_EXEC (acpi_db_initialize ());
91
92 return (status);
93 }
94
95
96 /*******************************************************************************
97 *
98 * FUNCTION: Acpi_enable_subsystem
99 *
100 * PARAMETERS: Flags - Init/enable Options
101 *
102 * RETURN: Status
103 *
104 * DESCRIPTION: Completes the subsystem initialization including hardware.
105 * Puts system into ACPI mode if it isn't already.
106 *
107 ******************************************************************************/
108
109 ACPI_STATUS
110 acpi_enable_subsystem (
111 u32 flags)
112 {
113 ACPI_STATUS status = AE_OK;
114
115
116 /* Sanity check the FADT for valid values */
117
118 status = acpi_cm_validate_fadt ();
119 if (ACPI_FAILURE (status)) {
120 return (status);
121 }
122
123 /*
124 * Install the default Op_region handlers. These are
125 * installed unless other handlers have already been
126 * installed via the Install_address_space_handler interface
127 */
128
129 if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
130 status = acpi_ev_install_default_address_space_handlers ();
131 if (ACPI_FAILURE (status)) {
132 return (status);
133 }
134 }
135
136 /*
137 * We must initialize the hardware before we can enable ACPI.
138 */
139
140 if (!(flags & ACPI_NO_HARDWARE_INIT)) {
141 status = acpi_hw_initialize ();
142 if (ACPI_FAILURE (status)) {
143 return (status);
144 }
145 }
146
147 /*
148 * Enable ACPI on this platform
149 */
150
151 if (!(flags & ACPI_NO_ACPI_ENABLE)) {
152 status = acpi_enable ();
153 if (ACPI_FAILURE (status)) {
154 return (status);
155 }
156 }
157
158 /*
159 * Note:
160 * We must have the hardware AND events initialized before we can execute
161 * ANY control methods SAFELY. Any control method can require ACPI hardware
162 * support, so the hardware MUST be initialized before execution!
163 */
164
165 if (!(flags & ACPI_NO_EVENT_INIT)) {
166 status = acpi_ev_initialize ();
167 if (ACPI_FAILURE (status)) {
168 return (status);
169 }
170 }
171
172
173 /*
174 * Initialize all device objects in the namespace
175 * This runs the _STA and _INI methods.
176 */
177
178 if (!(flags & ACPI_NO_DEVICE_INIT)) {
179 status = acpi_ns_initialize_devices ();
180 if (ACPI_FAILURE (status)) {
181 return (status);
182 }
183 }
184
185
186 /*
187 * Initialize the objects that remain uninitialized. This
188 * runs the executable AML that is part of the declaration of Op_regions
189 * and Fields.
190 */
191
192 if (!(flags & ACPI_NO_OBJECT_INIT)) {
193 status = acpi_ns_initialize_objects ();
194 if (ACPI_FAILURE (status)) {
195 return (status);
196 }
197 }
198
199
200 return (status);
201 }
202
203
204 /*******************************************************************************
205 *
206 * FUNCTION: Acpi_terminate
207 *
208 * PARAMETERS: None
209 *
210 * RETURN: Status
211 *
212 * DESCRIPTION: Shutdown the ACPI subsystem. Release all resources.
213 *
214 ******************************************************************************/
215
216 ACPI_STATUS
217 acpi_terminate (void)
218 {
219
220 /* Terminate the AML Debuger if present */
221
222 DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE);
223
224 /* TBD: [Investigate] This is no longer needed?*/
225 /* Acpi_cm_release_mutex (ACPI_MTX_DEBUG_CMD_READY); */
226
227
228 /* Shutdown and free all resources */
229
230 acpi_cm_subsystem_shutdown ();
231
232
233 /* Free the mutex objects */
234
235 acpi_cm_mutex_terminate ();
236
237
238 /* Now we can shutdown the OS-dependent layer */
239
240 acpi_os_terminate ();
241
242 return (AE_OK);
243 }
244
245
246 /******************************************************************************
247 *
248 * FUNCTION: Acpi_get_system_info
249 *
250 * PARAMETERS: Out_buffer - a pointer to a buffer to receive the
251 * resources for the device
252 * Buffer_length - the number of bytes available in the buffer
253 *
254 * RETURN: Status - the status of the call
255 *
256 * DESCRIPTION: This function is called to get information about the current
257 * state of the ACPI subsystem. It will return system information
258 * in the Out_buffer.
259 *
260 * If the function fails an appropriate status will be returned
261 * and the value of Out_buffer is undefined.
262 *
263 ******************************************************************************/
264
265 ACPI_STATUS
266 acpi_get_system_info (
267 ACPI_BUFFER *out_buffer)
268 {
269 ACPI_SYSTEM_INFO *info_ptr;
270 u32 i;
271
272
273 /*
274 * Must have a valid buffer
275 */
276 if ((!out_buffer) ||
277 (!out_buffer->pointer)) {
278 return (AE_BAD_PARAMETER);
279 }
280
281 if (out_buffer->length < sizeof (ACPI_SYSTEM_INFO)) {
282 /*
283 * Caller's buffer is too small
284 */
285 out_buffer->length = sizeof (ACPI_SYSTEM_INFO);
286
287 return (AE_BUFFER_OVERFLOW);
288 }
289
290
291 /*
292 * Set return length and get data
293 */
294 out_buffer->length = sizeof (ACPI_SYSTEM_INFO);
295 info_ptr = (ACPI_SYSTEM_INFO *) out_buffer->pointer;
296
297 info_ptr->acpi_ca_version = ACPI_CA_VERSION;
298
299 /* System flags (ACPI capabilities) */
300
301 info_ptr->flags = acpi_gbl_system_flags;
302
303 /* Timer resolution - 24 or 32 bits */
304 if (!acpi_gbl_FADT) {
305 info_ptr->timer_resolution = 0;
306 }
307 else if (acpi_gbl_FADT->tmr_val_ext == 0) {
308 info_ptr->timer_resolution = 24;
309 }
310 else {
311 info_ptr->timer_resolution = 32;
312 }
313
314 /* Clear the reserved fields */
315
316 info_ptr->reserved1 = 0;
317 info_ptr->reserved2 = 0;
318
319 /* Current debug levels */
320
321 info_ptr->debug_layer = acpi_dbg_layer;
322 info_ptr->debug_level = acpi_dbg_level;
323
324 /* Current status of the ACPI tables, per table type */
325
326 info_ptr->num_table_types = NUM_ACPI_TABLES;
327 for (i = 0; i < NUM_ACPI_TABLES; i++) {
328 info_ptr->table_info[i].count = acpi_gbl_acpi_tables[i].count;
329 }
330
331 return (AE_OK);
332 }
333
334
335 /******************************************************************************
336 *
337 * FUNCTION: Acpi_format_exception
338 *
339 * PARAMETERS: Out_buffer - a pointer to a buffer to receive the
340 * exception name
341 *
342 * RETURN: Status - the status of the call
343 *
344 * DESCRIPTION: This function translates an ACPI exception into an ASCII string.
345 *
346 ******************************************************************************/
347
348 ACPI_STATUS
349 acpi_format_exception (
350 ACPI_STATUS exception,
351 ACPI_BUFFER *out_buffer)
352 {
353 u32 length;
354 NATIVE_CHAR *formatted_exception;
355
356
357 /*
358 * Must have a valid buffer
359 */
360 if ((!out_buffer) ||
361 (!out_buffer->pointer)) {
362 return (AE_BAD_PARAMETER);
363 }
364
365
366 /* Convert the exception code (Handles bad exception codes) */
367
368 formatted_exception = acpi_cm_format_exception (exception);
369
370 /*
371 * Get length of string and check if it will fit in caller's buffer
372 */
373
374 length = STRLEN (formatted_exception);
375 if (out_buffer->length < length) {
376 out_buffer->length = length;
377 return (AE_BUFFER_OVERFLOW);
378 }
379
380
381 /* Copy the string, all done */
382
383 STRCPY (out_buffer->pointer, formatted_exception);
384
385 return (AE_OK);
386 }
387
388
389 /*****************************************************************************
390 *
391 * FUNCTION: Acpi_allocate
392 *
393 * PARAMETERS: Size - Size of the allocation
394 *
395 * RETURN: Address of the allocated memory on success, NULL on failure.
396 *
397 * DESCRIPTION: The subsystem's equivalent of malloc.
398 * External front-end to the Cm* memory manager
399 *
400 ****************************************************************************/
401
402 void *
403 acpi_allocate (
404 u32 size)
405 {
406
407 return (acpi_cm_allocate (size));
408 }
409
410
411 /*****************************************************************************
412 *
413 * FUNCTION: Acpi_callocate
414 *
415 * PARAMETERS: Size - Size of the allocation
416 *
417 * RETURN: Address of the allocated memory on success, NULL on failure.
418 *
419 * DESCRIPTION: The subsystem's equivalent of calloc.
420 * External front-end to the Cm* memory manager
421 *
422 ****************************************************************************/
423
424 void *
425 acpi_callocate (
426 u32 size)
427 {
428
429 return (acpi_cm_callocate (size));
430 }
431
432
433 /*****************************************************************************
434 *
435 * FUNCTION: Acpi_free
436 *
437 * PARAMETERS: Address - Address of the memory to deallocate
438 *
439 * RETURN: None
440 *
441 * DESCRIPTION: Frees the memory at Address
442 * External front-end to the Cm* memory manager
443 *
444 ****************************************************************************/
445
446 void
447 acpi_free (
448 void *address)
449 {
450
451 acpi_cm_free (address);
452 }