Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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