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