Subversion Repositories Kolibri OS

Rev

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

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: utresrc - Resource management utilities
  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 "acresrc.h"
  47.  
  48. #define _COMPONENT          ACPI_UTILITIES
  49. ACPI_MODULE_NAME("utresrc")
  50.  
  51. #if defined(ACPI_DEBUG_OUTPUT) || defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
  52. /*
  53.  * Strings used to decode resource descriptors.
  54.  * Used by both the disassembler and the debugger resource dump routines
  55.  */
  56. const char *acpi_gbl_bm_decode[] = {
  57.         "NotBusMaster",
  58.         "BusMaster"
  59. };
  60.  
  61. const char *acpi_gbl_config_decode[] = {
  62.         "0 - Good Configuration",
  63.         "1 - Acceptable Configuration",
  64.         "2 - Suboptimal Configuration",
  65.         "3 - ***Invalid Configuration***",
  66. };
  67.  
  68. const char *acpi_gbl_consume_decode[] = {
  69.         "ResourceProducer",
  70.         "ResourceConsumer"
  71. };
  72.  
  73. const char *acpi_gbl_dec_decode[] = {
  74.         "PosDecode",
  75.         "SubDecode"
  76. };
  77.  
  78. const char *acpi_gbl_he_decode[] = {
  79.         "Level",
  80.         "Edge"
  81. };
  82.  
  83. const char *acpi_gbl_io_decode[] = {
  84.         "Decode10",
  85.         "Decode16"
  86. };
  87.  
  88. const char *acpi_gbl_ll_decode[] = {
  89.         "ActiveHigh",
  90.         "ActiveLow",
  91.         "ActiveBoth",
  92.         "Reserved"
  93. };
  94.  
  95. const char *acpi_gbl_max_decode[] = {
  96.         "MaxNotFixed",
  97.         "MaxFixed"
  98. };
  99.  
  100. const char *acpi_gbl_mem_decode[] = {
  101.         "NonCacheable",
  102.         "Cacheable",
  103.         "WriteCombining",
  104.         "Prefetchable"
  105. };
  106.  
  107. const char *acpi_gbl_min_decode[] = {
  108.         "MinNotFixed",
  109.         "MinFixed"
  110. };
  111.  
  112. const char *acpi_gbl_mtp_decode[] = {
  113.         "AddressRangeMemory",
  114.         "AddressRangeReserved",
  115.         "AddressRangeACPI",
  116.         "AddressRangeNVS"
  117. };
  118.  
  119. const char *acpi_gbl_rng_decode[] = {
  120.         "InvalidRanges",
  121.         "NonISAOnlyRanges",
  122.         "ISAOnlyRanges",
  123.         "EntireRange"
  124. };
  125.  
  126. const char *acpi_gbl_rw_decode[] = {
  127.         "ReadOnly",
  128.         "ReadWrite"
  129. };
  130.  
  131. const char *acpi_gbl_shr_decode[] = {
  132.         "Exclusive",
  133.         "Shared",
  134.         "ExclusiveAndWake",     /* ACPI 5.0 */
  135.         "SharedAndWake"         /* ACPI 5.0 */
  136. };
  137.  
  138. const char *acpi_gbl_siz_decode[] = {
  139.         "Transfer8",
  140.         "Transfer8_16",
  141.         "Transfer16",
  142.         "InvalidSize"
  143. };
  144.  
  145. const char *acpi_gbl_trs_decode[] = {
  146.         "DenseTranslation",
  147.         "SparseTranslation"
  148. };
  149.  
  150. const char *acpi_gbl_ttp_decode[] = {
  151.         "TypeStatic",
  152.         "TypeTranslation"
  153. };
  154.  
  155. const char *acpi_gbl_typ_decode[] = {
  156.         "Compatibility",
  157.         "TypeA",
  158.         "TypeB",
  159.         "TypeF"
  160. };
  161.  
  162. const char *acpi_gbl_ppc_decode[] = {
  163.         "PullDefault",
  164.         "PullUp",
  165.         "PullDown",
  166.         "PullNone"
  167. };
  168.  
  169. const char *acpi_gbl_ior_decode[] = {
  170.         "IoRestrictionNone",
  171.         "IoRestrictionInputOnly",
  172.         "IoRestrictionOutputOnly",
  173.         "IoRestrictionNoneAndPreserve"
  174. };
  175.  
  176. const char *acpi_gbl_dts_decode[] = {
  177.         "Width8bit",
  178.         "Width16bit",
  179.         "Width32bit",
  180.         "Width64bit",
  181.         "Width128bit",
  182.         "Width256bit",
  183. };
  184.  
  185. /* GPIO connection type */
  186.  
  187. const char *acpi_gbl_ct_decode[] = {
  188.         "Interrupt",
  189.         "I/O"
  190. };
  191.  
  192. /* Serial bus type */
  193.  
  194. const char *acpi_gbl_sbt_decode[] = {
  195.         "/* UNKNOWN serial bus type */",
  196.         "I2C",
  197.         "SPI",
  198.         "UART"
  199. };
  200.  
  201. /* I2C serial bus access mode */
  202.  
  203. const char *acpi_gbl_am_decode[] = {
  204.         "AddressingMode7Bit",
  205.         "AddressingMode10Bit"
  206. };
  207.  
  208. /* I2C serial bus slave mode */
  209.  
  210. const char *acpi_gbl_sm_decode[] = {
  211.         "ControllerInitiated",
  212.         "DeviceInitiated"
  213. };
  214.  
  215. /* SPI serial bus wire mode */
  216.  
  217. const char *acpi_gbl_wm_decode[] = {
  218.         "FourWireMode",
  219.         "ThreeWireMode"
  220. };
  221.  
  222. /* SPI serial clock phase */
  223.  
  224. const char *acpi_gbl_cph_decode[] = {
  225.         "ClockPhaseFirst",
  226.         "ClockPhaseSecond"
  227. };
  228.  
  229. /* SPI serial bus clock polarity */
  230.  
  231. const char *acpi_gbl_cpo_decode[] = {
  232.         "ClockPolarityLow",
  233.         "ClockPolarityHigh"
  234. };
  235.  
  236. /* SPI serial bus device polarity */
  237.  
  238. const char *acpi_gbl_dp_decode[] = {
  239.         "PolarityLow",
  240.         "PolarityHigh"
  241. };
  242.  
  243. /* UART serial bus endian */
  244.  
  245. const char *acpi_gbl_ed_decode[] = {
  246.         "LittleEndian",
  247.         "BigEndian"
  248. };
  249.  
  250. /* UART serial bus bits per byte */
  251.  
  252. const char *acpi_gbl_bpb_decode[] = {
  253.         "DataBitsFive",
  254.         "DataBitsSix",
  255.         "DataBitsSeven",
  256.         "DataBitsEight",
  257.         "DataBitsNine",
  258.         "/* UNKNOWN Bits per byte */",
  259.         "/* UNKNOWN Bits per byte */",
  260.         "/* UNKNOWN Bits per byte */"
  261. };
  262.  
  263. /* UART serial bus stop bits */
  264.  
  265. const char *acpi_gbl_sb_decode[] = {
  266.         "StopBitsZero",
  267.         "StopBitsOne",
  268.         "StopBitsOnePlusHalf",
  269.         "StopBitsTwo"
  270. };
  271.  
  272. /* UART serial bus flow control */
  273.  
  274. const char *acpi_gbl_fc_decode[] = {
  275.         "FlowControlNone",
  276.         "FlowControlHardware",
  277.         "FlowControlXON",
  278.         "/* UNKNOWN flow control keyword */"
  279. };
  280.  
  281. /* UART serial bus parity type */
  282.  
  283. const char *acpi_gbl_pt_decode[] = {
  284.         "ParityTypeNone",
  285.         "ParityTypeEven",
  286.         "ParityTypeOdd",
  287.         "ParityTypeMark",
  288.         "ParityTypeSpace",
  289.         "/* UNKNOWN parity keyword */",
  290.         "/* UNKNOWN parity keyword */",
  291.         "/* UNKNOWN parity keyword */"
  292. };
  293.  
  294. #endif
  295.  
  296. /*
  297.  * Base sizes of the raw AML resource descriptors, indexed by resource type.
  298.  * Zero indicates a reserved (and therefore invalid) resource type.
  299.  */
  300. const u8 acpi_gbl_resource_aml_sizes[] = {
  301.         /* Small descriptors */
  302.  
  303.         0,
  304.         0,
  305.         0,
  306.         0,
  307.         ACPI_AML_SIZE_SMALL(struct aml_resource_irq),
  308.         ACPI_AML_SIZE_SMALL(struct aml_resource_dma),
  309.         ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent),
  310.         ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent),
  311.         ACPI_AML_SIZE_SMALL(struct aml_resource_io),
  312.         ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io),
  313.         ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_dma),
  314.         0,
  315.         0,
  316.         0,
  317.         ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small),
  318.         ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag),
  319.  
  320.         /* Large descriptors */
  321.  
  322.         0,
  323.         ACPI_AML_SIZE_LARGE(struct aml_resource_memory24),
  324.         ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register),
  325.         0,
  326.         ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large),
  327.         ACPI_AML_SIZE_LARGE(struct aml_resource_memory32),
  328.         ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32),
  329.         ACPI_AML_SIZE_LARGE(struct aml_resource_address32),
  330.         ACPI_AML_SIZE_LARGE(struct aml_resource_address16),
  331.         ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq),
  332.         ACPI_AML_SIZE_LARGE(struct aml_resource_address64),
  333.         ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64),
  334.         ACPI_AML_SIZE_LARGE(struct aml_resource_gpio),
  335.         0,
  336.         ACPI_AML_SIZE_LARGE(struct aml_resource_common_serialbus),
  337. };
  338.  
  339. const u8 acpi_gbl_resource_aml_serial_bus_sizes[] = {
  340.         0,
  341.         ACPI_AML_SIZE_LARGE(struct aml_resource_i2c_serialbus),
  342.         ACPI_AML_SIZE_LARGE(struct aml_resource_spi_serialbus),
  343.         ACPI_AML_SIZE_LARGE(struct aml_resource_uart_serialbus),
  344. };
  345.  
  346. /*
  347.  * Resource types, used to validate the resource length field.
  348.  * The length of fixed-length types must match exactly, variable
  349.  * lengths must meet the minimum required length, etc.
  350.  * Zero indicates a reserved (and therefore invalid) resource type.
  351.  */
  352. static const u8 acpi_gbl_resource_types[] = {
  353.         /* Small descriptors */
  354.  
  355.         0,
  356.         0,
  357.         0,
  358.         0,
  359.         ACPI_SMALL_VARIABLE_LENGTH,     /* 04 IRQ */
  360.         ACPI_FIXED_LENGTH,      /* 05 DMA */
  361.         ACPI_SMALL_VARIABLE_LENGTH,     /* 06 start_dependent_functions */
  362.         ACPI_FIXED_LENGTH,      /* 07 end_dependent_functions */
  363.         ACPI_FIXED_LENGTH,      /* 08 IO */
  364.         ACPI_FIXED_LENGTH,      /* 09 fixed_IO */
  365.         ACPI_FIXED_LENGTH,      /* 0A fixed_DMA */
  366.         0,
  367.         0,
  368.         0,
  369.         ACPI_VARIABLE_LENGTH,   /* 0E vendor_short */
  370.         ACPI_FIXED_LENGTH,      /* 0F end_tag */
  371.  
  372.         /* Large descriptors */
  373.  
  374.         0,
  375.         ACPI_FIXED_LENGTH,      /* 01 Memory24 */
  376.         ACPI_FIXED_LENGTH,      /* 02 generic_register */
  377.         0,
  378.         ACPI_VARIABLE_LENGTH,   /* 04 vendor_long */
  379.         ACPI_FIXED_LENGTH,      /* 05 Memory32 */
  380.         ACPI_FIXED_LENGTH,      /* 06 memory32_fixed */
  381.         ACPI_VARIABLE_LENGTH,   /* 07 Dword* address */
  382.         ACPI_VARIABLE_LENGTH,   /* 08 Word* address */
  383.         ACPI_VARIABLE_LENGTH,   /* 09 extended_IRQ */
  384.         ACPI_VARIABLE_LENGTH,   /* 0A Qword* address */
  385.         ACPI_FIXED_LENGTH,      /* 0B Extended* address */
  386.         ACPI_VARIABLE_LENGTH,   /* 0C Gpio* */
  387.         0,
  388.         ACPI_VARIABLE_LENGTH    /* 0E *serial_bus */
  389. };
  390.  
  391. /*******************************************************************************
  392.  *
  393.  * FUNCTION:    acpi_ut_walk_aml_resources
  394.  *
  395.  * PARAMETERS:  walk_state          - Current walk info
  396.  * PARAMETERS:  aml                 - Pointer to the raw AML resource template
  397.  *              aml_length          - Length of the entire template
  398.  *              user_function       - Called once for each descriptor found. If
  399.  *                                    NULL, a pointer to the end_tag is returned
  400.  *              context             - Passed to user_function
  401.  *
  402.  * RETURN:      Status
  403.  *
  404.  * DESCRIPTION: Walk a raw AML resource list(buffer). User function called
  405.  *              once for each resource found.
  406.  *
  407.  ******************************************************************************/
  408.  
  409. acpi_status
  410. acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
  411.                            u8 *aml,
  412.                            acpi_size aml_length,
  413.                            acpi_walk_aml_callback user_function, void **context)
  414. {
  415.         acpi_status status;
  416.         u8 *end_aml;
  417.         u8 resource_index;
  418.         u32 length;
  419.         u32 offset = 0;
  420.         u8 end_tag[2] = { 0x79, 0x00 };
  421.  
  422.         ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
  423.  
  424.         /* The absolute minimum resource template is one end_tag descriptor */
  425.  
  426.         if (aml_length < sizeof(struct aml_resource_end_tag)) {
  427.                 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
  428.         }
  429.  
  430.         /* Point to the end of the resource template buffer */
  431.  
  432.         end_aml = aml + aml_length;
  433.  
  434.         /* Walk the byte list, abort on any invalid descriptor type or length */
  435.  
  436.         while (aml < end_aml) {
  437.  
  438.                 /* Validate the Resource Type and Resource Length */
  439.  
  440.                 status =
  441.                     acpi_ut_validate_resource(walk_state, aml, &resource_index);
  442.                 if (ACPI_FAILURE(status)) {
  443.                         /*
  444.                          * Exit on failure. Cannot continue because the descriptor length
  445.                          * may be bogus also.
  446.                          */
  447.                         return_ACPI_STATUS(status);
  448.                 }
  449.  
  450.                 /* Get the length of this descriptor */
  451.  
  452.                 length = acpi_ut_get_descriptor_length(aml);
  453.  
  454.                 /* Invoke the user function */
  455.  
  456.                 if (user_function) {
  457.                         status =
  458.                             user_function(aml, length, offset, resource_index,
  459.                                           context);
  460.                         if (ACPI_FAILURE(status)) {
  461.                                 return_ACPI_STATUS(status);
  462.                         }
  463.                 }
  464.  
  465.                 /* An end_tag descriptor terminates this resource template */
  466.  
  467.                 if (acpi_ut_get_resource_type(aml) ==
  468.                     ACPI_RESOURCE_NAME_END_TAG) {
  469.                         /*
  470.                          * There must be at least one more byte in the buffer for
  471.                          * the 2nd byte of the end_tag
  472.                          */
  473.                         if ((aml + 1) >= end_aml) {
  474.                                 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
  475.                         }
  476.  
  477.                         /* Return the pointer to the end_tag if requested */
  478.  
  479.                         if (!user_function) {
  480.                                 *context = aml;
  481.                         }
  482.  
  483.                         /* Normal exit */
  484.  
  485.                         return_ACPI_STATUS(AE_OK);
  486.                 }
  487.  
  488.                 aml += length;
  489.                 offset += length;
  490.         }
  491.  
  492.         /* Did not find an end_tag descriptor */
  493.  
  494.         if (user_function) {
  495.  
  496.                 /* Insert an end_tag anyway. acpi_rs_get_list_length always leaves room */
  497.  
  498.                 (void)acpi_ut_validate_resource(walk_state, end_tag,
  499.                                                 &resource_index);
  500.                 status =
  501.                     user_function(end_tag, 2, offset, resource_index, context);
  502.                 if (ACPI_FAILURE(status)) {
  503.                         return_ACPI_STATUS(status);
  504.                 }
  505.         }
  506.  
  507.         return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
  508. }
  509.  
  510. /*******************************************************************************
  511.  *
  512.  * FUNCTION:    acpi_ut_validate_resource
  513.  *
  514.  * PARAMETERS:  walk_state          - Current walk info
  515.  *              aml                 - Pointer to the raw AML resource descriptor
  516.  *              return_index        - Where the resource index is returned. NULL
  517.  *                                    if the index is not required.
  518.  *
  519.  * RETURN:      Status, and optionally the Index into the global resource tables
  520.  *
  521.  * DESCRIPTION: Validate an AML resource descriptor by checking the Resource
  522.  *              Type and Resource Length. Returns an index into the global
  523.  *              resource information/dispatch tables for later use.
  524.  *
  525.  ******************************************************************************/
  526.  
  527. acpi_status
  528. acpi_ut_validate_resource(struct acpi_walk_state *walk_state,
  529.                           void *aml, u8 *return_index)
  530. {
  531.         union aml_resource *aml_resource;
  532.         u8 resource_type;
  533.         u8 resource_index;
  534.         acpi_rs_length resource_length;
  535.         acpi_rs_length minimum_resource_length;
  536.  
  537.         ACPI_FUNCTION_ENTRY();
  538.  
  539.         /*
  540.          * 1) Validate the resource_type field (Byte 0)
  541.          */
  542.         resource_type = ACPI_GET8(aml);
  543.  
  544.         /*
  545.          * Byte 0 contains the descriptor name (Resource Type)
  546.          * Examine the large/small bit in the resource header
  547.          */
  548.         if (resource_type & ACPI_RESOURCE_NAME_LARGE) {
  549.  
  550.                 /* Verify the large resource type (name) against the max */
  551.  
  552.                 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
  553.                         goto invalid_resource;
  554.                 }
  555.  
  556.                 /*
  557.                  * Large Resource Type -- bits 6:0 contain the name
  558.                  * Translate range 0x80-0x8B to index range 0x10-0x1B
  559.                  */
  560.                 resource_index = (u8) (resource_type - 0x70);
  561.         } else {
  562.                 /*
  563.                  * Small Resource Type -- bits 6:3 contain the name
  564.                  * Shift range to index range 0x00-0x0F
  565.                  */
  566.                 resource_index = (u8)
  567.                     ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
  568.         }
  569.  
  570.         /*
  571.          * Check validity of the resource type, via acpi_gbl_resource_types. Zero
  572.          * indicates an invalid resource.
  573.          */
  574.         if (!acpi_gbl_resource_types[resource_index]) {
  575.                 goto invalid_resource;
  576.         }
  577.  
  578.         /*
  579.          * Validate the resource_length field. This ensures that the length
  580.          * is at least reasonable, and guarantees that it is non-zero.
  581.          */
  582.         resource_length = acpi_ut_get_resource_length(aml);
  583.         minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index];
  584.  
  585.         /* Validate based upon the type of resource - fixed length or variable */
  586.  
  587.         switch (acpi_gbl_resource_types[resource_index]) {
  588.         case ACPI_FIXED_LENGTH:
  589.  
  590.                 /* Fixed length resource, length must match exactly */
  591.  
  592.                 if (resource_length != minimum_resource_length) {
  593.                         goto bad_resource_length;
  594.                 }
  595.                 break;
  596.  
  597.         case ACPI_VARIABLE_LENGTH:
  598.  
  599.                 /* Variable length resource, length must be at least the minimum */
  600.  
  601.                 if (resource_length < minimum_resource_length) {
  602.                         goto bad_resource_length;
  603.                 }
  604.                 break;
  605.  
  606.         case ACPI_SMALL_VARIABLE_LENGTH:
  607.  
  608.                 /* Small variable length resource, length can be (Min) or (Min-1) */
  609.  
  610.                 if ((resource_length > minimum_resource_length) ||
  611.                     (resource_length < (minimum_resource_length - 1))) {
  612.                         goto bad_resource_length;
  613.                 }
  614.                 break;
  615.  
  616.         default:
  617.  
  618.                 /* Shouldn't happen (because of validation earlier), but be sure */
  619.  
  620.                 goto invalid_resource;
  621.         }
  622.  
  623.         aml_resource = ACPI_CAST_PTR(union aml_resource, aml);
  624.         if (resource_type == ACPI_RESOURCE_NAME_SERIAL_BUS) {
  625.  
  626.                 /* Validate the bus_type field */
  627.  
  628.                 if ((aml_resource->common_serial_bus.type == 0) ||
  629.                     (aml_resource->common_serial_bus.type >
  630.                      AML_RESOURCE_MAX_SERIALBUSTYPE)) {
  631.                         if (walk_state) {
  632.                                 ACPI_ERROR((AE_INFO,
  633.                                             "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X",
  634.                                             aml_resource->common_serial_bus.
  635.                                             type));
  636.                         }
  637.                         return (AE_AML_INVALID_RESOURCE_TYPE);
  638.                 }
  639.         }
  640.  
  641.         /* Optionally return the resource table index */
  642.  
  643.         if (return_index) {
  644.                 *return_index = resource_index;
  645.         }
  646.  
  647.         return (AE_OK);
  648.  
  649. invalid_resource:
  650.  
  651.         if (walk_state) {
  652.                 ACPI_ERROR((AE_INFO,
  653.                             "Invalid/unsupported resource descriptor: Type 0x%2.2X",
  654.                             resource_type));
  655.         }
  656.         return (AE_AML_INVALID_RESOURCE_TYPE);
  657.  
  658. bad_resource_length:
  659.  
  660.         if (walk_state) {
  661.                 ACPI_ERROR((AE_INFO,
  662.                             "Invalid resource descriptor length: Type "
  663.                             "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X",
  664.                             resource_type, resource_length,
  665.                             minimum_resource_length));
  666.         }
  667.         return (AE_AML_BAD_RESOURCE_LENGTH);
  668. }
  669.  
  670. /*******************************************************************************
  671.  *
  672.  * FUNCTION:    acpi_ut_get_resource_type
  673.  *
  674.  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
  675.  *
  676.  * RETURN:      The Resource Type with no extraneous bits (except the
  677.  *              Large/Small descriptor bit -- this is left alone)
  678.  *
  679.  * DESCRIPTION: Extract the Resource Type/Name from the first byte of
  680.  *              a resource descriptor.
  681.  *
  682.  ******************************************************************************/
  683.  
  684. u8 acpi_ut_get_resource_type(void *aml)
  685. {
  686.         ACPI_FUNCTION_ENTRY();
  687.  
  688.         /*
  689.          * Byte 0 contains the descriptor name (Resource Type)
  690.          * Examine the large/small bit in the resource header
  691.          */
  692.         if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
  693.  
  694.                 /* Large Resource Type -- bits 6:0 contain the name */
  695.  
  696.                 return (ACPI_GET8(aml));
  697.         } else {
  698.                 /* Small Resource Type -- bits 6:3 contain the name */
  699.  
  700.                 return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
  701.         }
  702. }
  703.  
  704. /*******************************************************************************
  705.  *
  706.  * FUNCTION:    acpi_ut_get_resource_length
  707.  *
  708.  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
  709.  *
  710.  * RETURN:      Byte Length
  711.  *
  712.  * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By
  713.  *              definition, this does not include the size of the descriptor
  714.  *              header or the length field itself.
  715.  *
  716.  ******************************************************************************/
  717.  
  718. u16 acpi_ut_get_resource_length(void *aml)
  719. {
  720.         acpi_rs_length resource_length;
  721.  
  722.         ACPI_FUNCTION_ENTRY();
  723.  
  724.         /*
  725.          * Byte 0 contains the descriptor name (Resource Type)
  726.          * Examine the large/small bit in the resource header
  727.          */
  728.         if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
  729.  
  730.                 /* Large Resource type -- bytes 1-2 contain the 16-bit length */
  731.  
  732.                 ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1));
  733.  
  734.         } else {
  735.                 /* Small Resource type -- bits 2:0 of byte 0 contain the length */
  736.  
  737.                 resource_length = (u16) (ACPI_GET8(aml) &
  738.                                          ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
  739.         }
  740.  
  741.         return (resource_length);
  742. }
  743.  
  744. /*******************************************************************************
  745.  *
  746.  * FUNCTION:    acpi_ut_get_resource_header_length
  747.  *
  748.  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
  749.  *
  750.  * RETURN:      Length of the AML header (depends on large/small descriptor)
  751.  *
  752.  * DESCRIPTION: Get the length of the header for this resource.
  753.  *
  754.  ******************************************************************************/
  755.  
  756. u8 acpi_ut_get_resource_header_length(void *aml)
  757. {
  758.         ACPI_FUNCTION_ENTRY();
  759.  
  760.         /* Examine the large/small bit in the resource header */
  761.  
  762.         if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
  763.                 return (sizeof(struct aml_resource_large_header));
  764.         } else {
  765.                 return (sizeof(struct aml_resource_small_header));
  766.         }
  767. }
  768.  
  769. /*******************************************************************************
  770.  *
  771.  * FUNCTION:    acpi_ut_get_descriptor_length
  772.  *
  773.  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
  774.  *
  775.  * RETURN:      Byte length
  776.  *
  777.  * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the
  778.  *              length of the descriptor header and the length field itself.
  779.  *              Used to walk descriptor lists.
  780.  *
  781.  ******************************************************************************/
  782.  
  783. u32 acpi_ut_get_descriptor_length(void *aml)
  784. {
  785.         ACPI_FUNCTION_ENTRY();
  786.  
  787.         /*
  788.          * Get the Resource Length (does not include header length) and add
  789.          * the header length (depends on if this is a small or large resource)
  790.          */
  791.         return (acpi_ut_get_resource_length(aml) +
  792.                 acpi_ut_get_resource_header_length(aml));
  793. }
  794.  
  795. /*******************************************************************************
  796.  *
  797.  * FUNCTION:    acpi_ut_get_resource_end_tag
  798.  *
  799.  * PARAMETERS:  obj_desc        - The resource template buffer object
  800.  *              end_tag         - Where the pointer to the end_tag is returned
  801.  *
  802.  * RETURN:      Status, pointer to the end tag
  803.  *
  804.  * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template
  805.  *              Note: allows a buffer length of zero.
  806.  *
  807.  ******************************************************************************/
  808.  
  809. acpi_status
  810. acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag)
  811. {
  812.         acpi_status status;
  813.  
  814.         ACPI_FUNCTION_TRACE(ut_get_resource_end_tag);
  815.  
  816.         /* Allow a buffer length of zero */
  817.  
  818.         if (!obj_desc->buffer.length) {
  819.                 *end_tag = obj_desc->buffer.pointer;
  820.                 return_ACPI_STATUS(AE_OK);
  821.         }
  822.  
  823.         /* Validate the template and get a pointer to the end_tag */
  824.  
  825.         status = acpi_ut_walk_aml_resources(NULL, obj_desc->buffer.pointer,
  826.                                             obj_desc->buffer.length, NULL,
  827.                                             (void **)end_tag);
  828.  
  829.         return_ACPI_STATUS(status);
  830. }
  831.