Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.13 278 lines 7.8 kB view raw
1/****************************************************************************** 2 * 3 * Module Name: utinit - Common ACPI subsystem initialization 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2005, 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 45#include <acpi/acpi.h> 46#include <acpi/acnamesp.h> 47#include <acpi/acevents.h> 48 49#define _COMPONENT ACPI_UTILITIES 50 ACPI_MODULE_NAME ("utinit") 51 52/* Local prototypes */ 53 54static void 55acpi_ut_fadt_register_error ( 56 char *register_name, 57 u32 value, 58 acpi_size offset); 59 60static void acpi_ut_terminate ( 61 void); 62 63 64/******************************************************************************* 65 * 66 * FUNCTION: acpi_ut_fadt_register_error 67 * 68 * PARAMETERS: register_name - Pointer to string identifying register 69 * Value - Actual register contents value 70 * Offset - Byte offset in the FADT 71 * 72 * RETURN: AE_BAD_VALUE 73 * 74 * DESCRIPTION: Display failure message 75 * 76 ******************************************************************************/ 77 78static void 79acpi_ut_fadt_register_error ( 80 char *register_name, 81 u32 value, 82 acpi_size offset) 83{ 84 85 ACPI_REPORT_WARNING ( 86 ("Invalid FADT value %s=%X at offset %X FADT=%p\n", 87 register_name, value, (u32) offset, acpi_gbl_FADT)); 88} 89 90 91/****************************************************************************** 92 * 93 * FUNCTION: acpi_ut_validate_fadt 94 * 95 * PARAMETERS: None 96 * 97 * RETURN: Status 98 * 99 * DESCRIPTION: Validate various ACPI registers in the FADT 100 * 101 ******************************************************************************/ 102 103acpi_status 104acpi_ut_validate_fadt ( 105 void) 106{ 107 108 /* 109 * Verify Fixed ACPI Description Table fields, 110 * but don't abort on any problems, just display error 111 */ 112 if (acpi_gbl_FADT->pm1_evt_len < 4) { 113 acpi_ut_fadt_register_error ("PM1_EVT_LEN", 114 (u32) acpi_gbl_FADT->pm1_evt_len, 115 ACPI_FADT_OFFSET (pm1_evt_len)); 116 } 117 118 if (!acpi_gbl_FADT->pm1_cnt_len) { 119 acpi_ut_fadt_register_error ("PM1_CNT_LEN", 0, 120 ACPI_FADT_OFFSET (pm1_cnt_len)); 121 } 122 123 if (!acpi_gbl_FADT->xpm1a_evt_blk.address) { 124 acpi_ut_fadt_register_error ("X_PM1a_EVT_BLK", 0, 125 ACPI_FADT_OFFSET (xpm1a_evt_blk.address)); 126 } 127 128 if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) { 129 acpi_ut_fadt_register_error ("X_PM1a_CNT_BLK", 0, 130 ACPI_FADT_OFFSET (xpm1a_cnt_blk.address)); 131 } 132 133 if (!acpi_gbl_FADT->xpm_tmr_blk.address) { 134 acpi_ut_fadt_register_error ("X_PM_TMR_BLK", 0, 135 ACPI_FADT_OFFSET (xpm_tmr_blk.address)); 136 } 137 138 if ((acpi_gbl_FADT->xpm2_cnt_blk.address && 139 !acpi_gbl_FADT->pm2_cnt_len)) { 140 acpi_ut_fadt_register_error ("PM2_CNT_LEN", 141 (u32) acpi_gbl_FADT->pm2_cnt_len, 142 ACPI_FADT_OFFSET (pm2_cnt_len)); 143 } 144 145 if (acpi_gbl_FADT->pm_tm_len < 4) { 146 acpi_ut_fadt_register_error ("PM_TM_LEN", 147 (u32) acpi_gbl_FADT->pm_tm_len, 148 ACPI_FADT_OFFSET (pm_tm_len)); 149 } 150 151 /* Length of GPE blocks must be a multiple of 2 */ 152 153 if (acpi_gbl_FADT->xgpe0_blk.address && 154 (acpi_gbl_FADT->gpe0_blk_len & 1)) { 155 acpi_ut_fadt_register_error ("(x)GPE0_BLK_LEN", 156 (u32) acpi_gbl_FADT->gpe0_blk_len, 157 ACPI_FADT_OFFSET (gpe0_blk_len)); 158 } 159 160 if (acpi_gbl_FADT->xgpe1_blk.address && 161 (acpi_gbl_FADT->gpe1_blk_len & 1)) { 162 acpi_ut_fadt_register_error ("(x)GPE1_BLK_LEN", 163 (u32) acpi_gbl_FADT->gpe1_blk_len, 164 ACPI_FADT_OFFSET (gpe1_blk_len)); 165 } 166 167 return (AE_OK); 168} 169 170 171/****************************************************************************** 172 * 173 * FUNCTION: acpi_ut_terminate 174 * 175 * PARAMETERS: none 176 * 177 * RETURN: none 178 * 179 * DESCRIPTION: Free global memory 180 * 181 ******************************************************************************/ 182 183static void 184acpi_ut_terminate ( 185 void) 186{ 187 struct acpi_gpe_block_info *gpe_block; 188 struct acpi_gpe_block_info *next_gpe_block; 189 struct acpi_gpe_xrupt_info *gpe_xrupt_info; 190 struct acpi_gpe_xrupt_info *next_gpe_xrupt_info; 191 192 193 ACPI_FUNCTION_TRACE ("ut_terminate"); 194 195 196 /* Free global tables, etc. */ 197 /* Free global GPE blocks and related info structures */ 198 199 gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; 200 while (gpe_xrupt_info) { 201 gpe_block = gpe_xrupt_info->gpe_block_list_head; 202 while (gpe_block) { 203 next_gpe_block = gpe_block->next; 204 ACPI_MEM_FREE (gpe_block->event_info); 205 ACPI_MEM_FREE (gpe_block->register_info); 206 ACPI_MEM_FREE (gpe_block); 207 208 gpe_block = next_gpe_block; 209 } 210 next_gpe_xrupt_info = gpe_xrupt_info->next; 211 ACPI_MEM_FREE (gpe_xrupt_info); 212 gpe_xrupt_info = next_gpe_xrupt_info; 213 } 214 215 return_VOID; 216} 217 218 219/******************************************************************************* 220 * 221 * FUNCTION: acpi_ut_subsystem_shutdown 222 * 223 * PARAMETERS: none 224 * 225 * RETURN: none 226 * 227 * DESCRIPTION: Shutdown the various subsystems. Don't delete the mutex 228 * objects here -- because the AML debugger may be still running. 229 * 230 ******************************************************************************/ 231 232void 233acpi_ut_subsystem_shutdown ( 234 void) 235{ 236 237 ACPI_FUNCTION_TRACE ("ut_subsystem_shutdown"); 238 239 /* Just exit if subsystem is already shutdown */ 240 241 if (acpi_gbl_shutdown) { 242 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 243 "ACPI Subsystem is already terminated\n")); 244 return_VOID; 245 } 246 247 /* Subsystem appears active, go ahead and shut it down */ 248 249 acpi_gbl_shutdown = TRUE; 250 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 251 "Shutting down ACPI Subsystem...\n")); 252 253 /* Close the acpi_event Handling */ 254 255 acpi_ev_terminate (); 256 257 /* Close the Namespace */ 258 259 acpi_ns_terminate (); 260 261 /* Close the globals */ 262 263 acpi_ut_terminate (); 264 265 /* Purge the local caches */ 266 267 (void) acpi_purge_cached_objects (); 268 269 /* Debug only - display leftover memory allocation, if any */ 270 271#ifdef ACPI_DBG_TRACK_ALLOCATIONS 272 acpi_ut_dump_allocations (ACPI_UINT32_MAX, NULL); 273#endif 274 275 return_VOID; 276} 277 278