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