167754Smsmith/*******************************************************************************
267754Smsmith *
377424Smsmith * Module Name: rsxface - Public interfaces to the resource manager
467754Smsmith *
567754Smsmith ******************************************************************************/
667754Smsmith
7217365Sjkim/*
8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2567754Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2967754Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4367754Smsmith
44272444Sjkim#define EXPORT_ACPI_INTERFACES
4567754Smsmith
46193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
47193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
48193341Sjkim#include <contrib/dev/acpica/include/acresrc.h>
49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
5067754Smsmith
5177424Smsmith#define _COMPONENT          ACPI_RESOURCES
5291116Smsmith        ACPI_MODULE_NAME    ("rsxface")
5367754Smsmith
54151937Sjkim/* Local macros for 16,32-bit to 64-bit conversion */
5567754Smsmith
56151937Sjkim#define ACPI_COPY_FIELD(Out, In, Field)  ((Out)->Field = (In)->Field)
57298714Sjkim#define ACPI_COPY_ADDRESS(Out, In)                       \
58151937Sjkim    ACPI_COPY_FIELD(Out, In, ResourceType);              \
59151937Sjkim    ACPI_COPY_FIELD(Out, In, ProducerConsumer);          \
60151937Sjkim    ACPI_COPY_FIELD(Out, In, Decode);                    \
61151937Sjkim    ACPI_COPY_FIELD(Out, In, MinAddressFixed);           \
62151937Sjkim    ACPI_COPY_FIELD(Out, In, MaxAddressFixed);           \
63151937Sjkim    ACPI_COPY_FIELD(Out, In, Info);                      \
64281396Sjkim    ACPI_COPY_FIELD(Out, In, Address.Granularity);       \
65281396Sjkim    ACPI_COPY_FIELD(Out, In, Address.Minimum);           \
66281396Sjkim    ACPI_COPY_FIELD(Out, In, Address.Maximum);           \
67281396Sjkim    ACPI_COPY_FIELD(Out, In, Address.TranslationOffset); \
68281396Sjkim    ACPI_COPY_FIELD(Out, In, Address.AddressLength);     \
69151937Sjkim    ACPI_COPY_FIELD(Out, In, ResourceSource);
70151937Sjkim
71151937Sjkim
72167802Sjkim/* Local prototypes */
73167802Sjkim
74167802Sjkimstatic ACPI_STATUS
75167802SjkimAcpiRsMatchVendorResource (
76167802Sjkim    ACPI_RESOURCE           *Resource,
77167802Sjkim    void                    *Context);
78167802Sjkim
79167802Sjkimstatic ACPI_STATUS
80167802SjkimAcpiRsValidateParameters (
81167802Sjkim    ACPI_HANDLE             DeviceHandle,
82167802Sjkim    ACPI_BUFFER             *Buffer,
83167802Sjkim    ACPI_NAMESPACE_NODE     **ReturnNode);
84167802Sjkim
85167802Sjkim
8667754Smsmith/*******************************************************************************
8767754Smsmith *
88167802Sjkim * FUNCTION:    AcpiRsValidateParameters
89167802Sjkim *
90167802Sjkim * PARAMETERS:  DeviceHandle    - Handle to a device
91167802Sjkim *              Buffer          - Pointer to a data buffer
92167802Sjkim *              ReturnNode      - Pointer to where the device node is returned
93167802Sjkim *
94167802Sjkim * RETURN:      Status
95167802Sjkim *
96167802Sjkim * DESCRIPTION: Common parameter validation for resource interfaces
97167802Sjkim *
98167802Sjkim ******************************************************************************/
99167802Sjkim
100167802Sjkimstatic ACPI_STATUS
101167802SjkimAcpiRsValidateParameters (
102167802Sjkim    ACPI_HANDLE             DeviceHandle,
103167802Sjkim    ACPI_BUFFER             *Buffer,
104167802Sjkim    ACPI_NAMESPACE_NODE     **ReturnNode)
105167802Sjkim{
106167802Sjkim    ACPI_STATUS             Status;
107167802Sjkim    ACPI_NAMESPACE_NODE     *Node;
108167802Sjkim
109167802Sjkim
110167802Sjkim    ACPI_FUNCTION_TRACE (RsValidateParameters);
111167802Sjkim
112167802Sjkim
113167802Sjkim    /*
114167802Sjkim     * Must have a valid handle to an ACPI device
115167802Sjkim     */
116167802Sjkim    if (!DeviceHandle)
117167802Sjkim    {
118167802Sjkim        return_ACPI_STATUS (AE_BAD_PARAMETER);
119167802Sjkim    }
120167802Sjkim
121200553Sjkim    Node = AcpiNsValidateHandle (DeviceHandle);
122167802Sjkim    if (!Node)
123167802Sjkim    {
124167802Sjkim        return_ACPI_STATUS (AE_BAD_PARAMETER);
125167802Sjkim    }
126167802Sjkim
127167802Sjkim    if (Node->Type != ACPI_TYPE_DEVICE)
128167802Sjkim    {
129167802Sjkim        return_ACPI_STATUS (AE_TYPE);
130167802Sjkim    }
131167802Sjkim
132167802Sjkim    /*
133167802Sjkim     * Validate the user buffer object
134167802Sjkim     *
135167802Sjkim     * if there is a non-zero buffer length we also need a valid pointer in
136167802Sjkim     * the buffer. If it's a zero buffer length, we'll be returning the
137167802Sjkim     * needed buffer size (later), so keep going.
138167802Sjkim     */
139167802Sjkim    Status = AcpiUtValidateBuffer (Buffer);
140167802Sjkim    if (ACPI_FAILURE (Status))
141167802Sjkim    {
142167802Sjkim        return_ACPI_STATUS (Status);
143167802Sjkim    }
144167802Sjkim
145167802Sjkim    *ReturnNode = Node;
146167802Sjkim    return_ACPI_STATUS (AE_OK);
147167802Sjkim}
148167802Sjkim
149167802Sjkim
150167802Sjkim/*******************************************************************************
151167802Sjkim *
15267754Smsmith * FUNCTION:    AcpiGetIrqRoutingTable
15367754Smsmith *
154167802Sjkim * PARAMETERS:  DeviceHandle    - Handle to the Bus device we are querying
155167802Sjkim *              RetBuffer       - Pointer to a buffer to receive the
15667754Smsmith *                                current resources for the device
15767754Smsmith *
15877424Smsmith * RETURN:      Status
15967754Smsmith *
16067754Smsmith * DESCRIPTION: This function is called to get the IRQ routing table for a
161167802Sjkim *              specific bus. The caller must first acquire a handle for the
162167802Sjkim *              desired bus. The routine table is placed in the buffer pointed
16367754Smsmith *              to by the RetBuffer variable parameter.
16467754Smsmith *
16567754Smsmith *              If the function fails an appropriate status will be returned
16667754Smsmith *              and the value of RetBuffer is undefined.
16767754Smsmith *
16867754Smsmith *              This function attempts to execute the _PRT method contained in
16967754Smsmith *              the object indicated by the passed DeviceHandle.
17067754Smsmith *
17167754Smsmith ******************************************************************************/
17267754Smsmith
17367754SmsmithACPI_STATUS
17467754SmsmithAcpiGetIrqRoutingTable  (
17567754Smsmith    ACPI_HANDLE             DeviceHandle,
17667754Smsmith    ACPI_BUFFER             *RetBuffer)
17767754Smsmith{
17867754Smsmith    ACPI_STATUS             Status;
179167802Sjkim    ACPI_NAMESPACE_NODE     *Node;
18067754Smsmith
18167754Smsmith
182167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetIrqRoutingTable);
18367754Smsmith
18477424Smsmith
185167802Sjkim    /* Validate parameters then dispatch to internal routine */
18667754Smsmith
187167802Sjkim    Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
18891116Smsmith    if (ACPI_FAILURE (Status))
18991116Smsmith    {
19091116Smsmith        return_ACPI_STATUS (Status);
19191116Smsmith    }
19291116Smsmith
193167802Sjkim    Status = AcpiRsGetPrtMethodData (Node, RetBuffer);
19467754Smsmith    return_ACPI_STATUS (Status);
19567754Smsmith}
19667754Smsmith
197167802SjkimACPI_EXPORT_SYMBOL (AcpiGetIrqRoutingTable)
19867754Smsmith
199167802Sjkim
20067754Smsmith/*******************************************************************************
20167754Smsmith *
20267754Smsmith * FUNCTION:    AcpiGetCurrentResources
20367754Smsmith *
204167802Sjkim * PARAMETERS:  DeviceHandle    - Handle to the device object for the
20567754Smsmith *                                device we are querying
206167802Sjkim *              RetBuffer       - Pointer to a buffer to receive the
20767754Smsmith *                                current resources for the device
20867754Smsmith *
20977424Smsmith * RETURN:      Status
21067754Smsmith *
21167754Smsmith * DESCRIPTION: This function is called to get the current resources for a
212167802Sjkim *              specific device. The caller must first acquire a handle for
213167802Sjkim *              the desired device. The resource data is placed in the buffer
21467754Smsmith *              pointed to by the RetBuffer variable parameter.
21567754Smsmith *
21667754Smsmith *              If the function fails an appropriate status will be returned
21767754Smsmith *              and the value of RetBuffer is undefined.
21867754Smsmith *
21967754Smsmith *              This function attempts to execute the _CRS method contained in
22067754Smsmith *              the object indicated by the passed DeviceHandle.
22167754Smsmith *
22267754Smsmith ******************************************************************************/
22367754Smsmith
22467754SmsmithACPI_STATUS
22567754SmsmithAcpiGetCurrentResources (
22667754Smsmith    ACPI_HANDLE             DeviceHandle,
22767754Smsmith    ACPI_BUFFER             *RetBuffer)
22867754Smsmith{
22967754Smsmith    ACPI_STATUS             Status;
230167802Sjkim    ACPI_NAMESPACE_NODE     *Node;
23167754Smsmith
23267754Smsmith
233167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetCurrentResources);
23467754Smsmith
23583174Smsmith
236167802Sjkim    /* Validate parameters then dispatch to internal routine */
23767754Smsmith
238167802Sjkim    Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
23991116Smsmith    if (ACPI_FAILURE (Status))
24091116Smsmith    {
24191116Smsmith        return_ACPI_STATUS (Status);
24291116Smsmith    }
24391116Smsmith
244167802Sjkim    Status = AcpiRsGetCrsMethodData (Node, RetBuffer);
24567754Smsmith    return_ACPI_STATUS (Status);
24667754Smsmith}
24767754Smsmith
248167802SjkimACPI_EXPORT_SYMBOL (AcpiGetCurrentResources)
24967754Smsmith
250167802Sjkim
25167754Smsmith/*******************************************************************************
25267754Smsmith *
25367754Smsmith * FUNCTION:    AcpiGetPossibleResources
25467754Smsmith *
255167802Sjkim * PARAMETERS:  DeviceHandle    - Handle to the device object for the
25667754Smsmith *                                device we are querying
257167802Sjkim *              RetBuffer       - Pointer to a buffer to receive the
25867754Smsmith *                                resources for the device
25967754Smsmith *
26077424Smsmith * RETURN:      Status
26167754Smsmith *
26267754Smsmith * DESCRIPTION: This function is called to get a list of the possible resources
263167802Sjkim *              for a specific device. The caller must first acquire a handle
264167802Sjkim *              for the desired device. The resource data is placed in the
26567754Smsmith *              buffer pointed to by the RetBuffer variable.
26667754Smsmith *
26767754Smsmith *              If the function fails an appropriate status will be returned
26867754Smsmith *              and the value of RetBuffer is undefined.
26967754Smsmith *
27067754Smsmith ******************************************************************************/
27167754Smsmith
27267754SmsmithACPI_STATUS
27367754SmsmithAcpiGetPossibleResources (
27467754Smsmith    ACPI_HANDLE             DeviceHandle,
27567754Smsmith    ACPI_BUFFER             *RetBuffer)
27667754Smsmith{
27767754Smsmith    ACPI_STATUS             Status;
278167802Sjkim    ACPI_NAMESPACE_NODE     *Node;
27967754Smsmith
28067754Smsmith
281167802Sjkim    ACPI_FUNCTION_TRACE (AcpiGetPossibleResources);
28267754Smsmith
28377424Smsmith
284167802Sjkim    /* Validate parameters then dispatch to internal routine */
28567754Smsmith
286167802Sjkim    Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
28791116Smsmith    if (ACPI_FAILURE (Status))
28891116Smsmith    {
28991116Smsmith        return_ACPI_STATUS (Status);
29091116Smsmith    }
29191116Smsmith
292167802Sjkim    Status = AcpiRsGetPrsMethodData (Node, RetBuffer);
29367754Smsmith    return_ACPI_STATUS (Status);
29467754Smsmith}
29567754Smsmith
296167802SjkimACPI_EXPORT_SYMBOL (AcpiGetPossibleResources)
29767754Smsmith
298167802Sjkim
29967754Smsmith/*******************************************************************************
30067754Smsmith *
301167802Sjkim * FUNCTION:    AcpiSetCurrentResources
302114237Snjl *
303167802Sjkim * PARAMETERS:  DeviceHandle    - Handle to the device object for the
304167802Sjkim *                                device we are setting resources
305167802Sjkim *              InBuffer        - Pointer to a buffer containing the
306167802Sjkim *                                resources to be set for the device
307114237Snjl *
308114237Snjl * RETURN:      Status
309114237Snjl *
310167802Sjkim * DESCRIPTION: This function is called to set the current resources for a
311167802Sjkim *              specific device. The caller must first acquire a handle for
312167802Sjkim *              the desired device. The resource data is passed to the routine
313167802Sjkim *              the buffer pointed to by the InBuffer variable.
314114237Snjl *
315114237Snjl ******************************************************************************/
316114237Snjl
317114237SnjlACPI_STATUS
318167802SjkimAcpiSetCurrentResources (
319167802Sjkim    ACPI_HANDLE             DeviceHandle,
320167802Sjkim    ACPI_BUFFER             *InBuffer)
321114237Snjl{
322167802Sjkim    ACPI_STATUS             Status;
323167802Sjkim    ACPI_NAMESPACE_NODE     *Node;
324114237Snjl
325114237Snjl
326167802Sjkim    ACPI_FUNCTION_TRACE (AcpiSetCurrentResources);
327114237Snjl
328114237Snjl
329167802Sjkim    /* Validate the buffer, don't allow zero length */
330167802Sjkim
331167802Sjkim    if ((!InBuffer) ||
332167802Sjkim        (!InBuffer->Pointer) ||
333167802Sjkim        (!InBuffer->Length))
334114237Snjl    {
335114237Snjl        return_ACPI_STATUS (AE_BAD_PARAMETER);
336114237Snjl    }
337114237Snjl
338167802Sjkim    /* Validate parameters then dispatch to internal routine */
339167802Sjkim
340167802Sjkim    Status = AcpiRsValidateParameters (DeviceHandle, InBuffer, &Node);
341114237Snjl    if (ACPI_FAILURE (Status))
342114237Snjl    {
343114237Snjl        return_ACPI_STATUS (Status);
344114237Snjl    }
345114237Snjl
346167802Sjkim    Status = AcpiRsSetSrsMethodData (Node, InBuffer);
347167802Sjkim    return_ACPI_STATUS (Status);
348167802Sjkim}
349126372Snjl
350167802SjkimACPI_EXPORT_SYMBOL (AcpiSetCurrentResources)
351126372Snjl
352126372Snjl
353228110Sjkim/*******************************************************************************
354228110Sjkim *
355228110Sjkim * FUNCTION:    AcpiGetEventResources
356228110Sjkim *
357228110Sjkim * PARAMETERS:  DeviceHandle    - Handle to the device object for the
358228110Sjkim *                                device we are getting resources
359228110Sjkim *              InBuffer        - Pointer to a buffer containing the
360228110Sjkim *                                resources to be set for the device
361228110Sjkim *
362228110Sjkim * RETURN:      Status
363228110Sjkim *
364228110Sjkim * DESCRIPTION: This function is called to get the event resources for a
365228110Sjkim *              specific device. The caller must first acquire a handle for
366228110Sjkim *              the desired device. The resource data is passed to the routine
367228110Sjkim *              the buffer pointed to by the InBuffer variable. Uses the
368228110Sjkim *              _AEI method.
369228110Sjkim *
370228110Sjkim ******************************************************************************/
371228110Sjkim
372228110SjkimACPI_STATUS
373228110SjkimAcpiGetEventResources (
374228110Sjkim    ACPI_HANDLE             DeviceHandle,
375228110Sjkim    ACPI_BUFFER             *RetBuffer)
376228110Sjkim{
377228110Sjkim    ACPI_STATUS             Status;
378228110Sjkim    ACPI_NAMESPACE_NODE     *Node;
379228110Sjkim
380228110Sjkim
381228110Sjkim    ACPI_FUNCTION_TRACE (AcpiGetEventResources);
382228110Sjkim
383228110Sjkim
384228110Sjkim    /* Validate parameters then dispatch to internal routine */
385228110Sjkim
386228110Sjkim    Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
387228110Sjkim    if (ACPI_FAILURE (Status))
388228110Sjkim    {
389228110Sjkim        return_ACPI_STATUS (Status);
390228110Sjkim    }
391228110Sjkim
392228110Sjkim    Status = AcpiRsGetAeiMethodData (Node, RetBuffer);
393228110Sjkim    return_ACPI_STATUS (Status);
394228110Sjkim}
395228110Sjkim
396228110SjkimACPI_EXPORT_SYMBOL (AcpiGetEventResources)
397228110Sjkim
398228110Sjkim
399167802Sjkim/******************************************************************************
400167802Sjkim *
401167802Sjkim * FUNCTION:    AcpiResourceToAddress64
402167802Sjkim *
403167802Sjkim * PARAMETERS:  Resource        - Pointer to a resource
404167802Sjkim *              Out             - Pointer to the users's return buffer
405167802Sjkim *                                (a struct acpi_resource_address64)
406167802Sjkim *
407167802Sjkim * RETURN:      Status
408167802Sjkim *
409167802Sjkim * DESCRIPTION: If the resource is an address16, address32, or address64,
410167802Sjkim *              copy it to the address64 return buffer. This saves the
411167802Sjkim *              caller from having to duplicate code for different-sized
412167802Sjkim *              addresses.
413167802Sjkim *
414167802Sjkim ******************************************************************************/
415167802Sjkim
416167802SjkimACPI_STATUS
417167802SjkimAcpiResourceToAddress64 (
418167802Sjkim    ACPI_RESOURCE               *Resource,
419167802Sjkim    ACPI_RESOURCE_ADDRESS64     *Out)
420167802Sjkim{
421167802Sjkim    ACPI_RESOURCE_ADDRESS16     *Address16;
422167802Sjkim    ACPI_RESOURCE_ADDRESS32     *Address32;
423167802Sjkim
424167802Sjkim
425167802Sjkim    if (!Resource || !Out)
426114237Snjl    {
427167802Sjkim        return (AE_BAD_PARAMETER);
428167802Sjkim    }
429114237Snjl
430167802Sjkim    /* Convert 16 or 32 address descriptor to 64 */
431114237Snjl
432167802Sjkim    switch (Resource->Type)
433167802Sjkim    {
434167802Sjkim    case ACPI_RESOURCE_TYPE_ADDRESS16:
435114237Snjl
436298714Sjkim        Address16 = ACPI_CAST_PTR (
437298714Sjkim            ACPI_RESOURCE_ADDRESS16, &Resource->Data);
438167802Sjkim        ACPI_COPY_ADDRESS (Out, Address16);
439167802Sjkim        break;
440126372Snjl
441167802Sjkim    case ACPI_RESOURCE_TYPE_ADDRESS32:
442114237Snjl
443298714Sjkim        Address32 = ACPI_CAST_PTR (
444298714Sjkim            ACPI_RESOURCE_ADDRESS32, &Resource->Data);
445167802Sjkim        ACPI_COPY_ADDRESS (Out, Address32);
446167802Sjkim        break;
447114237Snjl
448167802Sjkim    case ACPI_RESOURCE_TYPE_ADDRESS64:
449114237Snjl
450167802Sjkim        /* Simple copy for 64 bit source */
451114237Snjl
452284583Sjkim        memcpy (Out, &Resource->Data, sizeof (ACPI_RESOURCE_ADDRESS64));
453167802Sjkim        break;
454114237Snjl
455167802Sjkim    default:
456250838Sjkim
457167802Sjkim        return (AE_BAD_PARAMETER);
458167802Sjkim    }
459114237Snjl
460167802Sjkim    return (AE_OK);
461167802Sjkim}
462114237Snjl
463167802SjkimACPI_EXPORT_SYMBOL (AcpiResourceToAddress64)
464126372Snjl
465126372Snjl
466167802Sjkim/*******************************************************************************
467167802Sjkim *
468167802Sjkim * FUNCTION:    AcpiGetVendorResource
469167802Sjkim *
470167802Sjkim * PARAMETERS:  DeviceHandle    - Handle for the parent device object
471167802Sjkim *              Name            - Method name for the parent resource
472167802Sjkim *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
473167802Sjkim *              Uuid            - Pointer to the UUID to be matched.
474167802Sjkim *                                includes both subtype and 16-byte UUID
475167802Sjkim *              RetBuffer       - Where the vendor resource is returned
476167802Sjkim *
477167802Sjkim * RETURN:      Status
478167802Sjkim *
479245582Sjkim * DESCRIPTION: Walk a resource template for the specified device to find a
480167802Sjkim *              vendor-defined resource that matches the supplied UUID and
481167802Sjkim *              UUID subtype. Returns a ACPI_RESOURCE of type Vendor.
482167802Sjkim *
483167802Sjkim ******************************************************************************/
484126372Snjl
485167802SjkimACPI_STATUS
486167802SjkimAcpiGetVendorResource (
487167802Sjkim    ACPI_HANDLE             DeviceHandle,
488167802Sjkim    char                    *Name,
489167802Sjkim    ACPI_VENDOR_UUID        *Uuid,
490167802Sjkim    ACPI_BUFFER             *RetBuffer)
491167802Sjkim{
492167802Sjkim    ACPI_VENDOR_WALK_INFO   Info;
493167802Sjkim    ACPI_STATUS             Status;
494167802Sjkim
495167802Sjkim
496167802Sjkim    /* Other parameters are validated by AcpiWalkResources */
497167802Sjkim
498167802Sjkim    if (!Uuid || !RetBuffer)
499167802Sjkim    {
500167802Sjkim        return (AE_BAD_PARAMETER);
501114237Snjl    }
502114237Snjl
503167802Sjkim    Info.Uuid = Uuid;
504167802Sjkim    Info.Buffer = RetBuffer;
505167802Sjkim    Info.Status = AE_NOT_EXIST;
506114237Snjl
507167802Sjkim    /* Walk the _CRS or _PRS resource list for this device */
508167802Sjkim
509298714Sjkim    Status = AcpiWalkResources (
510298714Sjkim        DeviceHandle, Name, AcpiRsMatchVendorResource, &Info);
511167802Sjkim    if (ACPI_FAILURE (Status))
512167802Sjkim    {
513167802Sjkim        return (Status);
514167802Sjkim    }
515167802Sjkim
516167802Sjkim    return (Info.Status);
517114237Snjl}
518114237Snjl
519167802SjkimACPI_EXPORT_SYMBOL (AcpiGetVendorResource)
520114237Snjl
521167802Sjkim
522114237Snjl/*******************************************************************************
523114237Snjl *
524167802Sjkim * FUNCTION:    AcpiRsMatchVendorResource
52567754Smsmith *
526167802Sjkim * PARAMETERS:  ACPI_WALK_RESOURCE_CALLBACK
52767754Smsmith *
52877424Smsmith * RETURN:      Status
52967754Smsmith *
530167802Sjkim * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
53167754Smsmith *
53267754Smsmith ******************************************************************************/
53367754Smsmith
534167802Sjkimstatic ACPI_STATUS
535167802SjkimAcpiRsMatchVendorResource (
536167802Sjkim    ACPI_RESOURCE           *Resource,
537167802Sjkim    void                    *Context)
53867754Smsmith{
539167802Sjkim    ACPI_VENDOR_WALK_INFO       *Info = Context;
540167802Sjkim    ACPI_RESOURCE_VENDOR_TYPED  *Vendor;
541167802Sjkim    ACPI_BUFFER                 *Buffer;
542167802Sjkim    ACPI_STATUS                 Status;
54367754Smsmith
54467754Smsmith
545167802Sjkim    /* Ignore all descriptors except Vendor */
54667754Smsmith
547167802Sjkim    if (Resource->Type != ACPI_RESOURCE_TYPE_VENDOR)
548167802Sjkim    {
549167802Sjkim        return (AE_OK);
550167802Sjkim    }
55177424Smsmith
552167802Sjkim    Vendor = &Resource->Data.VendorTyped;
553151937Sjkim
554167802Sjkim    /*
555167802Sjkim     * For a valid match, these conditions must hold:
556167802Sjkim     *
557167802Sjkim     * 1) Length of descriptor data must be at least as long as a UUID struct
558167802Sjkim     * 2) The UUID subtypes must match
559167802Sjkim     * 3) The UUID data must match
560167802Sjkim     */
561167802Sjkim    if ((Vendor->ByteLength < (ACPI_UUID_LENGTH + 1)) ||
562167802Sjkim        (Vendor->UuidSubtype != Info->Uuid->Subtype)  ||
563284583Sjkim        (memcmp (Vendor->Uuid, Info->Uuid->Data, ACPI_UUID_LENGTH)))
56467754Smsmith    {
565167802Sjkim        return (AE_OK);
56667754Smsmith    }
56767754Smsmith
568167802Sjkim    /* Validate/Allocate/Clear caller buffer */
569167802Sjkim
570167802Sjkim    Buffer = Info->Buffer;
571167802Sjkim    Status = AcpiUtInitializeBuffer (Buffer, Resource->Length);
572167802Sjkim    if (ACPI_FAILURE (Status))
573167802Sjkim    {
574167802Sjkim        return (Status);
575167802Sjkim    }
576167802Sjkim
577167802Sjkim    /* Found the correct resource, copy and return it */
578167802Sjkim
579284583Sjkim    memcpy (Buffer->Pointer, Resource, Resource->Length);
580167802Sjkim    Buffer->Length = Resource->Length;
581167802Sjkim
582167802Sjkim    /* Found the desired descriptor, terminate resource walk */
583167802Sjkim
584167802Sjkim    Info->Status = AE_OK;
585167802Sjkim    return (AE_CTRL_TERMINATE);
58667754Smsmith}
587114237Snjl
588114237Snjl
589167802Sjkim/*******************************************************************************
590114237Snjl *
591245582Sjkim * FUNCTION:    AcpiWalkResourceBuffer
592114237Snjl *
593245582Sjkim * PARAMETERS:  Buffer          - Formatted buffer returned by one of the
594245582Sjkim *                                various Get*Resource functions
595167802Sjkim *              UserFunction    - Called for each resource
596167802Sjkim *              Context         - Passed to UserFunction
597114237Snjl *
598114237Snjl * RETURN:      Status
599114237Snjl *
600245582Sjkim * DESCRIPTION: Walks the input resource template. The UserFunction is called
601245582Sjkim *              once for each resource in the list.
602114237Snjl *
603114237Snjl ******************************************************************************/
604114237Snjl
605114237SnjlACPI_STATUS
606245582SjkimAcpiWalkResourceBuffer (
607245582Sjkim    ACPI_BUFFER                 *Buffer,
608167802Sjkim    ACPI_WALK_RESOURCE_CALLBACK UserFunction,
609167802Sjkim    void                        *Context)
610114237Snjl{
611245582Sjkim    ACPI_STATUS                 Status = AE_OK;
612167802Sjkim    ACPI_RESOURCE               *Resource;
613167802Sjkim    ACPI_RESOURCE               *ResourceEnd;
614114237Snjl
615114237Snjl
616245582Sjkim    ACPI_FUNCTION_TRACE (AcpiWalkResourceBuffer);
617167802Sjkim
618167802Sjkim
619167802Sjkim    /* Parameter validation */
620167802Sjkim
621245582Sjkim    if (!Buffer || !Buffer->Pointer || !UserFunction)
622151937Sjkim    {
623167802Sjkim        return_ACPI_STATUS (AE_BAD_PARAMETER);
624167802Sjkim    }
625117521Snjl
626245582Sjkim    /* Buffer contains the resource list and length */
627114237Snjl
628245582Sjkim    Resource = ACPI_CAST_PTR (ACPI_RESOURCE, Buffer->Pointer);
629298714Sjkim    ResourceEnd = ACPI_ADD_PTR (
630298714Sjkim        ACPI_RESOURCE, Buffer->Pointer, Buffer->Length);
631117521Snjl
632167802Sjkim    /* Walk the resource list until the EndTag is found (or buffer end) */
633117521Snjl
634167802Sjkim    while (Resource < ResourceEnd)
635167802Sjkim    {
636246849Sjkim        /* Sanity check the resource type */
637114237Snjl
638167802Sjkim        if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
639167802Sjkim        {
640167802Sjkim            Status = AE_AML_INVALID_RESOURCE_TYPE;
641167802Sjkim            break;
642167802Sjkim        }
643167802Sjkim
644246849Sjkim        /* Sanity check the length. It must not be zero, or we loop forever */
645246849Sjkim
646246849Sjkim        if (!Resource->Length)
647246849Sjkim        {
648246849Sjkim            return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
649246849Sjkim        }
650246849Sjkim
651167802Sjkim        /* Invoke the user function, abort on any error returned */
652167802Sjkim
653167802Sjkim        Status = UserFunction (Resource, Context);
654167802Sjkim        if (ACPI_FAILURE (Status))
655167802Sjkim        {
656167802Sjkim            if (Status == AE_CTRL_TERMINATE)
657167802Sjkim            {
658167802Sjkim                /* This is an OK termination by the user function */
659167802Sjkim
660167802Sjkim                Status = AE_OK;
661167802Sjkim            }
662167802Sjkim            break;
663167802Sjkim        }
664167802Sjkim
665167802Sjkim        /* EndTag indicates end-of-list */
666167802Sjkim
667167802Sjkim        if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
668167802Sjkim        {
669167802Sjkim            break;
670167802Sjkim        }
671167802Sjkim
672167802Sjkim        /* Get the next resource descriptor */
673167802Sjkim
674243347Sjkim        Resource = ACPI_NEXT_RESOURCE (Resource);
675114237Snjl    }
676114237Snjl
677245582Sjkim    return_ACPI_STATUS (Status);
678245582Sjkim}
679245582Sjkim
680245582SjkimACPI_EXPORT_SYMBOL (AcpiWalkResourceBuffer)
681245582Sjkim
682245582Sjkim
683245582Sjkim/*******************************************************************************
684245582Sjkim *
685245582Sjkim * FUNCTION:    AcpiWalkResources
686245582Sjkim *
687245582Sjkim * PARAMETERS:  DeviceHandle    - Handle to the device object for the
688245582Sjkim *                                device we are querying
689245582Sjkim *              Name            - Method name of the resources we want.
690245582Sjkim *                                (METHOD_NAME__CRS, METHOD_NAME__PRS, or
691245582Sjkim *                                METHOD_NAME__AEI)
692245582Sjkim *              UserFunction    - Called for each resource
693245582Sjkim *              Context         - Passed to UserFunction
694245582Sjkim *
695245582Sjkim * RETURN:      Status
696245582Sjkim *
697245582Sjkim * DESCRIPTION: Retrieves the current or possible resource list for the
698245582Sjkim *              specified device. The UserFunction is called once for
699245582Sjkim *              each resource in the list.
700245582Sjkim *
701245582Sjkim ******************************************************************************/
702245582Sjkim
703245582SjkimACPI_STATUS
704245582SjkimAcpiWalkResources (
705245582Sjkim    ACPI_HANDLE                 DeviceHandle,
706245582Sjkim    char                        *Name,
707245582Sjkim    ACPI_WALK_RESOURCE_CALLBACK UserFunction,
708245582Sjkim    void                        *Context)
709245582Sjkim{
710245582Sjkim    ACPI_STATUS                 Status;
711245582Sjkim    ACPI_BUFFER                 Buffer;
712245582Sjkim
713245582Sjkim
714245582Sjkim    ACPI_FUNCTION_TRACE (AcpiWalkResources);
715245582Sjkim
716245582Sjkim
717245582Sjkim    /* Parameter validation */
718245582Sjkim
719245582Sjkim    if (!DeviceHandle || !UserFunction || !Name ||
720245582Sjkim        (!ACPI_COMPARE_NAME (Name, METHOD_NAME__CRS) &&
721245582Sjkim         !ACPI_COMPARE_NAME (Name, METHOD_NAME__PRS) &&
722245582Sjkim         !ACPI_COMPARE_NAME (Name, METHOD_NAME__AEI)))
723245582Sjkim    {
724245582Sjkim        return_ACPI_STATUS (AE_BAD_PARAMETER);
725245582Sjkim    }
726245582Sjkim
727245582Sjkim    /* Get the _CRS/_PRS/_AEI resource list */
728245582Sjkim
729245582Sjkim    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
730245582Sjkim    Status = AcpiRsGetMethodData (DeviceHandle, Name, &Buffer);
731245582Sjkim    if (ACPI_FAILURE (Status))
732245582Sjkim    {
733245582Sjkim        return_ACPI_STATUS (Status);
734245582Sjkim    }
735245582Sjkim
736245582Sjkim    /* Walk the resource list and cleanup */
737245582Sjkim
738245582Sjkim    Status = AcpiWalkResourceBuffer (&Buffer, UserFunction, Context);
739167802Sjkim    ACPI_FREE (Buffer.Pointer);
740167802Sjkim    return_ACPI_STATUS (Status);
741114237Snjl}
742167802Sjkim
743167802SjkimACPI_EXPORT_SYMBOL (AcpiWalkResources)
744