1*95857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /*******************************************************************************
395b482a8SLen Brown *
495b482a8SLen Brown * Module Name: rsutils - Utilities for the resource manager
595b482a8SLen Brown *
695b482a8SLen Brown ******************************************************************************/
795b482a8SLen Brown
895b482a8SLen Brown #include <acpi/acpi.h>
9e2f7a777SLen Brown #include "accommon.h"
10e2f7a777SLen Brown #include "acnamesp.h"
11e2f7a777SLen Brown #include "acresrc.h"
1295b482a8SLen Brown
1395b482a8SLen Brown #define _COMPONENT ACPI_RESOURCES
1495b482a8SLen Brown ACPI_MODULE_NAME("rsutils")
1595b482a8SLen Brown
1695b482a8SLen Brown /*******************************************************************************
1795b482a8SLen Brown *
1895b482a8SLen Brown * FUNCTION: acpi_rs_decode_bitmask
1995b482a8SLen Brown *
20ba494beeSBob Moore * PARAMETERS: mask - Bitmask to decode
21ba494beeSBob Moore * list - Where the converted list is returned
2295b482a8SLen Brown *
2395b482a8SLen Brown * RETURN: Count of bits set (length of list)
2495b482a8SLen Brown *
2595b482a8SLen Brown * DESCRIPTION: Convert a bit mask into a list of values
2695b482a8SLen Brown *
2795b482a8SLen Brown ******************************************************************************/
acpi_rs_decode_bitmask(u16 mask,u8 * list)2895b482a8SLen Brown u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
2995b482a8SLen Brown {
3095b482a8SLen Brown u8 i;
3195b482a8SLen Brown u8 bit_count;
3295b482a8SLen Brown
3395b482a8SLen Brown ACPI_FUNCTION_ENTRY();
3495b482a8SLen Brown
3595b482a8SLen Brown /* Decode the mask bits */
3695b482a8SLen Brown
3795b482a8SLen Brown for (i = 0, bit_count = 0; mask; i++) {
3895b482a8SLen Brown if (mask & 0x0001) {
3995b482a8SLen Brown list[bit_count] = i;
4095b482a8SLen Brown bit_count++;
4195b482a8SLen Brown }
4295b482a8SLen Brown
4395b482a8SLen Brown mask >>= 1;
4495b482a8SLen Brown }
4595b482a8SLen Brown
4695b482a8SLen Brown return (bit_count);
4795b482a8SLen Brown }
4895b482a8SLen Brown
4995b482a8SLen Brown /*******************************************************************************
5095b482a8SLen Brown *
5195b482a8SLen Brown * FUNCTION: acpi_rs_encode_bitmask
5295b482a8SLen Brown *
53ba494beeSBob Moore * PARAMETERS: list - List of values to encode
54ba494beeSBob Moore * count - Length of list
5595b482a8SLen Brown *
5695b482a8SLen Brown * RETURN: Encoded bitmask
5795b482a8SLen Brown *
5895b482a8SLen Brown * DESCRIPTION: Convert a list of values to an encoded bitmask
5995b482a8SLen Brown *
6095b482a8SLen Brown ******************************************************************************/
6195b482a8SLen Brown
acpi_rs_encode_bitmask(u8 * list,u8 count)6295b482a8SLen Brown u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
6395b482a8SLen Brown {
6495b482a8SLen Brown u32 i;
6595b482a8SLen Brown u16 mask;
6695b482a8SLen Brown
6795b482a8SLen Brown ACPI_FUNCTION_ENTRY();
6895b482a8SLen Brown
6995b482a8SLen Brown /* Encode the list into a single bitmask */
7095b482a8SLen Brown
7195b482a8SLen Brown for (i = 0, mask = 0; i < count; i++) {
7295b482a8SLen Brown mask |= (0x1 << list[i]);
7395b482a8SLen Brown }
7495b482a8SLen Brown
759c0d7939SLv Zheng return (mask);
7695b482a8SLen Brown }
7795b482a8SLen Brown
7895b482a8SLen Brown /*******************************************************************************
7995b482a8SLen Brown *
8095b482a8SLen Brown * FUNCTION: acpi_rs_move_data
8195b482a8SLen Brown *
82ba494beeSBob Moore * PARAMETERS: destination - Pointer to the destination descriptor
83ba494beeSBob Moore * source - Pointer to the source descriptor
8495b482a8SLen Brown * item_count - How many items to move
8595b482a8SLen Brown * move_type - Byte width
8695b482a8SLen Brown *
8795b482a8SLen Brown * RETURN: None
8895b482a8SLen Brown *
8995b482a8SLen Brown * DESCRIPTION: Move multiple data items from one descriptor to another. Handles
9095b482a8SLen Brown * alignment issues and endian issues if necessary, as configured
9195b482a8SLen Brown * via the ACPI_MOVE_* macros. (This is why a memcpy is not used)
9295b482a8SLen Brown *
9395b482a8SLen Brown ******************************************************************************/
9495b482a8SLen Brown
9595b482a8SLen Brown void
acpi_rs_move_data(void * destination,void * source,u16 item_count,u8 move_type)9695b482a8SLen Brown acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
9795b482a8SLen Brown {
9895b482a8SLen Brown u32 i;
9995b482a8SLen Brown
10095b482a8SLen Brown ACPI_FUNCTION_ENTRY();
10195b482a8SLen Brown
10295b482a8SLen Brown /* One move per item */
10395b482a8SLen Brown
10495b482a8SLen Brown for (i = 0; i < item_count; i++) {
10595b482a8SLen Brown switch (move_type) {
10695b482a8SLen Brown /*
10795b482a8SLen Brown * For the 8-bit case, we can perform the move all at once
10895b482a8SLen Brown * since there are no alignment or endian issues
10995b482a8SLen Brown */
11095b482a8SLen Brown case ACPI_RSC_MOVE8:
111e0fe0a8dSLin Ming case ACPI_RSC_MOVE_GPIO_RES:
112e0fe0a8dSLin Ming case ACPI_RSC_MOVE_SERIAL_VEN:
113e0fe0a8dSLin Ming case ACPI_RSC_MOVE_SERIAL_RES:
1141d1ea1b7SChao Guan
1154fa4616eSBob Moore memcpy(destination, source, item_count);
11695b482a8SLen Brown return;
11795b482a8SLen Brown
11895b482a8SLen Brown /*
11995b482a8SLen Brown * 16-, 32-, and 64-bit cases must use the move macros that perform
12058f87ed0SLucas De Marchi * endian conversion and/or accommodate hardware that cannot perform
12195b482a8SLen Brown * misaligned memory transfers
12295b482a8SLen Brown */
12395b482a8SLen Brown case ACPI_RSC_MOVE16:
124e0fe0a8dSLin Ming case ACPI_RSC_MOVE_GPIO_PIN:
1251d1ea1b7SChao Guan
12695b482a8SLen Brown ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i],
12795b482a8SLen Brown &ACPI_CAST_PTR(u16, source)[i]);
12895b482a8SLen Brown break;
12995b482a8SLen Brown
13095b482a8SLen Brown case ACPI_RSC_MOVE32:
1311d1ea1b7SChao Guan
13295b482a8SLen Brown ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i],
13395b482a8SLen Brown &ACPI_CAST_PTR(u32, source)[i]);
13495b482a8SLen Brown break;
13595b482a8SLen Brown
13695b482a8SLen Brown case ACPI_RSC_MOVE64:
1371d1ea1b7SChao Guan
13895b482a8SLen Brown ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i],
13995b482a8SLen Brown &ACPI_CAST_PTR(u64, source)[i]);
14095b482a8SLen Brown break;
14195b482a8SLen Brown
14295b482a8SLen Brown default:
1431d1ea1b7SChao Guan
14495b482a8SLen Brown return;
14595b482a8SLen Brown }
14695b482a8SLen Brown }
14795b482a8SLen Brown }
14895b482a8SLen Brown
14995b482a8SLen Brown /*******************************************************************************
15095b482a8SLen Brown *
15195b482a8SLen Brown * FUNCTION: acpi_rs_set_resource_length
15295b482a8SLen Brown *
15395b482a8SLen Brown * PARAMETERS: total_length - Length of the AML descriptor, including
15495b482a8SLen Brown * the header and length fields.
155ba494beeSBob Moore * aml - Pointer to the raw AML descriptor
15695b482a8SLen Brown *
15795b482a8SLen Brown * RETURN: None
15895b482a8SLen Brown *
15995b482a8SLen Brown * DESCRIPTION: Set the resource_length field of an AML
16095b482a8SLen Brown * resource descriptor, both Large and Small descriptors are
16195b482a8SLen Brown * supported automatically. Note: Descriptor Type field must
16295b482a8SLen Brown * be valid.
16395b482a8SLen Brown *
16495b482a8SLen Brown ******************************************************************************/
16595b482a8SLen Brown
16695b482a8SLen Brown void
acpi_rs_set_resource_length(acpi_rsdesc_size total_length,union aml_resource * aml)16795b482a8SLen Brown acpi_rs_set_resource_length(acpi_rsdesc_size total_length,
16895b482a8SLen Brown union aml_resource *aml)
16995b482a8SLen Brown {
17095b482a8SLen Brown acpi_rs_length resource_length;
17195b482a8SLen Brown
17295b482a8SLen Brown ACPI_FUNCTION_ENTRY();
17395b482a8SLen Brown
17495b482a8SLen Brown /* Length is the total descriptor length minus the header length */
17595b482a8SLen Brown
17695b482a8SLen Brown resource_length = (acpi_rs_length)
17795b482a8SLen Brown (total_length - acpi_ut_get_resource_header_length(aml));
17895b482a8SLen Brown
17995b482a8SLen Brown /* Length is stored differently for large and small descriptors */
18095b482a8SLen Brown
18195b482a8SLen Brown if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
18295b482a8SLen Brown
18395b482a8SLen Brown /* Large descriptor -- bytes 1-2 contain the 16-bit length */
18495b482a8SLen Brown
18595b482a8SLen Brown ACPI_MOVE_16_TO_16(&aml->large_header.resource_length,
18695b482a8SLen Brown &resource_length);
18795b482a8SLen Brown } else {
1881fad8738SBob Moore /*
1891fad8738SBob Moore * Small descriptor -- bits 2:0 of byte 0 contain the length
1901fad8738SBob Moore * Clear any existing length, preserving descriptor type bits
1911fad8738SBob Moore */
19295b482a8SLen Brown aml->small_header.descriptor_type = (u8)
1931fad8738SBob Moore ((aml->small_header.descriptor_type &
1941fad8738SBob Moore ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK)
19595b482a8SLen Brown | resource_length);
19695b482a8SLen Brown }
19795b482a8SLen Brown }
19895b482a8SLen Brown
19995b482a8SLen Brown /*******************************************************************************
20095b482a8SLen Brown *
20195b482a8SLen Brown * FUNCTION: acpi_rs_set_resource_header
20295b482a8SLen Brown *
20395b482a8SLen Brown * PARAMETERS: descriptor_type - Byte to be inserted as the type
20495b482a8SLen Brown * total_length - Length of the AML descriptor, including
20595b482a8SLen Brown * the header and length fields.
206ba494beeSBob Moore * aml - Pointer to the raw AML descriptor
20795b482a8SLen Brown *
20895b482a8SLen Brown * RETURN: None
20995b482a8SLen Brown *
21095b482a8SLen Brown * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML
21195b482a8SLen Brown * resource descriptor, both Large and Small descriptors are
21295b482a8SLen Brown * supported automatically
21395b482a8SLen Brown *
21495b482a8SLen Brown ******************************************************************************/
21595b482a8SLen Brown
21695b482a8SLen Brown void
acpi_rs_set_resource_header(u8 descriptor_type,acpi_rsdesc_size total_length,union aml_resource * aml)21795b482a8SLen Brown acpi_rs_set_resource_header(u8 descriptor_type,
21895b482a8SLen Brown acpi_rsdesc_size total_length,
21995b482a8SLen Brown union aml_resource *aml)
22095b482a8SLen Brown {
22195b482a8SLen Brown ACPI_FUNCTION_ENTRY();
22295b482a8SLen Brown
22395b482a8SLen Brown /* Set the Resource Type */
22495b482a8SLen Brown
22595b482a8SLen Brown aml->small_header.descriptor_type = descriptor_type;
22695b482a8SLen Brown
22795b482a8SLen Brown /* Set the Resource Length */
22895b482a8SLen Brown
22995b482a8SLen Brown acpi_rs_set_resource_length(total_length, aml);
23095b482a8SLen Brown }
23195b482a8SLen Brown
23295b482a8SLen Brown /*******************************************************************************
23395b482a8SLen Brown *
23495b482a8SLen Brown * FUNCTION: acpi_rs_strcpy
23595b482a8SLen Brown *
236ba494beeSBob Moore * PARAMETERS: destination - Pointer to the destination string
237ba494beeSBob Moore * source - Pointer to the source string
23895b482a8SLen Brown *
23995b482a8SLen Brown * RETURN: String length, including NULL terminator
24095b482a8SLen Brown *
24195b482a8SLen Brown * DESCRIPTION: Local string copy that returns the string length, saving a
24295b482a8SLen Brown * strcpy followed by a strlen.
24395b482a8SLen Brown *
24495b482a8SLen Brown ******************************************************************************/
24595b482a8SLen Brown
acpi_rs_strcpy(char * destination,char * source)24695b482a8SLen Brown static u16 acpi_rs_strcpy(char *destination, char *source)
24795b482a8SLen Brown {
24895b482a8SLen Brown u16 i;
24995b482a8SLen Brown
25095b482a8SLen Brown ACPI_FUNCTION_ENTRY();
25195b482a8SLen Brown
25295b482a8SLen Brown for (i = 0; source[i]; i++) {
25395b482a8SLen Brown destination[i] = source[i];
25495b482a8SLen Brown }
25595b482a8SLen Brown
25695b482a8SLen Brown destination[i] = 0;
25795b482a8SLen Brown
25895b482a8SLen Brown /* Return string length including the NULL terminator */
25995b482a8SLen Brown
26095b482a8SLen Brown return ((u16) (i + 1));
26195b482a8SLen Brown }
26295b482a8SLen Brown
26395b482a8SLen Brown /*******************************************************************************
26495b482a8SLen Brown *
26595b482a8SLen Brown * FUNCTION: acpi_rs_get_resource_source
26695b482a8SLen Brown *
26795b482a8SLen Brown * PARAMETERS: resource_length - Length field of the descriptor
26895b482a8SLen Brown * minimum_length - Minimum length of the descriptor (minus
26995b482a8SLen Brown * any optional fields)
27095b482a8SLen Brown * resource_source - Where the resource_source is returned
271ba494beeSBob Moore * aml - Pointer to the raw AML descriptor
27295b482a8SLen Brown * string_ptr - (optional) where to store the actual
27395b482a8SLen Brown * resource_source string
27495b482a8SLen Brown *
27595b482a8SLen Brown * RETURN: Length of the string plus NULL terminator, rounded up to native
27695b482a8SLen Brown * word boundary
27795b482a8SLen Brown *
27895b482a8SLen Brown * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor
27995b482a8SLen Brown * to an internal resource descriptor
28095b482a8SLen Brown *
28195b482a8SLen Brown ******************************************************************************/
28295b482a8SLen Brown
28395b482a8SLen Brown acpi_rs_length
acpi_rs_get_resource_source(acpi_rs_length resource_length,acpi_rs_length minimum_length,struct acpi_resource_source * resource_source,union aml_resource * aml,char * string_ptr)28495b482a8SLen Brown acpi_rs_get_resource_source(acpi_rs_length resource_length,
28595b482a8SLen Brown acpi_rs_length minimum_length,
28695b482a8SLen Brown struct acpi_resource_source * resource_source,
28795b482a8SLen Brown union aml_resource * aml, char *string_ptr)
28895b482a8SLen Brown {
28995b482a8SLen Brown acpi_rsdesc_size total_length;
29095b482a8SLen Brown u8 *aml_resource_source;
29195b482a8SLen Brown
29295b482a8SLen Brown ACPI_FUNCTION_ENTRY();
29395b482a8SLen Brown
29495b482a8SLen Brown total_length =
29595b482a8SLen Brown resource_length + sizeof(struct aml_resource_large_header);
29695b482a8SLen Brown aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
29795b482a8SLen Brown
29895b482a8SLen Brown /*
2991fad8738SBob Moore * resource_source is present if the length of the descriptor is longer
3001fad8738SBob Moore * than the minimum length.
30195b482a8SLen Brown *
30295b482a8SLen Brown * Note: Some resource descriptors will have an additional null, so
30395b482a8SLen Brown * we add 1 to the minimum length.
30495b482a8SLen Brown */
30595b482a8SLen Brown if (total_length > (acpi_rsdesc_size)(minimum_length + 1)) {
30695b482a8SLen Brown
30795b482a8SLen Brown /* Get the resource_source_index */
30895b482a8SLen Brown
30995b482a8SLen Brown resource_source->index = aml_resource_source[0];
31095b482a8SLen Brown
31195b482a8SLen Brown resource_source->string_ptr = string_ptr;
31295b482a8SLen Brown if (!string_ptr) {
31395b482a8SLen Brown /*
31495b482a8SLen Brown * String destination pointer is not specified; Set the String
31595b482a8SLen Brown * pointer to the end of the current resource_source structure.
31695b482a8SLen Brown */
31795b482a8SLen Brown resource_source->string_ptr =
31895b482a8SLen Brown ACPI_ADD_PTR(char, resource_source,
31995b482a8SLen Brown sizeof(struct acpi_resource_source));
32095b482a8SLen Brown }
32195b482a8SLen Brown
32295b482a8SLen Brown /*
32395b482a8SLen Brown * In order for the Resource length to be a multiple of the native
32495b482a8SLen Brown * word, calculate the length of the string (+1 for NULL terminator)
32595b482a8SLen Brown * and expand to the next word multiple.
32695b482a8SLen Brown *
32795b482a8SLen Brown * Zero the entire area of the buffer.
32895b482a8SLen Brown */
3293e8214e5SLv Zheng total_length =
3304fa4616eSBob Moore (u32)strlen(ACPI_CAST_PTR(char, &aml_resource_source[1])) +
3313e8214e5SLv Zheng 1;
3321fad8738SBob Moore
33395b482a8SLen Brown total_length = (u32)ACPI_ROUND_UP_TO_NATIVE_WORD(total_length);
33495b482a8SLen Brown
3354fa4616eSBob Moore memset(resource_source->string_ptr, 0, total_length);
33695b482a8SLen Brown
33795b482a8SLen Brown /* Copy the resource_source string to the destination */
33895b482a8SLen Brown
33995b482a8SLen Brown resource_source->string_length =
34095b482a8SLen Brown acpi_rs_strcpy(resource_source->string_ptr,
34195b482a8SLen Brown ACPI_CAST_PTR(char,
34295b482a8SLen Brown &aml_resource_source[1]));
34395b482a8SLen Brown
34495b482a8SLen Brown return ((acpi_rs_length)total_length);
34595b482a8SLen Brown }
34695b482a8SLen Brown
34795b482a8SLen Brown /* resource_source is not present */
34895b482a8SLen Brown
34995b482a8SLen Brown resource_source->index = 0;
35095b482a8SLen Brown resource_source->string_length = 0;
35195b482a8SLen Brown resource_source->string_ptr = NULL;
35295b482a8SLen Brown return (0);
35395b482a8SLen Brown }
35495b482a8SLen Brown
35595b482a8SLen Brown /*******************************************************************************
35695b482a8SLen Brown *
35795b482a8SLen Brown * FUNCTION: acpi_rs_set_resource_source
35895b482a8SLen Brown *
359ba494beeSBob Moore * PARAMETERS: aml - Pointer to the raw AML descriptor
36095b482a8SLen Brown * minimum_length - Minimum length of the descriptor (minus
36195b482a8SLen Brown * any optional fields)
36295b482a8SLen Brown * resource_source - Internal resource_source
36395b482a8SLen Brown
36495b482a8SLen Brown *
36595b482a8SLen Brown * RETURN: Total length of the AML descriptor
36695b482a8SLen Brown *
36795b482a8SLen Brown * DESCRIPTION: Convert an optional resource_source from internal format to a
36895b482a8SLen Brown * raw AML resource descriptor
36995b482a8SLen Brown *
37095b482a8SLen Brown ******************************************************************************/
37195b482a8SLen Brown
37295b482a8SLen Brown acpi_rsdesc_size
acpi_rs_set_resource_source(union aml_resource * aml,acpi_rs_length minimum_length,struct acpi_resource_source * resource_source)37395b482a8SLen Brown acpi_rs_set_resource_source(union aml_resource *aml,
37495b482a8SLen Brown acpi_rs_length minimum_length,
37595b482a8SLen Brown struct acpi_resource_source *resource_source)
37695b482a8SLen Brown {
37795b482a8SLen Brown u8 *aml_resource_source;
37895b482a8SLen Brown acpi_rsdesc_size descriptor_length;
37995b482a8SLen Brown
38095b482a8SLen Brown ACPI_FUNCTION_ENTRY();
38195b482a8SLen Brown
38295b482a8SLen Brown descriptor_length = minimum_length;
38395b482a8SLen Brown
38495b482a8SLen Brown /* Non-zero string length indicates presence of a resource_source */
38595b482a8SLen Brown
38695b482a8SLen Brown if (resource_source->string_length) {
38795b482a8SLen Brown
38895b482a8SLen Brown /* Point to the end of the AML descriptor */
38995b482a8SLen Brown
39095b482a8SLen Brown aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
39195b482a8SLen Brown
39295b482a8SLen Brown /* Copy the resource_source_index */
39395b482a8SLen Brown
39495b482a8SLen Brown aml_resource_source[0] = (u8) resource_source->index;
39595b482a8SLen Brown
39695b482a8SLen Brown /* Copy the resource_source string */
39795b482a8SLen Brown
3984fa4616eSBob Moore strcpy(ACPI_CAST_PTR(char, &aml_resource_source[1]),
39995b482a8SLen Brown resource_source->string_ptr);
40095b482a8SLen Brown
40195b482a8SLen Brown /*
40295b482a8SLen Brown * Add the length of the string (+ 1 for null terminator) to the
40395b482a8SLen Brown * final descriptor length
40495b482a8SLen Brown */
4051fad8738SBob Moore descriptor_length += ((acpi_rsdesc_size)
4061fad8738SBob Moore resource_source->string_length + 1);
40795b482a8SLen Brown }
40895b482a8SLen Brown
40995b482a8SLen Brown /* Return the new total length of the AML descriptor */
41095b482a8SLen Brown
41195b482a8SLen Brown return (descriptor_length);
41295b482a8SLen Brown }
41395b482a8SLen Brown
41495b482a8SLen Brown /*******************************************************************************
41595b482a8SLen Brown *
41695b482a8SLen Brown * FUNCTION: acpi_rs_get_prt_method_data
41795b482a8SLen Brown *
418ba494beeSBob Moore * PARAMETERS: node - Device node
41995b482a8SLen Brown * ret_buffer - Pointer to a buffer structure for the
42095b482a8SLen Brown * results
42195b482a8SLen Brown *
42295b482a8SLen Brown * RETURN: Status
42395b482a8SLen Brown *
42495b482a8SLen Brown * DESCRIPTION: This function is called to get the _PRT value of an object
42595b482a8SLen Brown * contained in an object specified by the handle passed in
42695b482a8SLen Brown *
42795b482a8SLen Brown * If the function fails an appropriate status will be returned
42895b482a8SLen Brown * and the contents of the callers buffer is undefined.
42995b482a8SLen Brown *
43095b482a8SLen Brown ******************************************************************************/
43195b482a8SLen Brown
43295b482a8SLen Brown acpi_status
acpi_rs_get_prt_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)43395b482a8SLen Brown acpi_rs_get_prt_method_data(struct acpi_namespace_node *node,
43495b482a8SLen Brown struct acpi_buffer *ret_buffer)
43595b482a8SLen Brown {
43695b482a8SLen Brown union acpi_operand_object *obj_desc;
43795b482a8SLen Brown acpi_status status;
43895b482a8SLen Brown
43995b482a8SLen Brown ACPI_FUNCTION_TRACE(rs_get_prt_method_data);
44095b482a8SLen Brown
44195b482a8SLen Brown /* Parameters guaranteed valid by caller */
44295b482a8SLen Brown
44395b482a8SLen Brown /* Execute the method, no parameters */
44495b482a8SLen Brown
4451fad8738SBob Moore status =
4461fad8738SBob Moore acpi_ut_evaluate_object(node, METHOD_NAME__PRT, ACPI_BTYPE_PACKAGE,
4471fad8738SBob Moore &obj_desc);
44895b482a8SLen Brown if (ACPI_FAILURE(status)) {
44995b482a8SLen Brown return_ACPI_STATUS(status);
45095b482a8SLen Brown }
45195b482a8SLen Brown
45295b482a8SLen Brown /*
45395b482a8SLen Brown * Create a resource linked list from the byte stream buffer that comes
45495b482a8SLen Brown * back from the _CRS method execution.
45595b482a8SLen Brown */
45695b482a8SLen Brown status = acpi_rs_create_pci_routing_table(obj_desc, ret_buffer);
45795b482a8SLen Brown
45895b482a8SLen Brown /* On exit, we must delete the object returned by evaluate_object */
45995b482a8SLen Brown
46095b482a8SLen Brown acpi_ut_remove_reference(obj_desc);
46195b482a8SLen Brown return_ACPI_STATUS(status);
46295b482a8SLen Brown }
46395b482a8SLen Brown
46495b482a8SLen Brown /*******************************************************************************
46595b482a8SLen Brown *
46695b482a8SLen Brown * FUNCTION: acpi_rs_get_crs_method_data
46795b482a8SLen Brown *
468ba494beeSBob Moore * PARAMETERS: node - Device node
46995b482a8SLen Brown * ret_buffer - Pointer to a buffer structure for the
47095b482a8SLen Brown * results
47195b482a8SLen Brown *
47295b482a8SLen Brown * RETURN: Status
47395b482a8SLen Brown *
47495b482a8SLen Brown * DESCRIPTION: This function is called to get the _CRS value of an object
47595b482a8SLen Brown * contained in an object specified by the handle passed in
47695b482a8SLen Brown *
47795b482a8SLen Brown * If the function fails an appropriate status will be returned
47895b482a8SLen Brown * and the contents of the callers buffer is undefined.
47995b482a8SLen Brown *
48095b482a8SLen Brown ******************************************************************************/
48195b482a8SLen Brown
48295b482a8SLen Brown acpi_status
acpi_rs_get_crs_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)48395b482a8SLen Brown acpi_rs_get_crs_method_data(struct acpi_namespace_node *node,
48495b482a8SLen Brown struct acpi_buffer *ret_buffer)
48595b482a8SLen Brown {
48695b482a8SLen Brown union acpi_operand_object *obj_desc;
48795b482a8SLen Brown acpi_status status;
48895b482a8SLen Brown
48995b482a8SLen Brown ACPI_FUNCTION_TRACE(rs_get_crs_method_data);
49095b482a8SLen Brown
49195b482a8SLen Brown /* Parameters guaranteed valid by caller */
49295b482a8SLen Brown
49395b482a8SLen Brown /* Execute the method, no parameters */
49495b482a8SLen Brown
4951fad8738SBob Moore status =
4961fad8738SBob Moore acpi_ut_evaluate_object(node, METHOD_NAME__CRS, ACPI_BTYPE_BUFFER,
4971fad8738SBob Moore &obj_desc);
49895b482a8SLen Brown if (ACPI_FAILURE(status)) {
49995b482a8SLen Brown return_ACPI_STATUS(status);
50095b482a8SLen Brown }
50195b482a8SLen Brown
50295b482a8SLen Brown /*
50395b482a8SLen Brown * Make the call to create a resource linked list from the
50495b482a8SLen Brown * byte stream buffer that comes back from the _CRS method
50595b482a8SLen Brown * execution.
50695b482a8SLen Brown */
50795b482a8SLen Brown status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
50895b482a8SLen Brown
509ba494beeSBob Moore /* On exit, we must delete the object returned by evaluateObject */
51095b482a8SLen Brown
51195b482a8SLen Brown acpi_ut_remove_reference(obj_desc);
51295b482a8SLen Brown return_ACPI_STATUS(status);
51395b482a8SLen Brown }
51495b482a8SLen Brown
51595b482a8SLen Brown /*******************************************************************************
51695b482a8SLen Brown *
51795b482a8SLen Brown * FUNCTION: acpi_rs_get_prs_method_data
51895b482a8SLen Brown *
519ba494beeSBob Moore * PARAMETERS: node - Device node
52095b482a8SLen Brown * ret_buffer - Pointer to a buffer structure for the
52195b482a8SLen Brown * results
52295b482a8SLen Brown *
52395b482a8SLen Brown * RETURN: Status
52495b482a8SLen Brown *
52595b482a8SLen Brown * DESCRIPTION: This function is called to get the _PRS value of an object
52695b482a8SLen Brown * contained in an object specified by the handle passed in
52795b482a8SLen Brown *
52895b482a8SLen Brown * If the function fails an appropriate status will be returned
52995b482a8SLen Brown * and the contents of the callers buffer is undefined.
53095b482a8SLen Brown *
53195b482a8SLen Brown ******************************************************************************/
53295b482a8SLen Brown
53395b482a8SLen Brown acpi_status
acpi_rs_get_prs_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)53495b482a8SLen Brown acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
53595b482a8SLen Brown struct acpi_buffer *ret_buffer)
53695b482a8SLen Brown {
53795b482a8SLen Brown union acpi_operand_object *obj_desc;
53895b482a8SLen Brown acpi_status status;
53995b482a8SLen Brown
54095b482a8SLen Brown ACPI_FUNCTION_TRACE(rs_get_prs_method_data);
54195b482a8SLen Brown
54295b482a8SLen Brown /* Parameters guaranteed valid by caller */
54395b482a8SLen Brown
54495b482a8SLen Brown /* Execute the method, no parameters */
54595b482a8SLen Brown
5461fad8738SBob Moore status =
5471fad8738SBob Moore acpi_ut_evaluate_object(node, METHOD_NAME__PRS, ACPI_BTYPE_BUFFER,
5481fad8738SBob Moore &obj_desc);
54995b482a8SLen Brown if (ACPI_FAILURE(status)) {
55095b482a8SLen Brown return_ACPI_STATUS(status);
55195b482a8SLen Brown }
55295b482a8SLen Brown
55395b482a8SLen Brown /*
55495b482a8SLen Brown * Make the call to create a resource linked list from the
55595b482a8SLen Brown * byte stream buffer that comes back from the _CRS method
55695b482a8SLen Brown * execution.
55795b482a8SLen Brown */
55895b482a8SLen Brown status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
55995b482a8SLen Brown
560ba494beeSBob Moore /* On exit, we must delete the object returned by evaluateObject */
56195b482a8SLen Brown
56295b482a8SLen Brown acpi_ut_remove_reference(obj_desc);
56395b482a8SLen Brown return_ACPI_STATUS(status);
56495b482a8SLen Brown }
56595b482a8SLen Brown
56695b482a8SLen Brown /*******************************************************************************
56795b482a8SLen Brown *
568a91cdde2SBob Moore * FUNCTION: acpi_rs_get_aei_method_data
569a91cdde2SBob Moore *
570ba494beeSBob Moore * PARAMETERS: node - Device node
571a91cdde2SBob Moore * ret_buffer - Pointer to a buffer structure for the
572a91cdde2SBob Moore * results
573a91cdde2SBob Moore *
574a91cdde2SBob Moore * RETURN: Status
575a91cdde2SBob Moore *
576a91cdde2SBob Moore * DESCRIPTION: This function is called to get the _AEI value of an object
577a91cdde2SBob Moore * contained in an object specified by the handle passed in
578a91cdde2SBob Moore *
579a91cdde2SBob Moore * If the function fails an appropriate status will be returned
580a91cdde2SBob Moore * and the contents of the callers buffer is undefined.
581a91cdde2SBob Moore *
582a91cdde2SBob Moore ******************************************************************************/
583a91cdde2SBob Moore
584a91cdde2SBob Moore acpi_status
acpi_rs_get_aei_method_data(struct acpi_namespace_node * node,struct acpi_buffer * ret_buffer)585a91cdde2SBob Moore acpi_rs_get_aei_method_data(struct acpi_namespace_node *node,
586a91cdde2SBob Moore struct acpi_buffer *ret_buffer)
587a91cdde2SBob Moore {
588a91cdde2SBob Moore union acpi_operand_object *obj_desc;
589a91cdde2SBob Moore acpi_status status;
590a91cdde2SBob Moore
591a91cdde2SBob Moore ACPI_FUNCTION_TRACE(rs_get_aei_method_data);
592a91cdde2SBob Moore
593a91cdde2SBob Moore /* Parameters guaranteed valid by caller */
594a91cdde2SBob Moore
595a91cdde2SBob Moore /* Execute the method, no parameters */
596a91cdde2SBob Moore
5971fad8738SBob Moore status =
5981fad8738SBob Moore acpi_ut_evaluate_object(node, METHOD_NAME__AEI, ACPI_BTYPE_BUFFER,
5991fad8738SBob Moore &obj_desc);
600a91cdde2SBob Moore if (ACPI_FAILURE(status)) {
601a91cdde2SBob Moore return_ACPI_STATUS(status);
602a91cdde2SBob Moore }
603a91cdde2SBob Moore
604a91cdde2SBob Moore /*
605a91cdde2SBob Moore * Make the call to create a resource linked list from the
606a91cdde2SBob Moore * byte stream buffer that comes back from the _CRS method
607a91cdde2SBob Moore * execution.
608a91cdde2SBob Moore */
609a91cdde2SBob Moore status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
610a91cdde2SBob Moore
611ba494beeSBob Moore /* On exit, we must delete the object returned by evaluateObject */
612a91cdde2SBob Moore
613a91cdde2SBob Moore acpi_ut_remove_reference(obj_desc);
614a91cdde2SBob Moore return_ACPI_STATUS(status);
615a91cdde2SBob Moore }
616a91cdde2SBob Moore
617a91cdde2SBob Moore /*******************************************************************************
618a91cdde2SBob Moore *
61995b482a8SLen Brown * FUNCTION: acpi_rs_get_method_data
62095b482a8SLen Brown *
621ba494beeSBob Moore * PARAMETERS: handle - Handle to the containing object
622ba494beeSBob Moore * path - Path to method, relative to Handle
62395b482a8SLen Brown * ret_buffer - Pointer to a buffer structure for the
62495b482a8SLen Brown * results
62595b482a8SLen Brown *
62695b482a8SLen Brown * RETURN: Status
62795b482a8SLen Brown *
62895b482a8SLen Brown * DESCRIPTION: This function is called to get the _CRS or _PRS value of an
62995b482a8SLen Brown * object contained in an object specified by the handle passed in
63095b482a8SLen Brown *
63195b482a8SLen Brown * If the function fails an appropriate status will be returned
63295b482a8SLen Brown * and the contents of the callers buffer is undefined.
63395b482a8SLen Brown *
63495b482a8SLen Brown ******************************************************************************/
63595b482a8SLen Brown
63695b482a8SLen Brown acpi_status
acpi_rs_get_method_data(acpi_handle handle,const char * path,struct acpi_buffer * ret_buffer)63795b482a8SLen Brown acpi_rs_get_method_data(acpi_handle handle,
6380dfaaa3dSBob Moore const char *path, struct acpi_buffer *ret_buffer)
63995b482a8SLen Brown {
64095b482a8SLen Brown union acpi_operand_object *obj_desc;
64195b482a8SLen Brown acpi_status status;
64295b482a8SLen Brown
64395b482a8SLen Brown ACPI_FUNCTION_TRACE(rs_get_method_data);
64495b482a8SLen Brown
64595b482a8SLen Brown /* Parameters guaranteed valid by caller */
64695b482a8SLen Brown
64795b482a8SLen Brown /* Execute the method, no parameters */
64895b482a8SLen Brown
64995b482a8SLen Brown status =
6500fdce476SRafael J. Wysocki acpi_ut_evaluate_object(ACPI_CAST_PTR
6510fdce476SRafael J. Wysocki (struct acpi_namespace_node, handle), path,
6520fdce476SRafael J. Wysocki ACPI_BTYPE_BUFFER, &obj_desc);
65395b482a8SLen Brown if (ACPI_FAILURE(status)) {
65495b482a8SLen Brown return_ACPI_STATUS(status);
65595b482a8SLen Brown }
65695b482a8SLen Brown
65795b482a8SLen Brown /*
65895b482a8SLen Brown * Make the call to create a resource linked list from the
65995b482a8SLen Brown * byte stream buffer that comes back from the method
66095b482a8SLen Brown * execution.
66195b482a8SLen Brown */
66295b482a8SLen Brown status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
66395b482a8SLen Brown
66495b482a8SLen Brown /* On exit, we must delete the object returned by evaluate_object */
66595b482a8SLen Brown
66695b482a8SLen Brown acpi_ut_remove_reference(obj_desc);
66795b482a8SLen Brown return_ACPI_STATUS(status);
66895b482a8SLen Brown }
66995b482a8SLen Brown
67095b482a8SLen Brown /*******************************************************************************
67195b482a8SLen Brown *
67295b482a8SLen Brown * FUNCTION: acpi_rs_set_srs_method_data
67395b482a8SLen Brown *
674ba494beeSBob Moore * PARAMETERS: node - Device node
67595b482a8SLen Brown * in_buffer - Pointer to a buffer structure of the
67695b482a8SLen Brown * parameter
67795b482a8SLen Brown *
67895b482a8SLen Brown * RETURN: Status
67995b482a8SLen Brown *
68095b482a8SLen Brown * DESCRIPTION: This function is called to set the _SRS of an object contained
68195b482a8SLen Brown * in an object specified by the handle passed in
68295b482a8SLen Brown *
68395b482a8SLen Brown * If the function fails an appropriate status will be returned
68495b482a8SLen Brown * and the contents of the callers buffer is undefined.
68595b482a8SLen Brown *
68695b482a8SLen Brown * Note: Parameters guaranteed valid by caller
68795b482a8SLen Brown *
68895b482a8SLen Brown ******************************************************************************/
68995b482a8SLen Brown
69095b482a8SLen Brown acpi_status
acpi_rs_set_srs_method_data(struct acpi_namespace_node * node,struct acpi_buffer * in_buffer)69195b482a8SLen Brown acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
69295b482a8SLen Brown struct acpi_buffer *in_buffer)
69395b482a8SLen Brown {
69495b482a8SLen Brown struct acpi_evaluate_info *info;
69595b482a8SLen Brown union acpi_operand_object *args[2];
69695b482a8SLen Brown acpi_status status;
69795b482a8SLen Brown struct acpi_buffer buffer;
69895b482a8SLen Brown
69995b482a8SLen Brown ACPI_FUNCTION_TRACE(rs_set_srs_method_data);
70095b482a8SLen Brown
70195b482a8SLen Brown /* Allocate and initialize the evaluation information block */
70295b482a8SLen Brown
70395b482a8SLen Brown info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
70495b482a8SLen Brown if (!info) {
70595b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY);
70695b482a8SLen Brown }
70795b482a8SLen Brown
70895b482a8SLen Brown info->prefix_node = node;
70929a241ccSBob Moore info->relative_pathname = METHOD_NAME__SRS;
71095b482a8SLen Brown info->parameters = args;
71195b482a8SLen Brown info->flags = ACPI_IGNORE_RETURN_VALUE;
71295b482a8SLen Brown
71395b482a8SLen Brown /*
71495b482a8SLen Brown * The in_buffer parameter will point to a linked list of
71595b482a8SLen Brown * resource parameters. It needs to be formatted into a
71695b482a8SLen Brown * byte stream to be sent in as an input parameter to _SRS
71795b482a8SLen Brown *
71895b482a8SLen Brown * Convert the linked list into a byte stream
71995b482a8SLen Brown */
72095b482a8SLen Brown buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
7219a0a3597SLv Zheng status = acpi_rs_create_aml_resources(in_buffer, &buffer);
72295b482a8SLen Brown if (ACPI_FAILURE(status)) {
72395b482a8SLen Brown goto cleanup;
72495b482a8SLen Brown }
72595b482a8SLen Brown
72695b482a8SLen Brown /* Create and initialize the method parameter object */
72795b482a8SLen Brown
72895b482a8SLen Brown args[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
72995b482a8SLen Brown if (!args[0]) {
73095b482a8SLen Brown /*
73195b482a8SLen Brown * Must free the buffer allocated above (otherwise it is freed
73295b482a8SLen Brown * later)
73395b482a8SLen Brown */
73495b482a8SLen Brown ACPI_FREE(buffer.pointer);
73595b482a8SLen Brown status = AE_NO_MEMORY;
73695b482a8SLen Brown goto cleanup;
73795b482a8SLen Brown }
73895b482a8SLen Brown
73995b482a8SLen Brown args[0]->buffer.length = (u32) buffer.length;
74095b482a8SLen Brown args[0]->buffer.pointer = buffer.pointer;
74195b482a8SLen Brown args[0]->common.flags = AOPOBJ_DATA_VALID;
74295b482a8SLen Brown args[1] = NULL;
74395b482a8SLen Brown
74495b482a8SLen Brown /* Execute the method, no return value is expected */
74595b482a8SLen Brown
74695b482a8SLen Brown status = acpi_ns_evaluate(info);
74795b482a8SLen Brown
74895b482a8SLen Brown /* Clean up and return the status from acpi_ns_evaluate */
74995b482a8SLen Brown
75095b482a8SLen Brown acpi_ut_remove_reference(args[0]);
75195b482a8SLen Brown
75295b482a8SLen Brown cleanup:
75395b482a8SLen Brown ACPI_FREE(info);
75495b482a8SLen Brown return_ACPI_STATUS(status);
75595b482a8SLen Brown }
756