195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
276a6225bSBob Moore /******************************************************************************
376a6225bSBob Moore *
476a6225bSBob Moore * Module Name: nsconvert - Object conversions for objects returned by
576a6225bSBob Moore * predefined methods
676a6225bSBob Moore *
7*612c2932SBob Moore * Copyright (C) 2000 - 2023, Intel Corp.
876a6225bSBob Moore *
995857638SErik Schmauss *****************************************************************************/
1076a6225bSBob Moore
1176a6225bSBob Moore #include <acpi/acpi.h>
1276a6225bSBob Moore #include "accommon.h"
1376a6225bSBob Moore #include "acnamesp.h"
1476a6225bSBob Moore #include "acinterp.h"
1576a6225bSBob Moore #include "acpredef.h"
1676a6225bSBob Moore #include "amlresrc.h"
1776a6225bSBob Moore
1876a6225bSBob Moore #define _COMPONENT ACPI_NAMESPACE
1976a6225bSBob Moore ACPI_MODULE_NAME("nsconvert")
2076a6225bSBob Moore
2176a6225bSBob Moore /*******************************************************************************
2276a6225bSBob Moore *
2376a6225bSBob Moore * FUNCTION: acpi_ns_convert_to_integer
2476a6225bSBob Moore *
2576a6225bSBob Moore * PARAMETERS: original_object - Object to be converted
2676a6225bSBob Moore * return_object - Where the new converted object is returned
2776a6225bSBob Moore *
2876a6225bSBob Moore * RETURN: Status. AE_OK if conversion was successful.
2976a6225bSBob Moore *
3076a6225bSBob Moore * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
3176a6225bSBob Moore *
3276a6225bSBob Moore ******************************************************************************/
3376a6225bSBob Moore acpi_status
acpi_ns_convert_to_integer(union acpi_operand_object * original_object,union acpi_operand_object ** return_object)3476a6225bSBob Moore acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
3576a6225bSBob Moore union acpi_operand_object **return_object)
3676a6225bSBob Moore {
3776a6225bSBob Moore union acpi_operand_object *new_object;
3876a6225bSBob Moore acpi_status status;
3976a6225bSBob Moore u64 value = 0;
4076a6225bSBob Moore u32 i;
4176a6225bSBob Moore
4276a6225bSBob Moore switch (original_object->common.type) {
4376a6225bSBob Moore case ACPI_TYPE_STRING:
4476a6225bSBob Moore
4576a6225bSBob Moore /* String-to-Integer conversion */
4676a6225bSBob Moore
47fe97d287SBob Moore status =
48fe97d287SBob Moore acpi_ut_strtoul64(original_object->string.pointer, &value);
4976a6225bSBob Moore if (ACPI_FAILURE(status)) {
5076a6225bSBob Moore return (status);
5176a6225bSBob Moore }
5276a6225bSBob Moore break;
5376a6225bSBob Moore
5476a6225bSBob Moore case ACPI_TYPE_BUFFER:
5576a6225bSBob Moore
5676a6225bSBob Moore /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
5776a6225bSBob Moore
5876a6225bSBob Moore if (original_object->buffer.length > 8) {
5976a6225bSBob Moore return (AE_AML_OPERAND_TYPE);
6076a6225bSBob Moore }
6176a6225bSBob Moore
6276a6225bSBob Moore /* Extract each buffer byte to create the integer */
6376a6225bSBob Moore
6476a6225bSBob Moore for (i = 0; i < original_object->buffer.length; i++) {
651fad8738SBob Moore value |= ((u64)
661fad8738SBob Moore original_object->buffer.pointer[i] << (i *
671fad8738SBob Moore 8));
6876a6225bSBob Moore }
6976a6225bSBob Moore break;
7076a6225bSBob Moore
7176a6225bSBob Moore default:
721d1ea1b7SChao Guan
7376a6225bSBob Moore return (AE_AML_OPERAND_TYPE);
7476a6225bSBob Moore }
7576a6225bSBob Moore
7676a6225bSBob Moore new_object = acpi_ut_create_integer_object(value);
7776a6225bSBob Moore if (!new_object) {
7876a6225bSBob Moore return (AE_NO_MEMORY);
7976a6225bSBob Moore }
8076a6225bSBob Moore
8176a6225bSBob Moore *return_object = new_object;
8276a6225bSBob Moore return (AE_OK);
8376a6225bSBob Moore }
8476a6225bSBob Moore
8576a6225bSBob Moore /*******************************************************************************
8676a6225bSBob Moore *
8776a6225bSBob Moore * FUNCTION: acpi_ns_convert_to_string
8876a6225bSBob Moore *
8976a6225bSBob Moore * PARAMETERS: original_object - Object to be converted
9076a6225bSBob Moore * return_object - Where the new converted object is returned
9176a6225bSBob Moore *
9276a6225bSBob Moore * RETURN: Status. AE_OK if conversion was successful.
9376a6225bSBob Moore *
9476a6225bSBob Moore * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
9576a6225bSBob Moore *
9676a6225bSBob Moore ******************************************************************************/
9776a6225bSBob Moore
9876a6225bSBob Moore acpi_status
acpi_ns_convert_to_string(union acpi_operand_object * original_object,union acpi_operand_object ** return_object)9976a6225bSBob Moore acpi_ns_convert_to_string(union acpi_operand_object *original_object,
10076a6225bSBob Moore union acpi_operand_object **return_object)
10176a6225bSBob Moore {
10276a6225bSBob Moore union acpi_operand_object *new_object;
10376a6225bSBob Moore acpi_size length;
10476a6225bSBob Moore acpi_status status;
10576a6225bSBob Moore
10676a6225bSBob Moore switch (original_object->common.type) {
10776a6225bSBob Moore case ACPI_TYPE_INTEGER:
10876a6225bSBob Moore /*
10976a6225bSBob Moore * Integer-to-String conversion. Commonly, convert
11076a6225bSBob Moore * an integer of value 0 to a NULL string. The last element of
11176a6225bSBob Moore * _BIF and _BIX packages occasionally need this fix.
11276a6225bSBob Moore */
11376a6225bSBob Moore if (original_object->integer.value == 0) {
11476a6225bSBob Moore
11576a6225bSBob Moore /* Allocate a new NULL string object */
11676a6225bSBob Moore
11776a6225bSBob Moore new_object = acpi_ut_create_string_object(0);
11876a6225bSBob Moore if (!new_object) {
11976a6225bSBob Moore return (AE_NO_MEMORY);
12076a6225bSBob Moore }
12176a6225bSBob Moore } else {
1221fad8738SBob Moore status = acpi_ex_convert_to_string(original_object,
12376a6225bSBob Moore &new_object,
12476a6225bSBob Moore ACPI_IMPLICIT_CONVERT_HEX);
12576a6225bSBob Moore if (ACPI_FAILURE(status)) {
12676a6225bSBob Moore return (status);
12776a6225bSBob Moore }
12876a6225bSBob Moore }
12976a6225bSBob Moore break;
13076a6225bSBob Moore
13176a6225bSBob Moore case ACPI_TYPE_BUFFER:
13276a6225bSBob Moore /*
13376a6225bSBob Moore * Buffer-to-String conversion. Use a to_string
13476a6225bSBob Moore * conversion, no transform performed on the buffer data. The best
13576a6225bSBob Moore * example of this is the _BIF method, where the string data from
13676a6225bSBob Moore * the battery is often (incorrectly) returned as buffer object(s).
13776a6225bSBob Moore */
13876a6225bSBob Moore length = 0;
13976a6225bSBob Moore while ((length < original_object->buffer.length) &&
14076a6225bSBob Moore (original_object->buffer.pointer[length])) {
14176a6225bSBob Moore length++;
14276a6225bSBob Moore }
14376a6225bSBob Moore
14476a6225bSBob Moore /* Allocate a new string object */
14576a6225bSBob Moore
14676a6225bSBob Moore new_object = acpi_ut_create_string_object(length);
14776a6225bSBob Moore if (!new_object) {
14876a6225bSBob Moore return (AE_NO_MEMORY);
14976a6225bSBob Moore }
15076a6225bSBob Moore
15176a6225bSBob Moore /*
15276a6225bSBob Moore * Copy the raw buffer data with no transform. String is already NULL
15376a6225bSBob Moore * terminated at Length+1.
15476a6225bSBob Moore */
1554fa4616eSBob Moore memcpy(new_object->string.pointer,
15676a6225bSBob Moore original_object->buffer.pointer, length);
15776a6225bSBob Moore break;
15876a6225bSBob Moore
15976a6225bSBob Moore default:
1601d1ea1b7SChao Guan
16176a6225bSBob Moore return (AE_AML_OPERAND_TYPE);
16276a6225bSBob Moore }
16376a6225bSBob Moore
16476a6225bSBob Moore *return_object = new_object;
16576a6225bSBob Moore return (AE_OK);
16676a6225bSBob Moore }
16776a6225bSBob Moore
16876a6225bSBob Moore /*******************************************************************************
16976a6225bSBob Moore *
17076a6225bSBob Moore * FUNCTION: acpi_ns_convert_to_buffer
17176a6225bSBob Moore *
17276a6225bSBob Moore * PARAMETERS: original_object - Object to be converted
17376a6225bSBob Moore * return_object - Where the new converted object is returned
17476a6225bSBob Moore *
17576a6225bSBob Moore * RETURN: Status. AE_OK if conversion was successful.
17676a6225bSBob Moore *
17776a6225bSBob Moore * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer.
17876a6225bSBob Moore *
17976a6225bSBob Moore ******************************************************************************/
18076a6225bSBob Moore
18176a6225bSBob Moore acpi_status
acpi_ns_convert_to_buffer(union acpi_operand_object * original_object,union acpi_operand_object ** return_object)18276a6225bSBob Moore acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
18376a6225bSBob Moore union acpi_operand_object **return_object)
18476a6225bSBob Moore {
18576a6225bSBob Moore union acpi_operand_object *new_object;
18676a6225bSBob Moore acpi_status status;
18776a6225bSBob Moore union acpi_operand_object **elements;
18876a6225bSBob Moore u32 *dword_buffer;
18976a6225bSBob Moore u32 count;
19076a6225bSBob Moore u32 i;
19176a6225bSBob Moore
19276a6225bSBob Moore switch (original_object->common.type) {
19376a6225bSBob Moore case ACPI_TYPE_INTEGER:
19476a6225bSBob Moore /*
19576a6225bSBob Moore * Integer-to-Buffer conversion.
19676a6225bSBob Moore * Convert the Integer to a packed-byte buffer. _MAT and other
19776a6225bSBob Moore * objects need this sometimes, if a read has been performed on a
19876a6225bSBob Moore * Field object that is less than or equal to the global integer
19976a6225bSBob Moore * size (32 or 64 bits).
20076a6225bSBob Moore */
20176a6225bSBob Moore status =
20276a6225bSBob Moore acpi_ex_convert_to_buffer(original_object, &new_object);
20376a6225bSBob Moore if (ACPI_FAILURE(status)) {
20476a6225bSBob Moore return (status);
20576a6225bSBob Moore }
20676a6225bSBob Moore break;
20776a6225bSBob Moore
20876a6225bSBob Moore case ACPI_TYPE_STRING:
20976a6225bSBob Moore
21076a6225bSBob Moore /* String-to-Buffer conversion. Simple data copy */
21176a6225bSBob Moore
2121fad8738SBob Moore new_object = acpi_ut_create_buffer_object
2131fad8738SBob Moore (original_object->string.length);
21476a6225bSBob Moore if (!new_object) {
21576a6225bSBob Moore return (AE_NO_MEMORY);
21676a6225bSBob Moore }
21776a6225bSBob Moore
2184fa4616eSBob Moore memcpy(new_object->buffer.pointer,
21976a6225bSBob Moore original_object->string.pointer,
22076a6225bSBob Moore original_object->string.length);
22176a6225bSBob Moore break;
22276a6225bSBob Moore
22376a6225bSBob Moore case ACPI_TYPE_PACKAGE:
22476a6225bSBob Moore /*
22576a6225bSBob Moore * This case is often seen for predefined names that must return a
22676a6225bSBob Moore * Buffer object with multiple DWORD integers within. For example,
22776a6225bSBob Moore * _FDE and _GTM. The Package can be converted to a Buffer.
22876a6225bSBob Moore */
22976a6225bSBob Moore
23076a6225bSBob Moore /* All elements of the Package must be integers */
23176a6225bSBob Moore
23276a6225bSBob Moore elements = original_object->package.elements;
23376a6225bSBob Moore count = original_object->package.count;
23476a6225bSBob Moore
23576a6225bSBob Moore for (i = 0; i < count; i++) {
23676a6225bSBob Moore if ((!*elements) ||
23776a6225bSBob Moore ((*elements)->common.type != ACPI_TYPE_INTEGER)) {
23876a6225bSBob Moore return (AE_AML_OPERAND_TYPE);
23976a6225bSBob Moore }
24076a6225bSBob Moore elements++;
24176a6225bSBob Moore }
24276a6225bSBob Moore
24376a6225bSBob Moore /* Create the new buffer object to replace the Package */
24476a6225bSBob Moore
24576a6225bSBob Moore new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count));
24676a6225bSBob Moore if (!new_object) {
24776a6225bSBob Moore return (AE_NO_MEMORY);
24876a6225bSBob Moore }
24976a6225bSBob Moore
25076a6225bSBob Moore /* Copy the package elements (integers) to the buffer as DWORDs */
25176a6225bSBob Moore
25276a6225bSBob Moore elements = original_object->package.elements;
25376a6225bSBob Moore dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer);
25476a6225bSBob Moore
25576a6225bSBob Moore for (i = 0; i < count; i++) {
25676a6225bSBob Moore *dword_buffer = (u32)(*elements)->integer.value;
25776a6225bSBob Moore dword_buffer++;
25876a6225bSBob Moore elements++;
25976a6225bSBob Moore }
26076a6225bSBob Moore break;
26176a6225bSBob Moore
26276a6225bSBob Moore default:
2631d1ea1b7SChao Guan
26476a6225bSBob Moore return (AE_AML_OPERAND_TYPE);
26576a6225bSBob Moore }
26676a6225bSBob Moore
26776a6225bSBob Moore *return_object = new_object;
26876a6225bSBob Moore return (AE_OK);
26976a6225bSBob Moore }
27096b44cc6SLv Zheng
27196b44cc6SLv Zheng /*******************************************************************************
27296b44cc6SLv Zheng *
27396b44cc6SLv Zheng * FUNCTION: acpi_ns_convert_to_unicode
27496b44cc6SLv Zheng *
2754debda53SLv Zheng * PARAMETERS: scope - Namespace node for the method/object
2764debda53SLv Zheng * original_object - ASCII String Object to be converted
27796b44cc6SLv Zheng * return_object - Where the new converted object is returned
27896b44cc6SLv Zheng *
27996b44cc6SLv Zheng * RETURN: Status. AE_OK if conversion was successful.
28096b44cc6SLv Zheng *
28196b44cc6SLv Zheng * DESCRIPTION: Attempt to convert a String object to a Unicode string Buffer.
28296b44cc6SLv Zheng *
28396b44cc6SLv Zheng ******************************************************************************/
28496b44cc6SLv Zheng
28596b44cc6SLv Zheng acpi_status
acpi_ns_convert_to_unicode(struct acpi_namespace_node * scope,union acpi_operand_object * original_object,union acpi_operand_object ** return_object)2864debda53SLv Zheng acpi_ns_convert_to_unicode(struct acpi_namespace_node *scope,
2874debda53SLv Zheng union acpi_operand_object *original_object,
28896b44cc6SLv Zheng union acpi_operand_object **return_object)
28996b44cc6SLv Zheng {
29096b44cc6SLv Zheng union acpi_operand_object *new_object;
29196b44cc6SLv Zheng char *ascii_string;
29296b44cc6SLv Zheng u16 *unicode_buffer;
29396b44cc6SLv Zheng u32 unicode_length;
29496b44cc6SLv Zheng u32 i;
29596b44cc6SLv Zheng
29696b44cc6SLv Zheng if (!original_object) {
29796b44cc6SLv Zheng return (AE_OK);
29896b44cc6SLv Zheng }
29996b44cc6SLv Zheng
30096b44cc6SLv Zheng /* If a Buffer was returned, it must be at least two bytes long */
30196b44cc6SLv Zheng
30296b44cc6SLv Zheng if (original_object->common.type == ACPI_TYPE_BUFFER) {
30396b44cc6SLv Zheng if (original_object->buffer.length < 2) {
30496b44cc6SLv Zheng return (AE_AML_OPERAND_VALUE);
30596b44cc6SLv Zheng }
30696b44cc6SLv Zheng
30796b44cc6SLv Zheng *return_object = NULL;
30896b44cc6SLv Zheng return (AE_OK);
30996b44cc6SLv Zheng }
31096b44cc6SLv Zheng
31196b44cc6SLv Zheng /*
31296b44cc6SLv Zheng * The original object is an ASCII string. Convert this string to
31396b44cc6SLv Zheng * a unicode buffer.
31496b44cc6SLv Zheng */
31596b44cc6SLv Zheng ascii_string = original_object->string.pointer;
31696b44cc6SLv Zheng unicode_length = (original_object->string.length * 2) + 2;
31796b44cc6SLv Zheng
31896b44cc6SLv Zheng /* Create a new buffer object for the Unicode data */
31996b44cc6SLv Zheng
32096b44cc6SLv Zheng new_object = acpi_ut_create_buffer_object(unicode_length);
32196b44cc6SLv Zheng if (!new_object) {
32296b44cc6SLv Zheng return (AE_NO_MEMORY);
32396b44cc6SLv Zheng }
32496b44cc6SLv Zheng
32596b44cc6SLv Zheng unicode_buffer = ACPI_CAST_PTR(u16, new_object->buffer.pointer);
32696b44cc6SLv Zheng
32796b44cc6SLv Zheng /* Convert ASCII to Unicode */
32896b44cc6SLv Zheng
32996b44cc6SLv Zheng for (i = 0; i < original_object->string.length; i++) {
33096b44cc6SLv Zheng unicode_buffer[i] = (u16)ascii_string[i];
33196b44cc6SLv Zheng }
33296b44cc6SLv Zheng
33396b44cc6SLv Zheng *return_object = new_object;
33496b44cc6SLv Zheng return (AE_OK);
33596b44cc6SLv Zheng }
33688fd0ac8SLv Zheng
33788fd0ac8SLv Zheng /*******************************************************************************
33888fd0ac8SLv Zheng *
33988fd0ac8SLv Zheng * FUNCTION: acpi_ns_convert_to_resource
34088fd0ac8SLv Zheng *
3414debda53SLv Zheng * PARAMETERS: scope - Namespace node for the method/object
3424debda53SLv Zheng * original_object - Object to be converted
34388fd0ac8SLv Zheng * return_object - Where the new converted object is returned
34488fd0ac8SLv Zheng *
34588fd0ac8SLv Zheng * RETURN: Status. AE_OK if conversion was successful
34688fd0ac8SLv Zheng *
34788fd0ac8SLv Zheng * DESCRIPTION: Attempt to convert a Integer object to a resource_template
34888fd0ac8SLv Zheng * Buffer.
34988fd0ac8SLv Zheng *
35088fd0ac8SLv Zheng ******************************************************************************/
35188fd0ac8SLv Zheng
35288fd0ac8SLv Zheng acpi_status
acpi_ns_convert_to_resource(struct acpi_namespace_node * scope,union acpi_operand_object * original_object,union acpi_operand_object ** return_object)3534debda53SLv Zheng acpi_ns_convert_to_resource(struct acpi_namespace_node *scope,
3544debda53SLv Zheng union acpi_operand_object *original_object,
35588fd0ac8SLv Zheng union acpi_operand_object **return_object)
35688fd0ac8SLv Zheng {
35788fd0ac8SLv Zheng union acpi_operand_object *new_object;
35888fd0ac8SLv Zheng u8 *buffer;
35988fd0ac8SLv Zheng
36088fd0ac8SLv Zheng /*
36188fd0ac8SLv Zheng * We can fix the following cases for an expected resource template:
36288fd0ac8SLv Zheng * 1. No return value (interpreter slack mode is disabled)
36388fd0ac8SLv Zheng * 2. A "Return (Zero)" statement
36488fd0ac8SLv Zheng * 3. A "Return empty buffer" statement
36588fd0ac8SLv Zheng *
36688fd0ac8SLv Zheng * We will return a buffer containing a single end_tag
36788fd0ac8SLv Zheng * resource descriptor.
36888fd0ac8SLv Zheng */
36988fd0ac8SLv Zheng if (original_object) {
37088fd0ac8SLv Zheng switch (original_object->common.type) {
37188fd0ac8SLv Zheng case ACPI_TYPE_INTEGER:
37288fd0ac8SLv Zheng
37388fd0ac8SLv Zheng /* We can only repair an Integer==0 */
37488fd0ac8SLv Zheng
37588fd0ac8SLv Zheng if (original_object->integer.value) {
37688fd0ac8SLv Zheng return (AE_AML_OPERAND_TYPE);
37788fd0ac8SLv Zheng }
37888fd0ac8SLv Zheng break;
37988fd0ac8SLv Zheng
38088fd0ac8SLv Zheng case ACPI_TYPE_BUFFER:
38188fd0ac8SLv Zheng
38288fd0ac8SLv Zheng if (original_object->buffer.length) {
38388fd0ac8SLv Zheng
38488fd0ac8SLv Zheng /* Additional checks can be added in the future */
38588fd0ac8SLv Zheng
38688fd0ac8SLv Zheng *return_object = NULL;
38788fd0ac8SLv Zheng return (AE_OK);
38888fd0ac8SLv Zheng }
38988fd0ac8SLv Zheng break;
39088fd0ac8SLv Zheng
39188fd0ac8SLv Zheng case ACPI_TYPE_STRING:
39288fd0ac8SLv Zheng default:
39388fd0ac8SLv Zheng
39488fd0ac8SLv Zheng return (AE_AML_OPERAND_TYPE);
39588fd0ac8SLv Zheng }
39688fd0ac8SLv Zheng }
39788fd0ac8SLv Zheng
39888fd0ac8SLv Zheng /* Create the new buffer object for the resource descriptor */
39988fd0ac8SLv Zheng
40088fd0ac8SLv Zheng new_object = acpi_ut_create_buffer_object(2);
40188fd0ac8SLv Zheng if (!new_object) {
40288fd0ac8SLv Zheng return (AE_NO_MEMORY);
40388fd0ac8SLv Zheng }
40488fd0ac8SLv Zheng
40588fd0ac8SLv Zheng buffer = ACPI_CAST_PTR(u8, new_object->buffer.pointer);
40688fd0ac8SLv Zheng
40788fd0ac8SLv Zheng /* Initialize the Buffer with a single end_tag descriptor */
40888fd0ac8SLv Zheng
40988fd0ac8SLv Zheng buffer[0] = (ACPI_RESOURCE_NAME_END_TAG | ASL_RDESC_END_TAG_SIZE);
41088fd0ac8SLv Zheng buffer[1] = 0x00;
41188fd0ac8SLv Zheng
41288fd0ac8SLv Zheng *return_object = new_object;
41388fd0ac8SLv Zheng return (AE_OK);
41488fd0ac8SLv Zheng }
415ee387409SLv Zheng
416ee387409SLv Zheng /*******************************************************************************
417ee387409SLv Zheng *
418ee387409SLv Zheng * FUNCTION: acpi_ns_convert_to_reference
419ee387409SLv Zheng *
420ee387409SLv Zheng * PARAMETERS: scope - Namespace node for the method/object
421ee387409SLv Zheng * original_object - Object to be converted
422ee387409SLv Zheng * return_object - Where the new converted object is returned
423ee387409SLv Zheng *
424ee387409SLv Zheng * RETURN: Status. AE_OK if conversion was successful
425ee387409SLv Zheng *
426ee387409SLv Zheng * DESCRIPTION: Attempt to convert a Integer object to a object_reference.
427ee387409SLv Zheng * Buffer.
428ee387409SLv Zheng *
429ee387409SLv Zheng ******************************************************************************/
430ee387409SLv Zheng
431ee387409SLv Zheng acpi_status
acpi_ns_convert_to_reference(struct acpi_namespace_node * scope,union acpi_operand_object * original_object,union acpi_operand_object ** return_object)432ee387409SLv Zheng acpi_ns_convert_to_reference(struct acpi_namespace_node *scope,
433ee387409SLv Zheng union acpi_operand_object *original_object,
434ee387409SLv Zheng union acpi_operand_object **return_object)
435ee387409SLv Zheng {
436ee387409SLv Zheng union acpi_operand_object *new_object = NULL;
437ee387409SLv Zheng acpi_status status;
438ee387409SLv Zheng struct acpi_namespace_node *node;
439ee387409SLv Zheng union acpi_generic_state scope_info;
440ee387409SLv Zheng char *name;
441ee387409SLv Zheng
442ee387409SLv Zheng ACPI_FUNCTION_NAME(ns_convert_to_reference);
443ee387409SLv Zheng
444ee387409SLv Zheng /* Convert path into internal presentation */
445ee387409SLv Zheng
446ee387409SLv Zheng status =
447ee387409SLv Zheng acpi_ns_internalize_name(original_object->string.pointer, &name);
448ee387409SLv Zheng if (ACPI_FAILURE(status)) {
449ee387409SLv Zheng return_ACPI_STATUS(status);
450ee387409SLv Zheng }
451ee387409SLv Zheng
452ee387409SLv Zheng /* Find the namespace node */
453ee387409SLv Zheng
454ee387409SLv Zheng scope_info.scope.node =
455ee387409SLv Zheng ACPI_CAST_PTR(struct acpi_namespace_node, scope);
456ee387409SLv Zheng status =
457ee387409SLv Zheng acpi_ns_lookup(&scope_info, name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
458ee387409SLv Zheng ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
459ee387409SLv Zheng NULL, &node);
460ee387409SLv Zheng if (ACPI_FAILURE(status)) {
461ee387409SLv Zheng
462ee387409SLv Zheng /* Check if we are resolving a named reference within a package */
463ee387409SLv Zheng
46416ccf829SBob Moore ACPI_ERROR_NAMESPACE(&scope_info,
46516ccf829SBob Moore original_object->string.pointer, status);
466ee387409SLv Zheng goto error_exit;
467ee387409SLv Zheng }
468ee387409SLv Zheng
469ee387409SLv Zheng /* Create and init a new internal ACPI object */
470ee387409SLv Zheng
471ee387409SLv Zheng new_object = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
472ee387409SLv Zheng if (!new_object) {
473ee387409SLv Zheng status = AE_NO_MEMORY;
474ee387409SLv Zheng goto error_exit;
475ee387409SLv Zheng }
476ee387409SLv Zheng new_object->reference.node = node;
477ee387409SLv Zheng new_object->reference.object = node->object;
478ee387409SLv Zheng new_object->reference.class = ACPI_REFCLASS_NAME;
479ee387409SLv Zheng
480ee387409SLv Zheng /*
481ee387409SLv Zheng * Increase reference of the object if needed (the object is likely a
482ee387409SLv Zheng * null for device nodes).
483ee387409SLv Zheng */
484ee387409SLv Zheng acpi_ut_add_reference(node->object);
485ee387409SLv Zheng
486ee387409SLv Zheng error_exit:
487ee387409SLv Zheng ACPI_FREE(name);
488ee387409SLv Zheng *return_object = new_object;
489aaf7566fSBob Moore return (status);
490ee387409SLv Zheng }
491