rslist.c revision 241973
1193323Sed/*******************************************************************************
2193323Sed *
3193323Sed * Module Name: rslist - Linked list utilities
4193323Sed *
5193323Sed ******************************************************************************/
6193323Sed
7193323Sed/*
8193323Sed * Copyright (C) 2000 - 2012, Intel Corp.
9193323Sed * All rights reserved.
10193323Sed *
11193323Sed * Redistribution and use in source and binary forms, with or without
12193323Sed * modification, are permitted provided that the following conditions
13193323Sed * are met:
14193323Sed * 1. Redistributions of source code must retain the above copyright
15193323Sed *    notice, this list of conditions, and the following disclaimer,
16193323Sed *    without modification.
17193323Sed * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18193323Sed *    substantially similar to the "NO WARRANTY" disclaimer below
19193323Sed *    ("Disclaimer") and any redistribution must be conditioned upon
20193323Sed *    including a substantially similar Disclaimer requirement for further
21193323Sed *    binary redistribution.
22193323Sed * 3. Neither the names of the above-listed copyright holders nor the names
23193323Sed *    of any contributors may be used to endorse or promote products derived
24193323Sed *    from this software without specific prior written permission.
25193323Sed *
26198892Srdivacky * Alternatively, this software may be distributed under the terms of the
27193323Sed * GNU General Public License ("GPL") version 2 as published by the Free
28193323Sed * Software Foundation.
29193323Sed *
30198090Srdivacky * NO WARRANTY
31193323Sed * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32193323Sed * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33198090Srdivacky * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34193323Sed * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35193323Sed * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36193323Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37193323Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38193323Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39193323Sed * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40193323Sed * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41193323Sed * POSSIBILITY OF SUCH DAMAGES.
42193323Sed */
43193323Sed
44193323Sed#define __RSLIST_C__
45193323Sed
46193323Sed#include <contrib/dev/acpica/include/acpi.h>
47193323Sed#include <contrib/dev/acpica/include/accommon.h>
48193323Sed#include <contrib/dev/acpica/include/acresrc.h>
49193323Sed
50193323Sed#define _COMPONENT          ACPI_RESOURCES
51193323Sed        ACPI_MODULE_NAME    ("rslist")
52193323Sed
53193323Sed
54193323Sed/*******************************************************************************
55193323Sed *
56193323Sed * FUNCTION:    AcpiRsConvertAmlToResources
57193323Sed *
58198892Srdivacky * PARAMETERS:  ACPI_WALK_AML_CALLBACK
59193323Sed *              ResourcePtr             - Pointer to the buffer that will
60193323Sed *                                        contain the output structures
61193323Sed *
62193323Sed * RETURN:      Status
63193323Sed *
64193323Sed * DESCRIPTION: Convert an AML resource to an internal representation of the
65193323Sed *              resource that is aligned and easier to access.
66193323Sed *
67193323Sed ******************************************************************************/
68193323Sed
69193323SedACPI_STATUS
70193323SedAcpiRsConvertAmlToResources (
71193323Sed    UINT8                   *Aml,
72193323Sed    UINT32                  Length,
73193323Sed    UINT32                  Offset,
74193323Sed    UINT8                   ResourceIndex,
75193323Sed    void                    *Context)
76193323Sed{
77193323Sed    ACPI_RESOURCE           **ResourcePtr = ACPI_CAST_INDIRECT_PTR (
78193323Sed                                ACPI_RESOURCE, Context);
79193323Sed    ACPI_RESOURCE           *Resource;
80193323Sed    AML_RESOURCE            *AmlResource;
81193323Sed    ACPI_RSCONVERT_INFO     *ConversionTable;
82193323Sed    ACPI_STATUS             Status;
83193323Sed
84193323Sed
85193323Sed    ACPI_FUNCTION_TRACE (RsConvertAmlToResources);
86198892Srdivacky
87193323Sed
88193323Sed    /*
89193323Sed     * Check that the input buffer and all subsequent pointers into it
90193323Sed     * are aligned on a native word boundary. Most important on IA64
91193323Sed     */
92193323Sed    Resource = *ResourcePtr;
93193323Sed    if (ACPI_IS_MISALIGNED (Resource))
94193323Sed    {
95193323Sed        ACPI_WARNING ((AE_INFO,
96193323Sed            "Misaligned resource pointer %p", Resource));
97193323Sed    }
98193323Sed
99193323Sed    /* Get the appropriate conversion info table */
100193323Sed
101193323Sed    AmlResource = ACPI_CAST_PTR (AML_RESOURCE, Aml);
102193323Sed    if (AcpiUtGetResourceType (Aml) == ACPI_RESOURCE_NAME_SERIAL_BUS)
103193323Sed    {
104193323Sed        if (AmlResource->CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE)
105193323Sed        {
106193323Sed            ConversionTable = NULL;
107193323Sed        }
108193323Sed        else
109193323Sed        {
110193323Sed            /* This is an I2C, SPI, or UART SerialBus descriptor */
111193323Sed
112193323Sed            ConversionTable =
113193323Sed                AcpiGbl_ConvertResourceSerialBusDispatch[
114193323Sed                    AmlResource->CommonSerialBus.Type];
115193323Sed        }
116193323Sed    }
117193323Sed    else
118193323Sed    {
119193323Sed        ConversionTable =
120193323Sed            AcpiGbl_GetResourceDispatch[ResourceIndex];
121193323Sed    }
122193323Sed
123193323Sed    if (!ConversionTable)
124193323Sed    {
125193323Sed        ACPI_ERROR ((AE_INFO,
126193323Sed            "Invalid/unsupported resource descriptor: Type 0x%2.2X",
127193323Sed            ResourceIndex));
128193323Sed        return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
129193323Sed    }
130193323Sed
131193323Sed     /* Convert the AML byte stream resource to a local resource struct */
132193323Sed
133193323Sed    Status = AcpiRsConvertAmlToResource (
134193323Sed        Resource, AmlResource, ConversionTable);
135193323Sed    if (ACPI_FAILURE (Status))
136193323Sed    {
137193323Sed        ACPI_EXCEPTION ((AE_INFO, Status,
138193323Sed            "Could not convert AML resource (Type 0x%X)", *Aml));
139194178Sed        return_ACPI_STATUS (Status);
140194178Sed    }
141194178Sed
142194178Sed    ACPI_DEBUG_PRINT ((ACPI_DB_RESOURCES,
143194178Sed        "Type %.2X, AmlLength %.2X InternalLength %.2X\n",
144193323Sed        AcpiUtGetResourceType (Aml), Length,
145193323Sed        Resource->Length));
146193323Sed
147193323Sed    /* Point to the next structure in the output buffer */
148194178Sed
149193323Sed    *ResourcePtr = ACPI_NEXT_RESOURCE (Resource);
150193323Sed    return_ACPI_STATUS (AE_OK);
151193323Sed}
152193323Sed
153193323Sed
154193323Sed/*******************************************************************************
155193323Sed *
156193323Sed * FUNCTION:    AcpiRsConvertResourcesToAml
157193323Sed *
158193323Sed * PARAMETERS:  Resource            - Pointer to the resource linked list
159193323Sed *              AmlSizeNeeded       - Calculated size of the byte stream
160193323Sed *                                    needed from calling AcpiRsGetAmlLength()
161193323Sed *                                    The size of the OutputBuffer is
162193323Sed *                                    guaranteed to be >= AmlSizeNeeded
163193323Sed *              OutputBuffer        - Pointer to the buffer that will
164193323Sed *                                    contain the byte stream
165193323Sed *
166193323Sed * RETURN:      Status
167193323Sed *
168193323Sed * DESCRIPTION: Takes the resource linked list and parses it, creating a
169193323Sed *              byte stream of resources in the caller's output buffer
170193323Sed *
171193323Sed ******************************************************************************/
172193323Sed
173193323SedACPI_STATUS
174193323SedAcpiRsConvertResourcesToAml (
175193323Sed    ACPI_RESOURCE           *Resource,
176193323Sed    ACPI_SIZE               AmlSizeNeeded,
177193323Sed    UINT8                   *OutputBuffer)
178193323Sed{
179193323Sed    UINT8                   *Aml = OutputBuffer;
180193323Sed    UINT8                   *EndAml = OutputBuffer + AmlSizeNeeded;
181193323Sed    ACPI_RSCONVERT_INFO     *ConversionTable;
182193323Sed    ACPI_STATUS             Status;
183193323Sed
184193323Sed
185193323Sed    ACPI_FUNCTION_TRACE (RsConvertResourcesToAml);
186193323Sed
187193323Sed
188193323Sed    /* Walk the resource descriptor list, convert each descriptor */
189193323Sed
190193323Sed    while (Aml < EndAml)
191193323Sed    {
192193323Sed        /* Validate the (internal) Resource Type */
193193323Sed
194193323Sed        if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
195193323Sed        {
196193323Sed            ACPI_ERROR ((AE_INFO,
197193323Sed                "Invalid descriptor type (0x%X) in resource list",
198193323Sed                Resource->Type));
199193323Sed            return_ACPI_STATUS (AE_BAD_DATA);
200193323Sed        }
201193323Sed
202193323Sed        /* Perform the conversion */
203193323Sed
204193323Sed        if (Resource->Type == ACPI_RESOURCE_TYPE_SERIAL_BUS)
205193323Sed        {
206193323Sed            if (Resource->Data.CommonSerialBus.Type > AML_RESOURCE_MAX_SERIALBUSTYPE)
207193323Sed            {
208193323Sed                ConversionTable = NULL;
209193323Sed            }
210193323Sed            else
211193323Sed            {
212193323Sed                /* This is an I2C, SPI, or UART SerialBus descriptor */
213193323Sed
214193323Sed                ConversionTable = AcpiGbl_ConvertResourceSerialBusDispatch[
215193323Sed                    Resource->Data.CommonSerialBus.Type];
216193323Sed            }
217193323Sed        }
218193323Sed        else
219193323Sed        {
220193323Sed            ConversionTable = AcpiGbl_SetResourceDispatch[Resource->Type];
221193323Sed        }
222193323Sed
223193323Sed        if (!ConversionTable)
224193323Sed        {
225193323Sed            ACPI_ERROR ((AE_INFO,
226193323Sed                "Invalid/unsupported resource descriptor: Type 0x%2.2X",
227193323Sed                Resource->Type));
228193323Sed            return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
229193323Sed        }
230193323Sed
231193323Sed        Status = AcpiRsConvertResourceToAml (Resource,
232193323Sed                ACPI_CAST_PTR (AML_RESOURCE, Aml),
233193323Sed                ConversionTable);
234193323Sed        if (ACPI_FAILURE (Status))
235193323Sed        {
236194178Sed            ACPI_EXCEPTION ((AE_INFO, Status,
237193323Sed                "Could not convert resource (type 0x%X) to AML",
238193323Sed                Resource->Type));
239193323Sed            return_ACPI_STATUS (Status);
240193323Sed        }
241193323Sed
242193323Sed        /* Perform final sanity check on the new AML resource descriptor */
243193323Sed
244193323Sed        Status = AcpiUtValidateResource (
245193323Sed                    ACPI_CAST_PTR (AML_RESOURCE, Aml), NULL);
246193323Sed        if (ACPI_FAILURE (Status))
247199481Srdivacky        {
248193323Sed            return_ACPI_STATUS (Status);
249193323Sed        }
250193323Sed
251193323Sed        /* Check for end-of-list, normal exit */
252193323Sed
253193323Sed        if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
254193323Sed        {
255193323Sed            /* An End Tag indicates the end of the input Resource Template */
256193323Sed
257193323Sed            return_ACPI_STATUS (AE_OK);
258193323Sed        }
259193323Sed
260193323Sed        /*
261193323Sed         * Extract the total length of the new descriptor and set the
262193323Sed         * Aml to point to the next (output) resource descriptor
263193323Sed         */
264193323Sed        Aml += AcpiUtGetDescriptorLength (Aml);
265193323Sed
266193323Sed        /* Point to the next input resource descriptor */
267193323Sed
268193323Sed        Resource = ACPI_NEXT_RESOURCE (Resource);
269193323Sed    }
270193323Sed
271193323Sed    /* Completed buffer, but did not find an EndTag resource descriptor */
272193323Sed
273193323Sed    return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
274193323Sed}
275193323Sed