1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Module Name: exconcat - Concatenate-type AML operators
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Copyright (C) 2000 - 2020, Intel Corp.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun *****************************************************************************/
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <acpi/acpi.h>
11*4882a593Smuzhiyun #include "accommon.h"
12*4882a593Smuzhiyun #include "acinterp.h"
13*4882a593Smuzhiyun #include "amlresrc.h"
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #define _COMPONENT ACPI_EXECUTER
16*4882a593Smuzhiyun ACPI_MODULE_NAME("exconcat")
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun /* Local Prototypes */
19*4882a593Smuzhiyun static acpi_status
20*4882a593Smuzhiyun acpi_ex_convert_to_object_type_string(union acpi_operand_object *obj_desc,
21*4882a593Smuzhiyun union acpi_operand_object **result_desc);
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun /*******************************************************************************
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * FUNCTION: acpi_ex_do_concatenate
26*4882a593Smuzhiyun *
27*4882a593Smuzhiyun * PARAMETERS: operand0 - First source object
28*4882a593Smuzhiyun * operand1 - Second source object
29*4882a593Smuzhiyun * actual_return_desc - Where to place the return object
30*4882a593Smuzhiyun * walk_state - Current walk state
31*4882a593Smuzhiyun *
32*4882a593Smuzhiyun * RETURN: Status
33*4882a593Smuzhiyun *
34*4882a593Smuzhiyun * DESCRIPTION: Concatenate two objects with the ACPI-defined conversion
35*4882a593Smuzhiyun * rules as necessary.
36*4882a593Smuzhiyun * NOTE:
37*4882a593Smuzhiyun * Per the ACPI spec (up to 6.1), Concatenate only supports Integer,
38*4882a593Smuzhiyun * String, and Buffer objects. However, we support all objects here
39*4882a593Smuzhiyun * as an extension. This improves the usefulness of both Concatenate
40*4882a593Smuzhiyun * and the Printf/Fprintf macros. The extension returns a string
41*4882a593Smuzhiyun * describing the object type for the other objects.
42*4882a593Smuzhiyun * 02/2016.
43*4882a593Smuzhiyun *
44*4882a593Smuzhiyun ******************************************************************************/
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun acpi_status
acpi_ex_do_concatenate(union acpi_operand_object * operand0,union acpi_operand_object * operand1,union acpi_operand_object ** actual_return_desc,struct acpi_walk_state * walk_state)47*4882a593Smuzhiyun acpi_ex_do_concatenate(union acpi_operand_object *operand0,
48*4882a593Smuzhiyun union acpi_operand_object *operand1,
49*4882a593Smuzhiyun union acpi_operand_object **actual_return_desc,
50*4882a593Smuzhiyun struct acpi_walk_state *walk_state)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun union acpi_operand_object *local_operand0 = operand0;
53*4882a593Smuzhiyun union acpi_operand_object *local_operand1 = operand1;
54*4882a593Smuzhiyun union acpi_operand_object *temp_operand1 = NULL;
55*4882a593Smuzhiyun union acpi_operand_object *return_desc;
56*4882a593Smuzhiyun char *buffer;
57*4882a593Smuzhiyun acpi_object_type operand0_type;
58*4882a593Smuzhiyun acpi_object_type operand1_type;
59*4882a593Smuzhiyun acpi_status status;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(ex_do_concatenate);
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun /* Operand 0 preprocessing */
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun switch (operand0->common.type) {
66*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
67*4882a593Smuzhiyun case ACPI_TYPE_STRING:
68*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun operand0_type = operand0->common.type;
71*4882a593Smuzhiyun break;
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun default:
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /* For all other types, get the "object type" string */
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun status =
78*4882a593Smuzhiyun acpi_ex_convert_to_object_type_string(operand0,
79*4882a593Smuzhiyun &local_operand0);
80*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
81*4882a593Smuzhiyun goto cleanup;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun operand0_type = ACPI_TYPE_STRING;
85*4882a593Smuzhiyun break;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun /* Operand 1 preprocessing */
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun switch (operand1->common.type) {
91*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
92*4882a593Smuzhiyun case ACPI_TYPE_STRING:
93*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun operand1_type = operand1->common.type;
96*4882a593Smuzhiyun break;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun default:
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun /* For all other types, get the "object type" string */
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun status =
103*4882a593Smuzhiyun acpi_ex_convert_to_object_type_string(operand1,
104*4882a593Smuzhiyun &local_operand1);
105*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
106*4882a593Smuzhiyun goto cleanup;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun operand1_type = ACPI_TYPE_STRING;
110*4882a593Smuzhiyun break;
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun /*
114*4882a593Smuzhiyun * Convert the second operand if necessary. The first operand (0)
115*4882a593Smuzhiyun * determines the type of the second operand (1) (See the Data Types
116*4882a593Smuzhiyun * section of the ACPI specification). Both object types are
117*4882a593Smuzhiyun * guaranteed to be either Integer/String/Buffer by the operand
118*4882a593Smuzhiyun * resolution mechanism.
119*4882a593Smuzhiyun */
120*4882a593Smuzhiyun switch (operand0_type) {
121*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun status =
124*4882a593Smuzhiyun acpi_ex_convert_to_integer(local_operand1, &temp_operand1,
125*4882a593Smuzhiyun ACPI_IMPLICIT_CONVERSION);
126*4882a593Smuzhiyun break;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun status =
131*4882a593Smuzhiyun acpi_ex_convert_to_buffer(local_operand1, &temp_operand1);
132*4882a593Smuzhiyun break;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun case ACPI_TYPE_STRING:
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun switch (operand1_type) {
137*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
138*4882a593Smuzhiyun case ACPI_TYPE_STRING:
139*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun /* Other types have already been converted to string */
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun status =
144*4882a593Smuzhiyun acpi_ex_convert_to_string(local_operand1,
145*4882a593Smuzhiyun &temp_operand1,
146*4882a593Smuzhiyun ACPI_IMPLICIT_CONVERT_HEX);
147*4882a593Smuzhiyun break;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun default:
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun status = AE_OK;
152*4882a593Smuzhiyun break;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun break;
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun default:
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
159*4882a593Smuzhiyun operand0->common.type));
160*4882a593Smuzhiyun status = AE_AML_INTERNAL;
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
164*4882a593Smuzhiyun goto cleanup;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun /* Take care with any newly created operand objects */
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun if ((local_operand1 != operand1) && (local_operand1 != temp_operand1)) {
170*4882a593Smuzhiyun acpi_ut_remove_reference(local_operand1);
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun local_operand1 = temp_operand1;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun /*
176*4882a593Smuzhiyun * Both operands are now known to be the same object type
177*4882a593Smuzhiyun * (Both are Integer, String, or Buffer), and we can now perform
178*4882a593Smuzhiyun * the concatenation.
179*4882a593Smuzhiyun *
180*4882a593Smuzhiyun * There are three cases to handle, as per the ACPI spec:
181*4882a593Smuzhiyun *
182*4882a593Smuzhiyun * 1) Two Integers concatenated to produce a new Buffer
183*4882a593Smuzhiyun * 2) Two Strings concatenated to produce a new String
184*4882a593Smuzhiyun * 3) Two Buffers concatenated to produce a new Buffer
185*4882a593Smuzhiyun */
186*4882a593Smuzhiyun switch (operand0_type) {
187*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun /* Result of two Integers is a Buffer */
190*4882a593Smuzhiyun /* Need enough buffer space for two integers */
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun return_desc = acpi_ut_create_buffer_object((acpi_size)
193*4882a593Smuzhiyun ACPI_MUL_2
194*4882a593Smuzhiyun (acpi_gbl_integer_byte_width));
195*4882a593Smuzhiyun if (!return_desc) {
196*4882a593Smuzhiyun status = AE_NO_MEMORY;
197*4882a593Smuzhiyun goto cleanup;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun buffer = (char *)return_desc->buffer.pointer;
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun /* Copy the first integer, LSB first */
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun memcpy(buffer, &operand0->integer.value,
205*4882a593Smuzhiyun acpi_gbl_integer_byte_width);
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun /* Copy the second integer (LSB first) after the first */
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun memcpy(buffer + acpi_gbl_integer_byte_width,
210*4882a593Smuzhiyun &local_operand1->integer.value,
211*4882a593Smuzhiyun acpi_gbl_integer_byte_width);
212*4882a593Smuzhiyun break;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun case ACPI_TYPE_STRING:
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun /* Result of two Strings is a String */
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun return_desc = acpi_ut_create_string_object(((acpi_size)
219*4882a593Smuzhiyun local_operand0->
220*4882a593Smuzhiyun string.length +
221*4882a593Smuzhiyun local_operand1->
222*4882a593Smuzhiyun string.length));
223*4882a593Smuzhiyun if (!return_desc) {
224*4882a593Smuzhiyun status = AE_NO_MEMORY;
225*4882a593Smuzhiyun goto cleanup;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun buffer = return_desc->string.pointer;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun /* Concatenate the strings */
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun strcpy(buffer, local_operand0->string.pointer);
233*4882a593Smuzhiyun strcat(buffer, local_operand1->string.pointer);
234*4882a593Smuzhiyun break;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun /* Result of two Buffers is a Buffer */
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun return_desc = acpi_ut_create_buffer_object(((acpi_size)
241*4882a593Smuzhiyun operand0->buffer.
242*4882a593Smuzhiyun length +
243*4882a593Smuzhiyun local_operand1->
244*4882a593Smuzhiyun buffer.length));
245*4882a593Smuzhiyun if (!return_desc) {
246*4882a593Smuzhiyun status = AE_NO_MEMORY;
247*4882a593Smuzhiyun goto cleanup;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun buffer = (char *)return_desc->buffer.pointer;
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun /* Concatenate the buffers */
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun memcpy(buffer, operand0->buffer.pointer,
255*4882a593Smuzhiyun operand0->buffer.length);
256*4882a593Smuzhiyun memcpy(buffer + operand0->buffer.length,
257*4882a593Smuzhiyun local_operand1->buffer.pointer,
258*4882a593Smuzhiyun local_operand1->buffer.length);
259*4882a593Smuzhiyun break;
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun default:
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun /* Invalid object type, should not happen here */
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
266*4882a593Smuzhiyun operand0->common.type));
267*4882a593Smuzhiyun status = AE_AML_INTERNAL;
268*4882a593Smuzhiyun goto cleanup;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun *actual_return_desc = return_desc;
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun cleanup:
274*4882a593Smuzhiyun if (local_operand0 != operand0) {
275*4882a593Smuzhiyun acpi_ut_remove_reference(local_operand0);
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun if (local_operand1 != operand1) {
279*4882a593Smuzhiyun acpi_ut_remove_reference(local_operand1);
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun return_ACPI_STATUS(status);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun /*******************************************************************************
286*4882a593Smuzhiyun *
287*4882a593Smuzhiyun * FUNCTION: acpi_ex_convert_to_object_type_string
288*4882a593Smuzhiyun *
289*4882a593Smuzhiyun * PARAMETERS: obj_desc - Object to be converted
290*4882a593Smuzhiyun * return_desc - Where to place the return object
291*4882a593Smuzhiyun *
292*4882a593Smuzhiyun * RETURN: Status
293*4882a593Smuzhiyun *
294*4882a593Smuzhiyun * DESCRIPTION: Convert an object of arbitrary type to a string object that
295*4882a593Smuzhiyun * contains the namestring for the object. Used for the
296*4882a593Smuzhiyun * concatenate operator.
297*4882a593Smuzhiyun *
298*4882a593Smuzhiyun ******************************************************************************/
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun static acpi_status
acpi_ex_convert_to_object_type_string(union acpi_operand_object * obj_desc,union acpi_operand_object ** result_desc)301*4882a593Smuzhiyun acpi_ex_convert_to_object_type_string(union acpi_operand_object *obj_desc,
302*4882a593Smuzhiyun union acpi_operand_object **result_desc)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun union acpi_operand_object *return_desc;
305*4882a593Smuzhiyun const char *type_string;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun type_string = acpi_ut_get_type_name(obj_desc->common.type);
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun return_desc = acpi_ut_create_string_object(((acpi_size)strlen(type_string) + 9)); /* 9 For "[ Object]" */
310*4882a593Smuzhiyun if (!return_desc) {
311*4882a593Smuzhiyun return (AE_NO_MEMORY);
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun strcpy(return_desc->string.pointer, "[");
315*4882a593Smuzhiyun strcat(return_desc->string.pointer, type_string);
316*4882a593Smuzhiyun strcat(return_desc->string.pointer, " Object]");
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun *result_desc = return_desc;
319*4882a593Smuzhiyun return (AE_OK);
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun /*******************************************************************************
323*4882a593Smuzhiyun *
324*4882a593Smuzhiyun * FUNCTION: acpi_ex_concat_template
325*4882a593Smuzhiyun *
326*4882a593Smuzhiyun * PARAMETERS: operand0 - First source object
327*4882a593Smuzhiyun * operand1 - Second source object
328*4882a593Smuzhiyun * actual_return_desc - Where to place the return object
329*4882a593Smuzhiyun * walk_state - Current walk state
330*4882a593Smuzhiyun *
331*4882a593Smuzhiyun * RETURN: Status
332*4882a593Smuzhiyun *
333*4882a593Smuzhiyun * DESCRIPTION: Concatenate two resource templates
334*4882a593Smuzhiyun *
335*4882a593Smuzhiyun ******************************************************************************/
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun acpi_status
acpi_ex_concat_template(union acpi_operand_object * operand0,union acpi_operand_object * operand1,union acpi_operand_object ** actual_return_desc,struct acpi_walk_state * walk_state)338*4882a593Smuzhiyun acpi_ex_concat_template(union acpi_operand_object *operand0,
339*4882a593Smuzhiyun union acpi_operand_object *operand1,
340*4882a593Smuzhiyun union acpi_operand_object **actual_return_desc,
341*4882a593Smuzhiyun struct acpi_walk_state *walk_state)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun acpi_status status;
344*4882a593Smuzhiyun union acpi_operand_object *return_desc;
345*4882a593Smuzhiyun u8 *new_buf;
346*4882a593Smuzhiyun u8 *end_tag;
347*4882a593Smuzhiyun acpi_size length0;
348*4882a593Smuzhiyun acpi_size length1;
349*4882a593Smuzhiyun acpi_size new_length;
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(ex_concat_template);
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun /*
354*4882a593Smuzhiyun * Find the end_tag descriptor in each resource template.
355*4882a593Smuzhiyun * Note1: returned pointers point TO the end_tag, not past it.
356*4882a593Smuzhiyun * Note2: zero-length buffers are allowed; treated like one end_tag
357*4882a593Smuzhiyun */
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun /* Get the length of the first resource template */
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun status = acpi_ut_get_resource_end_tag(operand0, &end_tag);
362*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
363*4882a593Smuzhiyun return_ACPI_STATUS(status);
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer);
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun /* Get the length of the second resource template */
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun status = acpi_ut_get_resource_end_tag(operand1, &end_tag);
371*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
372*4882a593Smuzhiyun return_ACPI_STATUS(status);
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer);
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun /* Combine both lengths, minimum size will be 2 for end_tag */
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun new_length = length0 + length1 + sizeof(struct aml_resource_end_tag);
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun /* Create a new buffer object for the result (with one end_tag) */
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun return_desc = acpi_ut_create_buffer_object(new_length);
384*4882a593Smuzhiyun if (!return_desc) {
385*4882a593Smuzhiyun return_ACPI_STATUS(AE_NO_MEMORY);
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun /*
389*4882a593Smuzhiyun * Copy the templates to the new buffer, 0 first, then 1 follows. One
390*4882a593Smuzhiyun * end_tag descriptor is copied from Operand1.
391*4882a593Smuzhiyun */
392*4882a593Smuzhiyun new_buf = return_desc->buffer.pointer;
393*4882a593Smuzhiyun memcpy(new_buf, operand0->buffer.pointer, length0);
394*4882a593Smuzhiyun memcpy(new_buf + length0, operand1->buffer.pointer, length1);
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun /* Insert end_tag and set the checksum to zero, means "ignore checksum" */
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun new_buf[new_length - 1] = 0;
399*4882a593Smuzhiyun new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun /* Return the completed resource template */
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun *actual_return_desc = return_desc;
404*4882a593Smuzhiyun return_ACPI_STATUS(AE_OK);
405*4882a593Smuzhiyun }
406