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