rsxface.c revision 272444
185587Sobrien/*******************************************************************************
285587Sobrien *
385587Sobrien * Module Name: rsxface - Public interfaces to the resource manager
485587Sobrien *
585587Sobrien ******************************************************************************/
685587Sobrien
785587Sobrien/*
885587Sobrien * Copyright (C) 2000 - 2014, Intel Corp.
985587Sobrien * All rights reserved.
1085587Sobrien *
1185587Sobrien * Redistribution and use in source and binary forms, with or without
1285587Sobrien * modification, are permitted provided that the following conditions
1385587Sobrien * are met:
1485587Sobrien * 1. Redistributions of source code must retain the above copyright
1585587Sobrien *    notice, this list of conditions, and the following disclaimer,
1685587Sobrien *    without modification.
1785587Sobrien * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1885587Sobrien *    substantially similar to the "NO WARRANTY" disclaimer below
1985587Sobrien *    ("Disclaimer") and any redistribution must be conditioned upon
2085587Sobrien *    including a substantially similar Disclaimer requirement for further
2185587Sobrien *    binary redistribution.
2285587Sobrien * 3. Neither the names of the above-listed copyright holders nor the names
2385587Sobrien *    of any contributors may be used to endorse or promote products derived
2485587Sobrien *    from this software without specific prior written permission.
2585587Sobrien *
2685587Sobrien * Alternatively, this software may be distributed under the terms of the
2785587Sobrien * GNU General Public License ("GPL") version 2 as published by the Free
2885587Sobrien * Software Foundation.
2985587Sobrien *
3085587Sobrien * NO WARRANTY
3185587Sobrien * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3285587Sobrien * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3385587Sobrien * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3485587Sobrien * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3585587Sobrien * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36118194Sru * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3785587Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3885587Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3985587Sobrien * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4085587Sobrien * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4185587Sobrien * POSSIBILITY OF SUCH DAMAGES.
4285587Sobrien */
4385587Sobrien
4485587Sobrien#define __RSXFACE_C__
4585587Sobrien#define EXPORT_ACPI_INTERFACES
4685587Sobrien
4785587Sobrien#include <contrib/dev/acpica/include/acpi.h>
4885587Sobrien#include <contrib/dev/acpica/include/accommon.h>
4985587Sobrien#include <contrib/dev/acpica/include/acresrc.h>
5085587Sobrien#include <contrib/dev/acpica/include/acnamesp.h>
5185587Sobrien
5285587Sobrien#define _COMPONENT          ACPI_RESOURCES
5385587Sobrien        ACPI_MODULE_NAME    ("rsxface")
5485587Sobrien
5585587Sobrien/* Local macros for 16,32-bit to 64-bit conversion */
5685587Sobrien
5785587Sobrien#define ACPI_COPY_FIELD(Out, In, Field)  ((Out)->Field = (In)->Field)
5885587Sobrien#define ACPI_COPY_ADDRESS(Out, In)                      \
5985587Sobrien    ACPI_COPY_FIELD(Out, In, ResourceType);              \
6085587Sobrien    ACPI_COPY_FIELD(Out, In, ProducerConsumer);          \
6185587Sobrien    ACPI_COPY_FIELD(Out, In, Decode);                    \
6285587Sobrien    ACPI_COPY_FIELD(Out, In, MinAddressFixed);           \
6385587Sobrien    ACPI_COPY_FIELD(Out, In, MaxAddressFixed);           \
6485587Sobrien    ACPI_COPY_FIELD(Out, In, Info);                      \
6585587Sobrien    ACPI_COPY_FIELD(Out, In, Granularity);               \
6685587Sobrien    ACPI_COPY_FIELD(Out, In, Minimum);                   \
6785587Sobrien    ACPI_COPY_FIELD(Out, In, Maximum);                   \
6885587Sobrien    ACPI_COPY_FIELD(Out, In, TranslationOffset);         \
6985587Sobrien    ACPI_COPY_FIELD(Out, In, AddressLength);             \
7085587Sobrien    ACPI_COPY_FIELD(Out, In, ResourceSource);
7185587Sobrien
7285587Sobrien
7385587Sobrien/* Local prototypes */
7485587Sobrien
7585587Sobrienstatic ACPI_STATUS
7685587SobrienAcpiRsMatchVendorResource (
7785587Sobrien    ACPI_RESOURCE           *Resource,
78107806Sobrien    void                    *Context);
7985587Sobrien
8085587Sobrienstatic ACPI_STATUS
8185587SobrienAcpiRsValidateParameters (
8285587Sobrien    ACPI_HANDLE             DeviceHandle,
8385587Sobrien    ACPI_BUFFER             *Buffer,
8485587Sobrien    ACPI_NAMESPACE_NODE     **ReturnNode);
8585587Sobrien
8685587Sobrien
8785587Sobrien/*******************************************************************************
8885587Sobrien *
8985587Sobrien * FUNCTION:    AcpiRsValidateParameters
9085587Sobrien *
9185587Sobrien * PARAMETERS:  DeviceHandle    - Handle to a device
9285587Sobrien *              Buffer          - Pointer to a data buffer
9385587Sobrien *              ReturnNode      - Pointer to where the device node is returned
9485587Sobrien *
9585587Sobrien * RETURN:      Status
9690902Sdes *
9785587Sobrien * DESCRIPTION: Common parameter validation for resource interfaces
9885587Sobrien *
9985587Sobrien ******************************************************************************/
10085587Sobrien
10185587Sobrienstatic ACPI_STATUS
10285587SobrienAcpiRsValidateParameters (
10385587Sobrien    ACPI_HANDLE             DeviceHandle,
10485587Sobrien    ACPI_BUFFER             *Buffer,
10585587Sobrien    ACPI_NAMESPACE_NODE     **ReturnNode)
10685587Sobrien{
10785587Sobrien    ACPI_STATUS             Status;
10885587Sobrien    ACPI_NAMESPACE_NODE     *Node;
10985587Sobrien
11085587Sobrien
11185587Sobrien    ACPI_FUNCTION_TRACE (RsValidateParameters);
11285587Sobrien
11385587Sobrien
11485587Sobrien    /*
11585587Sobrien     * Must have a valid handle to an ACPI device
11685587Sobrien     */
11785587Sobrien    if (!DeviceHandle)
11885587Sobrien    {
11985587Sobrien        return_ACPI_STATUS (AE_BAD_PARAMETER);
120107806Sobrien    }
12185587Sobrien
12285587Sobrien    Node = AcpiNsValidateHandle (DeviceHandle);
12385587Sobrien    if (!Node)
12485587Sobrien    {
12585587Sobrien        return_ACPI_STATUS (AE_BAD_PARAMETER);
12685587Sobrien    }
12785587Sobrien
12885587Sobrien    if (Node->Type != ACPI_TYPE_DEVICE)
12985587Sobrien    {
13085587Sobrien        return_ACPI_STATUS (AE_TYPE);
13185587Sobrien    }
13285587Sobrien
13385587Sobrien    /*
13485587Sobrien     * Validate the user buffer object
13585587Sobrien     *
13685587Sobrien     * if there is a non-zero buffer length we also need a valid pointer in
13785587Sobrien     * the buffer. If it's a zero buffer length, we'll be returning the
13885587Sobrien     * needed buffer size (later), so keep going.
13985587Sobrien     */
14085587Sobrien    Status = AcpiUtValidateBuffer (Buffer);
14185587Sobrien    if (ACPI_FAILURE (Status))
14285587Sobrien    {
14385587Sobrien        return_ACPI_STATUS (Status);
14485587Sobrien    }
14585587Sobrien
14685587Sobrien    *ReturnNode = Node;
14785587Sobrien    return_ACPI_STATUS (AE_OK);
14885587Sobrien}
14985587Sobrien
15085587Sobrien
15185587Sobrien/*******************************************************************************
15285587Sobrien *
15385587Sobrien * FUNCTION:    AcpiGetIrqRoutingTable
15485587Sobrien *
15585587Sobrien * PARAMETERS:  DeviceHandle    - Handle to the Bus device we are querying
15685587Sobrien *              RetBuffer       - Pointer to a buffer to receive the
15785587Sobrien *                                current resources for the device
15885587Sobrien *
15985587Sobrien * RETURN:      Status
16085587Sobrien *
16185587Sobrien * DESCRIPTION: This function is called to get the IRQ routing table for a
16285587Sobrien *              specific bus. The caller must first acquire a handle for the
16385587Sobrien *              desired bus. The routine table is placed in the buffer pointed
16485587Sobrien *              to by the RetBuffer variable parameter.
16585587Sobrien *
16685587Sobrien *              If the function fails an appropriate status will be returned
16785587Sobrien *              and the value of RetBuffer is undefined.
16885587Sobrien *
16985587Sobrien *              This function attempts to execute the _PRT method contained in
17085587Sobrien *              the object indicated by the passed DeviceHandle.
17185587Sobrien *
17285587Sobrien ******************************************************************************/
17385587Sobrien
17485587SobrienACPI_STATUS
17585587SobrienAcpiGetIrqRoutingTable  (
17685587Sobrien    ACPI_HANDLE             DeviceHandle,
17785587Sobrien    ACPI_BUFFER             *RetBuffer)
17885587Sobrien{
17985587Sobrien    ACPI_STATUS             Status;
18085587Sobrien    ACPI_NAMESPACE_NODE     *Node;
18185587Sobrien
18285587Sobrien
18385587Sobrien    ACPI_FUNCTION_TRACE (AcpiGetIrqRoutingTable);
18485587Sobrien
18585587Sobrien
18685587Sobrien    /* Validate parameters then dispatch to internal routine */
18785587Sobrien
18885587Sobrien    Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
18985587Sobrien    if (ACPI_FAILURE (Status))
19085587Sobrien    {
19185587Sobrien        return_ACPI_STATUS (Status);
19285587Sobrien    }
19385587Sobrien
19485587Sobrien    Status = AcpiRsGetPrtMethodData (Node, RetBuffer);
19585587Sobrien    return_ACPI_STATUS (Status);
19685587Sobrien}
19785587Sobrien
19885587SobrienACPI_EXPORT_SYMBOL (AcpiGetIrqRoutingTable)
19985587Sobrien
20085587Sobrien
20185587Sobrien/*******************************************************************************
20285587Sobrien *
20385587Sobrien * FUNCTION:    AcpiGetCurrentResources
20485587Sobrien *
20585587Sobrien * PARAMETERS:  DeviceHandle    - Handle to the device object for the
20685587Sobrien *                                device we are querying
20785587Sobrien *              RetBuffer       - Pointer to a buffer to receive the
20885587Sobrien *                                current resources for the device
20985587Sobrien *
21085587Sobrien * RETURN:      Status
21185587Sobrien *
21285587Sobrien * DESCRIPTION: This function is called to get the current resources for a
21385587Sobrien *              specific device. The caller must first acquire a handle for
21485587Sobrien *              the desired device. The resource data is placed in the buffer
21585587Sobrien *              pointed to by the RetBuffer variable parameter.
21685587Sobrien *
21785587Sobrien *              If the function fails an appropriate status will be returned
21885587Sobrien *              and the value of RetBuffer is undefined.
21985587Sobrien *
22085587Sobrien *              This function attempts to execute the _CRS method contained in
22185587Sobrien *              the object indicated by the passed DeviceHandle.
22285587Sobrien *
22385587Sobrien ******************************************************************************/
22485587Sobrien
22585587SobrienACPI_STATUS
22685587SobrienAcpiGetCurrentResources (
22785587Sobrien    ACPI_HANDLE             DeviceHandle,
22885587Sobrien    ACPI_BUFFER             *RetBuffer)
22985587Sobrien{
23085587Sobrien    ACPI_STATUS             Status;
23185587Sobrien    ACPI_NAMESPACE_NODE     *Node;
23285587Sobrien
23385587Sobrien
23485587Sobrien    ACPI_FUNCTION_TRACE (AcpiGetCurrentResources);
23585587Sobrien
23685587Sobrien
23785587Sobrien    /* Validate parameters then dispatch to internal routine */
23885587Sobrien
23985587Sobrien    Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
24085587Sobrien    if (ACPI_FAILURE (Status))
24185587Sobrien    {
24285587Sobrien        return_ACPI_STATUS (Status);
24385587Sobrien    }
24485587Sobrien
24585587Sobrien    Status = AcpiRsGetCrsMethodData (Node, RetBuffer);
24685587Sobrien    return_ACPI_STATUS (Status);
24785587Sobrien}
24885587Sobrien
24985587SobrienACPI_EXPORT_SYMBOL (AcpiGetCurrentResources)
25085587Sobrien
25185587Sobrien
25285587Sobrien/*******************************************************************************
25385587Sobrien *
25485587Sobrien * FUNCTION:    AcpiGetPossibleResources
25585587Sobrien *
25685587Sobrien * PARAMETERS:  DeviceHandle    - Handle to the device object for the
25785587Sobrien *                                device we are querying
25885587Sobrien *              RetBuffer       - Pointer to a buffer to receive the
25985587Sobrien *                                resources for the device
26085587Sobrien *
26185587Sobrien * RETURN:      Status
26285587Sobrien *
26385587Sobrien * DESCRIPTION: This function is called to get a list of the possible resources
26485587Sobrien *              for a specific device. The caller must first acquire a handle
26585587Sobrien *              for the desired device. The resource data is placed in the
26685587Sobrien *              buffer pointed to by the RetBuffer variable.
26785587Sobrien *
26885587Sobrien *              If the function fails an appropriate status will be returned
26985587Sobrien *              and the value of RetBuffer is undefined.
27085587Sobrien *
27185587Sobrien ******************************************************************************/
27285587Sobrien
27385587SobrienACPI_STATUS
27485587SobrienAcpiGetPossibleResources (
27585587Sobrien    ACPI_HANDLE             DeviceHandle,
27685587Sobrien    ACPI_BUFFER             *RetBuffer)
27785587Sobrien{
27885587Sobrien    ACPI_STATUS             Status;
27985587Sobrien    ACPI_NAMESPACE_NODE     *Node;
28085587Sobrien
28185587Sobrien
28285587Sobrien    ACPI_FUNCTION_TRACE (AcpiGetPossibleResources);
28385587Sobrien
28485587Sobrien
285107806Sobrien    /* Validate parameters then dispatch to internal routine */
286107806Sobrien
28785587Sobrien    Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
28885587Sobrien    if (ACPI_FAILURE (Status))
28985587Sobrien    {
29085587Sobrien        return_ACPI_STATUS (Status);
29185587Sobrien    }
29285587Sobrien
29385587Sobrien    Status = AcpiRsGetPrsMethodData (Node, RetBuffer);
29485587Sobrien    return_ACPI_STATUS (Status);
29585587Sobrien}
29685587Sobrien
29785587SobrienACPI_EXPORT_SYMBOL (AcpiGetPossibleResources)
29885587Sobrien
29985587Sobrien
30085587Sobrien/*******************************************************************************
30185587Sobrien *
30285587Sobrien * FUNCTION:    AcpiSetCurrentResources
30385587Sobrien *
30485587Sobrien * PARAMETERS:  DeviceHandle    - Handle to the device object for the
30585587Sobrien *                                device we are setting resources
306118194Sru *              InBuffer        - Pointer to a buffer containing the
30785587Sobrien *                                resources to be set for the device
30885587Sobrien *
30985587Sobrien * RETURN:      Status
31085587Sobrien *
311118194Sru * DESCRIPTION: This function is called to set the current resources for a
31285587Sobrien *              specific device. The caller must first acquire a handle for
31385587Sobrien *              the desired device. The resource data is passed to the routine
314118194Sru *              the buffer pointed to by the InBuffer variable.
31585587Sobrien *
31685587Sobrien ******************************************************************************/
31785587Sobrien
31885587SobrienACPI_STATUS
31985587SobrienAcpiSetCurrentResources (
32085587Sobrien    ACPI_HANDLE             DeviceHandle,
32185587Sobrien    ACPI_BUFFER             *InBuffer)
32285587Sobrien{
32385587Sobrien    ACPI_STATUS             Status;
32485587Sobrien    ACPI_NAMESPACE_NODE     *Node;
32585587Sobrien
32685587Sobrien
32785587Sobrien    ACPI_FUNCTION_TRACE (AcpiSetCurrentResources);
32885587Sobrien
32985587Sobrien
33085587Sobrien    /* Validate the buffer, don't allow zero length */
331107806Sobrien
33285587Sobrien    if ((!InBuffer) ||
33385587Sobrien        (!InBuffer->Pointer) ||
33485587Sobrien        (!InBuffer->Length))
33585587Sobrien    {
33685587Sobrien        return_ACPI_STATUS (AE_BAD_PARAMETER);
33785587Sobrien    }
33885587Sobrien
33985587Sobrien    /* Validate parameters then dispatch to internal routine */
34085587Sobrien
34185587Sobrien    Status = AcpiRsValidateParameters (DeviceHandle, InBuffer, &Node);
34285587Sobrien    if (ACPI_FAILURE (Status))
34385587Sobrien    {
34485587Sobrien        return_ACPI_STATUS (Status);
34585587Sobrien    }
34685587Sobrien
34785587Sobrien    Status = AcpiRsSetSrsMethodData (Node, InBuffer);
34885587Sobrien    return_ACPI_STATUS (Status);
34985587Sobrien}
35085587Sobrien
35185587SobrienACPI_EXPORT_SYMBOL (AcpiSetCurrentResources)
35285587Sobrien
35385587Sobrien
35485587Sobrien/*******************************************************************************
35585587Sobrien *
35685587Sobrien * FUNCTION:    AcpiGetEventResources
35785587Sobrien *
35885587Sobrien * PARAMETERS:  DeviceHandle    - Handle to the device object for the
35985587Sobrien *                                device we are getting resources
36085587Sobrien *              InBuffer        - Pointer to a buffer containing the
36185587Sobrien *                                resources to be set for the device
36285587Sobrien *
36385587Sobrien * RETURN:      Status
36485587Sobrien *
36585587Sobrien * DESCRIPTION: This function is called to get the event resources for a
36685587Sobrien *              specific device. The caller must first acquire a handle for
36785587Sobrien *              the desired device. The resource data is passed to the routine
36885587Sobrien *              the buffer pointed to by the InBuffer variable. Uses the
36985587Sobrien *              _AEI method.
37085587Sobrien *
37185587Sobrien ******************************************************************************/
37285587Sobrien
37385587SobrienACPI_STATUS
37485587SobrienAcpiGetEventResources (
37585587Sobrien    ACPI_HANDLE             DeviceHandle,
37685587Sobrien    ACPI_BUFFER             *RetBuffer)
37785587Sobrien{
37885587Sobrien    ACPI_STATUS             Status;
37985587Sobrien    ACPI_NAMESPACE_NODE     *Node;
38085587Sobrien
38185587Sobrien
38285587Sobrien    ACPI_FUNCTION_TRACE (AcpiGetEventResources);
38385587Sobrien
38485587Sobrien
38585587Sobrien    /* Validate parameters then dispatch to internal routine */
38685587Sobrien
38785587Sobrien    Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
38885587Sobrien    if (ACPI_FAILURE (Status))
38985587Sobrien    {
39085587Sobrien        return_ACPI_STATUS (Status);
39185587Sobrien    }
39285587Sobrien
39385587Sobrien    Status = AcpiRsGetAeiMethodData (Node, RetBuffer);
39485587Sobrien    return_ACPI_STATUS (Status);
39585587Sobrien}
39685587Sobrien
39785587SobrienACPI_EXPORT_SYMBOL (AcpiGetEventResources)
39885587Sobrien
39985587Sobrien
40085587Sobrien/******************************************************************************
40185587Sobrien *
40285587Sobrien * FUNCTION:    AcpiResourceToAddress64
40385587Sobrien *
40485587Sobrien * PARAMETERS:  Resource        - Pointer to a resource
40585587Sobrien *              Out             - Pointer to the users's return buffer
40685587Sobrien *                                (a struct acpi_resource_address64)
40785587Sobrien *
40885587Sobrien * RETURN:      Status
40985587Sobrien *
41085587Sobrien * DESCRIPTION: If the resource is an address16, address32, or address64,
41185587Sobrien *              copy it to the address64 return buffer. This saves the
41285587Sobrien *              caller from having to duplicate code for different-sized
41385587Sobrien *              addresses.
41485587Sobrien *
41585587Sobrien ******************************************************************************/
41685587Sobrien
41785587SobrienACPI_STATUS
41885587SobrienAcpiResourceToAddress64 (
41985587Sobrien    ACPI_RESOURCE               *Resource,
42085587Sobrien    ACPI_RESOURCE_ADDRESS64     *Out)
42185587Sobrien{
42285587Sobrien    ACPI_RESOURCE_ADDRESS16     *Address16;
42385587Sobrien    ACPI_RESOURCE_ADDRESS32     *Address32;
42485587Sobrien
42585587Sobrien
42685587Sobrien    if (!Resource || !Out)
42785587Sobrien    {
42885587Sobrien        return (AE_BAD_PARAMETER);
42985587Sobrien    }
43085587Sobrien
43185587Sobrien    /* Convert 16 or 32 address descriptor to 64 */
43285587Sobrien
43385587Sobrien    switch (Resource->Type)
43485587Sobrien    {
43585587Sobrien    case ACPI_RESOURCE_TYPE_ADDRESS16:
43685587Sobrien
43785587Sobrien        Address16 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS16, &Resource->Data);
43885587Sobrien        ACPI_COPY_ADDRESS (Out, Address16);
43985587Sobrien        break;
44085587Sobrien
44185587Sobrien    case ACPI_RESOURCE_TYPE_ADDRESS32:
44285587Sobrien
44385587Sobrien        Address32 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS32, &Resource->Data);
44485587Sobrien        ACPI_COPY_ADDRESS (Out, Address32);
44585587Sobrien        break;
44685587Sobrien
44785587Sobrien    case ACPI_RESOURCE_TYPE_ADDRESS64:
44885587Sobrien
449107806Sobrien        /* Simple copy for 64 bit source */
45085587Sobrien
45185587Sobrien        ACPI_MEMCPY (Out, &Resource->Data, sizeof (ACPI_RESOURCE_ADDRESS64));
45285587Sobrien        break;
45385587Sobrien
45485587Sobrien    default:
45585587Sobrien
45685587Sobrien        return (AE_BAD_PARAMETER);
45785587Sobrien    }
45885587Sobrien
459107806Sobrien    return (AE_OK);
46085587Sobrien}
46185587Sobrien
46285587SobrienACPI_EXPORT_SYMBOL (AcpiResourceToAddress64)
46385587Sobrien
46485587Sobrien
46585587Sobrien/*******************************************************************************
46685587Sobrien *
46785587Sobrien * FUNCTION:    AcpiGetVendorResource
46885587Sobrien *
46985587Sobrien * PARAMETERS:  DeviceHandle    - Handle for the parent device object
47085587Sobrien *              Name            - Method name for the parent resource
47185587Sobrien *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
47285587Sobrien *              Uuid            - Pointer to the UUID to be matched.
47385587Sobrien *                                includes both subtype and 16-byte UUID
47485587Sobrien *              RetBuffer       - Where the vendor resource is returned
47585587Sobrien *
47685587Sobrien * RETURN:      Status
47785587Sobrien *
478107806Sobrien * DESCRIPTION: Walk a resource template for the specified device to find a
47985587Sobrien *              vendor-defined resource that matches the supplied UUID and
48085587Sobrien *              UUID subtype. Returns a ACPI_RESOURCE of type Vendor.
48185587Sobrien *
48285587Sobrien ******************************************************************************/
48385587Sobrien
48485587SobrienACPI_STATUS
48585587SobrienAcpiGetVendorResource (
48685587Sobrien    ACPI_HANDLE             DeviceHandle,
48785587Sobrien    char                    *Name,
48885587Sobrien    ACPI_VENDOR_UUID        *Uuid,
48985587Sobrien    ACPI_BUFFER             *RetBuffer)
49085587Sobrien{
49185587Sobrien    ACPI_VENDOR_WALK_INFO   Info;
49285587Sobrien    ACPI_STATUS             Status;
49385587Sobrien
49485587Sobrien
49585587Sobrien    /* Other parameters are validated by AcpiWalkResources */
49685587Sobrien
49785587Sobrien    if (!Uuid || !RetBuffer)
49885587Sobrien    {
49985587Sobrien        return (AE_BAD_PARAMETER);
50085587Sobrien    }
50185587Sobrien
50285587Sobrien    Info.Uuid = Uuid;
50385587Sobrien    Info.Buffer = RetBuffer;
50485587Sobrien    Info.Status = AE_NOT_EXIST;
50585587Sobrien
50685587Sobrien    /* Walk the _CRS or _PRS resource list for this device */
50785587Sobrien
50885587Sobrien    Status = AcpiWalkResources (DeviceHandle, Name, AcpiRsMatchVendorResource,
50985587Sobrien                &Info);
51085587Sobrien    if (ACPI_FAILURE (Status))
51185587Sobrien    {
51285587Sobrien        return (Status);
51385587Sobrien    }
51485587Sobrien
51585587Sobrien    return (Info.Status);
51685587Sobrien}
51785587Sobrien
51885587SobrienACPI_EXPORT_SYMBOL (AcpiGetVendorResource)
51985587Sobrien
52085587Sobrien
52185587Sobrien/*******************************************************************************
52285587Sobrien *
52385587Sobrien * FUNCTION:    AcpiRsMatchVendorResource
52485587Sobrien *
52585587Sobrien * PARAMETERS:  ACPI_WALK_RESOURCE_CALLBACK
52685587Sobrien *
52785587Sobrien * RETURN:      Status
52885587Sobrien *
52985587Sobrien * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
53085587Sobrien *
531107806Sobrien ******************************************************************************/
53285587Sobrien
53385587Sobrienstatic ACPI_STATUS
53485587SobrienAcpiRsMatchVendorResource (
53585587Sobrien    ACPI_RESOURCE           *Resource,
53685587Sobrien    void                    *Context)
53785587Sobrien{
53885587Sobrien    ACPI_VENDOR_WALK_INFO       *Info = Context;
53985587Sobrien    ACPI_RESOURCE_VENDOR_TYPED  *Vendor;
54085587Sobrien    ACPI_BUFFER                 *Buffer;
54185587Sobrien    ACPI_STATUS                 Status;
54285587Sobrien
54385587Sobrien
54485587Sobrien    /* Ignore all descriptors except Vendor */
54585587Sobrien
54685587Sobrien    if (Resource->Type != ACPI_RESOURCE_TYPE_VENDOR)
54785587Sobrien    {
54885587Sobrien        return (AE_OK);
54985587Sobrien    }
55085587Sobrien
55185587Sobrien    Vendor = &Resource->Data.VendorTyped;
55285587Sobrien
55385587Sobrien    /*
55485587Sobrien     * For a valid match, these conditions must hold:
55585587Sobrien     *
55685587Sobrien     * 1) Length of descriptor data must be at least as long as a UUID struct
55785587Sobrien     * 2) The UUID subtypes must match
55885587Sobrien     * 3) The UUID data must match
55985587Sobrien     */
56085587Sobrien    if ((Vendor->ByteLength < (ACPI_UUID_LENGTH + 1)) ||
56185587Sobrien        (Vendor->UuidSubtype != Info->Uuid->Subtype)  ||
56285587Sobrien        (ACPI_MEMCMP (Vendor->Uuid, Info->Uuid->Data, ACPI_UUID_LENGTH)))
56385587Sobrien    {
56485587Sobrien        return (AE_OK);
56585587Sobrien    }
56685587Sobrien
56785587Sobrien    /* Validate/Allocate/Clear caller buffer */
56885587Sobrien
56985587Sobrien    Buffer = Info->Buffer;
57085587Sobrien    Status = AcpiUtInitializeBuffer (Buffer, Resource->Length);
57185587Sobrien    if (ACPI_FAILURE (Status))
57285587Sobrien    {
57385587Sobrien        return (Status);
57485587Sobrien    }
57585587Sobrien
57685587Sobrien    /* Found the correct resource, copy and return it */
57785587Sobrien
57885587Sobrien    ACPI_MEMCPY (Buffer->Pointer, Resource, Resource->Length);
57985587Sobrien    Buffer->Length = Resource->Length;
58085587Sobrien
58185587Sobrien    /* Found the desired descriptor, terminate resource walk */
58285587Sobrien
583107806Sobrien    Info->Status = AE_OK;
58485587Sobrien    return (AE_CTRL_TERMINATE);
58585587Sobrien}
58685587Sobrien
58785587Sobrien
58885587Sobrien/*******************************************************************************
58985587Sobrien *
590107806Sobrien * FUNCTION:    AcpiWalkResourceBuffer
59185587Sobrien *
592107806Sobrien * PARAMETERS:  Buffer          - Formatted buffer returned by one of the
593107806Sobrien *                                various Get*Resource functions
59485587Sobrien *              UserFunction    - Called for each resource
59585587Sobrien *              Context         - Passed to UserFunction
59685587Sobrien *
59785587Sobrien * RETURN:      Status
59885587Sobrien *
59985587Sobrien * DESCRIPTION: Walks the input resource template. The UserFunction is called
60085587Sobrien *              once for each resource in the list.
60185587Sobrien *
60285587Sobrien ******************************************************************************/
60385587Sobrien
60485587SobrienACPI_STATUS
60585587SobrienAcpiWalkResourceBuffer (
60685587Sobrien    ACPI_BUFFER                 *Buffer,
60785587Sobrien    ACPI_WALK_RESOURCE_CALLBACK UserFunction,
60885587Sobrien    void                        *Context)
60985587Sobrien{
61085587Sobrien    ACPI_STATUS                 Status = AE_OK;
61185587Sobrien    ACPI_RESOURCE               *Resource;
61285587Sobrien    ACPI_RESOURCE               *ResourceEnd;
61385587Sobrien
61485587Sobrien
61585587Sobrien    ACPI_FUNCTION_TRACE (AcpiWalkResourceBuffer);
61685587Sobrien
61785587Sobrien
61885587Sobrien    /* Parameter validation */
61985587Sobrien
62085587Sobrien    if (!Buffer || !Buffer->Pointer || !UserFunction)
62185587Sobrien    {
62285587Sobrien        return_ACPI_STATUS (AE_BAD_PARAMETER);
62385587Sobrien    }
62485587Sobrien
62585587Sobrien    /* Buffer contains the resource list and length */
62685587Sobrien
62785587Sobrien    Resource = ACPI_CAST_PTR (ACPI_RESOURCE, Buffer->Pointer);
62885587Sobrien    ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Buffer->Pointer, Buffer->Length);
62985587Sobrien
63085587Sobrien    /* Walk the resource list until the EndTag is found (or buffer end) */
63185587Sobrien
63285587Sobrien    while (Resource < ResourceEnd)
63385587Sobrien    {
63485587Sobrien        /* Sanity check the resource type */
63585587Sobrien
63685587Sobrien        if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
63785587Sobrien        {
63885587Sobrien            Status = AE_AML_INVALID_RESOURCE_TYPE;
63985587Sobrien            break;
64085587Sobrien        }
64185587Sobrien
64285587Sobrien        /* Sanity check the length. It must not be zero, or we loop forever */
64385587Sobrien
64485587Sobrien        if (!Resource->Length)
64585587Sobrien        {
64685587Sobrien            return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
64785587Sobrien        }
64885587Sobrien
64985587Sobrien        /* Invoke the user function, abort on any error returned */
65085587Sobrien
65185587Sobrien        Status = UserFunction (Resource, Context);
65285587Sobrien        if (ACPI_FAILURE (Status))
65385587Sobrien        {
65485587Sobrien            if (Status == AE_CTRL_TERMINATE)
65585587Sobrien            {
65685587Sobrien                /* This is an OK termination by the user function */
65785587Sobrien
65885587Sobrien                Status = AE_OK;
65985587Sobrien            }
66085587Sobrien            break;
66185587Sobrien        }
66285587Sobrien
66385587Sobrien        /* EndTag indicates end-of-list */
66485587Sobrien
66585587Sobrien        if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
66685587Sobrien        {
66785587Sobrien            break;
66885587Sobrien        }
66985587Sobrien
67085587Sobrien        /* Get the next resource descriptor */
67185587Sobrien
67285587Sobrien        Resource = ACPI_NEXT_RESOURCE (Resource);
67385587Sobrien    }
67485587Sobrien
67585587Sobrien    return_ACPI_STATUS (Status);
67685587Sobrien}
67785587Sobrien
67885587SobrienACPI_EXPORT_SYMBOL (AcpiWalkResourceBuffer)
67985587Sobrien
68085587Sobrien
68185587Sobrien/*******************************************************************************
68285587Sobrien *
68385587Sobrien * FUNCTION:    AcpiWalkResources
68485587Sobrien *
68585587Sobrien * PARAMETERS:  DeviceHandle    - Handle to the device object for the
68685587Sobrien *                                device we are querying
68785587Sobrien *              Name            - Method name of the resources we want.
68890902Sdes *                                (METHOD_NAME__CRS, METHOD_NAME__PRS, or
68990902Sdes *                                METHOD_NAME__AEI)
69090902Sdes *              UserFunction    - Called for each resource
69190902Sdes *              Context         - Passed to UserFunction
69290902Sdes *
69390902Sdes * RETURN:      Status
69490902Sdes *
69590902Sdes * DESCRIPTION: Retrieves the current or possible resource list for the
69690902Sdes *              specified device. The UserFunction is called once for
69790902Sdes *              each resource in the list.
698112336Sobrien *
699112336Sobrien ******************************************************************************/
700112336Sobrien
701112336SobrienACPI_STATUS
702112336SobrienAcpiWalkResources (
703118194Sru    ACPI_HANDLE                 DeviceHandle,
704118194Sru    char                        *Name,
705118194Sru    ACPI_WALK_RESOURCE_CALLBACK UserFunction,
706112336Sobrien    void                        *Context)
707112336Sobrien{
708112336Sobrien    ACPI_STATUS                 Status;
709112336Sobrien    ACPI_BUFFER                 Buffer;
710118194Sru
711112336Sobrien
712112336Sobrien    ACPI_FUNCTION_TRACE (AcpiWalkResources);
713112336Sobrien
714112336Sobrien
715112336Sobrien    /* Parameter validation */
716112336Sobrien
71790902Sdes    if (!DeviceHandle || !UserFunction || !Name ||
71890902Sdes        (!ACPI_COMPARE_NAME (Name, METHOD_NAME__CRS) &&
71990902Sdes         !ACPI_COMPARE_NAME (Name, METHOD_NAME__PRS) &&
720112336Sobrien         !ACPI_COMPARE_NAME (Name, METHOD_NAME__AEI)))
72190902Sdes    {
722112336Sobrien        return_ACPI_STATUS (AE_BAD_PARAMETER);
723112336Sobrien    }
724112336Sobrien
725112336Sobrien    /* Get the _CRS/_PRS/_AEI resource list */
726112336Sobrien
727112336Sobrien    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
728112336Sobrien    Status = AcpiRsGetMethodData (DeviceHandle, Name, &Buffer);
729112336Sobrien    if (ACPI_FAILURE (Status))
730112336Sobrien    {
731112336Sobrien        return_ACPI_STATUS (Status);
732112336Sobrien    }
733112336Sobrien
73490902Sdes    /* Walk the resource list and cleanup */
73590902Sdes
73690902Sdes    Status = AcpiWalkResourceBuffer (&Buffer, UserFunction, Context);
73790902Sdes    ACPI_FREE (Buffer.Pointer);
73885587Sobrien    return_ACPI_STATUS (Status);
73985587Sobrien}
74085587Sobrien
74185587SobrienACPI_EXPORT_SYMBOL (AcpiWalkResources)
74285587Sobrien