1 /****************************************************************************** 2 * 3 * Module Name: utxface - External interfaces, miscellaneous utility functions 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, Intel Corp. 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 #define EXPORT_ACPI_INTERFACES 45 46 #include <acpi/acpi.h> 47 #include "accommon.h" 48 #include "acdebug.h" 49 50 #define _COMPONENT ACPI_UTILITIES 51 ACPI_MODULE_NAME("utxface") 52 53 /******************************************************************************* 54 * 55 * FUNCTION: acpi_terminate 56 * 57 * PARAMETERS: None 58 * 59 * RETURN: Status 60 * 61 * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources. 62 * 63 ******************************************************************************/ 64 acpi_status __init acpi_terminate(void) 65 { 66 acpi_status status; 67 68 ACPI_FUNCTION_TRACE(acpi_terminate); 69 70 /* Just exit if subsystem is already shutdown */ 71 72 if (acpi_gbl_shutdown) { 73 ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated")); 74 return_ACPI_STATUS(AE_OK); 75 } 76 77 /* Subsystem appears active, go ahead and shut it down */ 78 79 acpi_gbl_shutdown = TRUE; 80 acpi_gbl_startup_flags = 0; 81 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); 82 83 /* Terminate the AML Debugger if present */ 84 85 ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); 86 87 /* Shutdown and free all resources */ 88 89 acpi_ut_subsystem_shutdown(); 90 91 /* Free the mutex objects */ 92 93 acpi_ut_mutex_terminate(); 94 95 /* Now we can shutdown the OS-dependent layer */ 96 97 status = acpi_os_terminate(); 98 return_ACPI_STATUS(status); 99 } 100 101 ACPI_EXPORT_SYMBOL_INIT(acpi_terminate) 102 103 #ifndef ACPI_ASL_COMPILER 104 #ifdef ACPI_FUTURE_USAGE 105 /******************************************************************************* 106 * 107 * FUNCTION: acpi_subsystem_status 108 * 109 * PARAMETERS: None 110 * 111 * RETURN: Status of the ACPI subsystem 112 * 113 * DESCRIPTION: Other drivers that use the ACPI subsystem should call this 114 * before making any other calls, to ensure the subsystem 115 * initialized successfully. 116 * 117 ******************************************************************************/ 118 acpi_status acpi_subsystem_status(void) 119 { 120 121 if (acpi_gbl_startup_flags & ACPI_INITIALIZED_OK) { 122 return (AE_OK); 123 } else { 124 return (AE_ERROR); 125 } 126 } 127 128 ACPI_EXPORT_SYMBOL(acpi_subsystem_status) 129 130 /******************************************************************************* 131 * 132 * FUNCTION: acpi_get_system_info 133 * 134 * PARAMETERS: out_buffer - A buffer to receive the resources for the 135 * device 136 * 137 * RETURN: status - the status of the call 138 * 139 * DESCRIPTION: This function is called to get information about the current 140 * state of the ACPI subsystem. It will return system information 141 * in the out_buffer. 142 * 143 * If the function fails an appropriate status will be returned 144 * and the value of out_buffer is undefined. 145 * 146 ******************************************************************************/ 147 acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) 148 { 149 struct acpi_system_info *info_ptr; 150 acpi_status status; 151 152 ACPI_FUNCTION_TRACE(acpi_get_system_info); 153 154 /* Parameter validation */ 155 156 status = acpi_ut_validate_buffer(out_buffer); 157 if (ACPI_FAILURE(status)) { 158 return_ACPI_STATUS(status); 159 } 160 161 /* Validate/Allocate/Clear caller buffer */ 162 163 status = 164 acpi_ut_initialize_buffer(out_buffer, 165 sizeof(struct acpi_system_info)); 166 if (ACPI_FAILURE(status)) { 167 return_ACPI_STATUS(status); 168 } 169 170 /* 171 * Populate the return buffer 172 */ 173 info_ptr = (struct acpi_system_info *)out_buffer->pointer; 174 175 info_ptr->acpi_ca_version = ACPI_CA_VERSION; 176 177 /* System flags (ACPI capabilities) */ 178 179 info_ptr->flags = ACPI_SYS_MODE_ACPI; 180 181 /* Timer resolution - 24 or 32 bits */ 182 183 if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) { 184 info_ptr->timer_resolution = 24; 185 } else { 186 info_ptr->timer_resolution = 32; 187 } 188 189 /* Clear the reserved fields */ 190 191 info_ptr->reserved1 = 0; 192 info_ptr->reserved2 = 0; 193 194 /* Current debug levels */ 195 196 info_ptr->debug_layer = acpi_dbg_layer; 197 info_ptr->debug_level = acpi_dbg_level; 198 199 return_ACPI_STATUS(AE_OK); 200 } 201 202 ACPI_EXPORT_SYMBOL(acpi_get_system_info) 203 204 /******************************************************************************* 205 * 206 * FUNCTION: acpi_get_statistics 207 * 208 * PARAMETERS: stats - Where the statistics are returned 209 * 210 * RETURN: status - the status of the call 211 * 212 * DESCRIPTION: Get the contents of the various system counters 213 * 214 ******************************************************************************/ 215 acpi_status acpi_get_statistics(struct acpi_statistics *stats) 216 { 217 ACPI_FUNCTION_TRACE(acpi_get_statistics); 218 219 /* Parameter validation */ 220 221 if (!stats) { 222 return_ACPI_STATUS(AE_BAD_PARAMETER); 223 } 224 225 /* Various interrupt-based event counters */ 226 227 stats->sci_count = acpi_sci_count; 228 stats->gpe_count = acpi_gpe_count; 229 230 memcpy(stats->fixed_event_count, acpi_fixed_event_count, 231 sizeof(acpi_fixed_event_count)); 232 233 /* Other counters */ 234 235 stats->method_count = acpi_method_count; 236 237 return_ACPI_STATUS(AE_OK); 238 } 239 240 ACPI_EXPORT_SYMBOL(acpi_get_statistics) 241 242 /***************************************************************************** 243 * 244 * FUNCTION: acpi_install_initialization_handler 245 * 246 * PARAMETERS: handler - Callback procedure 247 * function - Not (currently) used, see below 248 * 249 * RETURN: Status 250 * 251 * DESCRIPTION: Install an initialization handler 252 * 253 * TBD: When a second function is added, must save the Function also. 254 * 255 ****************************************************************************/ 256 acpi_status 257 acpi_install_initialization_handler(acpi_init_handler handler, u32 function) 258 { 259 260 if (!handler) { 261 return (AE_BAD_PARAMETER); 262 } 263 264 if (acpi_gbl_init_handler) { 265 return (AE_ALREADY_EXISTS); 266 } 267 268 acpi_gbl_init_handler = handler; 269 return (AE_OK); 270 } 271 272 ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) 273 #endif /* ACPI_FUTURE_USAGE */ 274 275 /***************************************************************************** 276 * 277 * FUNCTION: acpi_purge_cached_objects 278 * 279 * PARAMETERS: None 280 * 281 * RETURN: Status 282 * 283 * DESCRIPTION: Empty all caches (delete the cached objects) 284 * 285 ****************************************************************************/ 286 acpi_status acpi_purge_cached_objects(void) 287 { 288 ACPI_FUNCTION_TRACE(acpi_purge_cached_objects); 289 290 (void)acpi_os_purge_cache(acpi_gbl_state_cache); 291 (void)acpi_os_purge_cache(acpi_gbl_operand_cache); 292 (void)acpi_os_purge_cache(acpi_gbl_ps_node_cache); 293 (void)acpi_os_purge_cache(acpi_gbl_ps_node_ext_cache); 294 295 return_ACPI_STATUS(AE_OK); 296 } 297 298 ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) 299 300 /***************************************************************************** 301 * 302 * FUNCTION: acpi_install_interface 303 * 304 * PARAMETERS: interface_name - The interface to install 305 * 306 * RETURN: Status 307 * 308 * DESCRIPTION: Install an _OSI interface to the global list 309 * 310 ****************************************************************************/ 311 acpi_status acpi_install_interface(acpi_string interface_name) 312 { 313 acpi_status status; 314 struct acpi_interface_info *interface_info; 315 316 /* Parameter validation */ 317 318 if (!interface_name || (strlen(interface_name) == 0)) { 319 return (AE_BAD_PARAMETER); 320 } 321 322 status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); 323 if (ACPI_FAILURE(status)) { 324 return (status); 325 } 326 327 /* Check if the interface name is already in the global list */ 328 329 interface_info = acpi_ut_get_interface(interface_name); 330 if (interface_info) { 331 /* 332 * The interface already exists in the list. This is OK if the 333 * interface has been marked invalid -- just clear the bit. 334 */ 335 if (interface_info->flags & ACPI_OSI_INVALID) { 336 interface_info->flags &= ~ACPI_OSI_INVALID; 337 status = AE_OK; 338 } else { 339 status = AE_ALREADY_EXISTS; 340 } 341 } else { 342 /* New interface name, install into the global list */ 343 344 status = acpi_ut_install_interface(interface_name); 345 } 346 347 acpi_os_release_mutex(acpi_gbl_osi_mutex); 348 return (status); 349 } 350 351 ACPI_EXPORT_SYMBOL(acpi_install_interface) 352 353 /***************************************************************************** 354 * 355 * FUNCTION: acpi_remove_interface 356 * 357 * PARAMETERS: interface_name - The interface to remove 358 * 359 * RETURN: Status 360 * 361 * DESCRIPTION: Remove an _OSI interface from the global list 362 * 363 ****************************************************************************/ 364 acpi_status acpi_remove_interface(acpi_string interface_name) 365 { 366 acpi_status status; 367 368 /* Parameter validation */ 369 370 if (!interface_name || (strlen(interface_name) == 0)) { 371 return (AE_BAD_PARAMETER); 372 } 373 374 status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); 375 if (ACPI_FAILURE(status)) { 376 return (status); 377 } 378 379 status = acpi_ut_remove_interface(interface_name); 380 381 acpi_os_release_mutex(acpi_gbl_osi_mutex); 382 return (status); 383 } 384 385 ACPI_EXPORT_SYMBOL(acpi_remove_interface) 386 387 /***************************************************************************** 388 * 389 * FUNCTION: acpi_install_interface_handler 390 * 391 * PARAMETERS: handler - The _OSI interface handler to install 392 * NULL means "remove existing handler" 393 * 394 * RETURN: Status 395 * 396 * DESCRIPTION: Install a handler for the predefined _OSI ACPI method. 397 * invoked during execution of the internal implementation of 398 * _OSI. A NULL handler simply removes any existing handler. 399 * 400 ****************************************************************************/ 401 acpi_status acpi_install_interface_handler(acpi_interface_handler handler) 402 { 403 acpi_status status; 404 405 status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); 406 if (ACPI_FAILURE(status)) { 407 return (status); 408 } 409 410 if (handler && acpi_gbl_interface_handler) { 411 status = AE_ALREADY_EXISTS; 412 } else { 413 acpi_gbl_interface_handler = handler; 414 } 415 416 acpi_os_release_mutex(acpi_gbl_osi_mutex); 417 return (status); 418 } 419 420 ACPI_EXPORT_SYMBOL(acpi_install_interface_handler) 421 422 /***************************************************************************** 423 * 424 * FUNCTION: acpi_update_interfaces 425 * 426 * PARAMETERS: action - Actions to be performed during the 427 * update 428 * 429 * RETURN: Status 430 * 431 * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor 432 * string or/and feature group strings. 433 * 434 ****************************************************************************/ 435 acpi_status acpi_update_interfaces(u8 action) 436 { 437 acpi_status status; 438 439 status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); 440 if (ACPI_FAILURE(status)) { 441 return (status); 442 } 443 444 status = acpi_ut_update_interfaces(action); 445 446 acpi_os_release_mutex(acpi_gbl_osi_mutex); 447 return (status); 448 } 449 450 /***************************************************************************** 451 * 452 * FUNCTION: acpi_check_address_range 453 * 454 * PARAMETERS: space_id - Address space ID 455 * address - Start address 456 * length - Length 457 * warn - TRUE if warning on overlap desired 458 * 459 * RETURN: Count of the number of conflicts detected. 460 * 461 * DESCRIPTION: Check if the input address range overlaps any of the 462 * ASL operation region address ranges. 463 * 464 ****************************************************************************/ 465 466 u32 467 acpi_check_address_range(acpi_adr_space_type space_id, 468 acpi_physical_address address, 469 acpi_size length, u8 warn) 470 { 471 u32 overlaps; 472 acpi_status status; 473 474 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 475 if (ACPI_FAILURE(status)) { 476 return (0); 477 } 478 479 overlaps = acpi_ut_check_address_range(space_id, address, 480 (u32)length, warn); 481 482 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 483 return (overlaps); 484 } 485 486 ACPI_EXPORT_SYMBOL(acpi_check_address_range) 487 #endif /* !ACPI_ASL_COMPILER */ 488 /******************************************************************************* 489 * 490 * FUNCTION: acpi_decode_pld_buffer 491 * 492 * PARAMETERS: in_buffer - Buffer returned by _PLD method 493 * length - Length of the in_buffer 494 * return_buffer - Where the decode buffer is returned 495 * 496 * RETURN: Status and the decoded _PLD buffer. User must deallocate 497 * the buffer via ACPI_FREE. 498 * 499 * DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into 500 * a local struct that is much more useful to an ACPI driver. 501 * 502 ******************************************************************************/ 503 acpi_status 504 acpi_decode_pld_buffer(u8 *in_buffer, 505 acpi_size length, struct acpi_pld_info ** return_buffer) 506 { 507 struct acpi_pld_info *pld_info; 508 u32 *buffer = ACPI_CAST_PTR(u32, in_buffer); 509 u32 dword; 510 511 /* Parameter validation */ 512 513 if (!in_buffer || !return_buffer 514 || (length < ACPI_PLD_REV1_BUFFER_SIZE)) { 515 return (AE_BAD_PARAMETER); 516 } 517 518 pld_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pld_info)); 519 if (!pld_info) { 520 return (AE_NO_MEMORY); 521 } 522 523 /* First 32-bit DWord */ 524 525 ACPI_MOVE_32_TO_32(&dword, &buffer[0]); 526 pld_info->revision = ACPI_PLD_GET_REVISION(&dword); 527 pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword); 528 pld_info->red = ACPI_PLD_GET_RED(&dword); 529 pld_info->green = ACPI_PLD_GET_GREEN(&dword); 530 pld_info->blue = ACPI_PLD_GET_BLUE(&dword); 531 532 /* Second 32-bit DWord */ 533 534 ACPI_MOVE_32_TO_32(&dword, &buffer[1]); 535 pld_info->width = ACPI_PLD_GET_WIDTH(&dword); 536 pld_info->height = ACPI_PLD_GET_HEIGHT(&dword); 537 538 /* Third 32-bit DWord */ 539 540 ACPI_MOVE_32_TO_32(&dword, &buffer[2]); 541 pld_info->user_visible = ACPI_PLD_GET_USER_VISIBLE(&dword); 542 pld_info->dock = ACPI_PLD_GET_DOCK(&dword); 543 pld_info->lid = ACPI_PLD_GET_LID(&dword); 544 pld_info->panel = ACPI_PLD_GET_PANEL(&dword); 545 pld_info->vertical_position = ACPI_PLD_GET_VERTICAL(&dword); 546 pld_info->horizontal_position = ACPI_PLD_GET_HORIZONTAL(&dword); 547 pld_info->shape = ACPI_PLD_GET_SHAPE(&dword); 548 pld_info->group_orientation = ACPI_PLD_GET_ORIENTATION(&dword); 549 pld_info->group_token = ACPI_PLD_GET_TOKEN(&dword); 550 pld_info->group_position = ACPI_PLD_GET_POSITION(&dword); 551 pld_info->bay = ACPI_PLD_GET_BAY(&dword); 552 553 /* Fourth 32-bit DWord */ 554 555 ACPI_MOVE_32_TO_32(&dword, &buffer[3]); 556 pld_info->ejectable = ACPI_PLD_GET_EJECTABLE(&dword); 557 pld_info->ospm_eject_required = ACPI_PLD_GET_OSPM_EJECT(&dword); 558 pld_info->cabinet_number = ACPI_PLD_GET_CABINET(&dword); 559 pld_info->card_cage_number = ACPI_PLD_GET_CARD_CAGE(&dword); 560 pld_info->reference = ACPI_PLD_GET_REFERENCE(&dword); 561 pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword); 562 pld_info->order = ACPI_PLD_GET_ORDER(&dword); 563 564 if (length >= ACPI_PLD_REV2_BUFFER_SIZE) { 565 566 /* Fifth 32-bit DWord (Revision 2 of _PLD) */ 567 568 ACPI_MOVE_32_TO_32(&dword, &buffer[4]); 569 pld_info->vertical_offset = ACPI_PLD_GET_VERT_OFFSET(&dword); 570 pld_info->horizontal_offset = ACPI_PLD_GET_HORIZ_OFFSET(&dword); 571 } 572 573 *return_buffer = pld_info; 574 return (AE_OK); 575 } 576 577 ACPI_EXPORT_SYMBOL(acpi_decode_pld_buffer) 578