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