]> Git Repo - J-linux.git/blob - drivers/acpi/acpica/psargs.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / acpi / acpica / psargs.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: psargs - Parse AML opcode arguments
5  *
6  * Copyright (C) 2000 - 2023, Intel Corp.
7  *
8  *****************************************************************************/
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acparser.h"
13 #include "amlcode.h"
14 #include "acnamesp.h"
15 #include "acdispat.h"
16 #include "acconvert.h"
17
18 #define _COMPONENT          ACPI_PARSER
19 ACPI_MODULE_NAME("psargs")
20
21 /* Local prototypes */
22 static u32
23 acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
24
25 static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
26                                                        *parser_state);
27
28 static void acpi_ps_free_field_list(union acpi_parse_object *start);
29
30 /*******************************************************************************
31  *
32  * FUNCTION:    acpi_ps_get_next_package_length
33  *
34  * PARAMETERS:  parser_state        - Current parser state object
35  *
36  * RETURN:      Decoded package length. On completion, the AML pointer points
37  *              past the length byte or bytes.
38  *
39  * DESCRIPTION: Decode and return a package length field.
40  *              Note: Largest package length is 28 bits, from ACPI specification
41  *
42  ******************************************************************************/
43
44 static u32
45 acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
46 {
47         u8 *aml = parser_state->aml;
48         u32 package_length = 0;
49         u32 byte_count;
50         u8 byte_zero_mask = 0x3F;       /* Default [0:5] */
51
52         ACPI_FUNCTION_TRACE(ps_get_next_package_length);
53
54         /*
55          * Byte 0 bits [6:7] contain the number of additional bytes
56          * used to encode the package length, either 0,1,2, or 3
57          */
58         byte_count = (aml[0] >> 6);
59         parser_state->aml += ((acpi_size)byte_count + 1);
60
61         /* Get bytes 3, 2, 1 as needed */
62
63         while (byte_count) {
64                 /*
65                  * Final bit positions for the package length bytes:
66                  *      Byte3->[20:27]
67                  *      Byte2->[12:19]
68                  *      Byte1->[04:11]
69                  *      Byte0->[00:03]
70                  */
71                 package_length |= (aml[byte_count] << ((byte_count << 3) - 4));
72
73                 byte_zero_mask = 0x0F;  /* Use bits [0:3] of byte 0 */
74                 byte_count--;
75         }
76
77         /* Byte 0 is a special case, either bits [0:3] or [0:5] are used */
78
79         package_length |= (aml[0] & byte_zero_mask);
80         return_UINT32(package_length);
81 }
82
83 /*******************************************************************************
84  *
85  * FUNCTION:    acpi_ps_get_next_package_end
86  *
87  * PARAMETERS:  parser_state        - Current parser state object
88  *
89  * RETURN:      Pointer to end-of-package +1
90  *
91  * DESCRIPTION: Get next package length and return a pointer past the end of
92  *              the package. Consumes the package length field
93  *
94  ******************************************************************************/
95
96 u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state)
97 {
98         u8 *start = parser_state->aml;
99         u32 package_length;
100
101         ACPI_FUNCTION_TRACE(ps_get_next_package_end);
102
103         /* Function below updates parser_state->Aml */
104
105         package_length = acpi_ps_get_next_package_length(parser_state);
106
107         return_PTR(start + package_length);     /* end of package */
108 }
109
110 /*******************************************************************************
111  *
112  * FUNCTION:    acpi_ps_get_next_namestring
113  *
114  * PARAMETERS:  parser_state        - Current parser state object
115  *
116  * RETURN:      Pointer to the start of the name string (pointer points into
117  *              the AML.
118  *
119  * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name
120  *              prefix characters. Set parser state to point past the string.
121  *              (Name is consumed from the AML.)
122  *
123  ******************************************************************************/
124
125 char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
126 {
127         u8 *start = parser_state->aml;
128         u8 *end = parser_state->aml;
129
130         ACPI_FUNCTION_TRACE(ps_get_next_namestring);
131
132         /* Point past any namestring prefix characters (backslash or carat) */
133
134         while (ACPI_IS_ROOT_PREFIX(*end) || ACPI_IS_PARENT_PREFIX(*end)) {
135                 end++;
136         }
137
138         /* Decode the path prefix character */
139
140         switch (*end) {
141         case 0:
142
143                 /* null_name */
144
145                 if (end == start) {
146                         start = NULL;
147                 }
148                 end++;
149                 break;
150
151         case AML_DUAL_NAME_PREFIX:
152
153                 /* Two name segments */
154
155                 end += 1 + (2 * ACPI_NAMESEG_SIZE);
156                 break;
157
158         case AML_MULTI_NAME_PREFIX:
159
160                 /* Multiple name segments, 4 chars each, count in next byte */
161
162                 end += 2 + (*(end + 1) * ACPI_NAMESEG_SIZE);
163                 break;
164
165         default:
166
167                 /* Single name segment */
168
169                 end += ACPI_NAMESEG_SIZE;
170                 break;
171         }
172
173         parser_state->aml = end;
174         return_PTR((char *)start);
175 }
176
177 /*******************************************************************************
178  *
179  * FUNCTION:    acpi_ps_get_next_namepath
180  *
181  * PARAMETERS:  parser_state        - Current parser state object
182  *              arg                 - Where the namepath will be stored
183  *              arg_count           - If the namepath points to a control method
184  *                                    the method's argument is returned here.
185  *              possible_method_call - Whether the namepath can possibly be the
186  *                                    start of a method call
187  *
188  * RETURN:      Status
189  *
190  * DESCRIPTION: Get next name (if method call, return # of required args).
191  *              Names are looked up in the internal namespace to determine
192  *              if the name represents a control method. If a method
193  *              is found, the number of arguments to the method is returned.
194  *              This information is critical for parsing to continue correctly.
195  *
196  ******************************************************************************/
197
198 acpi_status
199 acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
200                           struct acpi_parse_state *parser_state,
201                           union acpi_parse_object *arg, u8 possible_method_call)
202 {
203         acpi_status status;
204         char *path;
205         union acpi_parse_object *name_op;
206         union acpi_operand_object *method_desc;
207         struct acpi_namespace_node *node;
208         u8 *start = parser_state->aml;
209
210         ACPI_FUNCTION_TRACE(ps_get_next_namepath);
211
212         path = acpi_ps_get_next_namestring(parser_state);
213         acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
214
215         /* Null path case is allowed, just exit */
216
217         if (!path) {
218                 arg->common.value.name = path;
219                 return_ACPI_STATUS(AE_OK);
220         }
221
222         /*
223          * Lookup the name in the internal namespace, starting with the current
224          * scope. We don't want to add anything new to the namespace here,
225          * however, so we use MODE_EXECUTE.
226          * Allow searching of the parent tree, but don't open a new scope -
227          * we just want to lookup the object (must be mode EXECUTE to perform
228          * the upsearch)
229          */
230         status = acpi_ns_lookup(walk_state->scope_info, path,
231                                 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
232                                 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
233                                 NULL, &node);
234
235         /*
236          * If this name is a control method invocation, we must
237          * setup the method call
238          */
239         if (ACPI_SUCCESS(status) &&
240             possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
241                 if ((GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
242                      ARGP_SUPERNAME)
243                     || (GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
244                         ARGP_TARGET)) {
245                         /*
246                          * acpi_ps_get_next_namestring has increased the AML pointer past
247                          * the method invocation namestring, so we need to restore the
248                          * saved AML pointer back to the original method invocation
249                          * namestring.
250                          */
251                         walk_state->parser_state.aml = start;
252                         walk_state->arg_count = 1;
253                         acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
254                 }
255
256                 /* This name is actually a control method invocation */
257
258                 method_desc = acpi_ns_get_attached_object(node);
259                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
260                                   "Control Method invocation %4.4s - %p Desc %p Path=%p\n",
261                                   node->name.ascii, node, method_desc, path));
262
263                 name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start);
264                 if (!name_op) {
265                         return_ACPI_STATUS(AE_NO_MEMORY);
266                 }
267
268                 /* Change Arg into a METHOD CALL and attach name to it */
269
270                 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
271                 name_op->common.value.name = path;
272
273                 /* Point METHODCALL/NAME to the METHOD Node */
274
275                 name_op->common.node = node;
276                 acpi_ps_append_arg(arg, name_op);
277
278                 if (!method_desc) {
279                         ACPI_ERROR((AE_INFO,
280                                     "Control Method %p has no attached object",
281                                     node));
282                         return_ACPI_STATUS(AE_AML_INTERNAL);
283                 }
284
285                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
286                                   "Control Method - %p Args %X\n",
287                                   node, method_desc->method.param_count));
288
289                 /* Get the number of arguments to expect */
290
291                 walk_state->arg_count = method_desc->method.param_count;
292                 return_ACPI_STATUS(AE_OK);
293         }
294
295         /*
296          * Special handling if the name was not found during the lookup -
297          * some not_found cases are allowed
298          */
299         if (status == AE_NOT_FOUND) {
300
301                 /* 1) not_found is ok during load pass 1/2 (allow forward references) */
302
303                 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) !=
304                     ACPI_PARSE_EXECUTE) {
305                         status = AE_OK;
306                 }
307
308                 /* 2) not_found during a cond_ref_of(x) is ok by definition */
309
310                 else if (walk_state->op->common.aml_opcode ==
311                          AML_CONDITIONAL_REF_OF_OP) {
312                         status = AE_OK;
313                 }
314
315                 /*
316                  * 3) not_found while building a Package is ok at this point, we
317                  * may flag as an error later if slack mode is not enabled.
318                  * (Some ASL code depends on allowing this behavior)
319                  */
320                 else if ((arg->common.parent) &&
321                          ((arg->common.parent->common.aml_opcode ==
322                            AML_PACKAGE_OP)
323                           || (arg->common.parent->common.aml_opcode ==
324                               AML_VARIABLE_PACKAGE_OP))) {
325                         status = AE_OK;
326                 }
327         }
328
329         /* Final exception check (may have been changed from code above) */
330
331         if (ACPI_FAILURE(status)) {
332                 ACPI_ERROR_NAMESPACE(walk_state->scope_info, path, status);
333
334                 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) ==
335                     ACPI_PARSE_EXECUTE) {
336
337                         /* Report a control method execution error */
338
339                         status = acpi_ds_method_error(status, walk_state);
340                 }
341         }
342
343         /* Save the namepath */
344
345         arg->common.value.name = path;
346         return_ACPI_STATUS(status);
347 }
348
349 /*******************************************************************************
350  *
351  * FUNCTION:    acpi_ps_get_next_simple_arg
352  *
353  * PARAMETERS:  parser_state        - Current parser state object
354  *              arg_type            - The argument type (AML_*_ARG)
355  *              arg                 - Where the argument is returned
356  *
357  * RETURN:      None
358  *
359  * DESCRIPTION: Get the next simple argument (constant, string, or namestring)
360  *
361  ******************************************************************************/
362
363 void
364 acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
365                             u32 arg_type, union acpi_parse_object *arg)
366 {
367         u32 length;
368         u16 opcode;
369         u8 *aml = parser_state->aml;
370
371         ACPI_FUNCTION_TRACE_U32(ps_get_next_simple_arg, arg_type);
372
373         switch (arg_type) {
374         case ARGP_BYTEDATA:
375
376                 /* Get 1 byte from the AML stream */
377
378                 opcode = AML_BYTE_OP;
379                 arg->common.value.integer = (u64) *aml;
380                 length = 1;
381                 break;
382
383         case ARGP_WORDDATA:
384
385                 /* Get 2 bytes from the AML stream */
386
387                 opcode = AML_WORD_OP;
388                 ACPI_MOVE_16_TO_64(&arg->common.value.integer, aml);
389                 length = 2;
390                 break;
391
392         case ARGP_DWORDDATA:
393
394                 /* Get 4 bytes from the AML stream */
395
396                 opcode = AML_DWORD_OP;
397                 ACPI_MOVE_32_TO_64(&arg->common.value.integer, aml);
398                 length = 4;
399                 break;
400
401         case ARGP_QWORDDATA:
402
403                 /* Get 8 bytes from the AML stream */
404
405                 opcode = AML_QWORD_OP;
406                 ACPI_MOVE_64_TO_64(&arg->common.value.integer, aml);
407                 length = 8;
408                 break;
409
410         case ARGP_CHARLIST:
411
412                 /* Get a pointer to the string, point past the string */
413
414                 opcode = AML_STRING_OP;
415                 arg->common.value.string = ACPI_CAST_PTR(char, aml);
416
417                 /* Find the null terminator */
418
419                 length = 0;
420                 while (aml[length]) {
421                         length++;
422                 }
423                 length++;
424                 break;
425
426         case ARGP_NAME:
427         case ARGP_NAMESTRING:
428
429                 acpi_ps_init_op(arg, AML_INT_NAMEPATH_OP);
430                 arg->common.value.name =
431                     acpi_ps_get_next_namestring(parser_state);
432                 return_VOID;
433
434         default:
435
436                 ACPI_ERROR((AE_INFO, "Invalid ArgType 0x%X", arg_type));
437                 return_VOID;
438         }
439
440         acpi_ps_init_op(arg, opcode);
441         parser_state->aml += length;
442         return_VOID;
443 }
444
445 /*******************************************************************************
446  *
447  * FUNCTION:    acpi_ps_get_next_field
448  *
449  * PARAMETERS:  parser_state        - Current parser state object
450  *
451  * RETURN:      A newly allocated FIELD op
452  *
453  * DESCRIPTION: Get next field (named_field, reserved_field, or access_field)
454  *
455  ******************************************************************************/
456
457 static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
458                                                        *parser_state)
459 {
460         u8 *aml;
461         union acpi_parse_object *field;
462         union acpi_parse_object *arg = NULL;
463         u16 opcode;
464         u32 name;
465         u8 access_type;
466         u8 access_attribute;
467         u8 access_length;
468         u32 pkg_length;
469         u8 *pkg_end;
470         u32 buffer_length;
471
472         ACPI_FUNCTION_TRACE(ps_get_next_field);
473
474         ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
475         aml = parser_state->aml;
476
477         /* Determine field type */
478
479         switch (ACPI_GET8(parser_state->aml)) {
480         case AML_FIELD_OFFSET_OP:
481
482                 opcode = AML_INT_RESERVEDFIELD_OP;
483                 parser_state->aml++;
484                 break;
485
486         case AML_FIELD_ACCESS_OP:
487
488                 opcode = AML_INT_ACCESSFIELD_OP;
489                 parser_state->aml++;
490                 break;
491
492         case AML_FIELD_CONNECTION_OP:
493
494                 opcode = AML_INT_CONNECTION_OP;
495                 parser_state->aml++;
496                 break;
497
498         case AML_FIELD_EXT_ACCESS_OP:
499
500                 opcode = AML_INT_EXTACCESSFIELD_OP;
501                 parser_state->aml++;
502                 break;
503
504         default:
505
506                 opcode = AML_INT_NAMEDFIELD_OP;
507                 break;
508         }
509
510         /* Allocate a new field op */
511
512         field = acpi_ps_alloc_op(opcode, aml);
513         if (!field) {
514                 return_PTR(NULL);
515         }
516
517         /* Decode the field type */
518
519         ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
520         switch (opcode) {
521         case AML_INT_NAMEDFIELD_OP:
522
523                 /* Get the 4-character name */
524
525                 ACPI_MOVE_32_TO_32(&name, parser_state->aml);
526                 acpi_ps_set_name(field, name);
527                 parser_state->aml += ACPI_NAMESEG_SIZE;
528
529                 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
530
531 #ifdef ACPI_ASL_COMPILER
532                 /*
533                  * Because the package length isn't represented as a parse tree object,
534                  * take comments surrounding this and add to the previously created
535                  * parse node.
536                  */
537                 if (field->common.inline_comment) {
538                         field->common.name_comment =
539                             field->common.inline_comment;
540                 }
541                 field->common.inline_comment = acpi_gbl_current_inline_comment;
542                 acpi_gbl_current_inline_comment = NULL;
543 #endif
544
545                 /* Get the length which is encoded as a package length */
546
547                 field->common.value.size =
548                     acpi_ps_get_next_package_length(parser_state);
549                 break;
550
551         case AML_INT_RESERVEDFIELD_OP:
552
553                 /* Get the length which is encoded as a package length */
554
555                 field->common.value.size =
556                     acpi_ps_get_next_package_length(parser_state);
557                 break;
558
559         case AML_INT_ACCESSFIELD_OP:
560         case AML_INT_EXTACCESSFIELD_OP:
561
562                 /*
563                  * Get access_type and access_attrib and merge into the field Op
564                  * access_type is first operand, access_attribute is second. stuff
565                  * these bytes into the node integer value for convenience.
566                  */
567
568                 /* Get the two bytes (Type/Attribute) */
569
570                 access_type = ACPI_GET8(parser_state->aml);
571                 parser_state->aml++;
572                 access_attribute = ACPI_GET8(parser_state->aml);
573                 parser_state->aml++;
574
575                 field->common.value.integer = (u8)access_type;
576                 field->common.value.integer |= (u16)(access_attribute << 8);
577
578                 /* This opcode has a third byte, access_length */
579
580                 if (opcode == AML_INT_EXTACCESSFIELD_OP) {
581                         access_length = ACPI_GET8(parser_state->aml);
582                         parser_state->aml++;
583
584                         field->common.value.integer |=
585                             (u32)(access_length << 16);
586                 }
587                 break;
588
589         case AML_INT_CONNECTION_OP:
590
591                 /*
592                  * Argument for Connection operator can be either a Buffer
593                  * (resource descriptor), or a name_string.
594                  */
595                 aml = parser_state->aml;
596                 if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) {
597                         parser_state->aml++;
598
599                         ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
600                         pkg_end = parser_state->aml;
601                         pkg_length =
602                             acpi_ps_get_next_package_length(parser_state);
603                         pkg_end += pkg_length;
604
605                         ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
606                         if (parser_state->aml < pkg_end) {
607
608                                 /* Non-empty list */
609
610                                 arg =
611                                     acpi_ps_alloc_op(AML_INT_BYTELIST_OP, aml);
612                                 if (!arg) {
613                                         acpi_ps_free_op(field);
614                                         return_PTR(NULL);
615                                 }
616
617                                 /* Get the actual buffer length argument */
618
619                                 opcode = ACPI_GET8(parser_state->aml);
620                                 parser_state->aml++;
621
622                                 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
623                                 switch (opcode) {
624                                 case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
625
626                                         buffer_length =
627                                             ACPI_GET8(parser_state->aml);
628                                         parser_state->aml += 1;
629                                         break;
630
631                                 case AML_WORD_OP:       /* AML_WORDDATA_ARG */
632
633                                         buffer_length =
634                                             ACPI_GET16(parser_state->aml);
635                                         parser_state->aml += 2;
636                                         break;
637
638                                 case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
639
640                                         buffer_length =
641                                             ACPI_GET32(parser_state->aml);
642                                         parser_state->aml += 4;
643                                         break;
644
645                                 default:
646
647                                         buffer_length = 0;
648                                         break;
649                                 }
650
651                                 /* Fill in bytelist data */
652
653                                 ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
654                                 arg->named.value.size = buffer_length;
655                                 arg->named.data = parser_state->aml;
656                         }
657
658                         /* Skip to End of byte data */
659
660                         parser_state->aml = pkg_end;
661                 } else {
662                         arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, aml);
663                         if (!arg) {
664                                 acpi_ps_free_op(field);
665                                 return_PTR(NULL);
666                         }
667
668                         /* Get the Namestring argument */
669
670                         arg->common.value.name =
671                             acpi_ps_get_next_namestring(parser_state);
672                 }
673
674                 /* Link the buffer/namestring to parent (CONNECTION_OP) */
675
676                 acpi_ps_append_arg(field, arg);
677                 break;
678
679         default:
680
681                 /* Opcode was set in previous switch */
682                 break;
683         }
684
685         return_PTR(field);
686 }
687
688 /*******************************************************************************
689  *
690  * FUNCTION:    acpi_ps_free_field_list
691  *
692  * PARAMETERS:  start               - First Op in field list
693  *
694  * RETURN:      None.
695  *
696  * DESCRIPTION: Free all Op objects inside a field list.
697  *
698  ******************************************************************************/
699
700 static void acpi_ps_free_field_list(union acpi_parse_object *start)
701 {
702         union acpi_parse_object *cur = start;
703         union acpi_parse_object *next;
704         union acpi_parse_object *arg;
705
706         while (cur) {
707                 next = cur->common.next;
708
709                 /* AML_INT_CONNECTION_OP can have a single argument */
710
711                 arg = acpi_ps_get_arg(cur, 0);
712                 if (arg) {
713                         acpi_ps_free_op(arg);
714                 }
715
716                 acpi_ps_free_op(cur);
717                 cur = next;
718         }
719 }
720
721 /*******************************************************************************
722  *
723  * FUNCTION:    acpi_ps_get_next_arg
724  *
725  * PARAMETERS:  walk_state          - Current state
726  *              parser_state        - Current parser state object
727  *              arg_type            - The argument type (AML_*_ARG)
728  *              return_arg          - Where the next arg is returned
729  *
730  * RETURN:      Status, and an op object containing the next argument.
731  *
732  * DESCRIPTION: Get next argument (including complex list arguments that require
733  *              pushing the parser stack)
734  *
735  ******************************************************************************/
736
737 acpi_status
738 acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
739                      struct acpi_parse_state *parser_state,
740                      u32 arg_type, union acpi_parse_object **return_arg)
741 {
742         union acpi_parse_object *arg = NULL;
743         union acpi_parse_object *prev = NULL;
744         union acpi_parse_object *field;
745         u32 subop;
746         acpi_status status = AE_OK;
747
748         ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state);
749
750         ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
751                           "Expected argument type ARGP: %s (%2.2X)\n",
752                           acpi_ut_get_argument_type_name(arg_type), arg_type));
753
754         switch (arg_type) {
755         case ARGP_BYTEDATA:
756         case ARGP_WORDDATA:
757         case ARGP_DWORDDATA:
758         case ARGP_CHARLIST:
759         case ARGP_NAME:
760         case ARGP_NAMESTRING:
761
762                 /* Constants, strings, and namestrings are all the same size */
763
764                 arg = acpi_ps_alloc_op(AML_BYTE_OP, parser_state->aml);
765                 if (!arg) {
766                         return_ACPI_STATUS(AE_NO_MEMORY);
767                 }
768
769                 acpi_ps_get_next_simple_arg(parser_state, arg_type, arg);
770                 break;
771
772         case ARGP_PKGLENGTH:
773
774                 /* Package length, nothing returned */
775
776                 parser_state->pkg_end =
777                     acpi_ps_get_next_package_end(parser_state);
778                 break;
779
780         case ARGP_FIELDLIST:
781
782                 if (parser_state->aml < parser_state->pkg_end) {
783
784                         /* Non-empty list */
785
786                         while (parser_state->aml < parser_state->pkg_end) {
787                                 field = acpi_ps_get_next_field(parser_state);
788                                 if (!field) {
789                                         if (arg) {
790                                                 acpi_ps_free_field_list(arg);
791                                         }
792
793                                         return_ACPI_STATUS(AE_NO_MEMORY);
794                                 }
795
796                                 if (prev) {
797                                         prev->common.next = field;
798                                 } else {
799                                         arg = field;
800                                 }
801                                 prev = field;
802                         }
803
804                         /* Skip to End of byte data */
805
806                         parser_state->aml = parser_state->pkg_end;
807                 }
808                 break;
809
810         case ARGP_BYTELIST:
811
812                 if (parser_state->aml < parser_state->pkg_end) {
813
814                         /* Non-empty list */
815
816                         arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP,
817                                                parser_state->aml);
818                         if (!arg) {
819                                 return_ACPI_STATUS(AE_NO_MEMORY);
820                         }
821
822                         /* Fill in bytelist data */
823
824                         arg->common.value.size = (u32)
825                             ACPI_PTR_DIFF(parser_state->pkg_end,
826                                           parser_state->aml);
827                         arg->named.data = parser_state->aml;
828
829                         /* Skip to End of byte data */
830
831                         parser_state->aml = parser_state->pkg_end;
832                 }
833                 break;
834
835         case ARGP_SIMPLENAME:
836         case ARGP_NAME_OR_REF:
837
838                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
839                                   "**** SimpleName/NameOrRef: %s (%2.2X)\n",
840                                   acpi_ut_get_argument_type_name(arg_type),
841                                   arg_type));
842
843                 subop = acpi_ps_peek_opcode(parser_state);
844                 if (subop == 0 ||
845                     acpi_ps_is_leading_char(subop) ||
846                     ACPI_IS_ROOT_PREFIX(subop) ||
847                     ACPI_IS_PARENT_PREFIX(subop)) {
848
849                         /* null_name or name_string */
850
851                         arg =
852                             acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
853                                              parser_state->aml);
854                         if (!arg) {
855                                 return_ACPI_STATUS(AE_NO_MEMORY);
856                         }
857
858                         status =
859                             acpi_ps_get_next_namepath(walk_state, parser_state,
860                                                       arg,
861                                                       ACPI_NOT_METHOD_CALL);
862                         if (ACPI_FAILURE(status)) {
863                                 acpi_ps_free_op(arg);
864                                 return_ACPI_STATUS(status);
865                         }
866                 } else {
867                         /* Single complex argument, nothing returned */
868
869                         walk_state->arg_count = 1;
870                 }
871                 break;
872
873         case ARGP_TARGET:
874         case ARGP_SUPERNAME:
875
876                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
877                                   "**** Target/Supername: %s (%2.2X)\n",
878                                   acpi_ut_get_argument_type_name(arg_type),
879                                   arg_type));
880
881                 subop = acpi_ps_peek_opcode(parser_state);
882                 if (subop == 0 ||
883                     acpi_ps_is_leading_char(subop) ||
884                     ACPI_IS_ROOT_PREFIX(subop) ||
885                     ACPI_IS_PARENT_PREFIX(subop)) {
886
887                         /* NULL target (zero). Convert to a NULL namepath */
888
889                         arg =
890                             acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
891                                              parser_state->aml);
892                         if (!arg) {
893                                 return_ACPI_STATUS(AE_NO_MEMORY);
894                         }
895
896                         status =
897                             acpi_ps_get_next_namepath(walk_state, parser_state,
898                                                       arg,
899                                                       ACPI_POSSIBLE_METHOD_CALL);
900                         if (ACPI_FAILURE(status)) {
901                                 acpi_ps_free_op(arg);
902                                 return_ACPI_STATUS(status);
903                         }
904
905                         if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {
906
907                                 /* Free method call op and corresponding namestring sub-ob */
908
909                                 acpi_ps_free_op(arg->common.value.arg);
910                                 acpi_ps_free_op(arg);
911                                 arg = NULL;
912                                 walk_state->arg_count = 1;
913                         }
914                 } else {
915                         /* Single complex argument, nothing returned */
916
917                         walk_state->arg_count = 1;
918                 }
919                 break;
920
921         case ARGP_DATAOBJ:
922         case ARGP_TERMARG:
923
924                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
925                                   "**** TermArg/DataObj: %s (%2.2X)\n",
926                                   acpi_ut_get_argument_type_name(arg_type),
927                                   arg_type));
928
929                 /* Single complex argument, nothing returned */
930
931                 walk_state->arg_count = 1;
932                 break;
933
934         case ARGP_DATAOBJLIST:
935         case ARGP_TERMLIST:
936         case ARGP_OBJLIST:
937
938                 if (parser_state->aml < parser_state->pkg_end) {
939
940                         /* Non-empty list of variable arguments, nothing returned */
941
942                         walk_state->arg_count = ACPI_VAR_ARGS;
943                 }
944                 break;
945
946         default:
947
948                 ACPI_ERROR((AE_INFO, "Invalid ArgType: 0x%X", arg_type));
949                 status = AE_AML_OPERAND_TYPE;
950                 break;
951         }
952
953         *return_arg = arg;
954         return_ACPI_STATUS(status);
955 }
This page took 0.080992 seconds and 4 git commands to generate.