162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
262306a36Sopenharmony_ci/*******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Module Name: rsxface - Public interfaces to the resource manager
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci ******************************************************************************/
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#define EXPORT_ACPI_INTERFACES
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <acpi/acpi.h>
1162306a36Sopenharmony_ci#include "accommon.h"
1262306a36Sopenharmony_ci#include "acresrc.h"
1362306a36Sopenharmony_ci#include "acnamesp.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define _COMPONENT          ACPI_RESOURCES
1662306a36Sopenharmony_ciACPI_MODULE_NAME("rsxface")
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* Local macros for 16,32-bit to 64-bit conversion */
1962306a36Sopenharmony_ci#define ACPI_COPY_FIELD(out, in, field)  ((out)->field = (in)->field)
2062306a36Sopenharmony_ci#define ACPI_COPY_ADDRESS(out, in)                       \
2162306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, resource_type);             \
2262306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, producer_consumer);         \
2362306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, decode);                    \
2462306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, min_address_fixed);         \
2562306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, max_address_fixed);         \
2662306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, info);                      \
2762306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, address.granularity);       \
2862306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, address.minimum);           \
2962306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, address.maximum);           \
3062306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, address.translation_offset); \
3162306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, address.address_length);    \
3262306a36Sopenharmony_ci	ACPI_COPY_FIELD(out, in, resource_source);
3362306a36Sopenharmony_ci/* Local prototypes */
3462306a36Sopenharmony_cistatic acpi_status
3562306a36Sopenharmony_ciacpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context);
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_cistatic acpi_status
3862306a36Sopenharmony_ciacpi_rs_validate_parameters(acpi_handle device_handle,
3962306a36Sopenharmony_ci			    struct acpi_buffer *buffer,
4062306a36Sopenharmony_ci			    struct acpi_namespace_node **return_node);
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci/*******************************************************************************
4362306a36Sopenharmony_ci *
4462306a36Sopenharmony_ci * FUNCTION:    acpi_rs_validate_parameters
4562306a36Sopenharmony_ci *
4662306a36Sopenharmony_ci * PARAMETERS:  device_handle   - Handle to a device
4762306a36Sopenharmony_ci *              buffer          - Pointer to a data buffer
4862306a36Sopenharmony_ci *              return_node     - Pointer to where the device node is returned
4962306a36Sopenharmony_ci *
5062306a36Sopenharmony_ci * RETURN:      Status
5162306a36Sopenharmony_ci *
5262306a36Sopenharmony_ci * DESCRIPTION: Common parameter validation for resource interfaces
5362306a36Sopenharmony_ci *
5462306a36Sopenharmony_ci ******************************************************************************/
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_cistatic acpi_status
5762306a36Sopenharmony_ciacpi_rs_validate_parameters(acpi_handle device_handle,
5862306a36Sopenharmony_ci			    struct acpi_buffer *buffer,
5962306a36Sopenharmony_ci			    struct acpi_namespace_node **return_node)
6062306a36Sopenharmony_ci{
6162306a36Sopenharmony_ci	acpi_status status;
6262306a36Sopenharmony_ci	struct acpi_namespace_node *node;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(rs_validate_parameters);
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	/*
6762306a36Sopenharmony_ci	 * Must have a valid handle to an ACPI device
6862306a36Sopenharmony_ci	 */
6962306a36Sopenharmony_ci	if (!device_handle) {
7062306a36Sopenharmony_ci		return_ACPI_STATUS(AE_BAD_PARAMETER);
7162306a36Sopenharmony_ci	}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	node = acpi_ns_validate_handle(device_handle);
7462306a36Sopenharmony_ci	if (!node) {
7562306a36Sopenharmony_ci		return_ACPI_STATUS(AE_BAD_PARAMETER);
7662306a36Sopenharmony_ci	}
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	if (node->type != ACPI_TYPE_DEVICE) {
7962306a36Sopenharmony_ci		return_ACPI_STATUS(AE_TYPE);
8062306a36Sopenharmony_ci	}
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	/*
8362306a36Sopenharmony_ci	 * Validate the user buffer object
8462306a36Sopenharmony_ci	 *
8562306a36Sopenharmony_ci	 * if there is a non-zero buffer length we also need a valid pointer in
8662306a36Sopenharmony_ci	 * the buffer. If it's a zero buffer length, we'll be returning the
8762306a36Sopenharmony_ci	 * needed buffer size (later), so keep going.
8862306a36Sopenharmony_ci	 */
8962306a36Sopenharmony_ci	status = acpi_ut_validate_buffer(buffer);
9062306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
9162306a36Sopenharmony_ci		return_ACPI_STATUS(status);
9262306a36Sopenharmony_ci	}
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	*return_node = node;
9562306a36Sopenharmony_ci	return_ACPI_STATUS(AE_OK);
9662306a36Sopenharmony_ci}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci/*******************************************************************************
9962306a36Sopenharmony_ci *
10062306a36Sopenharmony_ci * FUNCTION:    acpi_get_irq_routing_table
10162306a36Sopenharmony_ci *
10262306a36Sopenharmony_ci * PARAMETERS:  device_handle   - Handle to the Bus device we are querying
10362306a36Sopenharmony_ci *              ret_buffer      - Pointer to a buffer to receive the
10462306a36Sopenharmony_ci *                                current resources for the device
10562306a36Sopenharmony_ci *
10662306a36Sopenharmony_ci * RETURN:      Status
10762306a36Sopenharmony_ci *
10862306a36Sopenharmony_ci * DESCRIPTION: This function is called to get the IRQ routing table for a
10962306a36Sopenharmony_ci *              specific bus. The caller must first acquire a handle for the
11062306a36Sopenharmony_ci *              desired bus. The routine table is placed in the buffer pointed
11162306a36Sopenharmony_ci *              to by the ret_buffer variable parameter.
11262306a36Sopenharmony_ci *
11362306a36Sopenharmony_ci *              If the function fails an appropriate status will be returned
11462306a36Sopenharmony_ci *              and the value of ret_buffer is undefined.
11562306a36Sopenharmony_ci *
11662306a36Sopenharmony_ci *              This function attempts to execute the _PRT method contained in
11762306a36Sopenharmony_ci *              the object indicated by the passed device_handle.
11862306a36Sopenharmony_ci *
11962306a36Sopenharmony_ci ******************************************************************************/
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ciacpi_status
12262306a36Sopenharmony_ciacpi_get_irq_routing_table(acpi_handle device_handle,
12362306a36Sopenharmony_ci			   struct acpi_buffer *ret_buffer)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci	acpi_status status;
12662306a36Sopenharmony_ci	struct acpi_namespace_node *node;
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	/* Validate parameters then dispatch to internal routine */
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
13362306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
13462306a36Sopenharmony_ci		return_ACPI_STATUS(status);
13562306a36Sopenharmony_ci	}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	status = acpi_rs_get_prt_method_data(node, ret_buffer);
13862306a36Sopenharmony_ci	return_ACPI_STATUS(status);
13962306a36Sopenharmony_ci}
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table)
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci/*******************************************************************************
14462306a36Sopenharmony_ci *
14562306a36Sopenharmony_ci * FUNCTION:    acpi_get_current_resources
14662306a36Sopenharmony_ci *
14762306a36Sopenharmony_ci * PARAMETERS:  device_handle   - Handle to the device object for the
14862306a36Sopenharmony_ci *                                device we are querying
14962306a36Sopenharmony_ci *              ret_buffer      - Pointer to a buffer to receive the
15062306a36Sopenharmony_ci *                                current resources for the device
15162306a36Sopenharmony_ci *
15262306a36Sopenharmony_ci * RETURN:      Status
15362306a36Sopenharmony_ci *
15462306a36Sopenharmony_ci * DESCRIPTION: This function is called to get the current resources for a
15562306a36Sopenharmony_ci *              specific device. The caller must first acquire a handle for
15662306a36Sopenharmony_ci *              the desired device. The resource data is placed in the buffer
15762306a36Sopenharmony_ci *              pointed to by the ret_buffer variable parameter.
15862306a36Sopenharmony_ci *
15962306a36Sopenharmony_ci *              If the function fails an appropriate status will be returned
16062306a36Sopenharmony_ci *              and the value of ret_buffer is undefined.
16162306a36Sopenharmony_ci *
16262306a36Sopenharmony_ci *              This function attempts to execute the _CRS method contained in
16362306a36Sopenharmony_ci *              the object indicated by the passed device_handle.
16462306a36Sopenharmony_ci *
16562306a36Sopenharmony_ci ******************************************************************************/
16662306a36Sopenharmony_ciacpi_status
16762306a36Sopenharmony_ciacpi_get_current_resources(acpi_handle device_handle,
16862306a36Sopenharmony_ci			   struct acpi_buffer *ret_buffer)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	acpi_status status;
17162306a36Sopenharmony_ci	struct acpi_namespace_node *node;
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(acpi_get_current_resources);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	/* Validate parameters then dispatch to internal routine */
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
17862306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
17962306a36Sopenharmony_ci		return_ACPI_STATUS(status);
18062306a36Sopenharmony_ci	}
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	status = acpi_rs_get_crs_method_data(node, ret_buffer);
18362306a36Sopenharmony_ci	return_ACPI_STATUS(status);
18462306a36Sopenharmony_ci}
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_get_current_resources)
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci/*******************************************************************************
18962306a36Sopenharmony_ci *
19062306a36Sopenharmony_ci * FUNCTION:    acpi_get_possible_resources
19162306a36Sopenharmony_ci *
19262306a36Sopenharmony_ci * PARAMETERS:  device_handle   - Handle to the device object for the
19362306a36Sopenharmony_ci *                                device we are querying
19462306a36Sopenharmony_ci *              ret_buffer      - Pointer to a buffer to receive the
19562306a36Sopenharmony_ci *                                resources for the device
19662306a36Sopenharmony_ci *
19762306a36Sopenharmony_ci * RETURN:      Status
19862306a36Sopenharmony_ci *
19962306a36Sopenharmony_ci * DESCRIPTION: This function is called to get a list of the possible resources
20062306a36Sopenharmony_ci *              for a specific device. The caller must first acquire a handle
20162306a36Sopenharmony_ci *              for the desired device. The resource data is placed in the
20262306a36Sopenharmony_ci *              buffer pointed to by the ret_buffer variable.
20362306a36Sopenharmony_ci *
20462306a36Sopenharmony_ci *              If the function fails an appropriate status will be returned
20562306a36Sopenharmony_ci *              and the value of ret_buffer is undefined.
20662306a36Sopenharmony_ci *
20762306a36Sopenharmony_ci ******************************************************************************/
20862306a36Sopenharmony_ciacpi_status
20962306a36Sopenharmony_ciacpi_get_possible_resources(acpi_handle device_handle,
21062306a36Sopenharmony_ci			    struct acpi_buffer *ret_buffer)
21162306a36Sopenharmony_ci{
21262306a36Sopenharmony_ci	acpi_status status;
21362306a36Sopenharmony_ci	struct acpi_namespace_node *node;
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(acpi_get_possible_resources);
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	/* Validate parameters then dispatch to internal routine */
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci	status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
22062306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
22162306a36Sopenharmony_ci		return_ACPI_STATUS(status);
22262306a36Sopenharmony_ci	}
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	status = acpi_rs_get_prs_method_data(node, ret_buffer);
22562306a36Sopenharmony_ci	return_ACPI_STATUS(status);
22662306a36Sopenharmony_ci}
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci/*******************************************************************************
23162306a36Sopenharmony_ci *
23262306a36Sopenharmony_ci * FUNCTION:    acpi_set_current_resources
23362306a36Sopenharmony_ci *
23462306a36Sopenharmony_ci * PARAMETERS:  device_handle   - Handle to the device object for the
23562306a36Sopenharmony_ci *                                device we are setting resources
23662306a36Sopenharmony_ci *              in_buffer       - Pointer to a buffer containing the
23762306a36Sopenharmony_ci *                                resources to be set for the device
23862306a36Sopenharmony_ci *
23962306a36Sopenharmony_ci * RETURN:      Status
24062306a36Sopenharmony_ci *
24162306a36Sopenharmony_ci * DESCRIPTION: This function is called to set the current resources for a
24262306a36Sopenharmony_ci *              specific device. The caller must first acquire a handle for
24362306a36Sopenharmony_ci *              the desired device. The resource data is passed to the routine
24462306a36Sopenharmony_ci *              the buffer pointed to by the in_buffer variable.
24562306a36Sopenharmony_ci *
24662306a36Sopenharmony_ci ******************************************************************************/
24762306a36Sopenharmony_ciacpi_status
24862306a36Sopenharmony_ciacpi_set_current_resources(acpi_handle device_handle,
24962306a36Sopenharmony_ci			   struct acpi_buffer *in_buffer)
25062306a36Sopenharmony_ci{
25162306a36Sopenharmony_ci	acpi_status status;
25262306a36Sopenharmony_ci	struct acpi_namespace_node *node;
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(acpi_set_current_resources);
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	/* Validate the buffer, don't allow zero length */
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	if ((!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
25962306a36Sopenharmony_ci		return_ACPI_STATUS(AE_BAD_PARAMETER);
26062306a36Sopenharmony_ci	}
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci	/* Validate parameters then dispatch to internal routine */
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	status = acpi_rs_validate_parameters(device_handle, in_buffer, &node);
26562306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
26662306a36Sopenharmony_ci		return_ACPI_STATUS(status);
26762306a36Sopenharmony_ci	}
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	status = acpi_rs_set_srs_method_data(node, in_buffer);
27062306a36Sopenharmony_ci	return_ACPI_STATUS(status);
27162306a36Sopenharmony_ci}
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_set_current_resources)
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci/*******************************************************************************
27662306a36Sopenharmony_ci *
27762306a36Sopenharmony_ci * FUNCTION:    acpi_get_event_resources
27862306a36Sopenharmony_ci *
27962306a36Sopenharmony_ci * PARAMETERS:  device_handle   - Handle to the device object for the
28062306a36Sopenharmony_ci *                                device we are getting resources
28162306a36Sopenharmony_ci *              in_buffer       - Pointer to a buffer containing the
28262306a36Sopenharmony_ci *                                resources to be set for the device
28362306a36Sopenharmony_ci *
28462306a36Sopenharmony_ci * RETURN:      Status
28562306a36Sopenharmony_ci *
28662306a36Sopenharmony_ci * DESCRIPTION: This function is called to get the event resources for a
28762306a36Sopenharmony_ci *              specific device. The caller must first acquire a handle for
28862306a36Sopenharmony_ci *              the desired device. The resource data is passed to the routine
28962306a36Sopenharmony_ci *              the buffer pointed to by the in_buffer variable. Uses the
29062306a36Sopenharmony_ci *              _AEI method.
29162306a36Sopenharmony_ci *
29262306a36Sopenharmony_ci ******************************************************************************/
29362306a36Sopenharmony_ciacpi_status
29462306a36Sopenharmony_ciacpi_get_event_resources(acpi_handle device_handle,
29562306a36Sopenharmony_ci			 struct acpi_buffer *ret_buffer)
29662306a36Sopenharmony_ci{
29762306a36Sopenharmony_ci	acpi_status status;
29862306a36Sopenharmony_ci	struct acpi_namespace_node *node;
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(acpi_get_event_resources);
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci	/* Validate parameters then dispatch to internal routine */
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
30562306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
30662306a36Sopenharmony_ci		return_ACPI_STATUS(status);
30762306a36Sopenharmony_ci	}
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	status = acpi_rs_get_aei_method_data(node, ret_buffer);
31062306a36Sopenharmony_ci	return_ACPI_STATUS(status);
31162306a36Sopenharmony_ci}
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_get_event_resources)
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci/******************************************************************************
31662306a36Sopenharmony_ci *
31762306a36Sopenharmony_ci * FUNCTION:    acpi_resource_to_address64
31862306a36Sopenharmony_ci *
31962306a36Sopenharmony_ci * PARAMETERS:  resource        - Pointer to a resource
32062306a36Sopenharmony_ci *              out             - Pointer to the users's return buffer
32162306a36Sopenharmony_ci *                                (a struct acpi_resource_address64)
32262306a36Sopenharmony_ci *
32362306a36Sopenharmony_ci * RETURN:      Status
32462306a36Sopenharmony_ci *
32562306a36Sopenharmony_ci * DESCRIPTION: If the resource is an address16, address32, or address64,
32662306a36Sopenharmony_ci *              copy it to the address64 return buffer. This saves the
32762306a36Sopenharmony_ci *              caller from having to duplicate code for different-sized
32862306a36Sopenharmony_ci *              addresses.
32962306a36Sopenharmony_ci *
33062306a36Sopenharmony_ci ******************************************************************************/
33162306a36Sopenharmony_ciacpi_status
33262306a36Sopenharmony_ciacpi_resource_to_address64(struct acpi_resource *resource,
33362306a36Sopenharmony_ci			   struct acpi_resource_address64 *out)
33462306a36Sopenharmony_ci{
33562306a36Sopenharmony_ci	struct acpi_resource_address16 *address16;
33662306a36Sopenharmony_ci	struct acpi_resource_address32 *address32;
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci	if (!resource || !out) {
33962306a36Sopenharmony_ci		return (AE_BAD_PARAMETER);
34062306a36Sopenharmony_ci	}
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	/* Convert 16 or 32 address descriptor to 64 */
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci	switch (resource->type) {
34562306a36Sopenharmony_ci	case ACPI_RESOURCE_TYPE_ADDRESS16:
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci		address16 =
34862306a36Sopenharmony_ci		    ACPI_CAST_PTR(struct acpi_resource_address16,
34962306a36Sopenharmony_ci				  &resource->data);
35062306a36Sopenharmony_ci		ACPI_COPY_ADDRESS(out, address16);
35162306a36Sopenharmony_ci		break;
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	case ACPI_RESOURCE_TYPE_ADDRESS32:
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci		address32 =
35662306a36Sopenharmony_ci		    ACPI_CAST_PTR(struct acpi_resource_address32,
35762306a36Sopenharmony_ci				  &resource->data);
35862306a36Sopenharmony_ci		ACPI_COPY_ADDRESS(out, address32);
35962306a36Sopenharmony_ci		break;
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	case ACPI_RESOURCE_TYPE_ADDRESS64:
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci		/* Simple copy for 64 bit source */
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci		memcpy(out, &resource->data,
36662306a36Sopenharmony_ci		       sizeof(struct acpi_resource_address64));
36762306a36Sopenharmony_ci		break;
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	default:
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci		return (AE_BAD_PARAMETER);
37262306a36Sopenharmony_ci	}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	return (AE_OK);
37562306a36Sopenharmony_ci}
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_resource_to_address64)
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci/*******************************************************************************
38062306a36Sopenharmony_ci *
38162306a36Sopenharmony_ci * FUNCTION:    acpi_get_vendor_resource
38262306a36Sopenharmony_ci *
38362306a36Sopenharmony_ci * PARAMETERS:  device_handle   - Handle for the parent device object
38462306a36Sopenharmony_ci *              name            - Method name for the parent resource
38562306a36Sopenharmony_ci *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
38662306a36Sopenharmony_ci *              uuid            - Pointer to the UUID to be matched.
38762306a36Sopenharmony_ci *                                includes both subtype and 16-byte UUID
38862306a36Sopenharmony_ci *              ret_buffer      - Where the vendor resource is returned
38962306a36Sopenharmony_ci *
39062306a36Sopenharmony_ci * RETURN:      Status
39162306a36Sopenharmony_ci *
39262306a36Sopenharmony_ci * DESCRIPTION: Walk a resource template for the specified device to find a
39362306a36Sopenharmony_ci *              vendor-defined resource that matches the supplied UUID and
39462306a36Sopenharmony_ci *              UUID subtype. Returns a struct acpi_resource of type Vendor.
39562306a36Sopenharmony_ci *
39662306a36Sopenharmony_ci ******************************************************************************/
39762306a36Sopenharmony_ciacpi_status
39862306a36Sopenharmony_ciacpi_get_vendor_resource(acpi_handle device_handle,
39962306a36Sopenharmony_ci			 char *name,
40062306a36Sopenharmony_ci			 struct acpi_vendor_uuid *uuid,
40162306a36Sopenharmony_ci			 struct acpi_buffer *ret_buffer)
40262306a36Sopenharmony_ci{
40362306a36Sopenharmony_ci	struct acpi_vendor_walk_info info;
40462306a36Sopenharmony_ci	acpi_status status;
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci	/* Other parameters are validated by acpi_walk_resources */
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci	if (!uuid || !ret_buffer) {
40962306a36Sopenharmony_ci		return (AE_BAD_PARAMETER);
41062306a36Sopenharmony_ci	}
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci	info.uuid = uuid;
41362306a36Sopenharmony_ci	info.buffer = ret_buffer;
41462306a36Sopenharmony_ci	info.status = AE_NOT_EXIST;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	/* Walk the _CRS or _PRS resource list for this device */
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	status =
41962306a36Sopenharmony_ci	    acpi_walk_resources(device_handle, name,
42062306a36Sopenharmony_ci				acpi_rs_match_vendor_resource, &info);
42162306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
42262306a36Sopenharmony_ci		return (status);
42362306a36Sopenharmony_ci	}
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci	return (info.status);
42662306a36Sopenharmony_ci}
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_get_vendor_resource)
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci/*******************************************************************************
43162306a36Sopenharmony_ci *
43262306a36Sopenharmony_ci * FUNCTION:    acpi_rs_match_vendor_resource
43362306a36Sopenharmony_ci *
43462306a36Sopenharmony_ci * PARAMETERS:  acpi_walk_resource_callback
43562306a36Sopenharmony_ci *
43662306a36Sopenharmony_ci * RETURN:      Status
43762306a36Sopenharmony_ci *
43862306a36Sopenharmony_ci * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
43962306a36Sopenharmony_ci *
44062306a36Sopenharmony_ci ******************************************************************************/
44162306a36Sopenharmony_cistatic acpi_status
44262306a36Sopenharmony_ciacpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
44362306a36Sopenharmony_ci{
44462306a36Sopenharmony_ci	struct acpi_vendor_walk_info *info = context;
44562306a36Sopenharmony_ci	struct acpi_resource_vendor_typed *vendor;
44662306a36Sopenharmony_ci	struct acpi_buffer *buffer;
44762306a36Sopenharmony_ci	acpi_status status;
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	/* Ignore all descriptors except Vendor */
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci	if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) {
45262306a36Sopenharmony_ci		return (AE_OK);
45362306a36Sopenharmony_ci	}
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	vendor = &resource->data.vendor_typed;
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	/*
45862306a36Sopenharmony_ci	 * For a valid match, these conditions must hold:
45962306a36Sopenharmony_ci	 *
46062306a36Sopenharmony_ci	 * 1) Length of descriptor data must be at least as long as a UUID struct
46162306a36Sopenharmony_ci	 * 2) The UUID subtypes must match
46262306a36Sopenharmony_ci	 * 3) The UUID data must match
46362306a36Sopenharmony_ci	 */
46462306a36Sopenharmony_ci	if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) ||
46562306a36Sopenharmony_ci	    (vendor->uuid_subtype != info->uuid->subtype) ||
46662306a36Sopenharmony_ci	    (memcmp(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) {
46762306a36Sopenharmony_ci		return (AE_OK);
46862306a36Sopenharmony_ci	}
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci	/* Validate/Allocate/Clear caller buffer */
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	buffer = info->buffer;
47362306a36Sopenharmony_ci	status = acpi_ut_initialize_buffer(buffer, resource->length);
47462306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
47562306a36Sopenharmony_ci		return (status);
47662306a36Sopenharmony_ci	}
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	/* Found the correct resource, copy and return it */
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci	memcpy(buffer->pointer, resource, resource->length);
48162306a36Sopenharmony_ci	buffer->length = resource->length;
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci	/* Found the desired descriptor, terminate resource walk */
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	info->status = AE_OK;
48662306a36Sopenharmony_ci	return (AE_CTRL_TERMINATE);
48762306a36Sopenharmony_ci}
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci/*******************************************************************************
49062306a36Sopenharmony_ci *
49162306a36Sopenharmony_ci * FUNCTION:    acpi_walk_resource_buffer
49262306a36Sopenharmony_ci *
49362306a36Sopenharmony_ci * PARAMETERS:  buffer          - Formatted buffer returned by one of the
49462306a36Sopenharmony_ci *                                various Get*Resource functions
49562306a36Sopenharmony_ci *              user_function   - Called for each resource
49662306a36Sopenharmony_ci *              context         - Passed to user_function
49762306a36Sopenharmony_ci *
49862306a36Sopenharmony_ci * RETURN:      Status
49962306a36Sopenharmony_ci *
50062306a36Sopenharmony_ci * DESCRIPTION: Walks the input resource template. The user_function is called
50162306a36Sopenharmony_ci *              once for each resource in the list.
50262306a36Sopenharmony_ci *
50362306a36Sopenharmony_ci ******************************************************************************/
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ciacpi_status
50662306a36Sopenharmony_ciacpi_walk_resource_buffer(struct acpi_buffer *buffer,
50762306a36Sopenharmony_ci			  acpi_walk_resource_callback user_function,
50862306a36Sopenharmony_ci			  void *context)
50962306a36Sopenharmony_ci{
51062306a36Sopenharmony_ci	acpi_status status = AE_OK;
51162306a36Sopenharmony_ci	struct acpi_resource *resource;
51262306a36Sopenharmony_ci	struct acpi_resource *resource_end;
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(acpi_walk_resource_buffer);
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	/* Parameter validation */
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	if (!buffer || !buffer->pointer || !user_function) {
51962306a36Sopenharmony_ci		return_ACPI_STATUS(AE_BAD_PARAMETER);
52062306a36Sopenharmony_ci	}
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	/* Buffer contains the resource list and length */
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	resource = ACPI_CAST_PTR(struct acpi_resource, buffer->pointer);
52562306a36Sopenharmony_ci	resource_end =
52662306a36Sopenharmony_ci	    ACPI_ADD_PTR(struct acpi_resource, buffer->pointer, buffer->length);
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	/* Walk the resource list until the end_tag is found (or buffer end) */
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	while (resource < resource_end) {
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_ci		/* Sanity check the resource type */
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci		if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
53562306a36Sopenharmony_ci			status = AE_AML_INVALID_RESOURCE_TYPE;
53662306a36Sopenharmony_ci			break;
53762306a36Sopenharmony_ci		}
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci		/* Sanity check the length. It must not be zero, or we loop forever */
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci		if (!resource->length) {
54262306a36Sopenharmony_ci			return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
54362306a36Sopenharmony_ci		}
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci		/* Invoke the user function, abort on any error returned */
54662306a36Sopenharmony_ci
54762306a36Sopenharmony_ci		status = user_function(resource, context);
54862306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
54962306a36Sopenharmony_ci			if (status == AE_CTRL_TERMINATE) {
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci				/* This is an OK termination by the user function */
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci				status = AE_OK;
55462306a36Sopenharmony_ci			}
55562306a36Sopenharmony_ci			break;
55662306a36Sopenharmony_ci		}
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci		/* end_tag indicates end-of-list */
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci		if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
56162306a36Sopenharmony_ci			break;
56262306a36Sopenharmony_ci		}
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ci		/* Get the next resource descriptor */
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_ci		resource = ACPI_NEXT_RESOURCE(resource);
56762306a36Sopenharmony_ci	}
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	return_ACPI_STATUS(status);
57062306a36Sopenharmony_ci}
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_walk_resource_buffer)
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_ci/*******************************************************************************
57562306a36Sopenharmony_ci *
57662306a36Sopenharmony_ci * FUNCTION:    acpi_walk_resources
57762306a36Sopenharmony_ci *
57862306a36Sopenharmony_ci * PARAMETERS:  device_handle   - Handle to the device object for the
57962306a36Sopenharmony_ci *                                device we are querying
58062306a36Sopenharmony_ci *              name            - Method name of the resources we want.
58162306a36Sopenharmony_ci *                                (METHOD_NAME__CRS, METHOD_NAME__PRS, or
58262306a36Sopenharmony_ci *                                METHOD_NAME__AEI or METHOD_NAME__DMA)
58362306a36Sopenharmony_ci *              user_function   - Called for each resource
58462306a36Sopenharmony_ci *              context         - Passed to user_function
58562306a36Sopenharmony_ci *
58662306a36Sopenharmony_ci * RETURN:      Status
58762306a36Sopenharmony_ci *
58862306a36Sopenharmony_ci * DESCRIPTION: Retrieves the current or possible resource list for the
58962306a36Sopenharmony_ci *              specified device. The user_function is called once for
59062306a36Sopenharmony_ci *              each resource in the list.
59162306a36Sopenharmony_ci *
59262306a36Sopenharmony_ci ******************************************************************************/
59362306a36Sopenharmony_ciacpi_status
59462306a36Sopenharmony_ciacpi_walk_resources(acpi_handle device_handle,
59562306a36Sopenharmony_ci		    char *name,
59662306a36Sopenharmony_ci		    acpi_walk_resource_callback user_function, void *context)
59762306a36Sopenharmony_ci{
59862306a36Sopenharmony_ci	acpi_status status;
59962306a36Sopenharmony_ci	struct acpi_buffer buffer;
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE(acpi_walk_resources);
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci	/* Parameter validation */
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci	if (!device_handle || !user_function || !name ||
60662306a36Sopenharmony_ci	    (!ACPI_COMPARE_NAMESEG(name, METHOD_NAME__CRS) &&
60762306a36Sopenharmony_ci	     !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__PRS) &&
60862306a36Sopenharmony_ci	     !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__AEI) &&
60962306a36Sopenharmony_ci	     !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__DMA))) {
61062306a36Sopenharmony_ci		return_ACPI_STATUS(AE_BAD_PARAMETER);
61162306a36Sopenharmony_ci	}
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci	/* Get the _CRS/_PRS/_AEI/_DMA resource list */
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
61662306a36Sopenharmony_ci	status = acpi_rs_get_method_data(device_handle, name, &buffer);
61762306a36Sopenharmony_ci	if (ACPI_FAILURE(status)) {
61862306a36Sopenharmony_ci		return_ACPI_STATUS(status);
61962306a36Sopenharmony_ci	}
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci	/* Walk the resource list and cleanup */
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci	status = acpi_walk_resource_buffer(&buffer, user_function, context);
62462306a36Sopenharmony_ci	ACPI_FREE(buffer.pointer);
62562306a36Sopenharmony_ci	return_ACPI_STATUS(status);
62662306a36Sopenharmony_ci}
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ciACPI_EXPORT_SYMBOL(acpi_walk_resources)
629