xref: /openbmc/linux/drivers/acpi/acpica/rsutils.c (revision c13aca79ff3c4af5fd31a5b2743a90eba6e36a26)
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