1 /*******************************************************************************
   2  *
   3  * Module Name: rsxface - Public interfaces to the resource manager
   4  *
   5  ******************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 
  45 #define __RSXFACE_C__
  46 #define EXPORT_ACPI_INTERFACES
  47 
  48 #include "acpi.h"
  49 #include "accommon.h"
  50 #include "acresrc.h"
  51 #include "acnamesp.h"
  52 
  53 #define _COMPONENT          ACPI_RESOURCES
  54         ACPI_MODULE_NAME    ("rsxface")
  55 
  56 /* Local macros for 16,32-bit to 64-bit conversion */
  57 
  58 #define ACPI_COPY_FIELD(Out, In, Field)  ((Out)->Field = (In)->Field)
  59 #define ACPI_COPY_ADDRESS(Out, In)                      \
  60     ACPI_COPY_FIELD(Out, In, ResourceType);              \
  61     ACPI_COPY_FIELD(Out, In, ProducerConsumer);          \
  62     ACPI_COPY_FIELD(Out, In, Decode);                    \
  63     ACPI_COPY_FIELD(Out, In, MinAddressFixed);           \
  64     ACPI_COPY_FIELD(Out, In, MaxAddressFixed);           \
  65     ACPI_COPY_FIELD(Out, In, Info);                      \
  66     ACPI_COPY_FIELD(Out, In, Granularity);               \
  67     ACPI_COPY_FIELD(Out, In, Minimum);                   \
  68     ACPI_COPY_FIELD(Out, In, Maximum);                   \
  69     ACPI_COPY_FIELD(Out, In, TranslationOffset);         \
  70     ACPI_COPY_FIELD(Out, In, AddressLength);             \
  71     ACPI_COPY_FIELD(Out, In, ResourceSource);
  72 
  73 
  74 /* Local prototypes */
  75 
  76 static ACPI_STATUS
  77 AcpiRsMatchVendorResource (
  78     ACPI_RESOURCE           *Resource,
  79     void                    *Context);
  80 
  81 static ACPI_STATUS
  82 AcpiRsValidateParameters (
  83     ACPI_HANDLE             DeviceHandle,
  84     ACPI_BUFFER             *Buffer,
  85     ACPI_NAMESPACE_NODE     **ReturnNode);
  86 
  87 
  88 /*******************************************************************************
  89  *
  90  * FUNCTION:    AcpiRsValidateParameters
  91  *
  92  * PARAMETERS:  DeviceHandle    - Handle to a device
  93  *              Buffer          - Pointer to a data buffer
  94  *              ReturnNode      - Pointer to where the device node is returned
  95  *
  96  * RETURN:      Status
  97  *
  98  * DESCRIPTION: Common parameter validation for resource interfaces
  99  *
 100  ******************************************************************************/
 101 
 102 static ACPI_STATUS
 103 AcpiRsValidateParameters (
 104     ACPI_HANDLE             DeviceHandle,
 105     ACPI_BUFFER             *Buffer,
 106     ACPI_NAMESPACE_NODE     **ReturnNode)
 107 {
 108     ACPI_STATUS             Status;
 109     ACPI_NAMESPACE_NODE     *Node;
 110 
 111 
 112     ACPI_FUNCTION_TRACE (RsValidateParameters);
 113 
 114 
 115     /*
 116      * Must have a valid handle to an ACPI device
 117      */
 118     if (!DeviceHandle)
 119     {
 120         return_ACPI_STATUS (AE_BAD_PARAMETER);
 121     }
 122 
 123     Node = AcpiNsValidateHandle (DeviceHandle);
 124     if (!Node)
 125     {
 126         return_ACPI_STATUS (AE_BAD_PARAMETER);
 127     }
 128 
 129     if (Node->Type != ACPI_TYPE_DEVICE)
 130     {
 131         return_ACPI_STATUS (AE_TYPE);
 132     }
 133 
 134     /*
 135      * Validate the user buffer object
 136      *
 137      * if there is a non-zero buffer length we also need a valid pointer in
 138      * the buffer. If it's a zero buffer length, we'll be returning the
 139      * needed buffer size (later), so keep going.
 140      */
 141     Status = AcpiUtValidateBuffer (Buffer);
 142     if (ACPI_FAILURE (Status))
 143     {
 144         return_ACPI_STATUS (Status);
 145     }
 146 
 147     *ReturnNode = Node;
 148     return_ACPI_STATUS (AE_OK);
 149 }
 150 
 151 
 152 /*******************************************************************************
 153  *
 154  * FUNCTION:    AcpiGetIrqRoutingTable
 155  *
 156  * PARAMETERS:  DeviceHandle    - Handle to the Bus device we are querying
 157  *              RetBuffer       - Pointer to a buffer to receive the
 158  *                                current resources for the device
 159  *
 160  * RETURN:      Status
 161  *
 162  * DESCRIPTION: This function is called to get the IRQ routing table for a
 163  *              specific bus. The caller must first acquire a handle for the
 164  *              desired bus. The routine table is placed in the buffer pointed
 165  *              to by the RetBuffer variable parameter.
 166  *
 167  *              If the function fails an appropriate status will be returned
 168  *              and the value of RetBuffer is undefined.
 169  *
 170  *              This function attempts to execute the _PRT method contained in
 171  *              the object indicated by the passed DeviceHandle.
 172  *
 173  ******************************************************************************/
 174 
 175 ACPI_STATUS
 176 AcpiGetIrqRoutingTable  (
 177     ACPI_HANDLE             DeviceHandle,
 178     ACPI_BUFFER             *RetBuffer)
 179 {
 180     ACPI_STATUS             Status;
 181     ACPI_NAMESPACE_NODE     *Node;
 182 
 183 
 184     ACPI_FUNCTION_TRACE (AcpiGetIrqRoutingTable);
 185 
 186 
 187     /* Validate parameters then dispatch to internal routine */
 188 
 189     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
 190     if (ACPI_FAILURE (Status))
 191     {
 192         return_ACPI_STATUS (Status);
 193     }
 194 
 195     Status = AcpiRsGetPrtMethodData (Node, RetBuffer);
 196     return_ACPI_STATUS (Status);
 197 }
 198 
 199 ACPI_EXPORT_SYMBOL (AcpiGetIrqRoutingTable)
 200 
 201 
 202 /*******************************************************************************
 203  *
 204  * FUNCTION:    AcpiGetCurrentResources
 205  *
 206  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
 207  *                                device we are querying
 208  *              RetBuffer       - Pointer to a buffer to receive the
 209  *                                current resources for the device
 210  *
 211  * RETURN:      Status
 212  *
 213  * DESCRIPTION: This function is called to get the current resources for a
 214  *              specific device. The caller must first acquire a handle for
 215  *              the desired device. The resource data is placed in the buffer
 216  *              pointed to by the RetBuffer variable parameter.
 217  *
 218  *              If the function fails an appropriate status will be returned
 219  *              and the value of RetBuffer is undefined.
 220  *
 221  *              This function attempts to execute the _CRS method contained in
 222  *              the object indicated by the passed DeviceHandle.
 223  *
 224  ******************************************************************************/
 225 
 226 ACPI_STATUS
 227 AcpiGetCurrentResources (
 228     ACPI_HANDLE             DeviceHandle,
 229     ACPI_BUFFER             *RetBuffer)
 230 {
 231     ACPI_STATUS             Status;
 232     ACPI_NAMESPACE_NODE     *Node;
 233 
 234 
 235     ACPI_FUNCTION_TRACE (AcpiGetCurrentResources);
 236 
 237 
 238     /* Validate parameters then dispatch to internal routine */
 239 
 240     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
 241     if (ACPI_FAILURE (Status))
 242     {
 243         return_ACPI_STATUS (Status);
 244     }
 245 
 246     Status = AcpiRsGetCrsMethodData (Node, RetBuffer);
 247     return_ACPI_STATUS (Status);
 248 }
 249 
 250 ACPI_EXPORT_SYMBOL (AcpiGetCurrentResources)
 251 
 252 
 253 /*******************************************************************************
 254  *
 255  * FUNCTION:    AcpiGetPossibleResources
 256  *
 257  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
 258  *                                device we are querying
 259  *              RetBuffer       - Pointer to a buffer to receive the
 260  *                                resources for the device
 261  *
 262  * RETURN:      Status
 263  *
 264  * DESCRIPTION: This function is called to get a list of the possible resources
 265  *              for a specific device. The caller must first acquire a handle
 266  *              for the desired device. The resource data is placed in the
 267  *              buffer pointed to by the RetBuffer variable.
 268  *
 269  *              If the function fails an appropriate status will be returned
 270  *              and the value of RetBuffer is undefined.
 271  *
 272  ******************************************************************************/
 273 
 274 ACPI_STATUS
 275 AcpiGetPossibleResources (
 276     ACPI_HANDLE             DeviceHandle,
 277     ACPI_BUFFER             *RetBuffer)
 278 {
 279     ACPI_STATUS             Status;
 280     ACPI_NAMESPACE_NODE     *Node;
 281 
 282 
 283     ACPI_FUNCTION_TRACE (AcpiGetPossibleResources);
 284 
 285 
 286     /* Validate parameters then dispatch to internal routine */
 287 
 288     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
 289     if (ACPI_FAILURE (Status))
 290     {
 291         return_ACPI_STATUS (Status);
 292     }
 293 
 294     Status = AcpiRsGetPrsMethodData (Node, RetBuffer);
 295     return_ACPI_STATUS (Status);
 296 }
 297 
 298 ACPI_EXPORT_SYMBOL (AcpiGetPossibleResources)
 299 
 300 
 301 /*******************************************************************************
 302  *
 303  * FUNCTION:    AcpiSetCurrentResources
 304  *
 305  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
 306  *                                device we are setting resources
 307  *              InBuffer        - Pointer to a buffer containing the
 308  *                                resources to be set for the device
 309  *
 310  * RETURN:      Status
 311  *
 312  * DESCRIPTION: This function is called to set the current resources for a
 313  *              specific device. The caller must first acquire a handle for
 314  *              the desired device. The resource data is passed to the routine
 315  *              the buffer pointed to by the InBuffer variable.
 316  *
 317  ******************************************************************************/
 318 
 319 ACPI_STATUS
 320 AcpiSetCurrentResources (
 321     ACPI_HANDLE             DeviceHandle,
 322     ACPI_BUFFER             *InBuffer)
 323 {
 324     ACPI_STATUS             Status;
 325     ACPI_NAMESPACE_NODE     *Node;
 326 
 327 
 328     ACPI_FUNCTION_TRACE (AcpiSetCurrentResources);
 329 
 330 
 331     /* Validate the buffer, don't allow zero length */
 332 
 333     if ((!InBuffer) ||
 334         (!InBuffer->Pointer) ||
 335         (!InBuffer->Length))
 336     {
 337         return_ACPI_STATUS (AE_BAD_PARAMETER);
 338     }
 339 
 340     /* Validate parameters then dispatch to internal routine */
 341 
 342     Status = AcpiRsValidateParameters (DeviceHandle, InBuffer, &Node);
 343     if (ACPI_FAILURE (Status))
 344     {
 345         return_ACPI_STATUS (Status);
 346     }
 347 
 348     Status = AcpiRsSetSrsMethodData (Node, InBuffer);
 349     return_ACPI_STATUS (Status);
 350 }
 351 
 352 ACPI_EXPORT_SYMBOL (AcpiSetCurrentResources)
 353 
 354 
 355 /*******************************************************************************
 356  *
 357  * FUNCTION:    AcpiGetEventResources
 358  *
 359  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
 360  *                                device we are getting resources
 361  *              InBuffer        - Pointer to a buffer containing the
 362  *                                resources to be set for the device
 363  *
 364  * RETURN:      Status
 365  *
 366  * DESCRIPTION: This function is called to get the event resources for a
 367  *              specific device. The caller must first acquire a handle for
 368  *              the desired device. The resource data is passed to the routine
 369  *              the buffer pointed to by the InBuffer variable. Uses the
 370  *              _AEI method.
 371  *
 372  ******************************************************************************/
 373 
 374 ACPI_STATUS
 375 AcpiGetEventResources (
 376     ACPI_HANDLE             DeviceHandle,
 377     ACPI_BUFFER             *RetBuffer)
 378 {
 379     ACPI_STATUS             Status;
 380     ACPI_NAMESPACE_NODE     *Node;
 381 
 382 
 383     ACPI_FUNCTION_TRACE (AcpiGetEventResources);
 384 
 385 
 386     /* Validate parameters then dispatch to internal routine */
 387 
 388     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
 389     if (ACPI_FAILURE (Status))
 390     {
 391         return_ACPI_STATUS (Status);
 392     }
 393 
 394     Status = AcpiRsGetAeiMethodData (Node, RetBuffer);
 395     return_ACPI_STATUS (Status);
 396 }
 397 
 398 ACPI_EXPORT_SYMBOL (AcpiGetEventResources)
 399 
 400 
 401 /******************************************************************************
 402  *
 403  * FUNCTION:    AcpiResourceToAddress64
 404  *
 405  * PARAMETERS:  Resource        - Pointer to a resource
 406  *              Out             - Pointer to the users's return buffer
 407  *                                (a struct acpi_resource_address64)
 408  *
 409  * RETURN:      Status
 410  *
 411  * DESCRIPTION: If the resource is an address16, address32, or address64,
 412  *              copy it to the address64 return buffer. This saves the
 413  *              caller from having to duplicate code for different-sized
 414  *              addresses.
 415  *
 416  ******************************************************************************/
 417 
 418 ACPI_STATUS
 419 AcpiResourceToAddress64 (
 420     ACPI_RESOURCE               *Resource,
 421     ACPI_RESOURCE_ADDRESS64     *Out)
 422 {
 423     ACPI_RESOURCE_ADDRESS16     *Address16;
 424     ACPI_RESOURCE_ADDRESS32     *Address32;
 425 
 426 
 427     if (!Resource || !Out)
 428     {
 429         return (AE_BAD_PARAMETER);
 430     }
 431 
 432     /* Convert 16 or 32 address descriptor to 64 */
 433 
 434     switch (Resource->Type)
 435     {
 436     case ACPI_RESOURCE_TYPE_ADDRESS16:
 437 
 438         Address16 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS16, &Resource->Data);
 439         ACPI_COPY_ADDRESS (Out, Address16);
 440         break;
 441 
 442     case ACPI_RESOURCE_TYPE_ADDRESS32:
 443 
 444         Address32 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS32, &Resource->Data);
 445         ACPI_COPY_ADDRESS (Out, Address32);
 446         break;
 447 
 448     case ACPI_RESOURCE_TYPE_ADDRESS64:
 449 
 450         /* Simple copy for 64 bit source */
 451 
 452         ACPI_MEMCPY (Out, &Resource->Data, sizeof (ACPI_RESOURCE_ADDRESS64));
 453         break;
 454 
 455     default:
 456 
 457         return (AE_BAD_PARAMETER);
 458     }
 459 
 460     return (AE_OK);
 461 }
 462 
 463 ACPI_EXPORT_SYMBOL (AcpiResourceToAddress64)
 464 
 465 
 466 /*******************************************************************************
 467  *
 468  * FUNCTION:    AcpiGetVendorResource
 469  *
 470  * PARAMETERS:  DeviceHandle    - Handle for the parent device object
 471  *              Name            - Method name for the parent resource
 472  *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
 473  *              Uuid            - Pointer to the UUID to be matched.
 474  *                                includes both subtype and 16-byte UUID
 475  *              RetBuffer       - Where the vendor resource is returned
 476  *
 477  * RETURN:      Status
 478  *
 479  * DESCRIPTION: Walk a resource template for the specified device to find a
 480  *              vendor-defined resource that matches the supplied UUID and
 481  *              UUID subtype. Returns a ACPI_RESOURCE of type Vendor.
 482  *
 483  ******************************************************************************/
 484 
 485 ACPI_STATUS
 486 AcpiGetVendorResource (
 487     ACPI_HANDLE             DeviceHandle,
 488     char                    *Name,
 489     ACPI_VENDOR_UUID        *Uuid,
 490     ACPI_BUFFER             *RetBuffer)
 491 {
 492     ACPI_VENDOR_WALK_INFO   Info;
 493     ACPI_STATUS             Status;
 494 
 495 
 496     /* Other parameters are validated by AcpiWalkResources */
 497 
 498     if (!Uuid || !RetBuffer)
 499     {
 500         return (AE_BAD_PARAMETER);
 501     }
 502 
 503     Info.Uuid = Uuid;
 504     Info.Buffer = RetBuffer;
 505     Info.Status = AE_NOT_EXIST;
 506 
 507     /* Walk the _CRS or _PRS resource list for this device */
 508 
 509     Status = AcpiWalkResources (DeviceHandle, Name, AcpiRsMatchVendorResource,
 510                 &Info);
 511     if (ACPI_FAILURE (Status))
 512     {
 513         return (Status);
 514     }
 515 
 516     return (Info.Status);
 517 }
 518 
 519 ACPI_EXPORT_SYMBOL (AcpiGetVendorResource)
 520 
 521 
 522 /*******************************************************************************
 523  *
 524  * FUNCTION:    AcpiRsMatchVendorResource
 525  *
 526  * PARAMETERS:  ACPI_WALK_RESOURCE_CALLBACK
 527  *
 528  * RETURN:      Status
 529  *
 530  * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
 531  *
 532  ******************************************************************************/
 533 
 534 static ACPI_STATUS
 535 AcpiRsMatchVendorResource (
 536     ACPI_RESOURCE           *Resource,
 537     void                    *Context)
 538 {
 539     ACPI_VENDOR_WALK_INFO       *Info = Context;
 540     ACPI_RESOURCE_VENDOR_TYPED  *Vendor;
 541     ACPI_BUFFER                 *Buffer;
 542     ACPI_STATUS                 Status;
 543 
 544 
 545     /* Ignore all descriptors except Vendor */
 546 
 547     if (Resource->Type != ACPI_RESOURCE_TYPE_VENDOR)
 548     {
 549         return (AE_OK);
 550     }
 551 
 552     Vendor = &Resource->Data.VendorTyped;
 553 
 554     /*
 555      * For a valid match, these conditions must hold:
 556      *
 557      * 1) Length of descriptor data must be at least as long as a UUID struct
 558      * 2) The UUID subtypes must match
 559      * 3) The UUID data must match
 560      */
 561     if ((Vendor->ByteLength < (ACPI_UUID_LENGTH + 1)) ||
 562         (Vendor->UuidSubtype != Info->Uuid->Subtype)  ||
 563         (ACPI_MEMCMP (Vendor->Uuid, Info->Uuid->Data, ACPI_UUID_LENGTH)))
 564     {
 565         return (AE_OK);
 566     }
 567 
 568     /* Validate/Allocate/Clear caller buffer */
 569 
 570     Buffer = Info->Buffer;
 571     Status = AcpiUtInitializeBuffer (Buffer, Resource->Length);
 572     if (ACPI_FAILURE (Status))
 573     {
 574         return (Status);
 575     }
 576 
 577     /* Found the correct resource, copy and return it */
 578 
 579     ACPI_MEMCPY (Buffer->Pointer, Resource, Resource->Length);
 580     Buffer->Length = Resource->Length;
 581 
 582     /* Found the desired descriptor, terminate resource walk */
 583 
 584     Info->Status = AE_OK;
 585     return (AE_CTRL_TERMINATE);
 586 }
 587 
 588 
 589 /*******************************************************************************
 590  *
 591  * FUNCTION:    AcpiWalkResourceBuffer
 592  *
 593  * PARAMETERS:  Buffer          - Formatted buffer returned by one of the
 594  *                                various Get*Resource functions
 595  *              UserFunction    - Called for each resource
 596  *              Context         - Passed to UserFunction
 597  *
 598  * RETURN:      Status
 599  *
 600  * DESCRIPTION: Walks the input resource template. The UserFunction is called
 601  *              once for each resource in the list.
 602  *
 603  ******************************************************************************/
 604 
 605 ACPI_STATUS
 606 AcpiWalkResourceBuffer (
 607     ACPI_BUFFER                 *Buffer,
 608     ACPI_WALK_RESOURCE_CALLBACK UserFunction,
 609     void                        *Context)
 610 {
 611     ACPI_STATUS                 Status = AE_OK;
 612     ACPI_RESOURCE               *Resource;
 613     ACPI_RESOURCE               *ResourceEnd;
 614 
 615 
 616     ACPI_FUNCTION_TRACE (AcpiWalkResourceBuffer);
 617 
 618 
 619     /* Parameter validation */
 620 
 621     if (!Buffer || !Buffer->Pointer || !UserFunction)
 622     {
 623         return_ACPI_STATUS (AE_BAD_PARAMETER);
 624     }
 625 
 626     /* Buffer contains the resource list and length */
 627 
 628     Resource = ACPI_CAST_PTR (ACPI_RESOURCE, Buffer->Pointer);
 629     ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Buffer->Pointer, Buffer->Length);
 630 
 631     /* Walk the resource list until the EndTag is found (or buffer end) */
 632 
 633     while (Resource < ResourceEnd)
 634     {
 635         /* Sanity check the resource type */
 636 
 637         if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
 638         {
 639             Status = AE_AML_INVALID_RESOURCE_TYPE;
 640             break;
 641         }
 642 
 643         /* Sanity check the length. It must not be zero, or we loop forever */
 644 
 645         if (!Resource->Length)
 646         {
 647             return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
 648         }
 649 
 650         /* Invoke the user function, abort on any error returned */
 651 
 652         Status = UserFunction (Resource, Context);
 653         if (ACPI_FAILURE (Status))
 654         {
 655             if (Status == AE_CTRL_TERMINATE)
 656             {
 657                 /* This is an OK termination by the user function */
 658 
 659                 Status = AE_OK;
 660             }
 661             break;
 662         }
 663 
 664         /* EndTag indicates end-of-list */
 665 
 666         if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
 667         {
 668             break;
 669         }
 670 
 671         /* Get the next resource descriptor */
 672 
 673         Resource = ACPI_NEXT_RESOURCE (Resource);
 674     }
 675 
 676     return_ACPI_STATUS (Status);
 677 }
 678 
 679 ACPI_EXPORT_SYMBOL (AcpiWalkResourceBuffer)
 680 
 681 
 682 /*******************************************************************************
 683  *
 684  * FUNCTION:    AcpiWalkResources
 685  *
 686  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
 687  *                                device we are querying
 688  *              Name            - Method name of the resources we want.
 689  *                                (METHOD_NAME__CRS, METHOD_NAME__PRS, or
 690  *                                METHOD_NAME__AEI)
 691  *              UserFunction    - Called for each resource
 692  *              Context         - Passed to UserFunction
 693  *
 694  * RETURN:      Status
 695  *
 696  * DESCRIPTION: Retrieves the current or possible resource list for the
 697  *              specified device. The UserFunction is called once for
 698  *              each resource in the list.
 699  *
 700  ******************************************************************************/
 701 
 702 ACPI_STATUS
 703 AcpiWalkResources (
 704     ACPI_HANDLE                 DeviceHandle,
 705     char                        *Name,
 706     ACPI_WALK_RESOURCE_CALLBACK UserFunction,
 707     void                        *Context)
 708 {
 709     ACPI_STATUS                 Status;
 710     ACPI_BUFFER                 Buffer;
 711 
 712 
 713     ACPI_FUNCTION_TRACE (AcpiWalkResources);
 714 
 715 
 716     /* Parameter validation */
 717 
 718     if (!DeviceHandle || !UserFunction || !Name ||
 719         (!ACPI_COMPARE_NAME (Name, METHOD_NAME__CRS) &&
 720          !ACPI_COMPARE_NAME (Name, METHOD_NAME__PRS) &&
 721          !ACPI_COMPARE_NAME (Name, METHOD_NAME__AEI)))
 722     {
 723         return_ACPI_STATUS (AE_BAD_PARAMETER);
 724     }
 725 
 726     /* Get the _CRS/_PRS/_AEI resource list */
 727 
 728     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
 729     Status = AcpiRsGetMethodData (DeviceHandle, Name, &Buffer);
 730     if (ACPI_FAILURE (Status))
 731     {
 732         return_ACPI_STATUS (Status);
 733     }
 734 
 735     /* Walk the resource list and cleanup */
 736 
 737     Status = AcpiWalkResourceBuffer (&Buffer, UserFunction, Context);
 738     ACPI_FREE (Buffer.Pointer);
 739     return_ACPI_STATUS (Status);
 740 }
 741 
 742 ACPI_EXPORT_SYMBOL (AcpiWalkResources)