Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: utxface - External interfaces, miscellaneous utility functions
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #define EXPORT_ACPI_INTERFACES
0011 
0012 #include <acpi/acpi.h>
0013 #include "accommon.h"
0014 #include "acdebug.h"
0015 
0016 #define _COMPONENT          ACPI_UTILITIES
0017 ACPI_MODULE_NAME("utxface")
0018 
0019 /*******************************************************************************
0020  *
0021  * FUNCTION:    acpi_terminate
0022  *
0023  * PARAMETERS:  None
0024  *
0025  * RETURN:      Status
0026  *
0027  * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources.
0028  *
0029  ******************************************************************************/
0030 acpi_status ACPI_INIT_FUNCTION acpi_terminate(void)
0031 {
0032     acpi_status status;
0033 
0034     ACPI_FUNCTION_TRACE(acpi_terminate);
0035 
0036     /* Shutdown and free all resources */
0037 
0038     acpi_ut_subsystem_shutdown();
0039 
0040     /* Free the mutex objects */
0041 
0042     acpi_ut_mutex_terminate();
0043 
0044     /* Now we can shutdown the OS-dependent layer */
0045 
0046     status = acpi_os_terminate();
0047     return_ACPI_STATUS(status);
0048 }
0049 
0050 ACPI_EXPORT_SYMBOL_INIT(acpi_terminate)
0051 
0052 #ifndef ACPI_ASL_COMPILER
0053 #ifdef ACPI_FUTURE_USAGE
0054 /*******************************************************************************
0055  *
0056  * FUNCTION:    acpi_subsystem_status
0057  *
0058  * PARAMETERS:  None
0059  *
0060  * RETURN:      Status of the ACPI subsystem
0061  *
0062  * DESCRIPTION: Other drivers that use the ACPI subsystem should call this
0063  *              before making any other calls, to ensure the subsystem
0064  *              initialized successfully.
0065  *
0066  ******************************************************************************/
0067 acpi_status acpi_subsystem_status(void)
0068 {
0069 
0070     if (acpi_gbl_startup_flags & ACPI_INITIALIZED_OK) {
0071         return (AE_OK);
0072     } else {
0073         return (AE_ERROR);
0074     }
0075 }
0076 
0077 ACPI_EXPORT_SYMBOL(acpi_subsystem_status)
0078 
0079 /*******************************************************************************
0080  *
0081  * FUNCTION:    acpi_get_system_info
0082  *
0083  * PARAMETERS:  out_buffer      - A buffer to receive the resources for the
0084  *                                device
0085  *
0086  * RETURN:      status          - the status of the call
0087  *
0088  * DESCRIPTION: This function is called to get information about the current
0089  *              state of the ACPI subsystem. It will return system information
0090  *              in the out_buffer.
0091  *
0092  *              If the function fails an appropriate status will be returned
0093  *              and the value of out_buffer is undefined.
0094  *
0095  ******************************************************************************/
0096 acpi_status acpi_get_system_info(struct acpi_buffer *out_buffer)
0097 {
0098     struct acpi_system_info *info_ptr;
0099     acpi_status status;
0100 
0101     ACPI_FUNCTION_TRACE(acpi_get_system_info);
0102 
0103     /* Parameter validation */
0104 
0105     status = acpi_ut_validate_buffer(out_buffer);
0106     if (ACPI_FAILURE(status)) {
0107         return_ACPI_STATUS(status);
0108     }
0109 
0110     /* Validate/Allocate/Clear caller buffer */
0111 
0112     status =
0113         acpi_ut_initialize_buffer(out_buffer,
0114                       sizeof(struct acpi_system_info));
0115     if (ACPI_FAILURE(status)) {
0116         return_ACPI_STATUS(status);
0117     }
0118 
0119     /*
0120      * Populate the return buffer
0121      */
0122     info_ptr = (struct acpi_system_info *)out_buffer->pointer;
0123     info_ptr->acpi_ca_version = ACPI_CA_VERSION;
0124 
0125     /* System flags (ACPI capabilities) */
0126 
0127     info_ptr->flags = ACPI_SYS_MODE_ACPI;
0128 
0129     /* Timer resolution - 24 or 32 bits  */
0130 
0131     if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) {
0132         info_ptr->timer_resolution = 24;
0133     } else {
0134         info_ptr->timer_resolution = 32;
0135     }
0136 
0137     /* Clear the reserved fields */
0138 
0139     info_ptr->reserved1 = 0;
0140     info_ptr->reserved2 = 0;
0141 
0142     /* Current debug levels */
0143 
0144     info_ptr->debug_layer = acpi_dbg_layer;
0145     info_ptr->debug_level = acpi_dbg_level;
0146 
0147     return_ACPI_STATUS(AE_OK);
0148 }
0149 
0150 ACPI_EXPORT_SYMBOL(acpi_get_system_info)
0151 
0152 /*******************************************************************************
0153  *
0154  * FUNCTION:    acpi_get_statistics
0155  *
0156  * PARAMETERS:  stats           - Where the statistics are returned
0157  *
0158  * RETURN:      status          - the status of the call
0159  *
0160  * DESCRIPTION: Get the contents of the various system counters
0161  *
0162  ******************************************************************************/
0163 acpi_status acpi_get_statistics(struct acpi_statistics *stats)
0164 {
0165     ACPI_FUNCTION_TRACE(acpi_get_statistics);
0166 
0167     /* Parameter validation */
0168 
0169     if (!stats) {
0170         return_ACPI_STATUS(AE_BAD_PARAMETER);
0171     }
0172 
0173     /* Various interrupt-based event counters */
0174 
0175     stats->sci_count = acpi_sci_count;
0176     stats->gpe_count = acpi_gpe_count;
0177 
0178     memcpy(stats->fixed_event_count, acpi_fixed_event_count,
0179            sizeof(acpi_fixed_event_count));
0180 
0181     /* Other counters */
0182 
0183     stats->method_count = acpi_method_count;
0184     return_ACPI_STATUS(AE_OK);
0185 }
0186 
0187 ACPI_EXPORT_SYMBOL(acpi_get_statistics)
0188 
0189 /*****************************************************************************
0190  *
0191  * FUNCTION:    acpi_install_initialization_handler
0192  *
0193  * PARAMETERS:  handler             - Callback procedure
0194  *              function            - Not (currently) used, see below
0195  *
0196  * RETURN:      Status
0197  *
0198  * DESCRIPTION: Install an initialization handler
0199  *
0200  * TBD: When a second function is added, must save the Function also.
0201  *
0202  ****************************************************************************/
0203 acpi_status
0204 acpi_install_initialization_handler(acpi_init_handler handler, u32 function)
0205 {
0206 
0207     if (!handler) {
0208         return (AE_BAD_PARAMETER);
0209     }
0210 
0211     if (acpi_gbl_init_handler) {
0212         return (AE_ALREADY_EXISTS);
0213     }
0214 
0215     acpi_gbl_init_handler = handler;
0216     return (AE_OK);
0217 }
0218 
0219 ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler)
0220 #endif
0221 
0222 /*****************************************************************************
0223  *
0224  * FUNCTION:    acpi_purge_cached_objects
0225  *
0226  * PARAMETERS:  None
0227  *
0228  * RETURN:      Status
0229  *
0230  * DESCRIPTION: Empty all caches (delete the cached objects)
0231  *
0232  ****************************************************************************/
0233 acpi_status acpi_purge_cached_objects(void)
0234 {
0235     ACPI_FUNCTION_TRACE(acpi_purge_cached_objects);
0236 
0237     (void)acpi_os_purge_cache(acpi_gbl_state_cache);
0238     (void)acpi_os_purge_cache(acpi_gbl_operand_cache);
0239     (void)acpi_os_purge_cache(acpi_gbl_ps_node_cache);
0240     (void)acpi_os_purge_cache(acpi_gbl_ps_node_ext_cache);
0241 
0242     return_ACPI_STATUS(AE_OK);
0243 }
0244 
0245 ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects)
0246 
0247 /*****************************************************************************
0248  *
0249  * FUNCTION:    acpi_install_interface
0250  *
0251  * PARAMETERS:  interface_name      - The interface to install
0252  *
0253  * RETURN:      Status
0254  *
0255  * DESCRIPTION: Install an _OSI interface to the global list
0256  *
0257  ****************************************************************************/
0258 acpi_status acpi_install_interface(acpi_string interface_name)
0259 {
0260     acpi_status status;
0261     struct acpi_interface_info *interface_info;
0262 
0263     /* Parameter validation */
0264 
0265     if (!interface_name || (strlen(interface_name) == 0)) {
0266         return (AE_BAD_PARAMETER);
0267     }
0268 
0269     status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
0270     if (ACPI_FAILURE(status)) {
0271         return (status);
0272     }
0273 
0274     /* Check if the interface name is already in the global list */
0275 
0276     interface_info = acpi_ut_get_interface(interface_name);
0277     if (interface_info) {
0278         /*
0279          * The interface already exists in the list. This is OK if the
0280          * interface has been marked invalid -- just clear the bit.
0281          */
0282         if (interface_info->flags & ACPI_OSI_INVALID) {
0283             interface_info->flags &= ~ACPI_OSI_INVALID;
0284             status = AE_OK;
0285         } else {
0286             status = AE_ALREADY_EXISTS;
0287         }
0288     } else {
0289         /* New interface name, install into the global list */
0290 
0291         status = acpi_ut_install_interface(interface_name);
0292     }
0293 
0294     acpi_os_release_mutex(acpi_gbl_osi_mutex);
0295     return (status);
0296 }
0297 
0298 ACPI_EXPORT_SYMBOL(acpi_install_interface)
0299 
0300 /*****************************************************************************
0301  *
0302  * FUNCTION:    acpi_remove_interface
0303  *
0304  * PARAMETERS:  interface_name      - The interface to remove
0305  *
0306  * RETURN:      Status
0307  *
0308  * DESCRIPTION: Remove an _OSI interface from the global list
0309  *
0310  ****************************************************************************/
0311 acpi_status acpi_remove_interface(acpi_string interface_name)
0312 {
0313     acpi_status status;
0314 
0315     /* Parameter validation */
0316 
0317     if (!interface_name || (strlen(interface_name) == 0)) {
0318         return (AE_BAD_PARAMETER);
0319     }
0320 
0321     status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
0322     if (ACPI_FAILURE(status)) {
0323         return (status);
0324     }
0325 
0326     status = acpi_ut_remove_interface(interface_name);
0327 
0328     acpi_os_release_mutex(acpi_gbl_osi_mutex);
0329     return (status);
0330 }
0331 
0332 ACPI_EXPORT_SYMBOL(acpi_remove_interface)
0333 
0334 /*****************************************************************************
0335  *
0336  * FUNCTION:    acpi_install_interface_handler
0337  *
0338  * PARAMETERS:  handler             - The _OSI interface handler to install
0339  *                                    NULL means "remove existing handler"
0340  *
0341  * RETURN:      Status
0342  *
0343  * DESCRIPTION: Install a handler for the predefined _OSI ACPI method.
0344  *              invoked during execution of the internal implementation of
0345  *              _OSI. A NULL handler simply removes any existing handler.
0346  *
0347  ****************************************************************************/
0348 acpi_status acpi_install_interface_handler(acpi_interface_handler handler)
0349 {
0350     acpi_status status;
0351 
0352     status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
0353     if (ACPI_FAILURE(status)) {
0354         return (status);
0355     }
0356 
0357     if (handler && acpi_gbl_interface_handler) {
0358         status = AE_ALREADY_EXISTS;
0359     } else {
0360         acpi_gbl_interface_handler = handler;
0361     }
0362 
0363     acpi_os_release_mutex(acpi_gbl_osi_mutex);
0364     return (status);
0365 }
0366 
0367 ACPI_EXPORT_SYMBOL(acpi_install_interface_handler)
0368 
0369 /*****************************************************************************
0370  *
0371  * FUNCTION:    acpi_update_interfaces
0372  *
0373  * PARAMETERS:  action              - Actions to be performed during the
0374  *                                    update
0375  *
0376  * RETURN:      Status
0377  *
0378  * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor
0379  *              string or/and feature group strings.
0380  *
0381  ****************************************************************************/
0382 acpi_status acpi_update_interfaces(u8 action)
0383 {
0384     acpi_status status;
0385 
0386     status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
0387     if (ACPI_FAILURE(status)) {
0388         return (status);
0389     }
0390 
0391     status = acpi_ut_update_interfaces(action);
0392 
0393     acpi_os_release_mutex(acpi_gbl_osi_mutex);
0394     return (status);
0395 }
0396 
0397 /*****************************************************************************
0398  *
0399  * FUNCTION:    acpi_check_address_range
0400  *
0401  * PARAMETERS:  space_id            - Address space ID
0402  *              address             - Start address
0403  *              length              - Length
0404  *              warn                - TRUE if warning on overlap desired
0405  *
0406  * RETURN:      Count of the number of conflicts detected.
0407  *
0408  * DESCRIPTION: Check if the input address range overlaps any of the
0409  *              ASL operation region address ranges.
0410  *
0411  ****************************************************************************/
0412 
0413 u32
0414 acpi_check_address_range(acpi_adr_space_type space_id,
0415              acpi_physical_address address,
0416              acpi_size length, u8 warn)
0417 {
0418     u32 overlaps;
0419     acpi_status status;
0420 
0421     status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
0422     if (ACPI_FAILURE(status)) {
0423         return (0);
0424     }
0425 
0426     overlaps = acpi_ut_check_address_range(space_id, address,
0427                            (u32)length, warn);
0428 
0429     (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
0430     return (overlaps);
0431 }
0432 
0433 ACPI_EXPORT_SYMBOL(acpi_check_address_range)
0434 #endif              /* !ACPI_ASL_COMPILER */
0435 /*******************************************************************************
0436  *
0437  * FUNCTION:    acpi_decode_pld_buffer
0438  *
0439  * PARAMETERS:  in_buffer           - Buffer returned by _PLD method
0440  *              length              - Length of the in_buffer
0441  *              return_buffer       - Where the decode buffer is returned
0442  *
0443  * RETURN:      Status and the decoded _PLD buffer. User must deallocate
0444  *              the buffer via ACPI_FREE.
0445  *
0446  * DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into
0447  *              a local struct that is much more useful to an ACPI driver.
0448  *
0449  ******************************************************************************/
0450 acpi_status
0451 acpi_decode_pld_buffer(u8 *in_buffer,
0452                acpi_size length, struct acpi_pld_info **return_buffer)
0453 {
0454     struct acpi_pld_info *pld_info;
0455     u32 *buffer = ACPI_CAST_PTR(u32, in_buffer);
0456     u32 dword;
0457 
0458     /* Parameter validation */
0459 
0460     if (!in_buffer || !return_buffer
0461         || (length < ACPI_PLD_REV1_BUFFER_SIZE)) {
0462         return (AE_BAD_PARAMETER);
0463     }
0464 
0465     pld_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pld_info));
0466     if (!pld_info) {
0467         return (AE_NO_MEMORY);
0468     }
0469 
0470     /* First 32-bit DWord */
0471 
0472     ACPI_MOVE_32_TO_32(&dword, &buffer[0]);
0473     pld_info->revision = ACPI_PLD_GET_REVISION(&dword);
0474     pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword);
0475     pld_info->red = ACPI_PLD_GET_RED(&dword);
0476     pld_info->green = ACPI_PLD_GET_GREEN(&dword);
0477     pld_info->blue = ACPI_PLD_GET_BLUE(&dword);
0478 
0479     /* Second 32-bit DWord */
0480 
0481     ACPI_MOVE_32_TO_32(&dword, &buffer[1]);
0482     pld_info->width = ACPI_PLD_GET_WIDTH(&dword);
0483     pld_info->height = ACPI_PLD_GET_HEIGHT(&dword);
0484 
0485     /* Third 32-bit DWord */
0486 
0487     ACPI_MOVE_32_TO_32(&dword, &buffer[2]);
0488     pld_info->user_visible = ACPI_PLD_GET_USER_VISIBLE(&dword);
0489     pld_info->dock = ACPI_PLD_GET_DOCK(&dword);
0490     pld_info->lid = ACPI_PLD_GET_LID(&dword);
0491     pld_info->panel = ACPI_PLD_GET_PANEL(&dword);
0492     pld_info->vertical_position = ACPI_PLD_GET_VERTICAL(&dword);
0493     pld_info->horizontal_position = ACPI_PLD_GET_HORIZONTAL(&dword);
0494     pld_info->shape = ACPI_PLD_GET_SHAPE(&dword);
0495     pld_info->group_orientation = ACPI_PLD_GET_ORIENTATION(&dword);
0496     pld_info->group_token = ACPI_PLD_GET_TOKEN(&dword);
0497     pld_info->group_position = ACPI_PLD_GET_POSITION(&dword);
0498     pld_info->bay = ACPI_PLD_GET_BAY(&dword);
0499 
0500     /* Fourth 32-bit DWord */
0501 
0502     ACPI_MOVE_32_TO_32(&dword, &buffer[3]);
0503     pld_info->ejectable = ACPI_PLD_GET_EJECTABLE(&dword);
0504     pld_info->ospm_eject_required = ACPI_PLD_GET_OSPM_EJECT(&dword);
0505     pld_info->cabinet_number = ACPI_PLD_GET_CABINET(&dword);
0506     pld_info->card_cage_number = ACPI_PLD_GET_CARD_CAGE(&dword);
0507     pld_info->reference = ACPI_PLD_GET_REFERENCE(&dword);
0508     pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword);
0509     pld_info->order = ACPI_PLD_GET_ORDER(&dword);
0510 
0511     if (length >= ACPI_PLD_REV2_BUFFER_SIZE) {
0512 
0513         /* Fifth 32-bit DWord (Revision 2 of _PLD) */
0514 
0515         ACPI_MOVE_32_TO_32(&dword, &buffer[4]);
0516         pld_info->vertical_offset = ACPI_PLD_GET_VERT_OFFSET(&dword);
0517         pld_info->horizontal_offset = ACPI_PLD_GET_HORIZ_OFFSET(&dword);
0518     }
0519 
0520     *return_buffer = pld_info;
0521     return (AE_OK);
0522 }
0523 
0524 ACPI_EXPORT_SYMBOL(acpi_decode_pld_buffer)