]> err.no Git - linux-2.6/blob - drivers/acpi/utilities/utinit.c
ACPICA: Implement simplified Table Manager
[linux-2.6] / drivers / acpi / utilities / utinit.c
1 /******************************************************************************
2  *
3  * Module Name: utinit - Common ACPI subsystem initialization
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2006, R. Byron Moore
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #include <acpi/acpi.h>
45 #include <acpi/acnamesp.h>
46 #include <acpi/acevents.h>
47 #include <acpi/actables.h>
48
49 #define _COMPONENT          ACPI_UTILITIES
50 ACPI_MODULE_NAME("utinit")
51
52 /* Local prototypes */
53 static void
54 acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset);
55
56 static void acpi_ut_terminate(void);
57
58 /*******************************************************************************
59  *
60  * FUNCTION:    acpi_ut_fadt_register_error
61  *
62  * PARAMETERS:  register_name           - Pointer to string identifying register
63  *              Value                   - Actual register contents value
64  *              Offset                  - Byte offset in the FADT
65  *
66  * RETURN:      AE_BAD_VALUE
67  *
68  * DESCRIPTION: Display failure message
69  *
70  ******************************************************************************/
71
72 static void
73 acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset)
74 {
75
76         ACPI_WARNING((AE_INFO,
77                       "Invalid FADT value %s=%X at offset %X in FADT=%p",
78                       register_name, value, offset, &acpi_gbl_FADT));
79 }
80
81 /******************************************************************************
82  *
83  * FUNCTION:    acpi_ut_validate_fadt
84  *
85  * PARAMETERS:  None
86  *
87  * RETURN:      Status
88  *
89  * DESCRIPTION: Validate various ACPI registers in the FADT
90  *
91  ******************************************************************************/
92
93 acpi_status acpi_ut_validate_fadt(void)
94 {
95
96         /*
97          * Verify Fixed ACPI Description Table fields,
98          * but don't abort on any problems, just display error
99          */
100         if (acpi_gbl_FADT.pm1_event_length < 4) {
101                 acpi_ut_fadt_register_error("PM1_EVT_LEN",
102                                             (u32) acpi_gbl_FADT.
103                                             pm1_event_length,
104                                             ACPI_FADT_OFFSET(pm1_event_length));
105         }
106
107         if (!acpi_gbl_FADT.pm1_control_length) {
108                 acpi_ut_fadt_register_error("PM1_CNT_LEN", 0,
109                                             ACPI_FADT_OFFSET
110                                             (pm1_control_length));
111         }
112
113         if (!acpi_gbl_FADT.xpm1a_event_block.address) {
114                 acpi_ut_fadt_register_error("X_PM1a_EVT_BLK", 0,
115                                             ACPI_FADT_OFFSET(xpm1a_event_block.
116                                                              address));
117         }
118
119         if (!acpi_gbl_FADT.xpm1a_control_block.address) {
120                 acpi_ut_fadt_register_error("X_PM1a_CNT_BLK", 0,
121                                             ACPI_FADT_OFFSET
122                                             (xpm1a_control_block.address));
123         }
124
125         if (!acpi_gbl_FADT.xpm_timer_block.address) {
126                 acpi_ut_fadt_register_error("X_PM_TMR_BLK", 0,
127                                             ACPI_FADT_OFFSET(xpm_timer_block.
128                                                              address));
129         }
130
131         if ((acpi_gbl_FADT.xpm2_control_block.address &&
132              !acpi_gbl_FADT.pm2_control_length)) {
133                 acpi_ut_fadt_register_error("PM2_CNT_LEN",
134                                             (u32) acpi_gbl_FADT.
135                                             pm2_control_length,
136                                             ACPI_FADT_OFFSET
137                                             (pm2_control_length));
138         }
139
140         if (acpi_gbl_FADT.pm_timer_length < 4) {
141                 acpi_ut_fadt_register_error("PM_TM_LEN",
142                                             (u32) acpi_gbl_FADT.pm_timer_length,
143                                             ACPI_FADT_OFFSET(pm_timer_length));
144         }
145
146         /* Length of GPE blocks must be a multiple of 2 */
147
148         if (acpi_gbl_FADT.xgpe0_block.address &&
149             (acpi_gbl_FADT.gpe0_block_length & 1)) {
150                 acpi_ut_fadt_register_error("(x)GPE0_BLK_LEN",
151                                             (u32) acpi_gbl_FADT.
152                                             gpe0_block_length,
153                                             ACPI_FADT_OFFSET
154                                             (gpe0_block_length));
155         }
156
157         if (acpi_gbl_FADT.xgpe1_block.address &&
158             (acpi_gbl_FADT.gpe1_block_length & 1)) {
159                 acpi_ut_fadt_register_error("(x)GPE1_BLK_LEN",
160                                             (u32) acpi_gbl_FADT.
161                                             gpe1_block_length,
162                                             ACPI_FADT_OFFSET
163                                             (gpe1_block_length));
164         }
165
166         return (AE_OK);
167 }
168
169 /******************************************************************************
170  *
171  * FUNCTION:    acpi_ut_terminate
172  *
173  * PARAMETERS:  none
174  *
175  * RETURN:      none
176  *
177  * DESCRIPTION: Free global memory
178  *
179  ******************************************************************************/
180
181 static void acpi_ut_terminate(void)
182 {
183         struct acpi_gpe_block_info *gpe_block;
184         struct acpi_gpe_block_info *next_gpe_block;
185         struct acpi_gpe_xrupt_info *gpe_xrupt_info;
186         struct acpi_gpe_xrupt_info *next_gpe_xrupt_info;
187
188         ACPI_FUNCTION_TRACE(ut_terminate);
189
190         /* Free global GPE blocks and related info structures */
191
192         gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
193         while (gpe_xrupt_info) {
194                 gpe_block = gpe_xrupt_info->gpe_block_list_head;
195                 while (gpe_block) {
196                         next_gpe_block = gpe_block->next;
197                         ACPI_FREE(gpe_block->event_info);
198                         ACPI_FREE(gpe_block->register_info);
199                         ACPI_FREE(gpe_block);
200
201                         gpe_block = next_gpe_block;
202                 }
203                 next_gpe_xrupt_info = gpe_xrupt_info->next;
204                 ACPI_FREE(gpe_xrupt_info);
205                 gpe_xrupt_info = next_gpe_xrupt_info;
206         }
207
208         return_VOID;
209 }
210
211 /*******************************************************************************
212  *
213  * FUNCTION:    acpi_ut_subsystem_shutdown
214  *
215  * PARAMETERS:  none
216  *
217  * RETURN:      none
218  *
219  * DESCRIPTION: Shutdown the various subsystems.  Don't delete the mutex
220  *              objects here -- because the AML debugger may be still running.
221  *
222  ******************************************************************************/
223
224 void acpi_ut_subsystem_shutdown(void)
225 {
226
227         ACPI_FUNCTION_TRACE(ut_subsystem_shutdown);
228
229         /* Just exit if subsystem is already shutdown */
230
231         if (acpi_gbl_shutdown) {
232                 ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated"));
233                 return_VOID;
234         }
235
236         /* Subsystem appears active, go ahead and shut it down */
237
238         acpi_gbl_shutdown = TRUE;
239         acpi_gbl_startup_flags = 0;
240         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
241
242         /* Close the acpi_event Handling */
243
244         acpi_ev_terminate();
245
246         /* Close the Namespace */
247
248         acpi_ns_terminate();
249
250         /* Delete the ACPI tables */
251
252         acpi_tb_terminate();
253
254         /* Close the globals */
255
256         acpi_ut_terminate();
257
258         /* Purge the local caches */
259
260         (void)acpi_ut_delete_caches();
261         return_VOID;
262 }