xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/resources/rsxface.c (revision f8da8f3477d3c18142e59d17d05a545982faa5a8)
1 /*******************************************************************************
2  *
3  * Module Name: rsxface - Public interfaces to the resource manager
4  *
5  ******************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2013, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 
117 #define __RSXFACE_C__
118 
119 #include "acpi.h"
120 #include "accommon.h"
121 #include "acresrc.h"
122 #include "acnamesp.h"
123 
124 #define _COMPONENT          ACPI_RESOURCES
125         ACPI_MODULE_NAME    ("rsxface")
126 
127 /* Local macros for 16,32-bit to 64-bit conversion */
128 
129 #define ACPI_COPY_FIELD(Out, In, Field)  ((Out)->Field = (In)->Field)
130 #define ACPI_COPY_ADDRESS(Out, In)                      \
131     ACPI_COPY_FIELD(Out, In, ResourceType);              \
132     ACPI_COPY_FIELD(Out, In, ProducerConsumer);          \
133     ACPI_COPY_FIELD(Out, In, Decode);                    \
134     ACPI_COPY_FIELD(Out, In, MinAddressFixed);           \
135     ACPI_COPY_FIELD(Out, In, MaxAddressFixed);           \
136     ACPI_COPY_FIELD(Out, In, Info);                      \
137     ACPI_COPY_FIELD(Out, In, Granularity);               \
138     ACPI_COPY_FIELD(Out, In, Minimum);                   \
139     ACPI_COPY_FIELD(Out, In, Maximum);                   \
140     ACPI_COPY_FIELD(Out, In, TranslationOffset);         \
141     ACPI_COPY_FIELD(Out, In, AddressLength);             \
142     ACPI_COPY_FIELD(Out, In, ResourceSource);
143 
144 
145 /* Local prototypes */
146 
147 static ACPI_STATUS
148 AcpiRsMatchVendorResource (
149     ACPI_RESOURCE           *Resource,
150     void                    *Context);
151 
152 static ACPI_STATUS
153 AcpiRsValidateParameters (
154     ACPI_HANDLE             DeviceHandle,
155     ACPI_BUFFER             *Buffer,
156     ACPI_NAMESPACE_NODE     **ReturnNode);
157 
158 
159 /*******************************************************************************
160  *
161  * FUNCTION:    AcpiRsValidateParameters
162  *
163  * PARAMETERS:  DeviceHandle    - Handle to a device
164  *              Buffer          - Pointer to a data buffer
165  *              ReturnNode      - Pointer to where the device node is returned
166  *
167  * RETURN:      Status
168  *
169  * DESCRIPTION: Common parameter validation for resource interfaces
170  *
171  ******************************************************************************/
172 
173 static ACPI_STATUS
174 AcpiRsValidateParameters (
175     ACPI_HANDLE             DeviceHandle,
176     ACPI_BUFFER             *Buffer,
177     ACPI_NAMESPACE_NODE     **ReturnNode)
178 {
179     ACPI_STATUS             Status;
180     ACPI_NAMESPACE_NODE     *Node;
181 
182 
183     ACPI_FUNCTION_TRACE (RsValidateParameters);
184 
185 
186     /*
187      * Must have a valid handle to an ACPI device
188      */
189     if (!DeviceHandle)
190     {
191         return_ACPI_STATUS (AE_BAD_PARAMETER);
192     }
193 
194     Node = AcpiNsValidateHandle (DeviceHandle);
195     if (!Node)
196     {
197         return_ACPI_STATUS (AE_BAD_PARAMETER);
198     }
199 
200     if (Node->Type != ACPI_TYPE_DEVICE)
201     {
202         return_ACPI_STATUS (AE_TYPE);
203     }
204 
205     /*
206      * Validate the user buffer object
207      *
208      * if there is a non-zero buffer length we also need a valid pointer in
209      * the buffer. If it's a zero buffer length, we'll be returning the
210      * needed buffer size (later), so keep going.
211      */
212     Status = AcpiUtValidateBuffer (Buffer);
213     if (ACPI_FAILURE (Status))
214     {
215         return_ACPI_STATUS (Status);
216     }
217 
218     *ReturnNode = Node;
219     return_ACPI_STATUS (AE_OK);
220 }
221 
222 
223 /*******************************************************************************
224  *
225  * FUNCTION:    AcpiGetIrqRoutingTable
226  *
227  * PARAMETERS:  DeviceHandle    - Handle to the Bus device we are querying
228  *              RetBuffer       - Pointer to a buffer to receive the
229  *                                current resources for the device
230  *
231  * RETURN:      Status
232  *
233  * DESCRIPTION: This function is called to get the IRQ routing table for a
234  *              specific bus. The caller must first acquire a handle for the
235  *              desired bus. The routine table is placed in the buffer pointed
236  *              to by the RetBuffer variable parameter.
237  *
238  *              If the function fails an appropriate status will be returned
239  *              and the value of RetBuffer is undefined.
240  *
241  *              This function attempts to execute the _PRT method contained in
242  *              the object indicated by the passed DeviceHandle.
243  *
244  ******************************************************************************/
245 
246 ACPI_STATUS
247 AcpiGetIrqRoutingTable  (
248     ACPI_HANDLE             DeviceHandle,
249     ACPI_BUFFER             *RetBuffer)
250 {
251     ACPI_STATUS             Status;
252     ACPI_NAMESPACE_NODE     *Node;
253 
254 
255     ACPI_FUNCTION_TRACE (AcpiGetIrqRoutingTable);
256 
257 
258     /* Validate parameters then dispatch to internal routine */
259 
260     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
261     if (ACPI_FAILURE (Status))
262     {
263         return_ACPI_STATUS (Status);
264     }
265 
266     Status = AcpiRsGetPrtMethodData (Node, RetBuffer);
267     return_ACPI_STATUS (Status);
268 }
269 
270 ACPI_EXPORT_SYMBOL (AcpiGetIrqRoutingTable)
271 
272 
273 /*******************************************************************************
274  *
275  * FUNCTION:    AcpiGetCurrentResources
276  *
277  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
278  *                                device we are querying
279  *              RetBuffer       - Pointer to a buffer to receive the
280  *                                current resources for the device
281  *
282  * RETURN:      Status
283  *
284  * DESCRIPTION: This function is called to get the current resources for a
285  *              specific device. The caller must first acquire a handle for
286  *              the desired device. The resource data is placed in the buffer
287  *              pointed to by the RetBuffer variable parameter.
288  *
289  *              If the function fails an appropriate status will be returned
290  *              and the value of RetBuffer is undefined.
291  *
292  *              This function attempts to execute the _CRS method contained in
293  *              the object indicated by the passed DeviceHandle.
294  *
295  ******************************************************************************/
296 
297 ACPI_STATUS
298 AcpiGetCurrentResources (
299     ACPI_HANDLE             DeviceHandle,
300     ACPI_BUFFER             *RetBuffer)
301 {
302     ACPI_STATUS             Status;
303     ACPI_NAMESPACE_NODE     *Node;
304 
305 
306     ACPI_FUNCTION_TRACE (AcpiGetCurrentResources);
307 
308 
309     /* Validate parameters then dispatch to internal routine */
310 
311     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
312     if (ACPI_FAILURE (Status))
313     {
314         return_ACPI_STATUS (Status);
315     }
316 
317     Status = AcpiRsGetCrsMethodData (Node, RetBuffer);
318     return_ACPI_STATUS (Status);
319 }
320 
321 ACPI_EXPORT_SYMBOL (AcpiGetCurrentResources)
322 
323 
324 /*******************************************************************************
325  *
326  * FUNCTION:    AcpiGetPossibleResources
327  *
328  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
329  *                                device we are querying
330  *              RetBuffer       - Pointer to a buffer to receive the
331  *                                resources for the device
332  *
333  * RETURN:      Status
334  *
335  * DESCRIPTION: This function is called to get a list of the possible resources
336  *              for a specific device. The caller must first acquire a handle
337  *              for the desired device. The resource data is placed in the
338  *              buffer pointed to by the RetBuffer variable.
339  *
340  *              If the function fails an appropriate status will be returned
341  *              and the value of RetBuffer is undefined.
342  *
343  ******************************************************************************/
344 
345 ACPI_STATUS
346 AcpiGetPossibleResources (
347     ACPI_HANDLE             DeviceHandle,
348     ACPI_BUFFER             *RetBuffer)
349 {
350     ACPI_STATUS             Status;
351     ACPI_NAMESPACE_NODE     *Node;
352 
353 
354     ACPI_FUNCTION_TRACE (AcpiGetPossibleResources);
355 
356 
357     /* Validate parameters then dispatch to internal routine */
358 
359     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
360     if (ACPI_FAILURE (Status))
361     {
362         return_ACPI_STATUS (Status);
363     }
364 
365     Status = AcpiRsGetPrsMethodData (Node, RetBuffer);
366     return_ACPI_STATUS (Status);
367 }
368 
369 ACPI_EXPORT_SYMBOL (AcpiGetPossibleResources)
370 
371 
372 /*******************************************************************************
373  *
374  * FUNCTION:    AcpiSetCurrentResources
375  *
376  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
377  *                                device we are setting resources
378  *              InBuffer        - Pointer to a buffer containing the
379  *                                resources to be set for the device
380  *
381  * RETURN:      Status
382  *
383  * DESCRIPTION: This function is called to set the current resources for a
384  *              specific device. The caller must first acquire a handle for
385  *              the desired device. The resource data is passed to the routine
386  *              the buffer pointed to by the InBuffer variable.
387  *
388  ******************************************************************************/
389 
390 ACPI_STATUS
391 AcpiSetCurrentResources (
392     ACPI_HANDLE             DeviceHandle,
393     ACPI_BUFFER             *InBuffer)
394 {
395     ACPI_STATUS             Status;
396     ACPI_NAMESPACE_NODE     *Node;
397 
398 
399     ACPI_FUNCTION_TRACE (AcpiSetCurrentResources);
400 
401 
402     /* Validate the buffer, don't allow zero length */
403 
404     if ((!InBuffer) ||
405         (!InBuffer->Pointer) ||
406         (!InBuffer->Length))
407     {
408         return_ACPI_STATUS (AE_BAD_PARAMETER);
409     }
410 
411     /* Validate parameters then dispatch to internal routine */
412 
413     Status = AcpiRsValidateParameters (DeviceHandle, InBuffer, &Node);
414     if (ACPI_FAILURE (Status))
415     {
416         return_ACPI_STATUS (Status);
417     }
418 
419     Status = AcpiRsSetSrsMethodData (Node, InBuffer);
420     return_ACPI_STATUS (Status);
421 }
422 
423 ACPI_EXPORT_SYMBOL (AcpiSetCurrentResources)
424 
425 
426 /*******************************************************************************
427  *
428  * FUNCTION:    AcpiGetEventResources
429  *
430  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
431  *                                device we are getting resources
432  *              InBuffer        - Pointer to a buffer containing the
433  *                                resources to be set for the device
434  *
435  * RETURN:      Status
436  *
437  * DESCRIPTION: This function is called to get the event resources for a
438  *              specific device. The caller must first acquire a handle for
439  *              the desired device. The resource data is passed to the routine
440  *              the buffer pointed to by the InBuffer variable. Uses the
441  *              _AEI method.
442  *
443  ******************************************************************************/
444 
445 ACPI_STATUS
446 AcpiGetEventResources (
447     ACPI_HANDLE             DeviceHandle,
448     ACPI_BUFFER             *RetBuffer)
449 {
450     ACPI_STATUS             Status;
451     ACPI_NAMESPACE_NODE     *Node;
452 
453 
454     ACPI_FUNCTION_TRACE (AcpiGetEventResources);
455 
456 
457     /* Validate parameters then dispatch to internal routine */
458 
459     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
460     if (ACPI_FAILURE (Status))
461     {
462         return_ACPI_STATUS (Status);
463     }
464 
465     Status = AcpiRsGetAeiMethodData (Node, RetBuffer);
466     return_ACPI_STATUS (Status);
467 }
468 
469 ACPI_EXPORT_SYMBOL (AcpiGetEventResources)
470 
471 
472 /******************************************************************************
473  *
474  * FUNCTION:    AcpiResourceToAddress64
475  *
476  * PARAMETERS:  Resource        - Pointer to a resource
477  *              Out             - Pointer to the users's return buffer
478  *                                (a struct acpi_resource_address64)
479  *
480  * RETURN:      Status
481  *
482  * DESCRIPTION: If the resource is an address16, address32, or address64,
483  *              copy it to the address64 return buffer. This saves the
484  *              caller from having to duplicate code for different-sized
485  *              addresses.
486  *
487  ******************************************************************************/
488 
489 ACPI_STATUS
490 AcpiResourceToAddress64 (
491     ACPI_RESOURCE               *Resource,
492     ACPI_RESOURCE_ADDRESS64     *Out)
493 {
494     ACPI_RESOURCE_ADDRESS16     *Address16;
495     ACPI_RESOURCE_ADDRESS32     *Address32;
496 
497 
498     if (!Resource || !Out)
499     {
500         return (AE_BAD_PARAMETER);
501     }
502 
503     /* Convert 16 or 32 address descriptor to 64 */
504 
505     switch (Resource->Type)
506     {
507     case ACPI_RESOURCE_TYPE_ADDRESS16:
508 
509         Address16 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS16, &Resource->Data);
510         ACPI_COPY_ADDRESS (Out, Address16);
511         break;
512 
513     case ACPI_RESOURCE_TYPE_ADDRESS32:
514 
515         Address32 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS32, &Resource->Data);
516         ACPI_COPY_ADDRESS (Out, Address32);
517         break;
518 
519     case ACPI_RESOURCE_TYPE_ADDRESS64:
520 
521         /* Simple copy for 64 bit source */
522 
523         ACPI_MEMCPY (Out, &Resource->Data, sizeof (ACPI_RESOURCE_ADDRESS64));
524         break;
525 
526     default:
527 
528         return (AE_BAD_PARAMETER);
529     }
530 
531     return (AE_OK);
532 }
533 
534 ACPI_EXPORT_SYMBOL (AcpiResourceToAddress64)
535 
536 
537 /*******************************************************************************
538  *
539  * FUNCTION:    AcpiGetVendorResource
540  *
541  * PARAMETERS:  DeviceHandle    - Handle for the parent device object
542  *              Name            - Method name for the parent resource
543  *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
544  *              Uuid            - Pointer to the UUID to be matched.
545  *                                includes both subtype and 16-byte UUID
546  *              RetBuffer       - Where the vendor resource is returned
547  *
548  * RETURN:      Status
549  *
550  * DESCRIPTION: Walk a resource template for the specified device to find a
551  *              vendor-defined resource that matches the supplied UUID and
552  *              UUID subtype. Returns a ACPI_RESOURCE of type Vendor.
553  *
554  ******************************************************************************/
555 
556 ACPI_STATUS
557 AcpiGetVendorResource (
558     ACPI_HANDLE             DeviceHandle,
559     char                    *Name,
560     ACPI_VENDOR_UUID        *Uuid,
561     ACPI_BUFFER             *RetBuffer)
562 {
563     ACPI_VENDOR_WALK_INFO   Info;
564     ACPI_STATUS             Status;
565 
566 
567     /* Other parameters are validated by AcpiWalkResources */
568 
569     if (!Uuid || !RetBuffer)
570     {
571         return (AE_BAD_PARAMETER);
572     }
573 
574     Info.Uuid = Uuid;
575     Info.Buffer = RetBuffer;
576     Info.Status = AE_NOT_EXIST;
577 
578     /* Walk the _CRS or _PRS resource list for this device */
579 
580     Status = AcpiWalkResources (DeviceHandle, Name, AcpiRsMatchVendorResource,
581                 &Info);
582     if (ACPI_FAILURE (Status))
583     {
584         return (Status);
585     }
586 
587     return (Info.Status);
588 }
589 
590 ACPI_EXPORT_SYMBOL (AcpiGetVendorResource)
591 
592 
593 /*******************************************************************************
594  *
595  * FUNCTION:    AcpiRsMatchVendorResource
596  *
597  * PARAMETERS:  ACPI_WALK_RESOURCE_CALLBACK
598  *
599  * RETURN:      Status
600  *
601  * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
602  *
603  ******************************************************************************/
604 
605 static ACPI_STATUS
606 AcpiRsMatchVendorResource (
607     ACPI_RESOURCE           *Resource,
608     void                    *Context)
609 {
610     ACPI_VENDOR_WALK_INFO       *Info = Context;
611     ACPI_RESOURCE_VENDOR_TYPED  *Vendor;
612     ACPI_BUFFER                 *Buffer;
613     ACPI_STATUS                 Status;
614 
615 
616     /* Ignore all descriptors except Vendor */
617 
618     if (Resource->Type != ACPI_RESOURCE_TYPE_VENDOR)
619     {
620         return (AE_OK);
621     }
622 
623     Vendor = &Resource->Data.VendorTyped;
624 
625     /*
626      * For a valid match, these conditions must hold:
627      *
628      * 1) Length of descriptor data must be at least as long as a UUID struct
629      * 2) The UUID subtypes must match
630      * 3) The UUID data must match
631      */
632     if ((Vendor->ByteLength < (ACPI_UUID_LENGTH + 1)) ||
633         (Vendor->UuidSubtype != Info->Uuid->Subtype)  ||
634         (ACPI_MEMCMP (Vendor->Uuid, Info->Uuid->Data, ACPI_UUID_LENGTH)))
635     {
636         return (AE_OK);
637     }
638 
639     /* Validate/Allocate/Clear caller buffer */
640 
641     Buffer = Info->Buffer;
642     Status = AcpiUtInitializeBuffer (Buffer, Resource->Length);
643     if (ACPI_FAILURE (Status))
644     {
645         return (Status);
646     }
647 
648     /* Found the correct resource, copy and return it */
649 
650     ACPI_MEMCPY (Buffer->Pointer, Resource, Resource->Length);
651     Buffer->Length = Resource->Length;
652 
653     /* Found the desired descriptor, terminate resource walk */
654 
655     Info->Status = AE_OK;
656     return (AE_CTRL_TERMINATE);
657 }
658 
659 
660 /*******************************************************************************
661  *
662  * FUNCTION:    AcpiWalkResourceBuffer
663  *
664  * PARAMETERS:  Buffer          - Formatted buffer returned by one of the
665  *                                various Get*Resource functions
666  *              UserFunction    - Called for each resource
667  *              Context         - Passed to UserFunction
668  *
669  * RETURN:      Status
670  *
671  * DESCRIPTION: Walks the input resource template. The UserFunction is called
672  *              once for each resource in the list.
673  *
674  ******************************************************************************/
675 
676 ACPI_STATUS
677 AcpiWalkResourceBuffer (
678     ACPI_BUFFER                 *Buffer,
679     ACPI_WALK_RESOURCE_CALLBACK UserFunction,
680     void                        *Context)
681 {
682     ACPI_STATUS                 Status = AE_OK;
683     ACPI_RESOURCE               *Resource;
684     ACPI_RESOURCE               *ResourceEnd;
685 
686 
687     ACPI_FUNCTION_TRACE (AcpiWalkResourceBuffer);
688 
689 
690     /* Parameter validation */
691 
692     if (!Buffer || !Buffer->Pointer || !UserFunction)
693     {
694         return_ACPI_STATUS (AE_BAD_PARAMETER);
695     }
696 
697     /* Buffer contains the resource list and length */
698 
699     Resource = ACPI_CAST_PTR (ACPI_RESOURCE, Buffer->Pointer);
700     ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Buffer->Pointer, Buffer->Length);
701 
702     /* Walk the resource list until the EndTag is found (or buffer end) */
703 
704     while (Resource < ResourceEnd)
705     {
706         /* Sanity check the resource type */
707 
708         if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
709         {
710             Status = AE_AML_INVALID_RESOURCE_TYPE;
711             break;
712         }
713 
714         /* Sanity check the length. It must not be zero, or we loop forever */
715 
716         if (!Resource->Length)
717         {
718             return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
719         }
720 
721         /* Invoke the user function, abort on any error returned */
722 
723         Status = UserFunction (Resource, Context);
724         if (ACPI_FAILURE (Status))
725         {
726             if (Status == AE_CTRL_TERMINATE)
727             {
728                 /* This is an OK termination by the user function */
729 
730                 Status = AE_OK;
731             }
732             break;
733         }
734 
735         /* EndTag indicates end-of-list */
736 
737         if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
738         {
739             break;
740         }
741 
742         /* Get the next resource descriptor */
743 
744         Resource = ACPI_NEXT_RESOURCE (Resource);
745     }
746 
747     return_ACPI_STATUS (Status);
748 }
749 
750 ACPI_EXPORT_SYMBOL (AcpiWalkResourceBuffer)
751 
752 
753 /*******************************************************************************
754  *
755  * FUNCTION:    AcpiWalkResources
756  *
757  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
758  *                                device we are querying
759  *              Name            - Method name of the resources we want.
760  *                                (METHOD_NAME__CRS, METHOD_NAME__PRS, or
761  *                                METHOD_NAME__AEI)
762  *              UserFunction    - Called for each resource
763  *              Context         - Passed to UserFunction
764  *
765  * RETURN:      Status
766  *
767  * DESCRIPTION: Retrieves the current or possible resource list for the
768  *              specified device. The UserFunction is called once for
769  *              each resource in the list.
770  *
771  ******************************************************************************/
772 
773 ACPI_STATUS
774 AcpiWalkResources (
775     ACPI_HANDLE                 DeviceHandle,
776     char                        *Name,
777     ACPI_WALK_RESOURCE_CALLBACK UserFunction,
778     void                        *Context)
779 {
780     ACPI_STATUS                 Status;
781     ACPI_BUFFER                 Buffer;
782 
783 
784     ACPI_FUNCTION_TRACE (AcpiWalkResources);
785 
786 
787     /* Parameter validation */
788 
789     if (!DeviceHandle || !UserFunction || !Name ||
790         (!ACPI_COMPARE_NAME (Name, METHOD_NAME__CRS) &&
791          !ACPI_COMPARE_NAME (Name, METHOD_NAME__PRS) &&
792          !ACPI_COMPARE_NAME (Name, METHOD_NAME__AEI)))
793     {
794         return_ACPI_STATUS (AE_BAD_PARAMETER);
795     }
796 
797     /* Get the _CRS/_PRS/_AEI resource list */
798 
799     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
800     Status = AcpiRsGetMethodData (DeviceHandle, Name, &Buffer);
801     if (ACPI_FAILURE (Status))
802     {
803         return_ACPI_STATUS (Status);
804     }
805 
806     /* Walk the resource list and cleanup */
807 
808     Status = AcpiWalkResourceBuffer (&Buffer, UserFunction, Context);
809     ACPI_FREE (Buffer.Pointer);
810     return_ACPI_STATUS (Status);
811 }
812 
813 ACPI_EXPORT_SYMBOL (AcpiWalkResources)
814