xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/resources/rsxface.c (revision 97dfeb96704e5dbc5bec32ad7b21379d0125e031)
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 - 2016, 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 #define EXPORT_ACPI_INTERFACES
117 
118 #include "acpi.h"
119 #include "accommon.h"
120 #include "acresrc.h"
121 #include "acnamesp.h"
122 
123 #define _COMPONENT          ACPI_RESOURCES
124         ACPI_MODULE_NAME    ("rsxface")
125 
126 /* Local macros for 16,32-bit to 64-bit conversion */
127 
128 #define ACPI_COPY_FIELD(Out, In, Field)  ((Out)->Field = (In)->Field)
129 #define ACPI_COPY_ADDRESS(Out, In)                       \
130     ACPI_COPY_FIELD(Out, In, ResourceType);              \
131     ACPI_COPY_FIELD(Out, In, ProducerConsumer);          \
132     ACPI_COPY_FIELD(Out, In, Decode);                    \
133     ACPI_COPY_FIELD(Out, In, MinAddressFixed);           \
134     ACPI_COPY_FIELD(Out, In, MaxAddressFixed);           \
135     ACPI_COPY_FIELD(Out, In, Info);                      \
136     ACPI_COPY_FIELD(Out, In, Address.Granularity);       \
137     ACPI_COPY_FIELD(Out, In, Address.Minimum);           \
138     ACPI_COPY_FIELD(Out, In, Address.Maximum);           \
139     ACPI_COPY_FIELD(Out, In, Address.TranslationOffset); \
140     ACPI_COPY_FIELD(Out, In, Address.AddressLength);     \
141     ACPI_COPY_FIELD(Out, In, ResourceSource);
142 
143 
144 /* Local prototypes */
145 
146 static ACPI_STATUS
147 AcpiRsMatchVendorResource (
148     ACPI_RESOURCE           *Resource,
149     void                    *Context);
150 
151 static ACPI_STATUS
152 AcpiRsValidateParameters (
153     ACPI_HANDLE             DeviceHandle,
154     ACPI_BUFFER             *Buffer,
155     ACPI_NAMESPACE_NODE     **ReturnNode);
156 
157 
158 /*******************************************************************************
159  *
160  * FUNCTION:    AcpiRsValidateParameters
161  *
162  * PARAMETERS:  DeviceHandle    - Handle to a device
163  *              Buffer          - Pointer to a data buffer
164  *              ReturnNode      - Pointer to where the device node is returned
165  *
166  * RETURN:      Status
167  *
168  * DESCRIPTION: Common parameter validation for resource interfaces
169  *
170  ******************************************************************************/
171 
172 static ACPI_STATUS
173 AcpiRsValidateParameters (
174     ACPI_HANDLE             DeviceHandle,
175     ACPI_BUFFER             *Buffer,
176     ACPI_NAMESPACE_NODE     **ReturnNode)
177 {
178     ACPI_STATUS             Status;
179     ACPI_NAMESPACE_NODE     *Node;
180 
181 
182     ACPI_FUNCTION_TRACE (RsValidateParameters);
183 
184 
185     /*
186      * Must have a valid handle to an ACPI device
187      */
188     if (!DeviceHandle)
189     {
190         return_ACPI_STATUS (AE_BAD_PARAMETER);
191     }
192 
193     Node = AcpiNsValidateHandle (DeviceHandle);
194     if (!Node)
195     {
196         return_ACPI_STATUS (AE_BAD_PARAMETER);
197     }
198 
199     if (Node->Type != ACPI_TYPE_DEVICE)
200     {
201         return_ACPI_STATUS (AE_TYPE);
202     }
203 
204     /*
205      * Validate the user buffer object
206      *
207      * if there is a non-zero buffer length we also need a valid pointer in
208      * the buffer. If it's a zero buffer length, we'll be returning the
209      * needed buffer size (later), so keep going.
210      */
211     Status = AcpiUtValidateBuffer (Buffer);
212     if (ACPI_FAILURE (Status))
213     {
214         return_ACPI_STATUS (Status);
215     }
216 
217     *ReturnNode = Node;
218     return_ACPI_STATUS (AE_OK);
219 }
220 
221 
222 /*******************************************************************************
223  *
224  * FUNCTION:    AcpiGetIrqRoutingTable
225  *
226  * PARAMETERS:  DeviceHandle    - Handle to the Bus device we are querying
227  *              RetBuffer       - Pointer to a buffer to receive the
228  *                                current resources for the device
229  *
230  * RETURN:      Status
231  *
232  * DESCRIPTION: This function is called to get the IRQ routing table for a
233  *              specific bus. The caller must first acquire a handle for the
234  *              desired bus. The routine table is placed in the buffer pointed
235  *              to by the RetBuffer variable parameter.
236  *
237  *              If the function fails an appropriate status will be returned
238  *              and the value of RetBuffer is undefined.
239  *
240  *              This function attempts to execute the _PRT method contained in
241  *              the object indicated by the passed DeviceHandle.
242  *
243  ******************************************************************************/
244 
245 ACPI_STATUS
246 AcpiGetIrqRoutingTable  (
247     ACPI_HANDLE             DeviceHandle,
248     ACPI_BUFFER             *RetBuffer)
249 {
250     ACPI_STATUS             Status;
251     ACPI_NAMESPACE_NODE     *Node;
252 
253 
254     ACPI_FUNCTION_TRACE (AcpiGetIrqRoutingTable);
255 
256 
257     /* Validate parameters then dispatch to internal routine */
258 
259     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
260     if (ACPI_FAILURE (Status))
261     {
262         return_ACPI_STATUS (Status);
263     }
264 
265     Status = AcpiRsGetPrtMethodData (Node, RetBuffer);
266     return_ACPI_STATUS (Status);
267 }
268 
269 ACPI_EXPORT_SYMBOL (AcpiGetIrqRoutingTable)
270 
271 
272 /*******************************************************************************
273  *
274  * FUNCTION:    AcpiGetCurrentResources
275  *
276  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
277  *                                device we are querying
278  *              RetBuffer       - Pointer to a buffer to receive the
279  *                                current resources for the device
280  *
281  * RETURN:      Status
282  *
283  * DESCRIPTION: This function is called to get the current resources for a
284  *              specific device. The caller must first acquire a handle for
285  *              the desired device. The resource data is placed in the buffer
286  *              pointed to by the RetBuffer variable parameter.
287  *
288  *              If the function fails an appropriate status will be returned
289  *              and the value of RetBuffer is undefined.
290  *
291  *              This function attempts to execute the _CRS method contained in
292  *              the object indicated by the passed DeviceHandle.
293  *
294  ******************************************************************************/
295 
296 ACPI_STATUS
297 AcpiGetCurrentResources (
298     ACPI_HANDLE             DeviceHandle,
299     ACPI_BUFFER             *RetBuffer)
300 {
301     ACPI_STATUS             Status;
302     ACPI_NAMESPACE_NODE     *Node;
303 
304 
305     ACPI_FUNCTION_TRACE (AcpiGetCurrentResources);
306 
307 
308     /* Validate parameters then dispatch to internal routine */
309 
310     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
311     if (ACPI_FAILURE (Status))
312     {
313         return_ACPI_STATUS (Status);
314     }
315 
316     Status = AcpiRsGetCrsMethodData (Node, RetBuffer);
317     return_ACPI_STATUS (Status);
318 }
319 
320 ACPI_EXPORT_SYMBOL (AcpiGetCurrentResources)
321 
322 
323 /*******************************************************************************
324  *
325  * FUNCTION:    AcpiGetPossibleResources
326  *
327  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
328  *                                device we are querying
329  *              RetBuffer       - Pointer to a buffer to receive the
330  *                                resources for the device
331  *
332  * RETURN:      Status
333  *
334  * DESCRIPTION: This function is called to get a list of the possible resources
335  *              for a specific device. The caller must first acquire a handle
336  *              for the desired device. The resource data is placed in the
337  *              buffer pointed to by the RetBuffer variable.
338  *
339  *              If the function fails an appropriate status will be returned
340  *              and the value of RetBuffer is undefined.
341  *
342  ******************************************************************************/
343 
344 ACPI_STATUS
345 AcpiGetPossibleResources (
346     ACPI_HANDLE             DeviceHandle,
347     ACPI_BUFFER             *RetBuffer)
348 {
349     ACPI_STATUS             Status;
350     ACPI_NAMESPACE_NODE     *Node;
351 
352 
353     ACPI_FUNCTION_TRACE (AcpiGetPossibleResources);
354 
355 
356     /* Validate parameters then dispatch to internal routine */
357 
358     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
359     if (ACPI_FAILURE (Status))
360     {
361         return_ACPI_STATUS (Status);
362     }
363 
364     Status = AcpiRsGetPrsMethodData (Node, RetBuffer);
365     return_ACPI_STATUS (Status);
366 }
367 
368 ACPI_EXPORT_SYMBOL (AcpiGetPossibleResources)
369 
370 
371 /*******************************************************************************
372  *
373  * FUNCTION:    AcpiSetCurrentResources
374  *
375  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
376  *                                device we are setting resources
377  *              InBuffer        - Pointer to a buffer containing the
378  *                                resources to be set for the device
379  *
380  * RETURN:      Status
381  *
382  * DESCRIPTION: This function is called to set the current resources for a
383  *              specific device. The caller must first acquire a handle for
384  *              the desired device. The resource data is passed to the routine
385  *              the buffer pointed to by the InBuffer variable.
386  *
387  ******************************************************************************/
388 
389 ACPI_STATUS
390 AcpiSetCurrentResources (
391     ACPI_HANDLE             DeviceHandle,
392     ACPI_BUFFER             *InBuffer)
393 {
394     ACPI_STATUS             Status;
395     ACPI_NAMESPACE_NODE     *Node;
396 
397 
398     ACPI_FUNCTION_TRACE (AcpiSetCurrentResources);
399 
400 
401     /* Validate the buffer, don't allow zero length */
402 
403     if ((!InBuffer) ||
404         (!InBuffer->Pointer) ||
405         (!InBuffer->Length))
406     {
407         return_ACPI_STATUS (AE_BAD_PARAMETER);
408     }
409 
410     /* Validate parameters then dispatch to internal routine */
411 
412     Status = AcpiRsValidateParameters (DeviceHandle, InBuffer, &Node);
413     if (ACPI_FAILURE (Status))
414     {
415         return_ACPI_STATUS (Status);
416     }
417 
418     Status = AcpiRsSetSrsMethodData (Node, InBuffer);
419     return_ACPI_STATUS (Status);
420 }
421 
422 ACPI_EXPORT_SYMBOL (AcpiSetCurrentResources)
423 
424 
425 /*******************************************************************************
426  *
427  * FUNCTION:    AcpiGetEventResources
428  *
429  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
430  *                                device we are getting resources
431  *              InBuffer        - Pointer to a buffer containing the
432  *                                resources to be set for the device
433  *
434  * RETURN:      Status
435  *
436  * DESCRIPTION: This function is called to get the event resources for a
437  *              specific device. The caller must first acquire a handle for
438  *              the desired device. The resource data is passed to the routine
439  *              the buffer pointed to by the InBuffer variable. Uses the
440  *              _AEI method.
441  *
442  ******************************************************************************/
443 
444 ACPI_STATUS
445 AcpiGetEventResources (
446     ACPI_HANDLE             DeviceHandle,
447     ACPI_BUFFER             *RetBuffer)
448 {
449     ACPI_STATUS             Status;
450     ACPI_NAMESPACE_NODE     *Node;
451 
452 
453     ACPI_FUNCTION_TRACE (AcpiGetEventResources);
454 
455 
456     /* Validate parameters then dispatch to internal routine */
457 
458     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
459     if (ACPI_FAILURE (Status))
460     {
461         return_ACPI_STATUS (Status);
462     }
463 
464     Status = AcpiRsGetAeiMethodData (Node, RetBuffer);
465     return_ACPI_STATUS (Status);
466 }
467 
468 ACPI_EXPORT_SYMBOL (AcpiGetEventResources)
469 
470 
471 /******************************************************************************
472  *
473  * FUNCTION:    AcpiResourceToAddress64
474  *
475  * PARAMETERS:  Resource        - Pointer to a resource
476  *              Out             - Pointer to the users's return buffer
477  *                                (a struct acpi_resource_address64)
478  *
479  * RETURN:      Status
480  *
481  * DESCRIPTION: If the resource is an address16, address32, or address64,
482  *              copy it to the address64 return buffer. This saves the
483  *              caller from having to duplicate code for different-sized
484  *              addresses.
485  *
486  ******************************************************************************/
487 
488 ACPI_STATUS
489 AcpiResourceToAddress64 (
490     ACPI_RESOURCE               *Resource,
491     ACPI_RESOURCE_ADDRESS64     *Out)
492 {
493     ACPI_RESOURCE_ADDRESS16     *Address16;
494     ACPI_RESOURCE_ADDRESS32     *Address32;
495 
496 
497     if (!Resource || !Out)
498     {
499         return (AE_BAD_PARAMETER);
500     }
501 
502     /* Convert 16 or 32 address descriptor to 64 */
503 
504     switch (Resource->Type)
505     {
506     case ACPI_RESOURCE_TYPE_ADDRESS16:
507 
508         Address16 = ACPI_CAST_PTR (
509             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 (
516             ACPI_RESOURCE_ADDRESS32, &Resource->Data);
517         ACPI_COPY_ADDRESS (Out, Address32);
518         break;
519 
520     case ACPI_RESOURCE_TYPE_ADDRESS64:
521 
522         /* Simple copy for 64 bit source */
523 
524         memcpy (Out, &Resource->Data, sizeof (ACPI_RESOURCE_ADDRESS64));
525         break;
526 
527     default:
528 
529         return (AE_BAD_PARAMETER);
530     }
531 
532     return (AE_OK);
533 }
534 
535 ACPI_EXPORT_SYMBOL (AcpiResourceToAddress64)
536 
537 
538 /*******************************************************************************
539  *
540  * FUNCTION:    AcpiGetVendorResource
541  *
542  * PARAMETERS:  DeviceHandle    - Handle for the parent device object
543  *              Name            - Method name for the parent resource
544  *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
545  *              Uuid            - Pointer to the UUID to be matched.
546  *                                includes both subtype and 16-byte UUID
547  *              RetBuffer       - Where the vendor resource is returned
548  *
549  * RETURN:      Status
550  *
551  * DESCRIPTION: Walk a resource template for the specified device to find a
552  *              vendor-defined resource that matches the supplied UUID and
553  *              UUID subtype. Returns a ACPI_RESOURCE of type Vendor.
554  *
555  ******************************************************************************/
556 
557 ACPI_STATUS
558 AcpiGetVendorResource (
559     ACPI_HANDLE             DeviceHandle,
560     char                    *Name,
561     ACPI_VENDOR_UUID        *Uuid,
562     ACPI_BUFFER             *RetBuffer)
563 {
564     ACPI_VENDOR_WALK_INFO   Info;
565     ACPI_STATUS             Status;
566 
567 
568     /* Other parameters are validated by AcpiWalkResources */
569 
570     if (!Uuid || !RetBuffer)
571     {
572         return (AE_BAD_PARAMETER);
573     }
574 
575     Info.Uuid = Uuid;
576     Info.Buffer = RetBuffer;
577     Info.Status = AE_NOT_EXIST;
578 
579     /* Walk the _CRS or _PRS resource list for this device */
580 
581     Status = AcpiWalkResources (
582         DeviceHandle, Name, AcpiRsMatchVendorResource, &Info);
583     if (ACPI_FAILURE (Status))
584     {
585         return (Status);
586     }
587 
588     return (Info.Status);
589 }
590 
591 ACPI_EXPORT_SYMBOL (AcpiGetVendorResource)
592 
593 
594 /*******************************************************************************
595  *
596  * FUNCTION:    AcpiRsMatchVendorResource
597  *
598  * PARAMETERS:  ACPI_WALK_RESOURCE_CALLBACK
599  *
600  * RETURN:      Status
601  *
602  * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
603  *
604  ******************************************************************************/
605 
606 static ACPI_STATUS
607 AcpiRsMatchVendorResource (
608     ACPI_RESOURCE           *Resource,
609     void                    *Context)
610 {
611     ACPI_VENDOR_WALK_INFO       *Info = Context;
612     ACPI_RESOURCE_VENDOR_TYPED  *Vendor;
613     ACPI_BUFFER                 *Buffer;
614     ACPI_STATUS                 Status;
615 
616 
617     /* Ignore all descriptors except Vendor */
618 
619     if (Resource->Type != ACPI_RESOURCE_TYPE_VENDOR)
620     {
621         return (AE_OK);
622     }
623 
624     Vendor = &Resource->Data.VendorTyped;
625 
626     /*
627      * For a valid match, these conditions must hold:
628      *
629      * 1) Length of descriptor data must be at least as long as a UUID struct
630      * 2) The UUID subtypes must match
631      * 3) The UUID data must match
632      */
633     if ((Vendor->ByteLength < (ACPI_UUID_LENGTH + 1)) ||
634         (Vendor->UuidSubtype != Info->Uuid->Subtype)  ||
635         (memcmp (Vendor->Uuid, Info->Uuid->Data, ACPI_UUID_LENGTH)))
636     {
637         return (AE_OK);
638     }
639 
640     /* Validate/Allocate/Clear caller buffer */
641 
642     Buffer = Info->Buffer;
643     Status = AcpiUtInitializeBuffer (Buffer, Resource->Length);
644     if (ACPI_FAILURE (Status))
645     {
646         return (Status);
647     }
648 
649     /* Found the correct resource, copy and return it */
650 
651     memcpy (Buffer->Pointer, Resource, Resource->Length);
652     Buffer->Length = Resource->Length;
653 
654     /* Found the desired descriptor, terminate resource walk */
655 
656     Info->Status = AE_OK;
657     return (AE_CTRL_TERMINATE);
658 }
659 
660 
661 /*******************************************************************************
662  *
663  * FUNCTION:    AcpiWalkResourceBuffer
664  *
665  * PARAMETERS:  Buffer          - Formatted buffer returned by one of the
666  *                                various Get*Resource functions
667  *              UserFunction    - Called for each resource
668  *              Context         - Passed to UserFunction
669  *
670  * RETURN:      Status
671  *
672  * DESCRIPTION: Walks the input resource template. The UserFunction is called
673  *              once for each resource in the list.
674  *
675  ******************************************************************************/
676 
677 ACPI_STATUS
678 AcpiWalkResourceBuffer (
679     ACPI_BUFFER                 *Buffer,
680     ACPI_WALK_RESOURCE_CALLBACK UserFunction,
681     void                        *Context)
682 {
683     ACPI_STATUS                 Status = AE_OK;
684     ACPI_RESOURCE               *Resource;
685     ACPI_RESOURCE               *ResourceEnd;
686 
687 
688     ACPI_FUNCTION_TRACE (AcpiWalkResourceBuffer);
689 
690 
691     /* Parameter validation */
692 
693     if (!Buffer || !Buffer->Pointer || !UserFunction)
694     {
695         return_ACPI_STATUS (AE_BAD_PARAMETER);
696     }
697 
698     /* Buffer contains the resource list and length */
699 
700     Resource = ACPI_CAST_PTR (ACPI_RESOURCE, Buffer->Pointer);
701     ResourceEnd = ACPI_ADD_PTR (
702         ACPI_RESOURCE, Buffer->Pointer, Buffer->Length);
703 
704     /* Walk the resource list until the EndTag is found (or buffer end) */
705 
706     while (Resource < ResourceEnd)
707     {
708         /* Sanity check the resource type */
709 
710         if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
711         {
712             Status = AE_AML_INVALID_RESOURCE_TYPE;
713             break;
714         }
715 
716         /* Sanity check the length. It must not be zero, or we loop forever */
717 
718         if (!Resource->Length)
719         {
720             return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
721         }
722 
723         /* Invoke the user function, abort on any error returned */
724 
725         Status = UserFunction (Resource, Context);
726         if (ACPI_FAILURE (Status))
727         {
728             if (Status == AE_CTRL_TERMINATE)
729             {
730                 /* This is an OK termination by the user function */
731 
732                 Status = AE_OK;
733             }
734             break;
735         }
736 
737         /* EndTag indicates end-of-list */
738 
739         if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
740         {
741             break;
742         }
743 
744         /* Get the next resource descriptor */
745 
746         Resource = ACPI_NEXT_RESOURCE (Resource);
747     }
748 
749     return_ACPI_STATUS (Status);
750 }
751 
752 ACPI_EXPORT_SYMBOL (AcpiWalkResourceBuffer)
753 
754 
755 /*******************************************************************************
756  *
757  * FUNCTION:    AcpiWalkResources
758  *
759  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
760  *                                device we are querying
761  *              Name            - Method name of the resources we want.
762  *                                (METHOD_NAME__CRS, METHOD_NAME__PRS, or
763  *                                METHOD_NAME__AEI)
764  *              UserFunction    - Called for each resource
765  *              Context         - Passed to UserFunction
766  *
767  * RETURN:      Status
768  *
769  * DESCRIPTION: Retrieves the current or possible resource list for the
770  *              specified device. The UserFunction is called once for
771  *              each resource in the list.
772  *
773  ******************************************************************************/
774 
775 ACPI_STATUS
776 AcpiWalkResources (
777     ACPI_HANDLE                 DeviceHandle,
778     char                        *Name,
779     ACPI_WALK_RESOURCE_CALLBACK UserFunction,
780     void                        *Context)
781 {
782     ACPI_STATUS                 Status;
783     ACPI_BUFFER                 Buffer;
784 
785 
786     ACPI_FUNCTION_TRACE (AcpiWalkResources);
787 
788 
789     /* Parameter validation */
790 
791     if (!DeviceHandle || !UserFunction || !Name ||
792         (!ACPI_COMPARE_NAME (Name, METHOD_NAME__CRS) &&
793          !ACPI_COMPARE_NAME (Name, METHOD_NAME__PRS) &&
794          !ACPI_COMPARE_NAME (Name, METHOD_NAME__AEI)))
795     {
796         return_ACPI_STATUS (AE_BAD_PARAMETER);
797     }
798 
799     /* Get the _CRS/_PRS/_AEI resource list */
800 
801     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
802     Status = AcpiRsGetMethodData (DeviceHandle, Name, &Buffer);
803     if (ACPI_FAILURE (Status))
804     {
805         return_ACPI_STATUS (Status);
806     }
807 
808     /* Walk the resource list and cleanup */
809 
810     Status = AcpiWalkResourceBuffer (&Buffer, UserFunction, Context);
811     ACPI_FREE (Buffer.Pointer);
812     return_ACPI_STATUS (Status);
813 }
814 
815 ACPI_EXPORT_SYMBOL (AcpiWalkResources)
816