18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 28c2ecf20Sopenharmony_ci/******************************************************************************* 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Module Name: rsxface - Public interfaces to the resource manager 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci ******************************************************************************/ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#define EXPORT_ACPI_INTERFACES 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <acpi/acpi.h> 118c2ecf20Sopenharmony_ci#include "accommon.h" 128c2ecf20Sopenharmony_ci#include "acresrc.h" 138c2ecf20Sopenharmony_ci#include "acnamesp.h" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define _COMPONENT ACPI_RESOURCES 168c2ecf20Sopenharmony_ciACPI_MODULE_NAME("rsxface") 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/* Local macros for 16,32-bit to 64-bit conversion */ 198c2ecf20Sopenharmony_ci#define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field) 208c2ecf20Sopenharmony_ci#define ACPI_COPY_ADDRESS(out, in) \ 218c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, resource_type); \ 228c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, producer_consumer); \ 238c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, decode); \ 248c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, min_address_fixed); \ 258c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, max_address_fixed); \ 268c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, info); \ 278c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, address.granularity); \ 288c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, address.minimum); \ 298c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, address.maximum); \ 308c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, address.translation_offset); \ 318c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, address.address_length); \ 328c2ecf20Sopenharmony_ci ACPI_COPY_FIELD(out, in, resource_source); 338c2ecf20Sopenharmony_ci/* Local prototypes */ 348c2ecf20Sopenharmony_cistatic acpi_status 358c2ecf20Sopenharmony_ciacpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic acpi_status 388c2ecf20Sopenharmony_ciacpi_rs_validate_parameters(acpi_handle device_handle, 398c2ecf20Sopenharmony_ci struct acpi_buffer *buffer, 408c2ecf20Sopenharmony_ci struct acpi_namespace_node **return_node); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/******************************************************************************* 438c2ecf20Sopenharmony_ci * 448c2ecf20Sopenharmony_ci * FUNCTION: acpi_rs_validate_parameters 458c2ecf20Sopenharmony_ci * 468c2ecf20Sopenharmony_ci * PARAMETERS: device_handle - Handle to a device 478c2ecf20Sopenharmony_ci * buffer - Pointer to a data buffer 488c2ecf20Sopenharmony_ci * return_node - Pointer to where the device node is returned 498c2ecf20Sopenharmony_ci * 508c2ecf20Sopenharmony_ci * RETURN: Status 518c2ecf20Sopenharmony_ci * 528c2ecf20Sopenharmony_ci * DESCRIPTION: Common parameter validation for resource interfaces 538c2ecf20Sopenharmony_ci * 548c2ecf20Sopenharmony_ci ******************************************************************************/ 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic acpi_status 578c2ecf20Sopenharmony_ciacpi_rs_validate_parameters(acpi_handle device_handle, 588c2ecf20Sopenharmony_ci struct acpi_buffer *buffer, 598c2ecf20Sopenharmony_ci struct acpi_namespace_node **return_node) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci acpi_status status; 628c2ecf20Sopenharmony_ci struct acpi_namespace_node *node; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci ACPI_FUNCTION_TRACE(rs_validate_parameters); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci /* 678c2ecf20Sopenharmony_ci * Must have a valid handle to an ACPI device 688c2ecf20Sopenharmony_ci */ 698c2ecf20Sopenharmony_ci if (!device_handle) { 708c2ecf20Sopenharmony_ci return_ACPI_STATUS(AE_BAD_PARAMETER); 718c2ecf20Sopenharmony_ci } 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci node = acpi_ns_validate_handle(device_handle); 748c2ecf20Sopenharmony_ci if (!node) { 758c2ecf20Sopenharmony_ci return_ACPI_STATUS(AE_BAD_PARAMETER); 768c2ecf20Sopenharmony_ci } 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci if (node->type != ACPI_TYPE_DEVICE) { 798c2ecf20Sopenharmony_ci return_ACPI_STATUS(AE_TYPE); 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci /* 838c2ecf20Sopenharmony_ci * Validate the user buffer object 848c2ecf20Sopenharmony_ci * 858c2ecf20Sopenharmony_ci * if there is a non-zero buffer length we also need a valid pointer in 868c2ecf20Sopenharmony_ci * the buffer. If it's a zero buffer length, we'll be returning the 878c2ecf20Sopenharmony_ci * needed buffer size (later), so keep going. 888c2ecf20Sopenharmony_ci */ 898c2ecf20Sopenharmony_ci status = acpi_ut_validate_buffer(buffer); 908c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) { 918c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 928c2ecf20Sopenharmony_ci } 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci *return_node = node; 958c2ecf20Sopenharmony_ci return_ACPI_STATUS(AE_OK); 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci/******************************************************************************* 998c2ecf20Sopenharmony_ci * 1008c2ecf20Sopenharmony_ci * FUNCTION: acpi_get_irq_routing_table 1018c2ecf20Sopenharmony_ci * 1028c2ecf20Sopenharmony_ci * PARAMETERS: device_handle - Handle to the Bus device we are querying 1038c2ecf20Sopenharmony_ci * ret_buffer - Pointer to a buffer to receive the 1048c2ecf20Sopenharmony_ci * current resources for the device 1058c2ecf20Sopenharmony_ci * 1068c2ecf20Sopenharmony_ci * RETURN: Status 1078c2ecf20Sopenharmony_ci * 1088c2ecf20Sopenharmony_ci * DESCRIPTION: This function is called to get the IRQ routing table for a 1098c2ecf20Sopenharmony_ci * specific bus. The caller must first acquire a handle for the 1108c2ecf20Sopenharmony_ci * desired bus. The routine table is placed in the buffer pointed 1118c2ecf20Sopenharmony_ci * to by the ret_buffer variable parameter. 1128c2ecf20Sopenharmony_ci * 1138c2ecf20Sopenharmony_ci * If the function fails an appropriate status will be returned 1148c2ecf20Sopenharmony_ci * and the value of ret_buffer is undefined. 1158c2ecf20Sopenharmony_ci * 1168c2ecf20Sopenharmony_ci * This function attempts to execute the _PRT method contained in 1178c2ecf20Sopenharmony_ci * the object indicated by the passed device_handle. 1188c2ecf20Sopenharmony_ci * 1198c2ecf20Sopenharmony_ci ******************************************************************************/ 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ciacpi_status 1228c2ecf20Sopenharmony_ciacpi_get_irq_routing_table(acpi_handle device_handle, 1238c2ecf20Sopenharmony_ci struct acpi_buffer *ret_buffer) 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci acpi_status status; 1268c2ecf20Sopenharmony_ci struct acpi_namespace_node *node; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci /* Validate parameters then dispatch to internal routine */ 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); 1338c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) { 1348c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 1358c2ecf20Sopenharmony_ci } 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci status = acpi_rs_get_prt_method_data(node, ret_buffer); 1388c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table) 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci/******************************************************************************* 1448c2ecf20Sopenharmony_ci * 1458c2ecf20Sopenharmony_ci * FUNCTION: acpi_get_current_resources 1468c2ecf20Sopenharmony_ci * 1478c2ecf20Sopenharmony_ci * PARAMETERS: device_handle - Handle to the device object for the 1488c2ecf20Sopenharmony_ci * device we are querying 1498c2ecf20Sopenharmony_ci * ret_buffer - Pointer to a buffer to receive the 1508c2ecf20Sopenharmony_ci * current resources for the device 1518c2ecf20Sopenharmony_ci * 1528c2ecf20Sopenharmony_ci * RETURN: Status 1538c2ecf20Sopenharmony_ci * 1548c2ecf20Sopenharmony_ci * DESCRIPTION: This function is called to get the current resources for a 1558c2ecf20Sopenharmony_ci * specific device. The caller must first acquire a handle for 1568c2ecf20Sopenharmony_ci * the desired device. The resource data is placed in the buffer 1578c2ecf20Sopenharmony_ci * pointed to by the ret_buffer variable parameter. 1588c2ecf20Sopenharmony_ci * 1598c2ecf20Sopenharmony_ci * If the function fails an appropriate status will be returned 1608c2ecf20Sopenharmony_ci * and the value of ret_buffer is undefined. 1618c2ecf20Sopenharmony_ci * 1628c2ecf20Sopenharmony_ci * This function attempts to execute the _CRS method contained in 1638c2ecf20Sopenharmony_ci * the object indicated by the passed device_handle. 1648c2ecf20Sopenharmony_ci * 1658c2ecf20Sopenharmony_ci ******************************************************************************/ 1668c2ecf20Sopenharmony_ciacpi_status 1678c2ecf20Sopenharmony_ciacpi_get_current_resources(acpi_handle device_handle, 1688c2ecf20Sopenharmony_ci struct acpi_buffer *ret_buffer) 1698c2ecf20Sopenharmony_ci{ 1708c2ecf20Sopenharmony_ci acpi_status status; 1718c2ecf20Sopenharmony_ci struct acpi_namespace_node *node; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci ACPI_FUNCTION_TRACE(acpi_get_current_resources); 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci /* Validate parameters then dispatch to internal routine */ 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); 1788c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) { 1798c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 1808c2ecf20Sopenharmony_ci } 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci status = acpi_rs_get_crs_method_data(node, ret_buffer); 1838c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 1848c2ecf20Sopenharmony_ci} 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_get_current_resources) 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci/******************************************************************************* 1898c2ecf20Sopenharmony_ci * 1908c2ecf20Sopenharmony_ci * FUNCTION: acpi_get_possible_resources 1918c2ecf20Sopenharmony_ci * 1928c2ecf20Sopenharmony_ci * PARAMETERS: device_handle - Handle to the device object for the 1938c2ecf20Sopenharmony_ci * device we are querying 1948c2ecf20Sopenharmony_ci * ret_buffer - Pointer to a buffer to receive the 1958c2ecf20Sopenharmony_ci * resources for the device 1968c2ecf20Sopenharmony_ci * 1978c2ecf20Sopenharmony_ci * RETURN: Status 1988c2ecf20Sopenharmony_ci * 1998c2ecf20Sopenharmony_ci * DESCRIPTION: This function is called to get a list of the possible resources 2008c2ecf20Sopenharmony_ci * for a specific device. The caller must first acquire a handle 2018c2ecf20Sopenharmony_ci * for the desired device. The resource data is placed in the 2028c2ecf20Sopenharmony_ci * buffer pointed to by the ret_buffer variable. 2038c2ecf20Sopenharmony_ci * 2048c2ecf20Sopenharmony_ci * If the function fails an appropriate status will be returned 2058c2ecf20Sopenharmony_ci * and the value of ret_buffer is undefined. 2068c2ecf20Sopenharmony_ci * 2078c2ecf20Sopenharmony_ci ******************************************************************************/ 2088c2ecf20Sopenharmony_ciacpi_status 2098c2ecf20Sopenharmony_ciacpi_get_possible_resources(acpi_handle device_handle, 2108c2ecf20Sopenharmony_ci struct acpi_buffer *ret_buffer) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci acpi_status status; 2138c2ecf20Sopenharmony_ci struct acpi_namespace_node *node; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci ACPI_FUNCTION_TRACE(acpi_get_possible_resources); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci /* Validate parameters then dispatch to internal routine */ 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); 2208c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) { 2218c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci status = acpi_rs_get_prs_method_data(node, ret_buffer); 2258c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 2268c2ecf20Sopenharmony_ci} 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_get_possible_resources) 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci/******************************************************************************* 2318c2ecf20Sopenharmony_ci * 2328c2ecf20Sopenharmony_ci * FUNCTION: acpi_set_current_resources 2338c2ecf20Sopenharmony_ci * 2348c2ecf20Sopenharmony_ci * PARAMETERS: device_handle - Handle to the device object for the 2358c2ecf20Sopenharmony_ci * device we are setting resources 2368c2ecf20Sopenharmony_ci * in_buffer - Pointer to a buffer containing the 2378c2ecf20Sopenharmony_ci * resources to be set for the device 2388c2ecf20Sopenharmony_ci * 2398c2ecf20Sopenharmony_ci * RETURN: Status 2408c2ecf20Sopenharmony_ci * 2418c2ecf20Sopenharmony_ci * DESCRIPTION: This function is called to set the current resources for a 2428c2ecf20Sopenharmony_ci * specific device. The caller must first acquire a handle for 2438c2ecf20Sopenharmony_ci * the desired device. The resource data is passed to the routine 2448c2ecf20Sopenharmony_ci * the buffer pointed to by the in_buffer variable. 2458c2ecf20Sopenharmony_ci * 2468c2ecf20Sopenharmony_ci ******************************************************************************/ 2478c2ecf20Sopenharmony_ciacpi_status 2488c2ecf20Sopenharmony_ciacpi_set_current_resources(acpi_handle device_handle, 2498c2ecf20Sopenharmony_ci struct acpi_buffer *in_buffer) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci acpi_status status; 2528c2ecf20Sopenharmony_ci struct acpi_namespace_node *node; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci ACPI_FUNCTION_TRACE(acpi_set_current_resources); 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci /* Validate the buffer, don't allow zero length */ 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci if ((!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) { 2598c2ecf20Sopenharmony_ci return_ACPI_STATUS(AE_BAD_PARAMETER); 2608c2ecf20Sopenharmony_ci } 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci /* Validate parameters then dispatch to internal routine */ 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci status = acpi_rs_validate_parameters(device_handle, in_buffer, &node); 2658c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) { 2668c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci status = acpi_rs_set_srs_method_data(node, in_buffer); 2708c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 2718c2ecf20Sopenharmony_ci} 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_set_current_resources) 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci/******************************************************************************* 2768c2ecf20Sopenharmony_ci * 2778c2ecf20Sopenharmony_ci * FUNCTION: acpi_get_event_resources 2788c2ecf20Sopenharmony_ci * 2798c2ecf20Sopenharmony_ci * PARAMETERS: device_handle - Handle to the device object for the 2808c2ecf20Sopenharmony_ci * device we are getting resources 2818c2ecf20Sopenharmony_ci * in_buffer - Pointer to a buffer containing the 2828c2ecf20Sopenharmony_ci * resources to be set for the device 2838c2ecf20Sopenharmony_ci * 2848c2ecf20Sopenharmony_ci * RETURN: Status 2858c2ecf20Sopenharmony_ci * 2868c2ecf20Sopenharmony_ci * DESCRIPTION: This function is called to get the event resources for a 2878c2ecf20Sopenharmony_ci * specific device. The caller must first acquire a handle for 2888c2ecf20Sopenharmony_ci * the desired device. The resource data is passed to the routine 2898c2ecf20Sopenharmony_ci * the buffer pointed to by the in_buffer variable. Uses the 2908c2ecf20Sopenharmony_ci * _AEI method. 2918c2ecf20Sopenharmony_ci * 2928c2ecf20Sopenharmony_ci ******************************************************************************/ 2938c2ecf20Sopenharmony_ciacpi_status 2948c2ecf20Sopenharmony_ciacpi_get_event_resources(acpi_handle device_handle, 2958c2ecf20Sopenharmony_ci struct acpi_buffer *ret_buffer) 2968c2ecf20Sopenharmony_ci{ 2978c2ecf20Sopenharmony_ci acpi_status status; 2988c2ecf20Sopenharmony_ci struct acpi_namespace_node *node; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci ACPI_FUNCTION_TRACE(acpi_get_event_resources); 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci /* Validate parameters then dispatch to internal routine */ 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); 3058c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) { 3068c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 3078c2ecf20Sopenharmony_ci } 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci status = acpi_rs_get_aei_method_data(node, ret_buffer); 3108c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 3118c2ecf20Sopenharmony_ci} 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_get_event_resources) 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci/****************************************************************************** 3168c2ecf20Sopenharmony_ci * 3178c2ecf20Sopenharmony_ci * FUNCTION: acpi_resource_to_address64 3188c2ecf20Sopenharmony_ci * 3198c2ecf20Sopenharmony_ci * PARAMETERS: resource - Pointer to a resource 3208c2ecf20Sopenharmony_ci * out - Pointer to the users's return buffer 3218c2ecf20Sopenharmony_ci * (a struct acpi_resource_address64) 3228c2ecf20Sopenharmony_ci * 3238c2ecf20Sopenharmony_ci * RETURN: Status 3248c2ecf20Sopenharmony_ci * 3258c2ecf20Sopenharmony_ci * DESCRIPTION: If the resource is an address16, address32, or address64, 3268c2ecf20Sopenharmony_ci * copy it to the address64 return buffer. This saves the 3278c2ecf20Sopenharmony_ci * caller from having to duplicate code for different-sized 3288c2ecf20Sopenharmony_ci * addresses. 3298c2ecf20Sopenharmony_ci * 3308c2ecf20Sopenharmony_ci ******************************************************************************/ 3318c2ecf20Sopenharmony_ciacpi_status 3328c2ecf20Sopenharmony_ciacpi_resource_to_address64(struct acpi_resource *resource, 3338c2ecf20Sopenharmony_ci struct acpi_resource_address64 *out) 3348c2ecf20Sopenharmony_ci{ 3358c2ecf20Sopenharmony_ci struct acpi_resource_address16 *address16; 3368c2ecf20Sopenharmony_ci struct acpi_resource_address32 *address32; 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci if (!resource || !out) { 3398c2ecf20Sopenharmony_ci return (AE_BAD_PARAMETER); 3408c2ecf20Sopenharmony_ci } 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci /* Convert 16 or 32 address descriptor to 64 */ 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci switch (resource->type) { 3458c2ecf20Sopenharmony_ci case ACPI_RESOURCE_TYPE_ADDRESS16: 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci address16 = 3488c2ecf20Sopenharmony_ci ACPI_CAST_PTR(struct acpi_resource_address16, 3498c2ecf20Sopenharmony_ci &resource->data); 3508c2ecf20Sopenharmony_ci ACPI_COPY_ADDRESS(out, address16); 3518c2ecf20Sopenharmony_ci break; 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci case ACPI_RESOURCE_TYPE_ADDRESS32: 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci address32 = 3568c2ecf20Sopenharmony_ci ACPI_CAST_PTR(struct acpi_resource_address32, 3578c2ecf20Sopenharmony_ci &resource->data); 3588c2ecf20Sopenharmony_ci ACPI_COPY_ADDRESS(out, address32); 3598c2ecf20Sopenharmony_ci break; 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci case ACPI_RESOURCE_TYPE_ADDRESS64: 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci /* Simple copy for 64 bit source */ 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci memcpy(out, &resource->data, 3668c2ecf20Sopenharmony_ci sizeof(struct acpi_resource_address64)); 3678c2ecf20Sopenharmony_ci break; 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci default: 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci return (AE_BAD_PARAMETER); 3728c2ecf20Sopenharmony_ci } 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci return (AE_OK); 3758c2ecf20Sopenharmony_ci} 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_resource_to_address64) 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci/******************************************************************************* 3808c2ecf20Sopenharmony_ci * 3818c2ecf20Sopenharmony_ci * FUNCTION: acpi_get_vendor_resource 3828c2ecf20Sopenharmony_ci * 3838c2ecf20Sopenharmony_ci * PARAMETERS: device_handle - Handle for the parent device object 3848c2ecf20Sopenharmony_ci * name - Method name for the parent resource 3858c2ecf20Sopenharmony_ci * (METHOD_NAME__CRS or METHOD_NAME__PRS) 3868c2ecf20Sopenharmony_ci * uuid - Pointer to the UUID to be matched. 3878c2ecf20Sopenharmony_ci * includes both subtype and 16-byte UUID 3888c2ecf20Sopenharmony_ci * ret_buffer - Where the vendor resource is returned 3898c2ecf20Sopenharmony_ci * 3908c2ecf20Sopenharmony_ci * RETURN: Status 3918c2ecf20Sopenharmony_ci * 3928c2ecf20Sopenharmony_ci * DESCRIPTION: Walk a resource template for the specified device to find a 3938c2ecf20Sopenharmony_ci * vendor-defined resource that matches the supplied UUID and 3948c2ecf20Sopenharmony_ci * UUID subtype. Returns a struct acpi_resource of type Vendor. 3958c2ecf20Sopenharmony_ci * 3968c2ecf20Sopenharmony_ci ******************************************************************************/ 3978c2ecf20Sopenharmony_ciacpi_status 3988c2ecf20Sopenharmony_ciacpi_get_vendor_resource(acpi_handle device_handle, 3998c2ecf20Sopenharmony_ci char *name, 4008c2ecf20Sopenharmony_ci struct acpi_vendor_uuid *uuid, 4018c2ecf20Sopenharmony_ci struct acpi_buffer *ret_buffer) 4028c2ecf20Sopenharmony_ci{ 4038c2ecf20Sopenharmony_ci struct acpi_vendor_walk_info info; 4048c2ecf20Sopenharmony_ci acpi_status status; 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci /* Other parameters are validated by acpi_walk_resources */ 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci if (!uuid || !ret_buffer) { 4098c2ecf20Sopenharmony_ci return (AE_BAD_PARAMETER); 4108c2ecf20Sopenharmony_ci } 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci info.uuid = uuid; 4138c2ecf20Sopenharmony_ci info.buffer = ret_buffer; 4148c2ecf20Sopenharmony_ci info.status = AE_NOT_EXIST; 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci /* Walk the _CRS or _PRS resource list for this device */ 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci status = 4198c2ecf20Sopenharmony_ci acpi_walk_resources(device_handle, name, 4208c2ecf20Sopenharmony_ci acpi_rs_match_vendor_resource, &info); 4218c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) { 4228c2ecf20Sopenharmony_ci return (status); 4238c2ecf20Sopenharmony_ci } 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci return (info.status); 4268c2ecf20Sopenharmony_ci} 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_get_vendor_resource) 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci/******************************************************************************* 4318c2ecf20Sopenharmony_ci * 4328c2ecf20Sopenharmony_ci * FUNCTION: acpi_rs_match_vendor_resource 4338c2ecf20Sopenharmony_ci * 4348c2ecf20Sopenharmony_ci * PARAMETERS: acpi_walk_resource_callback 4358c2ecf20Sopenharmony_ci * 4368c2ecf20Sopenharmony_ci * RETURN: Status 4378c2ecf20Sopenharmony_ci * 4388c2ecf20Sopenharmony_ci * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID 4398c2ecf20Sopenharmony_ci * 4408c2ecf20Sopenharmony_ci ******************************************************************************/ 4418c2ecf20Sopenharmony_cistatic acpi_status 4428c2ecf20Sopenharmony_ciacpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context) 4438c2ecf20Sopenharmony_ci{ 4448c2ecf20Sopenharmony_ci struct acpi_vendor_walk_info *info = context; 4458c2ecf20Sopenharmony_ci struct acpi_resource_vendor_typed *vendor; 4468c2ecf20Sopenharmony_ci struct acpi_buffer *buffer; 4478c2ecf20Sopenharmony_ci acpi_status status; 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_ci /* Ignore all descriptors except Vendor */ 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ci if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) { 4528c2ecf20Sopenharmony_ci return (AE_OK); 4538c2ecf20Sopenharmony_ci } 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci vendor = &resource->data.vendor_typed; 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_ci /* 4588c2ecf20Sopenharmony_ci * For a valid match, these conditions must hold: 4598c2ecf20Sopenharmony_ci * 4608c2ecf20Sopenharmony_ci * 1) Length of descriptor data must be at least as long as a UUID struct 4618c2ecf20Sopenharmony_ci * 2) The UUID subtypes must match 4628c2ecf20Sopenharmony_ci * 3) The UUID data must match 4638c2ecf20Sopenharmony_ci */ 4648c2ecf20Sopenharmony_ci if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) || 4658c2ecf20Sopenharmony_ci (vendor->uuid_subtype != info->uuid->subtype) || 4668c2ecf20Sopenharmony_ci (memcmp(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) { 4678c2ecf20Sopenharmony_ci return (AE_OK); 4688c2ecf20Sopenharmony_ci } 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci /* Validate/Allocate/Clear caller buffer */ 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci buffer = info->buffer; 4738c2ecf20Sopenharmony_ci status = acpi_ut_initialize_buffer(buffer, resource->length); 4748c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) { 4758c2ecf20Sopenharmony_ci return (status); 4768c2ecf20Sopenharmony_ci } 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci /* Found the correct resource, copy and return it */ 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci memcpy(buffer->pointer, resource, resource->length); 4818c2ecf20Sopenharmony_ci buffer->length = resource->length; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci /* Found the desired descriptor, terminate resource walk */ 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci info->status = AE_OK; 4868c2ecf20Sopenharmony_ci return (AE_CTRL_TERMINATE); 4878c2ecf20Sopenharmony_ci} 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci/******************************************************************************* 4908c2ecf20Sopenharmony_ci * 4918c2ecf20Sopenharmony_ci * FUNCTION: acpi_walk_resource_buffer 4928c2ecf20Sopenharmony_ci * 4938c2ecf20Sopenharmony_ci * PARAMETERS: buffer - Formatted buffer returned by one of the 4948c2ecf20Sopenharmony_ci * various Get*Resource functions 4958c2ecf20Sopenharmony_ci * user_function - Called for each resource 4968c2ecf20Sopenharmony_ci * context - Passed to user_function 4978c2ecf20Sopenharmony_ci * 4988c2ecf20Sopenharmony_ci * RETURN: Status 4998c2ecf20Sopenharmony_ci * 5008c2ecf20Sopenharmony_ci * DESCRIPTION: Walks the input resource template. The user_function is called 5018c2ecf20Sopenharmony_ci * once for each resource in the list. 5028c2ecf20Sopenharmony_ci * 5038c2ecf20Sopenharmony_ci ******************************************************************************/ 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ciacpi_status 5068c2ecf20Sopenharmony_ciacpi_walk_resource_buffer(struct acpi_buffer *buffer, 5078c2ecf20Sopenharmony_ci acpi_walk_resource_callback user_function, 5088c2ecf20Sopenharmony_ci void *context) 5098c2ecf20Sopenharmony_ci{ 5108c2ecf20Sopenharmony_ci acpi_status status = AE_OK; 5118c2ecf20Sopenharmony_ci struct acpi_resource *resource; 5128c2ecf20Sopenharmony_ci struct acpi_resource *resource_end; 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci ACPI_FUNCTION_TRACE(acpi_walk_resource_buffer); 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_ci /* Parameter validation */ 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_ci if (!buffer || !buffer->pointer || !user_function) { 5198c2ecf20Sopenharmony_ci return_ACPI_STATUS(AE_BAD_PARAMETER); 5208c2ecf20Sopenharmony_ci } 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci /* Buffer contains the resource list and length */ 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci resource = ACPI_CAST_PTR(struct acpi_resource, buffer->pointer); 5258c2ecf20Sopenharmony_ci resource_end = 5268c2ecf20Sopenharmony_ci ACPI_ADD_PTR(struct acpi_resource, buffer->pointer, buffer->length); 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci /* Walk the resource list until the end_tag is found (or buffer end) */ 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci while (resource < resource_end) { 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci /* Sanity check the resource type */ 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci if (resource->type > ACPI_RESOURCE_TYPE_MAX) { 5358c2ecf20Sopenharmony_ci status = AE_AML_INVALID_RESOURCE_TYPE; 5368c2ecf20Sopenharmony_ci break; 5378c2ecf20Sopenharmony_ci } 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_ci /* Sanity check the length. It must not be zero, or we loop forever */ 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci if (!resource->length) { 5428c2ecf20Sopenharmony_ci return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); 5438c2ecf20Sopenharmony_ci } 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci /* Invoke the user function, abort on any error returned */ 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci status = user_function(resource, context); 5488c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) { 5498c2ecf20Sopenharmony_ci if (status == AE_CTRL_TERMINATE) { 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_ci /* This is an OK termination by the user function */ 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci status = AE_OK; 5548c2ecf20Sopenharmony_ci } 5558c2ecf20Sopenharmony_ci break; 5568c2ecf20Sopenharmony_ci } 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci /* end_tag indicates end-of-list */ 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_ci if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { 5618c2ecf20Sopenharmony_ci break; 5628c2ecf20Sopenharmony_ci } 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_ci /* Get the next resource descriptor */ 5658c2ecf20Sopenharmony_ci 5668c2ecf20Sopenharmony_ci resource = ACPI_NEXT_RESOURCE(resource); 5678c2ecf20Sopenharmony_ci } 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 5708c2ecf20Sopenharmony_ci} 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_walk_resource_buffer) 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci/******************************************************************************* 5758c2ecf20Sopenharmony_ci * 5768c2ecf20Sopenharmony_ci * FUNCTION: acpi_walk_resources 5778c2ecf20Sopenharmony_ci * 5788c2ecf20Sopenharmony_ci * PARAMETERS: device_handle - Handle to the device object for the 5798c2ecf20Sopenharmony_ci * device we are querying 5808c2ecf20Sopenharmony_ci * name - Method name of the resources we want. 5818c2ecf20Sopenharmony_ci * (METHOD_NAME__CRS, METHOD_NAME__PRS, or 5828c2ecf20Sopenharmony_ci * METHOD_NAME__AEI or METHOD_NAME__DMA) 5838c2ecf20Sopenharmony_ci * user_function - Called for each resource 5848c2ecf20Sopenharmony_ci * context - Passed to user_function 5858c2ecf20Sopenharmony_ci * 5868c2ecf20Sopenharmony_ci * RETURN: Status 5878c2ecf20Sopenharmony_ci * 5888c2ecf20Sopenharmony_ci * DESCRIPTION: Retrieves the current or possible resource list for the 5898c2ecf20Sopenharmony_ci * specified device. The user_function is called once for 5908c2ecf20Sopenharmony_ci * each resource in the list. 5918c2ecf20Sopenharmony_ci * 5928c2ecf20Sopenharmony_ci ******************************************************************************/ 5938c2ecf20Sopenharmony_ciacpi_status 5948c2ecf20Sopenharmony_ciacpi_walk_resources(acpi_handle device_handle, 5958c2ecf20Sopenharmony_ci char *name, 5968c2ecf20Sopenharmony_ci acpi_walk_resource_callback user_function, void *context) 5978c2ecf20Sopenharmony_ci{ 5988c2ecf20Sopenharmony_ci acpi_status status; 5998c2ecf20Sopenharmony_ci struct acpi_buffer buffer; 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci ACPI_FUNCTION_TRACE(acpi_walk_resources); 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci /* Parameter validation */ 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci if (!device_handle || !user_function || !name || 6068c2ecf20Sopenharmony_ci (!ACPI_COMPARE_NAMESEG(name, METHOD_NAME__CRS) && 6078c2ecf20Sopenharmony_ci !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__PRS) && 6088c2ecf20Sopenharmony_ci !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__AEI) && 6098c2ecf20Sopenharmony_ci !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__DMA))) { 6108c2ecf20Sopenharmony_ci return_ACPI_STATUS(AE_BAD_PARAMETER); 6118c2ecf20Sopenharmony_ci } 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ci /* Get the _CRS/_PRS/_AEI/_DMA resource list */ 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_ci buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; 6168c2ecf20Sopenharmony_ci status = acpi_rs_get_method_data(device_handle, name, &buffer); 6178c2ecf20Sopenharmony_ci if (ACPI_FAILURE(status)) { 6188c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 6198c2ecf20Sopenharmony_ci } 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci /* Walk the resource list and cleanup */ 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci status = acpi_walk_resource_buffer(&buffer, user_function, context); 6248c2ecf20Sopenharmony_ci ACPI_FREE(buffer.pointer); 6258c2ecf20Sopenharmony_ci return_ACPI_STATUS(status); 6268c2ecf20Sopenharmony_ci} 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_walk_resources) 629