xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/resources/rsxface.c (revision 529cd177b573aaba391c8adc9c9f5ad76a14bf81)
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 - 2014, 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 #define EXPORT_ACPI_INTERFACES
119 
120 #include "acpi.h"
121 #include "accommon.h"
122 #include "acresrc.h"
123 #include "acnamesp.h"
124 
125 #define _COMPONENT          ACPI_RESOURCES
126         ACPI_MODULE_NAME    ("rsxface")
127 
128 /* Local macros for 16,32-bit to 64-bit conversion */
129 
130 #define ACPI_COPY_FIELD(Out, In, Field)  ((Out)->Field = (In)->Field)
131 #define ACPI_COPY_ADDRESS(Out, In)                      \
132     ACPI_COPY_FIELD(Out, In, ResourceType);              \
133     ACPI_COPY_FIELD(Out, In, ProducerConsumer);          \
134     ACPI_COPY_FIELD(Out, In, Decode);                    \
135     ACPI_COPY_FIELD(Out, In, MinAddressFixed);           \
136     ACPI_COPY_FIELD(Out, In, MaxAddressFixed);           \
137     ACPI_COPY_FIELD(Out, In, Info);                      \
138     ACPI_COPY_FIELD(Out, In, Granularity);               \
139     ACPI_COPY_FIELD(Out, In, Minimum);                   \
140     ACPI_COPY_FIELD(Out, In, Maximum);                   \
141     ACPI_COPY_FIELD(Out, In, TranslationOffset);         \
142     ACPI_COPY_FIELD(Out, In, AddressLength);             \
143     ACPI_COPY_FIELD(Out, In, ResourceSource);
144 
145 
146 /* Local prototypes */
147 
148 static ACPI_STATUS
149 AcpiRsMatchVendorResource (
150     ACPI_RESOURCE           *Resource,
151     void                    *Context);
152 
153 static ACPI_STATUS
154 AcpiRsValidateParameters (
155     ACPI_HANDLE             DeviceHandle,
156     ACPI_BUFFER             *Buffer,
157     ACPI_NAMESPACE_NODE     **ReturnNode);
158 
159 
160 /*******************************************************************************
161  *
162  * FUNCTION:    AcpiRsValidateParameters
163  *
164  * PARAMETERS:  DeviceHandle    - Handle to a device
165  *              Buffer          - Pointer to a data buffer
166  *              ReturnNode      - Pointer to where the device node is returned
167  *
168  * RETURN:      Status
169  *
170  * DESCRIPTION: Common parameter validation for resource interfaces
171  *
172  ******************************************************************************/
173 
174 static ACPI_STATUS
175 AcpiRsValidateParameters (
176     ACPI_HANDLE             DeviceHandle,
177     ACPI_BUFFER             *Buffer,
178     ACPI_NAMESPACE_NODE     **ReturnNode)
179 {
180     ACPI_STATUS             Status;
181     ACPI_NAMESPACE_NODE     *Node;
182 
183 
184     ACPI_FUNCTION_TRACE (RsValidateParameters);
185 
186 
187     /*
188      * Must have a valid handle to an ACPI device
189      */
190     if (!DeviceHandle)
191     {
192         return_ACPI_STATUS (AE_BAD_PARAMETER);
193     }
194 
195     Node = AcpiNsValidateHandle (DeviceHandle);
196     if (!Node)
197     {
198         return_ACPI_STATUS (AE_BAD_PARAMETER);
199     }
200 
201     if (Node->Type != ACPI_TYPE_DEVICE)
202     {
203         return_ACPI_STATUS (AE_TYPE);
204     }
205 
206     /*
207      * Validate the user buffer object
208      *
209      * if there is a non-zero buffer length we also need a valid pointer in
210      * the buffer. If it's a zero buffer length, we'll be returning the
211      * needed buffer size (later), so keep going.
212      */
213     Status = AcpiUtValidateBuffer (Buffer);
214     if (ACPI_FAILURE (Status))
215     {
216         return_ACPI_STATUS (Status);
217     }
218 
219     *ReturnNode = Node;
220     return_ACPI_STATUS (AE_OK);
221 }
222 
223 
224 /*******************************************************************************
225  *
226  * FUNCTION:    AcpiGetIrqRoutingTable
227  *
228  * PARAMETERS:  DeviceHandle    - Handle to the Bus device we are querying
229  *              RetBuffer       - Pointer to a buffer to receive the
230  *                                current resources for the device
231  *
232  * RETURN:      Status
233  *
234  * DESCRIPTION: This function is called to get the IRQ routing table for a
235  *              specific bus. The caller must first acquire a handle for the
236  *              desired bus. The routine table is placed in the buffer pointed
237  *              to by the RetBuffer variable parameter.
238  *
239  *              If the function fails an appropriate status will be returned
240  *              and the value of RetBuffer is undefined.
241  *
242  *              This function attempts to execute the _PRT method contained in
243  *              the object indicated by the passed DeviceHandle.
244  *
245  ******************************************************************************/
246 
247 ACPI_STATUS
248 AcpiGetIrqRoutingTable  (
249     ACPI_HANDLE             DeviceHandle,
250     ACPI_BUFFER             *RetBuffer)
251 {
252     ACPI_STATUS             Status;
253     ACPI_NAMESPACE_NODE     *Node;
254 
255 
256     ACPI_FUNCTION_TRACE (AcpiGetIrqRoutingTable);
257 
258 
259     /* Validate parameters then dispatch to internal routine */
260 
261     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
262     if (ACPI_FAILURE (Status))
263     {
264         return_ACPI_STATUS (Status);
265     }
266 
267     Status = AcpiRsGetPrtMethodData (Node, RetBuffer);
268     return_ACPI_STATUS (Status);
269 }
270 
271 ACPI_EXPORT_SYMBOL (AcpiGetIrqRoutingTable)
272 
273 
274 /*******************************************************************************
275  *
276  * FUNCTION:    AcpiGetCurrentResources
277  *
278  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
279  *                                device we are querying
280  *              RetBuffer       - Pointer to a buffer to receive the
281  *                                current resources for the device
282  *
283  * RETURN:      Status
284  *
285  * DESCRIPTION: This function is called to get the current resources for a
286  *              specific device. The caller must first acquire a handle for
287  *              the desired device. The resource data is placed in the buffer
288  *              pointed to by the RetBuffer variable parameter.
289  *
290  *              If the function fails an appropriate status will be returned
291  *              and the value of RetBuffer is undefined.
292  *
293  *              This function attempts to execute the _CRS method contained in
294  *              the object indicated by the passed DeviceHandle.
295  *
296  ******************************************************************************/
297 
298 ACPI_STATUS
299 AcpiGetCurrentResources (
300     ACPI_HANDLE             DeviceHandle,
301     ACPI_BUFFER             *RetBuffer)
302 {
303     ACPI_STATUS             Status;
304     ACPI_NAMESPACE_NODE     *Node;
305 
306 
307     ACPI_FUNCTION_TRACE (AcpiGetCurrentResources);
308 
309 
310     /* Validate parameters then dispatch to internal routine */
311 
312     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
313     if (ACPI_FAILURE (Status))
314     {
315         return_ACPI_STATUS (Status);
316     }
317 
318     Status = AcpiRsGetCrsMethodData (Node, RetBuffer);
319     return_ACPI_STATUS (Status);
320 }
321 
322 ACPI_EXPORT_SYMBOL (AcpiGetCurrentResources)
323 
324 
325 /*******************************************************************************
326  *
327  * FUNCTION:    AcpiGetPossibleResources
328  *
329  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
330  *                                device we are querying
331  *              RetBuffer       - Pointer to a buffer to receive the
332  *                                resources for the device
333  *
334  * RETURN:      Status
335  *
336  * DESCRIPTION: This function is called to get a list of the possible resources
337  *              for a specific device. The caller must first acquire a handle
338  *              for the desired device. The resource data is placed in the
339  *              buffer pointed to by the RetBuffer variable.
340  *
341  *              If the function fails an appropriate status will be returned
342  *              and the value of RetBuffer is undefined.
343  *
344  ******************************************************************************/
345 
346 ACPI_STATUS
347 AcpiGetPossibleResources (
348     ACPI_HANDLE             DeviceHandle,
349     ACPI_BUFFER             *RetBuffer)
350 {
351     ACPI_STATUS             Status;
352     ACPI_NAMESPACE_NODE     *Node;
353 
354 
355     ACPI_FUNCTION_TRACE (AcpiGetPossibleResources);
356 
357 
358     /* Validate parameters then dispatch to internal routine */
359 
360     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
361     if (ACPI_FAILURE (Status))
362     {
363         return_ACPI_STATUS (Status);
364     }
365 
366     Status = AcpiRsGetPrsMethodData (Node, RetBuffer);
367     return_ACPI_STATUS (Status);
368 }
369 
370 ACPI_EXPORT_SYMBOL (AcpiGetPossibleResources)
371 
372 
373 /*******************************************************************************
374  *
375  * FUNCTION:    AcpiSetCurrentResources
376  *
377  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
378  *                                device we are setting resources
379  *              InBuffer        - Pointer to a buffer containing the
380  *                                resources to be set for the device
381  *
382  * RETURN:      Status
383  *
384  * DESCRIPTION: This function is called to set the current resources for a
385  *              specific device. The caller must first acquire a handle for
386  *              the desired device. The resource data is passed to the routine
387  *              the buffer pointed to by the InBuffer variable.
388  *
389  ******************************************************************************/
390 
391 ACPI_STATUS
392 AcpiSetCurrentResources (
393     ACPI_HANDLE             DeviceHandle,
394     ACPI_BUFFER             *InBuffer)
395 {
396     ACPI_STATUS             Status;
397     ACPI_NAMESPACE_NODE     *Node;
398 
399 
400     ACPI_FUNCTION_TRACE (AcpiSetCurrentResources);
401 
402 
403     /* Validate the buffer, don't allow zero length */
404 
405     if ((!InBuffer) ||
406         (!InBuffer->Pointer) ||
407         (!InBuffer->Length))
408     {
409         return_ACPI_STATUS (AE_BAD_PARAMETER);
410     }
411 
412     /* Validate parameters then dispatch to internal routine */
413 
414     Status = AcpiRsValidateParameters (DeviceHandle, InBuffer, &Node);
415     if (ACPI_FAILURE (Status))
416     {
417         return_ACPI_STATUS (Status);
418     }
419 
420     Status = AcpiRsSetSrsMethodData (Node, InBuffer);
421     return_ACPI_STATUS (Status);
422 }
423 
424 ACPI_EXPORT_SYMBOL (AcpiSetCurrentResources)
425 
426 
427 /*******************************************************************************
428  *
429  * FUNCTION:    AcpiGetEventResources
430  *
431  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
432  *                                device we are getting resources
433  *              InBuffer        - Pointer to a buffer containing the
434  *                                resources to be set for the device
435  *
436  * RETURN:      Status
437  *
438  * DESCRIPTION: This function is called to get the event resources for a
439  *              specific device. The caller must first acquire a handle for
440  *              the desired device. The resource data is passed to the routine
441  *              the buffer pointed to by the InBuffer variable. Uses the
442  *              _AEI method.
443  *
444  ******************************************************************************/
445 
446 ACPI_STATUS
447 AcpiGetEventResources (
448     ACPI_HANDLE             DeviceHandle,
449     ACPI_BUFFER             *RetBuffer)
450 {
451     ACPI_STATUS             Status;
452     ACPI_NAMESPACE_NODE     *Node;
453 
454 
455     ACPI_FUNCTION_TRACE (AcpiGetEventResources);
456 
457 
458     /* Validate parameters then dispatch to internal routine */
459 
460     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
461     if (ACPI_FAILURE (Status))
462     {
463         return_ACPI_STATUS (Status);
464     }
465 
466     Status = AcpiRsGetAeiMethodData (Node, RetBuffer);
467     return_ACPI_STATUS (Status);
468 }
469 
470 ACPI_EXPORT_SYMBOL (AcpiGetEventResources)
471 
472 
473 /******************************************************************************
474  *
475  * FUNCTION:    AcpiResourceToAddress64
476  *
477  * PARAMETERS:  Resource        - Pointer to a resource
478  *              Out             - Pointer to the users's return buffer
479  *                                (a struct acpi_resource_address64)
480  *
481  * RETURN:      Status
482  *
483  * DESCRIPTION: If the resource is an address16, address32, or address64,
484  *              copy it to the address64 return buffer. This saves the
485  *              caller from having to duplicate code for different-sized
486  *              addresses.
487  *
488  ******************************************************************************/
489 
490 ACPI_STATUS
491 AcpiResourceToAddress64 (
492     ACPI_RESOURCE               *Resource,
493     ACPI_RESOURCE_ADDRESS64     *Out)
494 {
495     ACPI_RESOURCE_ADDRESS16     *Address16;
496     ACPI_RESOURCE_ADDRESS32     *Address32;
497 
498 
499     if (!Resource || !Out)
500     {
501         return (AE_BAD_PARAMETER);
502     }
503 
504     /* Convert 16 or 32 address descriptor to 64 */
505 
506     switch (Resource->Type)
507     {
508     case ACPI_RESOURCE_TYPE_ADDRESS16:
509 
510         Address16 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS16, &Resource->Data);
511         ACPI_COPY_ADDRESS (Out, Address16);
512         break;
513 
514     case ACPI_RESOURCE_TYPE_ADDRESS32:
515 
516         Address32 = ACPI_CAST_PTR (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         ACPI_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 (DeviceHandle, Name, AcpiRsMatchVendorResource,
582                 &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         (ACPI_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     ACPI_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 (ACPI_RESOURCE, Buffer->Pointer, Buffer->Length);
702 
703     /* Walk the resource list until the EndTag is found (or buffer end) */
704 
705     while (Resource < ResourceEnd)
706     {
707         /* Sanity check the resource type */
708 
709         if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
710         {
711             Status = AE_AML_INVALID_RESOURCE_TYPE;
712             break;
713         }
714 
715         /* Sanity check the length. It must not be zero, or we loop forever */
716 
717         if (!Resource->Length)
718         {
719             return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
720         }
721 
722         /* Invoke the user function, abort on any error returned */
723 
724         Status = UserFunction (Resource, Context);
725         if (ACPI_FAILURE (Status))
726         {
727             if (Status == AE_CTRL_TERMINATE)
728             {
729                 /* This is an OK termination by the user function */
730 
731                 Status = AE_OK;
732             }
733             break;
734         }
735 
736         /* EndTag indicates end-of-list */
737 
738         if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
739         {
740             break;
741         }
742 
743         /* Get the next resource descriptor */
744 
745         Resource = ACPI_NEXT_RESOURCE (Resource);
746     }
747 
748     return_ACPI_STATUS (Status);
749 }
750 
751 ACPI_EXPORT_SYMBOL (AcpiWalkResourceBuffer)
752 
753 
754 /*******************************************************************************
755  *
756  * FUNCTION:    AcpiWalkResources
757  *
758  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
759  *                                device we are querying
760  *              Name            - Method name of the resources we want.
761  *                                (METHOD_NAME__CRS, METHOD_NAME__PRS, or
762  *                                METHOD_NAME__AEI)
763  *              UserFunction    - Called for each resource
764  *              Context         - Passed to UserFunction
765  *
766  * RETURN:      Status
767  *
768  * DESCRIPTION: Retrieves the current or possible resource list for the
769  *              specified device. The UserFunction is called once for
770  *              each resource in the list.
771  *
772  ******************************************************************************/
773 
774 ACPI_STATUS
775 AcpiWalkResources (
776     ACPI_HANDLE                 DeviceHandle,
777     char                        *Name,
778     ACPI_WALK_RESOURCE_CALLBACK UserFunction,
779     void                        *Context)
780 {
781     ACPI_STATUS                 Status;
782     ACPI_BUFFER                 Buffer;
783 
784 
785     ACPI_FUNCTION_TRACE (AcpiWalkResources);
786 
787 
788     /* Parameter validation */
789 
790     if (!DeviceHandle || !UserFunction || !Name ||
791         (!ACPI_COMPARE_NAME (Name, METHOD_NAME__CRS) &&
792          !ACPI_COMPARE_NAME (Name, METHOD_NAME__PRS) &&
793          !ACPI_COMPARE_NAME (Name, METHOD_NAME__AEI)))
794     {
795         return_ACPI_STATUS (AE_BAD_PARAMETER);
796     }
797 
798     /* Get the _CRS/_PRS/_AEI resource list */
799 
800     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
801     Status = AcpiRsGetMethodData (DeviceHandle, Name, &Buffer);
802     if (ACPI_FAILURE (Status))
803     {
804         return_ACPI_STATUS (Status);
805     }
806 
807     /* Walk the resource list and cleanup */
808 
809     Status = AcpiWalkResourceBuffer (&Buffer, UserFunction, Context);
810     ACPI_FREE (Buffer.Pointer);
811     return_ACPI_STATUS (Status);
812 }
813 
814 ACPI_EXPORT_SYMBOL (AcpiWalkResources)
815