dmrestag.c revision 252279
146283Sdfr/******************************************************************************
246283Sdfr *
346283Sdfr * Module Name: dmrestag - Add tags to resource descriptors (Application-level)
446283Sdfr *
546283Sdfr *****************************************************************************/
646283Sdfr
746283Sdfr/*
846283Sdfr * Copyright (C) 2000 - 2013, Intel Corp.
946283Sdfr * All rights reserved.
1046283Sdfr *
1146283Sdfr * Redistribution and use in source and binary forms, with or without
1246283Sdfr * modification, are permitted provided that the following conditions
1346283Sdfr * are met:
1446283Sdfr * 1. Redistributions of source code must retain the above copyright
1546283Sdfr *    notice, this list of conditions, and the following disclaimer,
1646283Sdfr *    without modification.
1746283Sdfr * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1846283Sdfr *    substantially similar to the "NO WARRANTY" disclaimer below
1946283Sdfr *    ("Disclaimer") and any redistribution must be conditioned upon
2046283Sdfr *    including a substantially similar Disclaimer requirement for further
2146283Sdfr *    binary redistribution.
2246283Sdfr * 3. Neither the names of the above-listed copyright holders nor the names
2346283Sdfr *    of any contributors may be used to endorse or promote products derived
2446283Sdfr *    from this software without specific prior written permission.
2546283Sdfr *
2646283Sdfr * Alternatively, this software may be distributed under the terms of the
2746283Sdfr * GNU General Public License ("GPL") version 2 as published by the Free
2846283Sdfr * Software Foundation.
2946283Sdfr *
3046283Sdfr * NO WARRANTY
3146283Sdfr * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3246283Sdfr * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3346283Sdfr * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3446283Sdfr * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3546283Sdfr * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3646283Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3746283Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3846283Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3946283Sdfr * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4046283Sdfr * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4146283Sdfr * POSSIBILITY OF SUCH DAMAGES.
4246283Sdfr */
4346283Sdfr
4446283Sdfr
4546283Sdfr#include <contrib/dev/acpica/include/acpi.h>
4646283Sdfr#include <contrib/dev/acpica/include/accommon.h>
4746283Sdfr#include <contrib/dev/acpica/include/acparser.h>
4846283Sdfr#include <contrib/dev/acpica/include/acdisasm.h>
4946283Sdfr#include <contrib/dev/acpica/include/acnamesp.h>
5046283Sdfr#include <contrib/dev/acpica/include/amlcode.h>
5146283Sdfr
5246283Sdfr/* This module used for application-level code only */
5346283Sdfr
5446283Sdfr#define _COMPONENT          ACPI_CA_DISASSEMBLER
5546283Sdfr        ACPI_MODULE_NAME    ("dmrestag")
5646283Sdfr
5746283Sdfr/* Local prototypes */
5846283Sdfr
5946283Sdfrstatic void
6046283SdfrAcpiDmUpdateResourceName (
6146283Sdfr    ACPI_NAMESPACE_NODE     *ResourceNode);
6246283Sdfr
6346283Sdfrstatic char *
6446283SdfrAcpiDmSearchTagList (
6546283Sdfr    UINT32                  BitIndex,
6646283Sdfr    const ACPI_RESOURCE_TAG *TagList);
6746283Sdfr
6846283Sdfrstatic char *
6946283SdfrAcpiDmGetResourceTag (
7046283Sdfr    UINT32                  BitIndex,
7146283Sdfr    AML_RESOURCE            *Resource,
7246283Sdfr    UINT8                   ResourceIndex);
7346283Sdfr
7446283Sdfrstatic char *
7546283SdfrAcpiGetTagPathname (
7646283Sdfr    ACPI_PARSE_OBJECT       *Op,
7746283Sdfr    ACPI_NAMESPACE_NODE     *BufferNode,
7846283Sdfr    ACPI_NAMESPACE_NODE     *ResourceNode,
7946283Sdfr    UINT32                  BitIndex);
8046283Sdfr
8146283Sdfrstatic ACPI_NAMESPACE_NODE *
8246283SdfrAcpiDmGetResourceNode (
8346283Sdfr    ACPI_NAMESPACE_NODE     *BufferNode,
8446283Sdfr    UINT32                  BitIndex);
8546283Sdfr
8646283Sdfrstatic ACPI_STATUS
8746283SdfrAcpiDmAddResourceToNamespace (
8846283Sdfr    UINT8                   *Aml,
8946283Sdfr    UINT32                  Length,
9046283Sdfr    UINT32                  Offset,
9146283Sdfr    UINT8                   ResourceIndex,
9246283Sdfr    void                    **Context);
9346283Sdfr
9446283Sdfrstatic void
9546283SdfrAcpiDmAddResourcesToNamespace (
9646283Sdfr    ACPI_NAMESPACE_NODE     *BufferNode,
9746283Sdfr    ACPI_PARSE_OBJECT       *Op);
9846283Sdfr
9946283Sdfr
10046283Sdfr/******************************************************************************
10146283Sdfr *
10246283Sdfr * Resource Tag tables
10346283Sdfr *
10446283Sdfr * These are the predefined tags that refer to elements of a resource
10546283Sdfr * descriptor. Each name and offset is defined in the ACPI specification.
10646283Sdfr *
10746283Sdfr * Each table entry contains the bit offset of the field and the associated
10846283Sdfr * name.
10946283Sdfr *
11046283Sdfr ******************************************************************************/
11146283Sdfr
11246283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmIrqTags[] =
11346283Sdfr{
11446283Sdfr    {( 1 * 8),      ACPI_RESTAG_INTERRUPT},
11546283Sdfr    {( 3 * 8) + 0,  ACPI_RESTAG_INTERRUPTTYPE},
11646283Sdfr    {( 3 * 8) + 3,  ACPI_RESTAG_INTERRUPTLEVEL},
11746283Sdfr    {( 3 * 8) + 4,  ACPI_RESTAG_INTERRUPTSHARE},
11846283Sdfr    {0,             NULL}
11946283Sdfr};
12046283Sdfr
12146283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmDmaTags[] =
12246283Sdfr{
12346283Sdfr    {( 1 * 8),      ACPI_RESTAG_DMA},
12446283Sdfr    {( 2 * 8) + 0,  ACPI_RESTAG_XFERTYPE},
12546283Sdfr    {( 2 * 8) + 2,  ACPI_RESTAG_BUSMASTER},
12646283Sdfr    {( 2 * 8) + 5,  ACPI_RESTAG_DMATYPE},
12746283Sdfr    {0,             NULL}
12846283Sdfr};
12946283Sdfr
13046283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmIoTags[] =
13146283Sdfr{
13246283Sdfr    {( 1 * 8) + 0,  ACPI_RESTAG_DECODE},
13346283Sdfr    {( 2 * 8),      ACPI_RESTAG_MINADDR},
13446283Sdfr    {( 4 * 8),      ACPI_RESTAG_MAXADDR},
13546283Sdfr    {( 6 * 8),      ACPI_RESTAG_ALIGNMENT},
13646283Sdfr    {( 7 * 8),      ACPI_RESTAG_LENGTH},
13746283Sdfr    {0,             NULL}
13846283Sdfr};
13946283Sdfr
14046283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmFixedIoTags[] =
14146283Sdfr{
14246283Sdfr    {( 1 * 8),      ACPI_RESTAG_BASEADDRESS},
14346283Sdfr    {( 3 * 8),      ACPI_RESTAG_LENGTH},
14446283Sdfr    {0,             NULL}
14546283Sdfr};
14646283Sdfr
14746283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmFixedDmaTags[] =
14846283Sdfr{
14946283Sdfr    {( 1 * 8),      ACPI_RESTAG_DMA},
15046283Sdfr    {( 3 * 8),      ACPI_RESTAG_DMATYPE},
15146283Sdfr    {( 5 * 8),      ACPI_RESTAG_XFERTYPE},
15246283Sdfr    {0,             NULL}
15346283Sdfr};
15446283Sdfr
15546283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmMemory24Tags[] =
15646283Sdfr{
15746283Sdfr    {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
15846283Sdfr    {( 4 * 8),      ACPI_RESTAG_MINADDR},
15946283Sdfr    {( 6 * 8),      ACPI_RESTAG_MAXADDR},
16046283Sdfr    {( 8 * 8),      ACPI_RESTAG_ALIGNMENT},
16146283Sdfr    {(10 * 8),      ACPI_RESTAG_LENGTH},
16246283Sdfr    {0,             NULL}
16346283Sdfr};
16446283Sdfr
16546283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmRegisterTags[] =
16646283Sdfr{
16746283Sdfr    {( 3 * 8),      ACPI_RESTAG_ADDRESSSPACE},
16846283Sdfr    {( 4 * 8),      ACPI_RESTAG_REGISTERBITWIDTH},
16946283Sdfr    {( 5 * 8),      ACPI_RESTAG_REGISTERBITOFFSET},
17046283Sdfr    {( 6 * 8),      ACPI_RESTAG_ACCESSSIZE},
17146283Sdfr    {( 7 * 8),      ACPI_RESTAG_ADDRESS},
17246283Sdfr    {0,             NULL}
17346283Sdfr};
17446283Sdfr
17546283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmMemory32Tags[] =
17646283Sdfr{
17746283Sdfr    {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
17846283Sdfr    {( 4 * 8),      ACPI_RESTAG_MINADDR},
17946283Sdfr    {( 8 * 8),      ACPI_RESTAG_MAXADDR},
18046283Sdfr    {(12 * 8),      ACPI_RESTAG_ALIGNMENT},
18146283Sdfr    {(16 * 8),      ACPI_RESTAG_LENGTH},
18246283Sdfr    {0,             NULL}
18346283Sdfr};
18446283Sdfr
18546283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmFixedMemory32Tags[] =
18646283Sdfr{
18746283Sdfr    {( 3 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
18846283Sdfr    {( 4 * 8),      ACPI_RESTAG_BASEADDRESS},
18946283Sdfr    {( 8 * 8),      ACPI_RESTAG_LENGTH},
19046283Sdfr    {0,             NULL}
19146283Sdfr};
19246283Sdfr
19346283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmInterruptTags[] =
19446283Sdfr{
19546283Sdfr    {( 3 * 8) + 1,  ACPI_RESTAG_INTERRUPTTYPE},
19646283Sdfr    {( 3 * 8) + 2,  ACPI_RESTAG_INTERRUPTLEVEL},
19746283Sdfr    {( 3 * 8) + 3,  ACPI_RESTAG_INTERRUPTSHARE},
19846283Sdfr    {( 5 * 8),      ACPI_RESTAG_INTERRUPT},
19946283Sdfr    {0,             NULL}
20046283Sdfr};
20146283Sdfr
20246283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmAddress16Tags[] =
20346283Sdfr{
20446283Sdfr    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
20546283Sdfr    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
20646283Sdfr    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
20746283Sdfr    {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
20846283Sdfr    {( 8 * 8),      ACPI_RESTAG_MINADDR},
20946283Sdfr    {(10 * 8),      ACPI_RESTAG_MAXADDR},
21046283Sdfr    {(12 * 8),      ACPI_RESTAG_TRANSLATION},
21146283Sdfr    {(14 * 8),      ACPI_RESTAG_LENGTH},
21246283Sdfr    {0,             NULL}
21346283Sdfr};
21446283Sdfr
21546283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmAddress32Tags[] =
21646283Sdfr{
21746283Sdfr    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
21846283Sdfr    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
21946283Sdfr    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
22046283Sdfr    {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
22146283Sdfr    {(10 * 8),      ACPI_RESTAG_MINADDR},
22246283Sdfr    {(14 * 8),      ACPI_RESTAG_MAXADDR},
22346283Sdfr    {(18 * 8),      ACPI_RESTAG_TRANSLATION},
22446283Sdfr    {(22 * 8),      ACPI_RESTAG_LENGTH},
22546283Sdfr    {0,             NULL}
22646283Sdfr};
22746283Sdfr
22846283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmAddress64Tags[] =
22946283Sdfr{
23046283Sdfr    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
23146283Sdfr    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
23246283Sdfr    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
23346283Sdfr    {( 6 * 8),      ACPI_RESTAG_GRANULARITY},
23446283Sdfr    {(14 * 8),      ACPI_RESTAG_MINADDR},
23546283Sdfr    {(22 * 8),      ACPI_RESTAG_MAXADDR},
23646283Sdfr    {(30 * 8),      ACPI_RESTAG_TRANSLATION},
23746283Sdfr    {(38 * 8),      ACPI_RESTAG_LENGTH},
23846283Sdfr    {0,             NULL}
23946283Sdfr};
24046283Sdfr
24146283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmExtendedAddressTags[] =
24246283Sdfr{
24346283Sdfr    {( 4 * 8) + 1,  ACPI_RESTAG_DECODE},
24446283Sdfr    {( 4 * 8) + 2,  ACPI_RESTAG_MINTYPE},
24546283Sdfr    {( 4 * 8) + 3,  ACPI_RESTAG_MAXTYPE},
24646283Sdfr    {( 8 * 8),      ACPI_RESTAG_GRANULARITY},
24746283Sdfr    {(16 * 8),      ACPI_RESTAG_MINADDR},
24846283Sdfr    {(24 * 8),      ACPI_RESTAG_MAXADDR},
24946283Sdfr    {(32 * 8),      ACPI_RESTAG_TRANSLATION},
25046283Sdfr    {(40 * 8),      ACPI_RESTAG_LENGTH},
25146283Sdfr    {(48 * 8),      ACPI_RESTAG_TYPESPECIFICATTRIBUTES},
25246283Sdfr    {0,             NULL}
25346283Sdfr};
25446283Sdfr
25546283Sdfr/* Subtype tables for GPIO descriptors */
25646283Sdfr
25746283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmGpioIntTags[] =
25846283Sdfr{
25946283Sdfr    {( 7 * 8) + 0,  ACPI_RESTAG_MODE},
26046283Sdfr    {( 7 * 8) + 1,  ACPI_RESTAG_POLARITY},
26146283Sdfr    {( 7 * 8) + 3,  ACPI_RESTAG_INTERRUPTSHARE},
26246283Sdfr    {( 9 * 8),      ACPI_RESTAG_PINCONFIG},
26346283Sdfr    {(10 * 8),      ACPI_RESTAG_DRIVESTRENGTH},
26446283Sdfr    {(12 * 8),      ACPI_RESTAG_DEBOUNCETIME},
26546283Sdfr    {0,             NULL}
26646283Sdfr};
26746283Sdfr
26846283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmGpioIoTags[] =
26946283Sdfr{
27046283Sdfr    {( 7 * 8) + 0,  ACPI_RESTAG_IORESTRICTION},
27146283Sdfr    {( 7 * 8) + 3,  ACPI_RESTAG_INTERRUPTSHARE},
27246283Sdfr    {( 9 * 8),      ACPI_RESTAG_PINCONFIG},
27346283Sdfr    {(10 * 8),      ACPI_RESTAG_DRIVESTRENGTH},
27446283Sdfr    {(12 * 8),      ACPI_RESTAG_DEBOUNCETIME},
27546283Sdfr    {0,             NULL}
27646283Sdfr};
27746283Sdfr
27846283Sdfr/* Subtype tables for SerialBus descriptors */
27946283Sdfr
28046283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmI2cSerialBusTags[] =
28146283Sdfr{
28246283Sdfr    {( 6 * 8) + 0,  ACPI_RESTAG_SLAVEMODE},
28346283Sdfr    {( 7 * 8) + 0,  ACPI_RESTAG_MODE},
28446283Sdfr    {(12 * 8),      ACPI_RESTAG_SPEED},
28546283Sdfr    {(16 * 8),      ACPI_RESTAG_ADDRESS},
28646283Sdfr    {0,             NULL}
28746283Sdfr};
28846283Sdfr
28946283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmSpiSerialBusTags[] =
29046283Sdfr{
29146283Sdfr    {( 6 * 8) + 0,  ACPI_RESTAG_SLAVEMODE},
29246283Sdfr    {( 7 * 8) + 0,  ACPI_RESTAG_MODE},
29346283Sdfr    {( 7 * 8) + 1,  ACPI_RESTAG_DEVICEPOLARITY},
29446283Sdfr    {(12 * 8),      ACPI_RESTAG_SPEED},
29546283Sdfr    {(16 * 8),      ACPI_RESTAG_LENGTH},
29646283Sdfr    {(17 * 8),      ACPI_RESTAG_PHASE},
29746283Sdfr    {(18 * 8),      ACPI_RESTAG_POLARITY},
29846283Sdfr    {(19 * 8),      ACPI_RESTAG_ADDRESS},
29946283Sdfr    {0,             NULL}
30046283Sdfr};
30146283Sdfr
30246283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmUartSerialBusTags[] =
30346283Sdfr{
30446283Sdfr    {( 6 * 8) + 0,  ACPI_RESTAG_SLAVEMODE}, /* Note: not part of original macro */
30546283Sdfr    {( 7 * 8) + 0,  ACPI_RESTAG_FLOWCONTROL},
30646283Sdfr    {( 7 * 8) + 2,  ACPI_RESTAG_STOPBITS},
30746283Sdfr    {( 7 * 8) + 4,  ACPI_RESTAG_LENGTH},
30846283Sdfr    {( 7 * 8) + 7,  ACPI_RESTAG_ENDIANNESS},
30946283Sdfr    {(12 * 8),      ACPI_RESTAG_SPEED},
31046283Sdfr    {(16 * 8),      ACPI_RESTAG_LENGTH_RX},
31146283Sdfr    {(18 * 8),      ACPI_RESTAG_LENGTH_TX},
31246283Sdfr    {(20 * 8),      ACPI_RESTAG_PARITY},
31346283Sdfr    {(21 * 8),      ACPI_RESTAG_LINE},
31446283Sdfr    {0,             NULL}
31546283Sdfr};
31646283Sdfr
31746283Sdfr/* Subtype tables for Address descriptor type-specific flags */
31846283Sdfr
31946283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmMemoryFlagTags[] =
32046283Sdfr{
32146283Sdfr    {( 5 * 8) + 0,  ACPI_RESTAG_READWRITETYPE},
32246283Sdfr    {( 5 * 8) + 1,  ACPI_RESTAG_MEMTYPE},
32346283Sdfr    {( 5 * 8) + 3,  ACPI_RESTAG_MEMATTRIBUTES},
32446283Sdfr    {( 5 * 8) + 5,  ACPI_RESTAG_TYPE},
32546283Sdfr    {0,             NULL}
32646283Sdfr};
32746283Sdfr
32846283Sdfrstatic const ACPI_RESOURCE_TAG      AcpiDmIoFlagTags[] =
32946283Sdfr{
33046283Sdfr    {( 5 * 8) + 0,  ACPI_RESTAG_RANGETYPE},
33146283Sdfr    {( 5 * 8) + 4,  ACPI_RESTAG_TYPE},
33246283Sdfr    {( 5 * 8) + 5,  ACPI_RESTAG_TRANSTYPE},
33346283Sdfr    {0,             NULL}
33446283Sdfr};
33546283Sdfr
33646283Sdfr
33746283Sdfr/*
33846283Sdfr * Dispatch table used to obtain the correct tag table for a descriptor.
33946283Sdfr *
34046283Sdfr * A NULL in this table means one of three things:
34146283Sdfr * 1) The descriptor ID is reserved and invalid
34246283Sdfr * 2) The descriptor has no tags associated with it
34346283Sdfr * 3) The descriptor has subtypes and a separate table will be used.
34446283Sdfr */
34546283Sdfrstatic const ACPI_RESOURCE_TAG      *AcpiGbl_ResourceTags[] =
34646283Sdfr{
34746283Sdfr    /* Small descriptors */
34846283Sdfr
34946283Sdfr    NULL,                           /* 0x00, Reserved */
35046283Sdfr    NULL,                           /* 0x01, Reserved */
35146283Sdfr    NULL,                           /* 0x02, Reserved */
35246283Sdfr    NULL,                           /* 0x03, Reserved */
35346283Sdfr    AcpiDmIrqTags,                  /* 0x04, ACPI_RESOURCE_NAME_IRQ_FORMAT */
35446283Sdfr    AcpiDmDmaTags,                  /* 0x05, ACPI_RESOURCE_NAME_DMA_FORMAT */
35546283Sdfr    NULL,                           /* 0x06, ACPI_RESOURCE_NAME_START_DEPENDENT */
35646283Sdfr    NULL,                           /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */
35746283Sdfr    AcpiDmIoTags,                   /* 0x08, ACPI_RESOURCE_NAME_IO_PORT */
35846283Sdfr    AcpiDmFixedIoTags,              /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO_PORT */
35946283Sdfr    AcpiDmFixedDmaTags,             /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */
36046283Sdfr    NULL,                           /* 0x0B, Reserved */
36146283Sdfr    NULL,                           /* 0x0C, Reserved */
36246283Sdfr    NULL,                           /* 0x0D, Reserved */
36346283Sdfr    NULL,                           /* 0x0E, ACPI_RESOURCE_NAME_SMALL_VENDOR */
36446283Sdfr    NULL,                           /* 0x0F, ACPI_RESOURCE_NAME_END_TAG (not used) */
36546283Sdfr
36646283Sdfr    /* Large descriptors */
36746283Sdfr
36846283Sdfr    NULL,                           /* 0x00, Reserved */
36946283Sdfr    AcpiDmMemory24Tags,             /* 0x01, ACPI_RESOURCE_NAME_MEMORY_24 */
37046283Sdfr    AcpiDmRegisterTags,             /* 0x02, ACPI_RESOURCE_NAME_GENERIC_REGISTER */
37146283Sdfr    NULL,                           /* 0x03, Reserved */
37246283Sdfr    NULL,                           /* 0x04, ACPI_RESOURCE_NAME_LARGE_VENDOR */
37346283Sdfr    AcpiDmMemory32Tags,             /* 0x05, ACPI_RESOURCE_NAME_MEMORY_32 */
37446283Sdfr    AcpiDmFixedMemory32Tags,        /* 0x06, ACPI_RESOURCE_NAME_FIXED_MEMORY_32 */
37546283Sdfr    AcpiDmAddress32Tags,            /* 0x07, ACPI_RESOURCE_NAME_DWORD_ADDRESS_SPACE */
37646283Sdfr    AcpiDmAddress16Tags,            /* 0x08, ACPI_RESOURCE_NAME_WORD_ADDRESS_SPACE */
37746283Sdfr    AcpiDmInterruptTags,            /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_XRUPT */
37846283Sdfr    AcpiDmAddress64Tags,            /* 0x0A, ACPI_RESOURCE_NAME_QWORD_ADDRESS_SPACE */
37946283Sdfr    AcpiDmExtendedAddressTags,      /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS_SPACE */
38046283Sdfr    NULL,                           /* 0x0C, ACPI_RESOURCE_NAME_GPIO - Use Subtype table below */
38146283Sdfr    NULL,                           /* 0x0D, Reserved */
38246283Sdfr    NULL                            /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS - Use Subtype table below */
38346283Sdfr};
38446283Sdfr
38546283Sdfr/* GPIO Subtypes */
38646283Sdfr
38746283Sdfrstatic const ACPI_RESOURCE_TAG      *AcpiGbl_GpioResourceTags[] =
388{
389    AcpiDmGpioIntTags,              /* 0x00 Interrupt Connection */
390    AcpiDmGpioIoTags                /* 0x01 I/O Connection */
391};
392
393/* Serial Bus Subtypes */
394
395static const ACPI_RESOURCE_TAG      *AcpiGbl_SerialResourceTags[] =
396{
397    NULL,                           /* 0x00 Reserved */
398    AcpiDmI2cSerialBusTags,         /* 0x01 I2C SerialBus */
399    AcpiDmSpiSerialBusTags,         /* 0x02 SPI SerialBus */
400    AcpiDmUartSerialBusTags         /* 0x03 UART SerialBus */
401};
402
403/*
404 * Globals used to generate unique resource descriptor names. We use names that
405 * start with underscore and a prefix letter that is not used by other ACPI
406 * reserved names. To this, we append hex 0x00 through 0xFF. These 5 prefixes
407 * allow for 5*256 = 1280 unique names, probably sufficient for any single ASL
408 * file. If this becomes too small, we can use alpha+numerals for a total
409 * of 5*36*36 = 6480.
410 */
411#define ACPI_NUM_RES_PREFIX     5
412
413static UINT32                   AcpiGbl_NextResourceId = 0;
414static UINT8                    AcpiGbl_NextPrefix = 0;
415static char                     AcpiGbl_Prefix[ACPI_NUM_RES_PREFIX] =
416                                    {'Y','Z','J','K','X'};
417
418
419/*******************************************************************************
420 *
421 * FUNCTION:    AcpiDmCheckResourceReference
422 *
423 * PARAMETERS:  Op                  - Parse Op for the AML opcode
424 *              WalkState           - Current walk state (with valid scope)
425 *
426 * RETURN:      None
427 *
428 * DESCRIPTION: Convert a reference to a resource descriptor to a symbolic
429 *              reference if possible
430 *
431 * NOTE:        Bit index is used to transparently handle both resource bit
432 *              fields and byte fields.
433 *
434 ******************************************************************************/
435
436void
437AcpiDmCheckResourceReference (
438    ACPI_PARSE_OBJECT       *Op,
439    ACPI_WALK_STATE         *WalkState)
440{
441    ACPI_STATUS             Status;
442    ACPI_PARSE_OBJECT       *BufferNameOp;
443    ACPI_PARSE_OBJECT       *IndexOp;
444    ACPI_NAMESPACE_NODE     *BufferNode;
445    ACPI_NAMESPACE_NODE     *ResourceNode;
446    const ACPI_OPCODE_INFO  *OpInfo;
447    UINT32                  BitIndex;
448
449
450    /* We are only interested in the CreateXxxxField opcodes */
451
452    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
453    if (OpInfo->Type != AML_TYPE_CREATE_FIELD)
454    {
455        return;
456    }
457
458    /* Get the buffer term operand */
459
460    BufferNameOp = AcpiPsGetDepthNext (NULL, Op);
461
462    /* Must be a named buffer, not an arg or local or method call */
463
464    if (BufferNameOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
465    {
466        return;
467    }
468
469    /* Get the Index term, must be an integer constant to convert */
470
471    IndexOp = BufferNameOp->Common.Next;
472
473    /* Major cheat: The Node field is also used for the Tag ptr. Clear it now */
474
475    IndexOp->Common.Node = NULL;
476
477    OpInfo = AcpiPsGetOpcodeInfo (IndexOp->Common.AmlOpcode);
478    if (OpInfo->ObjectType != ACPI_TYPE_INTEGER)
479    {
480        return;
481    }
482
483    /* Get the bit offset of the descriptor within the buffer */
484
485    if ((Op->Common.AmlOpcode == AML_CREATE_BIT_FIELD_OP) ||
486        (Op->Common.AmlOpcode == AML_CREATE_FIELD_OP))
487    {
488        /* Index operand is a bit offset */
489
490        BitIndex = (UINT32) IndexOp->Common.Value.Integer;
491    }
492    else
493    {
494        /* Index operand is a byte offset, convert to bits */
495
496        BitIndex = (UINT32) ACPI_MUL_8 (IndexOp->Common.Value.Integer);
497    }
498
499    /* Lookup the buffer in the namespace */
500
501    Status = AcpiNsLookup (WalkState->ScopeInfo,
502                BufferNameOp->Common.Value.String, ACPI_TYPE_BUFFER,
503                ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState,
504                &BufferNode);
505    if (ACPI_FAILURE (Status))
506    {
507        return;
508    }
509
510    /* Validate object type, we must have a buffer */
511
512    if (BufferNode->Type != ACPI_TYPE_BUFFER)
513    {
514        return;
515    }
516
517    /* Find the resource descriptor node corresponding to the index */
518
519    ResourceNode = AcpiDmGetResourceNode (BufferNode, BitIndex);
520    if (!ResourceNode)
521    {
522        return;
523    }
524
525    /* Translate the Index to a resource tag pathname */
526
527    AcpiGetTagPathname (IndexOp, BufferNode, ResourceNode, BitIndex);
528}
529
530
531/*******************************************************************************
532 *
533 * FUNCTION:    AcpiDmGetResourceNode
534 *
535 * PARAMETERS:  BufferNode          - Node for the parent buffer
536 *              BitIndex            - Index into the resource descriptor
537 *
538 * RETURN:      Namespace node for the resource descriptor. NULL if not found
539 *
540 * DESCRIPTION: Find a resource descriptor that corresponds to the bit index
541 *
542 ******************************************************************************/
543
544static ACPI_NAMESPACE_NODE *
545AcpiDmGetResourceNode (
546    ACPI_NAMESPACE_NODE     *BufferNode,
547    UINT32                  BitIndex)
548{
549    ACPI_NAMESPACE_NODE     *Node;
550    UINT32                  ByteIndex = ACPI_DIV_8 (BitIndex);
551
552
553    /*
554     * Child list contains an entry for each resource descriptor. Find
555     * the descriptor that corresponds to the Index.
556     *
557     * If there are no children, this is not a resource template
558     */
559    Node = BufferNode->Child;
560    while (Node)
561    {
562        /*
563         * Check if the Index falls within this resource.
564         *
565         * Value contains the resource offset, Object contains the resource
566         * length (both in bytes)
567         */
568        if ((ByteIndex >= Node->Value) &&
569            (ByteIndex < (Node->Value + Node->Length)))
570        {
571            return (Node);
572        }
573
574        Node = Node->Peer;
575    }
576
577    return (NULL);
578}
579
580
581/*******************************************************************************
582 *
583 * FUNCTION:    AcpiGetTagPathname
584 *
585 * PARAMETERS:  BufferNode          - Node for the parent buffer
586 *              ResourceNode        - Node for a resource descriptor
587 *              BitIndex            - Index into the resource descriptor
588 *
589 * RETURN:      Full pathname for a resource tag. NULL if no match.
590 *              Path is returned in AML (packed) format.
591 *
592 * DESCRIPTION: Convert a BitIndex into a symbolic resource tag (full pathname)
593 *
594 ******************************************************************************/
595
596static char *
597AcpiGetTagPathname (
598    ACPI_PARSE_OBJECT       *IndexOp,
599    ACPI_NAMESPACE_NODE     *BufferNode,
600    ACPI_NAMESPACE_NODE     *ResourceNode,
601    UINT32                  BitIndex)
602{
603    ACPI_STATUS             Status;
604    UINT32                  ResourceBitIndex;
605    UINT8                   ResourceTableIndex;
606    ACPI_SIZE               RequiredSize;
607    char                    *Pathname;
608    AML_RESOURCE            *Aml;
609    ACPI_PARSE_OBJECT       *Op;
610    char                    *InternalPath;
611    char                    *Tag;
612
613
614    /* Get the Op that contains the actual buffer data */
615
616    Op = BufferNode->Op->Common.Value.Arg;
617    Op = Op->Common.Next;
618    if (!Op)
619    {
620        return (NULL);
621    }
622
623    /* Get the individual resource descriptor and validate it */
624
625    Aml = ACPI_CAST_PTR (AML_RESOURCE,
626            &Op->Named.Data[ResourceNode->Value]);
627
628    Status = AcpiUtValidateResource (NULL, Aml, &ResourceTableIndex);
629    if (ACPI_FAILURE (Status))
630    {
631        return (NULL);
632    }
633
634    /* Get offset into this descriptor (from offset into entire buffer) */
635
636    ResourceBitIndex = BitIndex - ACPI_MUL_8 (ResourceNode->Value);
637
638    /* Get the tag associated with this resource descriptor and offset */
639
640    Tag = AcpiDmGetResourceTag (ResourceBitIndex, Aml, ResourceTableIndex);
641    if (!Tag)
642    {
643        return (NULL);
644    }
645
646    /*
647     * Now that we know that we have a reference that can be converted to a
648     * symbol, change the name of the resource to a unique name.
649     */
650    AcpiDmUpdateResourceName (ResourceNode);
651
652    /* Get the full pathname to the parent buffer */
653
654    RequiredSize = AcpiNsGetPathnameLength (BufferNode);
655    if (!RequiredSize)
656    {
657        return (NULL);
658    }
659
660    Pathname = ACPI_ALLOCATE_ZEROED (RequiredSize + ACPI_PATH_SEGMENT_LENGTH);
661    if (!Pathname)
662    {
663        return (NULL);
664    }
665
666    Status = AcpiNsBuildExternalPath (BufferNode, RequiredSize, Pathname);
667    if (ACPI_FAILURE (Status))
668    {
669        ACPI_FREE (Pathname);
670        return (NULL);
671    }
672
673    /*
674     * Create the full path to the resource and tag by: remove the buffer name,
675     * append the resource descriptor name, append a dot, append the tag name.
676     *
677     * TBD: Always using the full path is a bit brute force, the path can be
678     * often be optimized with carats (if the original buffer namepath is a
679     * single nameseg). This doesn't really matter, because these paths do not
680     * end up in the final compiled AML, it's just an appearance issue for the
681     * disassembled code.
682     */
683    Pathname[ACPI_STRLEN (Pathname) - ACPI_NAME_SIZE] = 0;
684    ACPI_STRNCAT (Pathname, ResourceNode->Name.Ascii, ACPI_NAME_SIZE);
685    ACPI_STRCAT (Pathname, ".");
686    ACPI_STRNCAT (Pathname, Tag, ACPI_NAME_SIZE);
687
688    /* Internalize the namepath to AML format */
689
690    AcpiNsInternalizeName (Pathname, &InternalPath);
691    ACPI_FREE (Pathname);
692
693    /* Update the Op with the symbol */
694
695    AcpiPsInitOp (IndexOp, AML_INT_NAMEPATH_OP);
696    IndexOp->Common.Value.String = InternalPath;
697
698    /* We will need the tag later. Cheat by putting it in the Node field */
699
700    IndexOp->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Tag);
701    return (InternalPath);
702}
703
704
705/*******************************************************************************
706 *
707 * FUNCTION:    AcpiDmUpdateResourceName
708 *
709 * PARAMETERS:  ResourceNode        - Node for a resource descriptor
710 *
711 * RETURN:      Stores new name in the ResourceNode
712 *
713 * DESCRIPTION: Create a new, unique name for a resource descriptor. Used by
714 *              both the disassembly of the descriptor itself and any symbolic
715 *              references to the descriptor. Ignored if a unique name has
716 *              already been assigned to the resource.
717 *
718 * NOTE: Single threaded, suitable for applications only!
719 *
720 ******************************************************************************/
721
722static void
723AcpiDmUpdateResourceName (
724    ACPI_NAMESPACE_NODE     *ResourceNode)
725{
726    char                    Name[ACPI_NAME_SIZE];
727
728
729    /* Ignore if a unique name has already been assigned */
730
731    if (ResourceNode->Name.Integer != ACPI_DEFAULT_RESNAME)
732    {
733        return;
734    }
735
736    /* Generate a new ACPI name for the descriptor */
737
738    Name[0] = '_';
739    Name[1] = AcpiGbl_Prefix[AcpiGbl_NextPrefix];
740    Name[2] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 4);
741    Name[3] = AcpiUtHexToAsciiChar ((UINT64) AcpiGbl_NextResourceId, 0);
742
743    /* Update globals for next name */
744
745    AcpiGbl_NextResourceId++;
746    if (AcpiGbl_NextResourceId >= 256)
747    {
748        AcpiGbl_NextResourceId = 0;
749        AcpiGbl_NextPrefix++;
750        if (AcpiGbl_NextPrefix > ACPI_NUM_RES_PREFIX)
751        {
752            AcpiGbl_NextPrefix = 0;
753        }
754    }
755
756    /* Change the resource descriptor name */
757
758    ResourceNode->Name.Integer = *ACPI_CAST_PTR (UINT32, &Name[0]);
759}
760
761
762/*******************************************************************************
763 *
764 * FUNCTION:    AcpiDmGetResourceTag
765 *
766 * PARAMETERS:  BitIndex            - Index into the resource descriptor
767 *              Resource            - Pointer to the raw resource data
768 *              ResourceIndex       - Index correspoinding to the resource type
769 *
770 * RETURN:      Pointer to the resource tag (ACPI_NAME). NULL if no match.
771 *
772 * DESCRIPTION: Convert a BitIndex into a symbolic resource tag.
773 *
774 * Note: ResourceIndex should be previously validated and guaranteed to ve
775 *       valid.
776 *
777 ******************************************************************************/
778
779static char *
780AcpiDmGetResourceTag (
781    UINT32                  BitIndex,
782    AML_RESOURCE            *Resource,
783    UINT8                   ResourceIndex)
784{
785    const ACPI_RESOURCE_TAG *TagList;
786    char                    *Tag = NULL;
787
788
789    /* Get the tag list for this resource descriptor type */
790
791    TagList = AcpiGbl_ResourceTags[ResourceIndex];
792
793    /*
794     * Handle descriptors that have multiple subtypes
795     */
796    switch (Resource->DescriptorType)
797    {
798    case ACPI_RESOURCE_NAME_ADDRESS16:
799    case ACPI_RESOURCE_NAME_ADDRESS32:
800    case ACPI_RESOURCE_NAME_ADDRESS64:
801    case ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64:
802        /*
803         * Subtype differentiation is the flags.
804         * Kindof brute force, but just blindly search for an index match
805         */
806        if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_MEMORY_RANGE)
807        {
808            Tag = AcpiDmSearchTagList (BitIndex, AcpiDmMemoryFlagTags);
809        }
810        else if (Resource->Address.ResourceType == ACPI_ADDRESS_TYPE_IO_RANGE)
811        {
812            Tag = AcpiDmSearchTagList (BitIndex, AcpiDmIoFlagTags);
813        }
814
815        /* If we found a match, all done. Else, drop to normal search below */
816
817        if (Tag)
818        {
819            return (Tag);
820        }
821        break;
822
823    case ACPI_RESOURCE_NAME_GPIO:
824
825        /* GPIO connection has 2 subtypes: Interrupt and I/O */
826
827        if (Resource->Gpio.ConnectionType > AML_RESOURCE_MAX_GPIOTYPE)
828        {
829            return (NULL);
830        }
831
832        TagList = AcpiGbl_GpioResourceTags[Resource->Gpio.ConnectionType];
833        break;
834
835    case ACPI_RESOURCE_NAME_SERIAL_BUS:
836
837        /* SerialBus has 3 subtypes: I2C, SPI, and UART */
838
839        if ((Resource->CommonSerialBus.Type == 0) ||
840            (Resource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE))
841        {
842            return (NULL);
843        }
844
845        TagList = AcpiGbl_SerialResourceTags[Resource->CommonSerialBus.Type];
846        break;
847
848    default:
849
850        break;
851    }
852
853    /* Search for a match against the BitIndex */
854
855    if (TagList)
856    {
857        Tag = AcpiDmSearchTagList (BitIndex, TagList);
858    }
859
860    return (Tag);
861}
862
863
864/*******************************************************************************
865 *
866 * FUNCTION:    AcpiDmSearchTagList
867 *
868 * PARAMETERS:  BitIndex            - Index into the resource descriptor
869 *              TagList             - List to search
870 *
871 * RETURN:      Pointer to a tag (ACPI_NAME). NULL if no match found.
872 *
873 * DESCRIPTION: Search a tag list for a match to the input BitIndex. Matches
874 *              a fixed offset to a symbolic resource tag name.
875 *
876 ******************************************************************************/
877
878static char *
879AcpiDmSearchTagList (
880    UINT32                  BitIndex,
881    const ACPI_RESOURCE_TAG *TagList)
882{
883
884    /*
885     * Walk the null-terminated tag list to find a matching bit offset.
886     * We are looking for an exact match.
887     */
888    for ( ; TagList->Tag; TagList++)
889    {
890        if (BitIndex == TagList->BitIndex)
891        {
892            return (TagList->Tag);
893        }
894    }
895
896    /* A matching offset was not found */
897
898    return (NULL);
899}
900
901
902/*******************************************************************************
903 *
904 * FUNCTION:    AcpiDmFindResources
905 *
906 * PARAMETERS:  Root                - Root of the parse tree
907 *
908 * RETURN:      None
909 *
910 * DESCRIPTION: Add all ResourceTemplate declarations to the namespace. Each
911 *              resource descriptor in each template is given a node -- used
912 *              for later conversion of resource references to symbolic refs.
913 *
914 ******************************************************************************/
915
916void
917AcpiDmFindResources (
918    ACPI_PARSE_OBJECT       *Root)
919{
920    ACPI_PARSE_OBJECT       *Op = Root;
921    ACPI_PARSE_OBJECT       *Parent;
922
923
924    /* Walk the entire parse tree */
925
926    while (Op)
927    {
928        /* We are interested in Buffer() declarations */
929
930        if (Op->Common.AmlOpcode == AML_BUFFER_OP)
931        {
932            /* And only declarations of the form Name (XXXX, Buffer()... ) */
933
934            Parent = Op->Common.Parent;
935            if (Parent->Common.AmlOpcode == AML_NAME_OP)
936            {
937                /*
938                 * If the buffer is a resource template, add the individual
939                 * resource descriptors to the namespace, as children of the
940                 * buffer node.
941                 */
942                if (ACPI_SUCCESS (AcpiDmIsResourceTemplate (NULL, Op)))
943                {
944                    Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
945                    AcpiDmAddResourcesToNamespace (Parent->Common.Node, Op);
946                }
947            }
948        }
949
950        Op = AcpiPsGetDepthNext (Root, Op);
951    }
952}
953
954
955/*******************************************************************************
956 *
957 * FUNCTION:    AcpiDmAddResourcesToNamespace
958 *
959 * PARAMETERS:  BufferNode          - Node for the parent buffer
960 *              Op                  - Parse op for the buffer
961 *
962 * RETURN:      None
963 *
964 * DESCRIPTION: Add an entire resource template to the namespace. Each
965 *              resource descriptor is added as a namespace node.
966 *
967 ******************************************************************************/
968
969static void
970AcpiDmAddResourcesToNamespace (
971    ACPI_NAMESPACE_NODE     *BufferNode,
972    ACPI_PARSE_OBJECT       *Op)
973{
974    ACPI_PARSE_OBJECT       *NextOp;
975
976
977    /* Get to the ByteData list */
978
979    NextOp = Op->Common.Value.Arg;
980    NextOp = NextOp->Common.Next;
981    if (!NextOp)
982    {
983        return;
984    }
985
986    /* Set Node and Op to point to each other */
987
988    BufferNode->Op = Op;
989    Op->Common.Node = BufferNode;
990
991    /*
992     * Insert each resource into the namespace
993     * NextOp contains the Aml pointer and the Aml length
994     */
995    AcpiUtWalkAmlResources (NULL, (UINT8 *) NextOp->Named.Data,
996        (ACPI_SIZE) NextOp->Common.Value.Integer,
997        AcpiDmAddResourceToNamespace, (void **) BufferNode);
998}
999
1000
1001/*******************************************************************************
1002 *
1003 * FUNCTION:    AcpiDmAddResourceToNamespace
1004 *
1005 * PARAMETERS:  ACPI_WALK_AML_CALLBACK
1006 *              BufferNode              - Node for the parent buffer
1007 *
1008 * RETURN:      Status
1009 *
1010 * DESCRIPTION: Add one resource descriptor to the namespace as a child of the
1011 *              parent buffer. The same name is used for each descriptor. This
1012 *              is changed later to a unique name if the resource is actually
1013 *              referenced by an AML operator.
1014 *
1015 ******************************************************************************/
1016
1017static ACPI_STATUS
1018AcpiDmAddResourceToNamespace (
1019    UINT8                   *Aml,
1020    UINT32                  Length,
1021    UINT32                  Offset,
1022    UINT8                   ResourceIndex,
1023    void                    **Context)
1024{
1025    ACPI_STATUS             Status;
1026    ACPI_GENERIC_STATE      ScopeInfo;
1027    ACPI_NAMESPACE_NODE     *Node;
1028
1029
1030    /* TBD: Don't need to add descriptors that have no tags defined? */
1031
1032    /* Add the resource to the namespace, as child of the buffer */
1033
1034    ScopeInfo.Scope.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Context);
1035    Status = AcpiNsLookup (&ScopeInfo, "_TMP", ACPI_TYPE_LOCAL_RESOURCE,
1036                ACPI_IMODE_LOAD_PASS2,
1037                ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_PREFIX_IS_SCOPE,
1038                NULL, &Node);
1039    if (ACPI_FAILURE (Status))
1040    {
1041        return (AE_OK);
1042    }
1043
1044    /* Set the name to the default, changed later if resource is referenced */
1045
1046    Node->Name.Integer = ACPI_DEFAULT_RESNAME;
1047
1048    /* Save the offset of the descriptor (within the original buffer) */
1049
1050    Node->Value = Offset;
1051    Node->Length = Length;
1052    return (AE_OK);
1053}
1054