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