cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rsutils.c (22024B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/*******************************************************************************
      3 *
      4 * Module Name: rsutils - Utilities for the resource manager
      5 *
      6 ******************************************************************************/
      7
      8#include <acpi/acpi.h>
      9#include "accommon.h"
     10#include "acnamesp.h"
     11#include "acresrc.h"
     12
     13#define _COMPONENT          ACPI_RESOURCES
     14ACPI_MODULE_NAME("rsutils")
     15
     16/*******************************************************************************
     17 *
     18 * FUNCTION:    acpi_rs_decode_bitmask
     19 *
     20 * PARAMETERS:  mask            - Bitmask to decode
     21 *              list            - Where the converted list is returned
     22 *
     23 * RETURN:      Count of bits set (length of list)
     24 *
     25 * DESCRIPTION: Convert a bit mask into a list of values
     26 *
     27 ******************************************************************************/
     28u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
     29{
     30	u8 i;
     31	u8 bit_count;
     32
     33	ACPI_FUNCTION_ENTRY();
     34
     35	/* Decode the mask bits */
     36
     37	for (i = 0, bit_count = 0; mask; i++) {
     38		if (mask & 0x0001) {
     39			list[bit_count] = i;
     40			bit_count++;
     41		}
     42
     43		mask >>= 1;
     44	}
     45
     46	return (bit_count);
     47}
     48
     49/*******************************************************************************
     50 *
     51 * FUNCTION:    acpi_rs_encode_bitmask
     52 *
     53 * PARAMETERS:  list            - List of values to encode
     54 *              count           - Length of list
     55 *
     56 * RETURN:      Encoded bitmask
     57 *
     58 * DESCRIPTION: Convert a list of values to an encoded bitmask
     59 *
     60 ******************************************************************************/
     61
     62u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
     63{
     64	u32 i;
     65	u16 mask;
     66
     67	ACPI_FUNCTION_ENTRY();
     68
     69	/* Encode the list into a single bitmask */
     70
     71	for (i = 0, mask = 0; i < count; i++) {
     72		mask |= (0x1 << list[i]);
     73	}
     74
     75	return (mask);
     76}
     77
     78/*******************************************************************************
     79 *
     80 * FUNCTION:    acpi_rs_move_data
     81 *
     82 * PARAMETERS:  destination         - Pointer to the destination descriptor
     83 *              source              - Pointer to the source descriptor
     84 *              item_count          - How many items to move
     85 *              move_type           - Byte width
     86 *
     87 * RETURN:      None
     88 *
     89 * DESCRIPTION: Move multiple data items from one descriptor to another. Handles
     90 *              alignment issues and endian issues if necessary, as configured
     91 *              via the ACPI_MOVE_* macros. (This is why a memcpy is not used)
     92 *
     93 ******************************************************************************/
     94
     95void
     96acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
     97{
     98	u32 i;
     99
    100	ACPI_FUNCTION_ENTRY();
    101
    102	/* One move per item */
    103
    104	for (i = 0; i < item_count; i++) {
    105		switch (move_type) {
    106			/*
    107			 * For the 8-bit case, we can perform the move all at once
    108			 * since there are no alignment or endian issues
    109			 */
    110		case ACPI_RSC_MOVE8:
    111		case ACPI_RSC_MOVE_GPIO_RES:
    112		case ACPI_RSC_MOVE_SERIAL_VEN:
    113		case ACPI_RSC_MOVE_SERIAL_RES:
    114
    115			memcpy(destination, source, item_count);
    116			return;
    117
    118			/*
    119			 * 16-, 32-, and 64-bit cases must use the move macros that perform
    120			 * endian conversion and/or accommodate hardware that cannot perform
    121			 * misaligned memory transfers
    122			 */
    123		case ACPI_RSC_MOVE16:
    124		case ACPI_RSC_MOVE_GPIO_PIN:
    125
    126			ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i],
    127					   &ACPI_CAST_PTR(u16, source)[i]);
    128			break;
    129
    130		case ACPI_RSC_MOVE32:
    131
    132			ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i],
    133					   &ACPI_CAST_PTR(u32, source)[i]);
    134			break;
    135
    136		case ACPI_RSC_MOVE64:
    137
    138			ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i],
    139					   &ACPI_CAST_PTR(u64, source)[i]);
    140			break;
    141
    142		default:
    143
    144			return;
    145		}
    146	}
    147}
    148
    149/*******************************************************************************
    150 *
    151 * FUNCTION:    acpi_rs_set_resource_length
    152 *
    153 * PARAMETERS:  total_length        - Length of the AML descriptor, including
    154 *                                    the header and length fields.
    155 *              aml                 - Pointer to the raw AML descriptor
    156 *
    157 * RETURN:      None
    158 *
    159 * DESCRIPTION: Set the resource_length field of an AML
    160 *              resource descriptor, both Large and Small descriptors are
    161 *              supported automatically. Note: Descriptor Type field must
    162 *              be valid.
    163 *
    164 ******************************************************************************/
    165
    166void
    167acpi_rs_set_resource_length(acpi_rsdesc_size total_length,
    168			    union aml_resource *aml)
    169{
    170	acpi_rs_length resource_length;
    171
    172	ACPI_FUNCTION_ENTRY();
    173
    174	/* Length is the total descriptor length minus the header length */
    175
    176	resource_length = (acpi_rs_length)
    177	    (total_length - acpi_ut_get_resource_header_length(aml));
    178
    179	/* Length is stored differently for large and small descriptors */
    180
    181	if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
    182
    183		/* Large descriptor -- bytes 1-2 contain the 16-bit length */
    184
    185		ACPI_MOVE_16_TO_16(&aml->large_header.resource_length,
    186				   &resource_length);
    187	} else {
    188		/*
    189		 * Small descriptor -- bits 2:0 of byte 0 contain the length
    190		 * Clear any existing length, preserving descriptor type bits
    191		 */
    192		aml->small_header.descriptor_type = (u8)
    193		    ((aml->small_header.descriptor_type &
    194		      ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK)
    195		     | resource_length);
    196	}
    197}
    198
    199/*******************************************************************************
    200 *
    201 * FUNCTION:    acpi_rs_set_resource_header
    202 *
    203 * PARAMETERS:  descriptor_type     - Byte to be inserted as the type
    204 *              total_length        - Length of the AML descriptor, including
    205 *                                    the header and length fields.
    206 *              aml                 - Pointer to the raw AML descriptor
    207 *
    208 * RETURN:      None
    209 *
    210 * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML
    211 *              resource descriptor, both Large and Small descriptors are
    212 *              supported automatically
    213 *
    214 ******************************************************************************/
    215
    216void
    217acpi_rs_set_resource_header(u8 descriptor_type,
    218			    acpi_rsdesc_size total_length,
    219			    union aml_resource *aml)
    220{
    221	ACPI_FUNCTION_ENTRY();
    222
    223	/* Set the Resource Type */
    224
    225	aml->small_header.descriptor_type = descriptor_type;
    226
    227	/* Set the Resource Length */
    228
    229	acpi_rs_set_resource_length(total_length, aml);
    230}
    231
    232/*******************************************************************************
    233 *
    234 * FUNCTION:    acpi_rs_strcpy
    235 *
    236 * PARAMETERS:  destination         - Pointer to the destination string
    237 *              source              - Pointer to the source string
    238 *
    239 * RETURN:      String length, including NULL terminator
    240 *
    241 * DESCRIPTION: Local string copy that returns the string length, saving a
    242 *              strcpy followed by a strlen.
    243 *
    244 ******************************************************************************/
    245
    246static u16 acpi_rs_strcpy(char *destination, char *source)
    247{
    248	u16 i;
    249
    250	ACPI_FUNCTION_ENTRY();
    251
    252	for (i = 0; source[i]; i++) {
    253		destination[i] = source[i];
    254	}
    255
    256	destination[i] = 0;
    257
    258	/* Return string length including the NULL terminator */
    259
    260	return ((u16) (i + 1));
    261}
    262
    263/*******************************************************************************
    264 *
    265 * FUNCTION:    acpi_rs_get_resource_source
    266 *
    267 * PARAMETERS:  resource_length     - Length field of the descriptor
    268 *              minimum_length      - Minimum length of the descriptor (minus
    269 *                                    any optional fields)
    270 *              resource_source     - Where the resource_source is returned
    271 *              aml                 - Pointer to the raw AML descriptor
    272 *              string_ptr          - (optional) where to store the actual
    273 *                                    resource_source string
    274 *
    275 * RETURN:      Length of the string plus NULL terminator, rounded up to native
    276 *              word boundary
    277 *
    278 * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor
    279 *              to an internal resource descriptor
    280 *
    281 ******************************************************************************/
    282
    283acpi_rs_length
    284acpi_rs_get_resource_source(acpi_rs_length resource_length,
    285			    acpi_rs_length minimum_length,
    286			    struct acpi_resource_source * resource_source,
    287			    union aml_resource * aml, char *string_ptr)
    288{
    289	acpi_rsdesc_size total_length;
    290	u8 *aml_resource_source;
    291
    292	ACPI_FUNCTION_ENTRY();
    293
    294	total_length =
    295	    resource_length + sizeof(struct aml_resource_large_header);
    296	aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
    297
    298	/*
    299	 * resource_source is present if the length of the descriptor is longer
    300	 * than the minimum length.
    301	 *
    302	 * Note: Some resource descriptors will have an additional null, so
    303	 * we add 1 to the minimum length.
    304	 */
    305	if (total_length > (acpi_rsdesc_size)(minimum_length + 1)) {
    306
    307		/* Get the resource_source_index */
    308
    309		resource_source->index = aml_resource_source[0];
    310
    311		resource_source->string_ptr = string_ptr;
    312		if (!string_ptr) {
    313			/*
    314			 * String destination pointer is not specified; Set the String
    315			 * pointer to the end of the current resource_source structure.
    316			 */
    317			resource_source->string_ptr =
    318			    ACPI_ADD_PTR(char, resource_source,
    319					 sizeof(struct acpi_resource_source));
    320		}
    321
    322		/*
    323		 * In order for the Resource length to be a multiple of the native
    324		 * word, calculate the length of the string (+1 for NULL terminator)
    325		 * and expand to the next word multiple.
    326		 *
    327		 * Zero the entire area of the buffer.
    328		 */
    329		total_length =
    330		    (u32)strlen(ACPI_CAST_PTR(char, &aml_resource_source[1])) +
    331		    1;
    332
    333		total_length = (u32)ACPI_ROUND_UP_TO_NATIVE_WORD(total_length);
    334
    335		memset(resource_source->string_ptr, 0, total_length);
    336
    337		/* Copy the resource_source string to the destination */
    338
    339		resource_source->string_length =
    340		    acpi_rs_strcpy(resource_source->string_ptr,
    341				   ACPI_CAST_PTR(char,
    342						 &aml_resource_source[1]));
    343
    344		return ((acpi_rs_length)total_length);
    345	}
    346
    347	/* resource_source is not present */
    348
    349	resource_source->index = 0;
    350	resource_source->string_length = 0;
    351	resource_source->string_ptr = NULL;
    352	return (0);
    353}
    354
    355/*******************************************************************************
    356 *
    357 * FUNCTION:    acpi_rs_set_resource_source
    358 *
    359 * PARAMETERS:  aml                 - Pointer to the raw AML descriptor
    360 *              minimum_length      - Minimum length of the descriptor (minus
    361 *                                    any optional fields)
    362 *              resource_source     - Internal resource_source
    363
    364 *
    365 * RETURN:      Total length of the AML descriptor
    366 *
    367 * DESCRIPTION: Convert an optional resource_source from internal format to a
    368 *              raw AML resource descriptor
    369 *
    370 ******************************************************************************/
    371
    372acpi_rsdesc_size
    373acpi_rs_set_resource_source(union aml_resource *aml,
    374			    acpi_rs_length minimum_length,
    375			    struct acpi_resource_source *resource_source)
    376{
    377	u8 *aml_resource_source;
    378	acpi_rsdesc_size descriptor_length;
    379
    380	ACPI_FUNCTION_ENTRY();
    381
    382	descriptor_length = minimum_length;
    383
    384	/* Non-zero string length indicates presence of a resource_source */
    385
    386	if (resource_source->string_length) {
    387
    388		/* Point to the end of the AML descriptor */
    389
    390		aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
    391
    392		/* Copy the resource_source_index */
    393
    394		aml_resource_source[0] = (u8) resource_source->index;
    395
    396		/* Copy the resource_source string */
    397
    398		strcpy(ACPI_CAST_PTR(char, &aml_resource_source[1]),
    399		       resource_source->string_ptr);
    400
    401		/*
    402		 * Add the length of the string (+ 1 for null terminator) to the
    403		 * final descriptor length
    404		 */
    405		descriptor_length += ((acpi_rsdesc_size)
    406				      resource_source->string_length + 1);
    407	}
    408
    409	/* Return the new total length of the AML descriptor */
    410
    411	return (descriptor_length);
    412}
    413
    414/*******************************************************************************
    415 *
    416 * FUNCTION:    acpi_rs_get_prt_method_data
    417 *
    418 * PARAMETERS:  node            - Device node
    419 *              ret_buffer      - Pointer to a buffer structure for the
    420 *                                results
    421 *
    422 * RETURN:      Status
    423 *
    424 * DESCRIPTION: This function is called to get the _PRT value of an object
    425 *              contained in an object specified by the handle passed in
    426 *
    427 *              If the function fails an appropriate status will be returned
    428 *              and the contents of the callers buffer is undefined.
    429 *
    430 ******************************************************************************/
    431
    432acpi_status
    433acpi_rs_get_prt_method_data(struct acpi_namespace_node *node,
    434			    struct acpi_buffer *ret_buffer)
    435{
    436	union acpi_operand_object *obj_desc;
    437	acpi_status status;
    438
    439	ACPI_FUNCTION_TRACE(rs_get_prt_method_data);
    440
    441	/* Parameters guaranteed valid by caller */
    442
    443	/* Execute the method, no parameters */
    444
    445	status =
    446	    acpi_ut_evaluate_object(node, METHOD_NAME__PRT, ACPI_BTYPE_PACKAGE,
    447				    &obj_desc);
    448	if (ACPI_FAILURE(status)) {
    449		return_ACPI_STATUS(status);
    450	}
    451
    452	/*
    453	 * Create a resource linked list from the byte stream buffer that comes
    454	 * back from the _CRS method execution.
    455	 */
    456	status = acpi_rs_create_pci_routing_table(obj_desc, ret_buffer);
    457
    458	/* On exit, we must delete the object returned by evaluate_object */
    459
    460	acpi_ut_remove_reference(obj_desc);
    461	return_ACPI_STATUS(status);
    462}
    463
    464/*******************************************************************************
    465 *
    466 * FUNCTION:    acpi_rs_get_crs_method_data
    467 *
    468 * PARAMETERS:  node            - Device node
    469 *              ret_buffer      - Pointer to a buffer structure for the
    470 *                                results
    471 *
    472 * RETURN:      Status
    473 *
    474 * DESCRIPTION: This function is called to get the _CRS value of an object
    475 *              contained in an object specified by the handle passed in
    476 *
    477 *              If the function fails an appropriate status will be returned
    478 *              and the contents of the callers buffer is undefined.
    479 *
    480 ******************************************************************************/
    481
    482acpi_status
    483acpi_rs_get_crs_method_data(struct acpi_namespace_node *node,
    484			    struct acpi_buffer *ret_buffer)
    485{
    486	union acpi_operand_object *obj_desc;
    487	acpi_status status;
    488
    489	ACPI_FUNCTION_TRACE(rs_get_crs_method_data);
    490
    491	/* Parameters guaranteed valid by caller */
    492
    493	/* Execute the method, no parameters */
    494
    495	status =
    496	    acpi_ut_evaluate_object(node, METHOD_NAME__CRS, ACPI_BTYPE_BUFFER,
    497				    &obj_desc);
    498	if (ACPI_FAILURE(status)) {
    499		return_ACPI_STATUS(status);
    500	}
    501
    502	/*
    503	 * Make the call to create a resource linked list from the
    504	 * byte stream buffer that comes back from the _CRS method
    505	 * execution.
    506	 */
    507	status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
    508
    509	/* On exit, we must delete the object returned by evaluateObject */
    510
    511	acpi_ut_remove_reference(obj_desc);
    512	return_ACPI_STATUS(status);
    513}
    514
    515/*******************************************************************************
    516 *
    517 * FUNCTION:    acpi_rs_get_prs_method_data
    518 *
    519 * PARAMETERS:  node            - Device node
    520 *              ret_buffer      - Pointer to a buffer structure for the
    521 *                                results
    522 *
    523 * RETURN:      Status
    524 *
    525 * DESCRIPTION: This function is called to get the _PRS value of an object
    526 *              contained in an object specified by the handle passed in
    527 *
    528 *              If the function fails an appropriate status will be returned
    529 *              and the contents of the callers buffer is undefined.
    530 *
    531 ******************************************************************************/
    532
    533acpi_status
    534acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
    535			    struct acpi_buffer *ret_buffer)
    536{
    537	union acpi_operand_object *obj_desc;
    538	acpi_status status;
    539
    540	ACPI_FUNCTION_TRACE(rs_get_prs_method_data);
    541
    542	/* Parameters guaranteed valid by caller */
    543
    544	/* Execute the method, no parameters */
    545
    546	status =
    547	    acpi_ut_evaluate_object(node, METHOD_NAME__PRS, ACPI_BTYPE_BUFFER,
    548				    &obj_desc);
    549	if (ACPI_FAILURE(status)) {
    550		return_ACPI_STATUS(status);
    551	}
    552
    553	/*
    554	 * Make the call to create a resource linked list from the
    555	 * byte stream buffer that comes back from the _CRS method
    556	 * execution.
    557	 */
    558	status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
    559
    560	/* On exit, we must delete the object returned by evaluateObject */
    561
    562	acpi_ut_remove_reference(obj_desc);
    563	return_ACPI_STATUS(status);
    564}
    565
    566/*******************************************************************************
    567 *
    568 * FUNCTION:    acpi_rs_get_aei_method_data
    569 *
    570 * PARAMETERS:  node            - Device node
    571 *              ret_buffer      - Pointer to a buffer structure for the
    572 *                                results
    573 *
    574 * RETURN:      Status
    575 *
    576 * DESCRIPTION: This function is called to get the _AEI value of an object
    577 *              contained in an object specified by the handle passed in
    578 *
    579 *              If the function fails an appropriate status will be returned
    580 *              and the contents of the callers buffer is undefined.
    581 *
    582 ******************************************************************************/
    583
    584acpi_status
    585acpi_rs_get_aei_method_data(struct acpi_namespace_node *node,
    586			    struct acpi_buffer *ret_buffer)
    587{
    588	union acpi_operand_object *obj_desc;
    589	acpi_status status;
    590
    591	ACPI_FUNCTION_TRACE(rs_get_aei_method_data);
    592
    593	/* Parameters guaranteed valid by caller */
    594
    595	/* Execute the method, no parameters */
    596
    597	status =
    598	    acpi_ut_evaluate_object(node, METHOD_NAME__AEI, ACPI_BTYPE_BUFFER,
    599				    &obj_desc);
    600	if (ACPI_FAILURE(status)) {
    601		return_ACPI_STATUS(status);
    602	}
    603
    604	/*
    605	 * Make the call to create a resource linked list from the
    606	 * byte stream buffer that comes back from the _CRS method
    607	 * execution.
    608	 */
    609	status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
    610
    611	/* On exit, we must delete the object returned by evaluateObject */
    612
    613	acpi_ut_remove_reference(obj_desc);
    614	return_ACPI_STATUS(status);
    615}
    616
    617/*******************************************************************************
    618 *
    619 * FUNCTION:    acpi_rs_get_method_data
    620 *
    621 * PARAMETERS:  handle          - Handle to the containing object
    622 *              path            - Path to method, relative to Handle
    623 *              ret_buffer      - Pointer to a buffer structure for the
    624 *                                results
    625 *
    626 * RETURN:      Status
    627 *
    628 * DESCRIPTION: This function is called to get the _CRS or _PRS value of an
    629 *              object contained in an object specified by the handle passed in
    630 *
    631 *              If the function fails an appropriate status will be returned
    632 *              and the contents of the callers buffer is undefined.
    633 *
    634 ******************************************************************************/
    635
    636acpi_status
    637acpi_rs_get_method_data(acpi_handle handle,
    638			const char *path, struct acpi_buffer *ret_buffer)
    639{
    640	union acpi_operand_object *obj_desc;
    641	acpi_status status;
    642
    643	ACPI_FUNCTION_TRACE(rs_get_method_data);
    644
    645	/* Parameters guaranteed valid by caller */
    646
    647	/* Execute the method, no parameters */
    648
    649	status =
    650	    acpi_ut_evaluate_object(ACPI_CAST_PTR
    651				    (struct acpi_namespace_node, handle), path,
    652				    ACPI_BTYPE_BUFFER, &obj_desc);
    653	if (ACPI_FAILURE(status)) {
    654		return_ACPI_STATUS(status);
    655	}
    656
    657	/*
    658	 * Make the call to create a resource linked list from the
    659	 * byte stream buffer that comes back from the method
    660	 * execution.
    661	 */
    662	status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
    663
    664	/* On exit, we must delete the object returned by evaluate_object */
    665
    666	acpi_ut_remove_reference(obj_desc);
    667	return_ACPI_STATUS(status);
    668}
    669
    670/*******************************************************************************
    671 *
    672 * FUNCTION:    acpi_rs_set_srs_method_data
    673 *
    674 * PARAMETERS:  node            - Device node
    675 *              in_buffer       - Pointer to a buffer structure of the
    676 *                                parameter
    677 *
    678 * RETURN:      Status
    679 *
    680 * DESCRIPTION: This function is called to set the _SRS of an object contained
    681 *              in an object specified by the handle passed in
    682 *
    683 *              If the function fails an appropriate status will be returned
    684 *              and the contents of the callers buffer is undefined.
    685 *
    686 * Note: Parameters guaranteed valid by caller
    687 *
    688 ******************************************************************************/
    689
    690acpi_status
    691acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
    692			    struct acpi_buffer *in_buffer)
    693{
    694	struct acpi_evaluate_info *info;
    695	union acpi_operand_object *args[2];
    696	acpi_status status;
    697	struct acpi_buffer buffer;
    698
    699	ACPI_FUNCTION_TRACE(rs_set_srs_method_data);
    700
    701	/* Allocate and initialize the evaluation information block */
    702
    703	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
    704	if (!info) {
    705		return_ACPI_STATUS(AE_NO_MEMORY);
    706	}
    707
    708	info->prefix_node = node;
    709	info->relative_pathname = METHOD_NAME__SRS;
    710	info->parameters = args;
    711	info->flags = ACPI_IGNORE_RETURN_VALUE;
    712
    713	/*
    714	 * The in_buffer parameter will point to a linked list of
    715	 * resource parameters. It needs to be formatted into a
    716	 * byte stream to be sent in as an input parameter to _SRS
    717	 *
    718	 * Convert the linked list into a byte stream
    719	 */
    720	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
    721	status = acpi_rs_create_aml_resources(in_buffer, &buffer);
    722	if (ACPI_FAILURE(status)) {
    723		goto cleanup;
    724	}
    725
    726	/* Create and initialize the method parameter object */
    727
    728	args[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
    729	if (!args[0]) {
    730		/*
    731		 * Must free the buffer allocated above (otherwise it is freed
    732		 * later)
    733		 */
    734		ACPI_FREE(buffer.pointer);
    735		status = AE_NO_MEMORY;
    736		goto cleanup;
    737	}
    738
    739	args[0]->buffer.length = (u32) buffer.length;
    740	args[0]->buffer.pointer = buffer.pointer;
    741	args[0]->common.flags = AOPOBJ_DATA_VALID;
    742	args[1] = NULL;
    743
    744	/* Execute the method, no return value is expected */
    745
    746	status = acpi_ns_evaluate(info);
    747
    748	/* Clean up and return the status from acpi_ns_evaluate */
    749
    750	acpi_ut_remove_reference(args[0]);
    751
    752cleanup:
    753	ACPI_FREE(info);
    754	return_ACPI_STATUS(status);
    755}