1 /*******************************************************************************
   2  *
   3  * Module Name: rsxface - Public interfaces to the resource manager
   4  *
   5  ******************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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 
  47 #include "acpi.h"
  48 #include "accommon.h"
  49 #include "acresrc.h"
  50 #include "acnamesp.h"
  51 
  52 #define _COMPONENT          ACPI_RESOURCES
  53         ACPI_MODULE_NAME    ("rsxface")
  54 
  55 /* Local macros for 16,32-bit to 64-bit conversion */
  56 
  57 #define ACPI_COPY_FIELD(Out, In, Field)  ((Out)->Field = (In)->Field)
  58 #define ACPI_COPY_ADDRESS(Out, In)                      \
  59     ACPI_COPY_FIELD(Out, In, ResourceType);              \
  60     ACPI_COPY_FIELD(Out, In, ProducerConsumer);          \
  61     ACPI_COPY_FIELD(Out, In, Decode);                    \
  62     ACPI_COPY_FIELD(Out, In, MinAddressFixed);           \
  63     ACPI_COPY_FIELD(Out, In, MaxAddressFixed);           \
  64     ACPI_COPY_FIELD(Out, In, Info);                      \
  65     ACPI_COPY_FIELD(Out, In, Granularity);               \
  66     ACPI_COPY_FIELD(Out, In, Minimum);                   \
  67     ACPI_COPY_FIELD(Out, In, Maximum);                   \
  68     ACPI_COPY_FIELD(Out, In, TranslationOffset);         \
  69     ACPI_COPY_FIELD(Out, In, AddressLength);             \
  70     ACPI_COPY_FIELD(Out, In, ResourceSource);
  71 
  72 
  73 /* Local prototypes */
  74 
  75 static ACPI_STATUS
  76 AcpiRsMatchVendorResource (
  77     ACPI_RESOURCE           *Resource,
  78     void                    *Context);
  79 
  80 static ACPI_STATUS
  81 AcpiRsValidateParameters (
  82     ACPI_HANDLE             DeviceHandle,
  83     ACPI_BUFFER             *Buffer,
  84     ACPI_NAMESPACE_NODE     **ReturnNode);
  85 
  86 
  87 /*******************************************************************************
  88  *
  89  * FUNCTION:    AcpiRsValidateParameters
  90  *
  91  * PARAMETERS:  DeviceHandle    - Handle to a device
  92  *              Buffer          - Pointer to a data buffer
  93  *              ReturnNode      - Pointer to where the device node is returned
  94  *
  95  * RETURN:      Status
  96  *
  97  * DESCRIPTION: Common parameter validation for resource interfaces
  98  *
  99  ******************************************************************************/
 100 
 101 static ACPI_STATUS
 102 AcpiRsValidateParameters (
 103     ACPI_HANDLE             DeviceHandle,
 104     ACPI_BUFFER             *Buffer,
 105     ACPI_NAMESPACE_NODE     **ReturnNode)
 106 {
 107     ACPI_STATUS             Status;
 108     ACPI_NAMESPACE_NODE     *Node;
 109 
 110 
 111     ACPI_FUNCTION_TRACE (RsValidateParameters);
 112 
 113 
 114     /*
 115      * Must have a valid handle to an ACPI device
 116      */
 117     if (!DeviceHandle)
 118     {
 119         return_ACPI_STATUS (AE_BAD_PARAMETER);
 120     }
 121 
 122     Node = AcpiNsValidateHandle (DeviceHandle);
 123     if (!Node)
 124     {
 125         return_ACPI_STATUS (AE_BAD_PARAMETER);
 126     }
 127 
 128     if (Node->Type != ACPI_TYPE_DEVICE)
 129     {
 130         return_ACPI_STATUS (AE_TYPE);
 131     }
 132 
 133     /*
 134      * Validate the user buffer object
 135      *
 136      * if there is a non-zero buffer length we also need a valid pointer in
 137      * the buffer. If it's a zero buffer length, we'll be returning the
 138      * needed buffer size (later), so keep going.
 139      */
 140     Status = AcpiUtValidateBuffer (Buffer);
 141     if (ACPI_FAILURE (Status))
 142     {
 143         return_ACPI_STATUS (Status);
 144     }
 145 
 146     *ReturnNode = Node;
 147     return_ACPI_STATUS (AE_OK);
 148 }
 149 
 150 
 151 /*******************************************************************************
 152  *
 153  * FUNCTION:    AcpiGetIrqRoutingTable
 154  *
 155  * PARAMETERS:  DeviceHandle    - Handle to the Bus device we are querying
 156  *              RetBuffer       - Pointer to a buffer to receive the
 157  *                                current resources for the device
 158  *
 159  * RETURN:      Status
 160  *
 161  * DESCRIPTION: This function is called to get the IRQ routing table for a
 162  *              specific bus. The caller must first acquire a handle for the
 163  *              desired bus. The routine table is placed in the buffer pointed
 164  *              to by the RetBuffer variable parameter.
 165  *
 166  *              If the function fails an appropriate status will be returned
 167  *              and the value of RetBuffer is undefined.
 168  *
 169  *              This function attempts to execute the _PRT method contained in
 170  *              the object indicated by the passed DeviceHandle.
 171  *
 172  ******************************************************************************/
 173 
 174 ACPI_STATUS
 175 AcpiGetIrqRoutingTable  (
 176     ACPI_HANDLE             DeviceHandle,
 177     ACPI_BUFFER             *RetBuffer)
 178 {
 179     ACPI_STATUS             Status;
 180     ACPI_NAMESPACE_NODE     *Node;
 181 
 182 
 183     ACPI_FUNCTION_TRACE (AcpiGetIrqRoutingTable);
 184 
 185 
 186     /* Validate parameters then dispatch to internal routine */
 187 
 188     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
 189     if (ACPI_FAILURE (Status))
 190     {
 191         return_ACPI_STATUS (Status);
 192     }
 193 
 194     Status = AcpiRsGetPrtMethodData (Node, RetBuffer);
 195     return_ACPI_STATUS (Status);
 196 }
 197 
 198 ACPI_EXPORT_SYMBOL (AcpiGetIrqRoutingTable)
 199 
 200 
 201 /*******************************************************************************
 202  *
 203  * FUNCTION:    AcpiGetCurrentResources
 204  *
 205  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
 206  *                                device we are querying
 207  *              RetBuffer       - Pointer to a buffer to receive the
 208  *                                current resources for the device
 209  *
 210  * RETURN:      Status
 211  *
 212  * DESCRIPTION: This function is called to get the current resources for a
 213  *              specific device. The caller must first acquire a handle for
 214  *              the desired device. The resource data is placed in the buffer
 215  *              pointed to by the RetBuffer variable parameter.
 216  *
 217  *              If the function fails an appropriate status will be returned
 218  *              and the value of RetBuffer is undefined.
 219  *
 220  *              This function attempts to execute the _CRS method contained in
 221  *              the object indicated by the passed DeviceHandle.
 222  *
 223  ******************************************************************************/
 224 
 225 ACPI_STATUS
 226 AcpiGetCurrentResources (
 227     ACPI_HANDLE             DeviceHandle,
 228     ACPI_BUFFER             *RetBuffer)
 229 {
 230     ACPI_STATUS             Status;
 231     ACPI_NAMESPACE_NODE     *Node;
 232 
 233 
 234     ACPI_FUNCTION_TRACE (AcpiGetCurrentResources);
 235 
 236 
 237     /* Validate parameters then dispatch to internal routine */
 238 
 239     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
 240     if (ACPI_FAILURE (Status))
 241     {
 242         return_ACPI_STATUS (Status);
 243     }
 244 
 245     Status = AcpiRsGetCrsMethodData (Node, RetBuffer);
 246     return_ACPI_STATUS (Status);
 247 }
 248 
 249 ACPI_EXPORT_SYMBOL (AcpiGetCurrentResources)
 250 
 251 
 252 /*******************************************************************************
 253  *
 254  * FUNCTION:    AcpiGetPossibleResources
 255  *
 256  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
 257  *                                device we are querying
 258  *              RetBuffer       - Pointer to a buffer to receive the
 259  *                                resources for the device
 260  *
 261  * RETURN:      Status
 262  *
 263  * DESCRIPTION: This function is called to get a list of the possible resources
 264  *              for a specific device. The caller must first acquire a handle
 265  *              for the desired device. The resource data is placed in the
 266  *              buffer pointed to by the RetBuffer variable.
 267  *
 268  *              If the function fails an appropriate status will be returned
 269  *              and the value of RetBuffer is undefined.
 270  *
 271  ******************************************************************************/
 272 
 273 ACPI_STATUS
 274 AcpiGetPossibleResources (
 275     ACPI_HANDLE             DeviceHandle,
 276     ACPI_BUFFER             *RetBuffer)
 277 {
 278     ACPI_STATUS             Status;
 279     ACPI_NAMESPACE_NODE     *Node;
 280 
 281 
 282     ACPI_FUNCTION_TRACE (AcpiGetPossibleResources);
 283 
 284 
 285     /* Validate parameters then dispatch to internal routine */
 286 
 287     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
 288     if (ACPI_FAILURE (Status))
 289     {
 290         return_ACPI_STATUS (Status);
 291     }
 292 
 293     Status = AcpiRsGetPrsMethodData (Node, RetBuffer);
 294     return_ACPI_STATUS (Status);
 295 }
 296 
 297 ACPI_EXPORT_SYMBOL (AcpiGetPossibleResources)
 298 
 299 
 300 /*******************************************************************************
 301  *
 302  * FUNCTION:    AcpiSetCurrentResources
 303  *
 304  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
 305  *                                device we are setting resources
 306  *              InBuffer        - Pointer to a buffer containing the
 307  *                                resources to be set for the device
 308  *
 309  * RETURN:      Status
 310  *
 311  * DESCRIPTION: This function is called to set the current resources for a
 312  *              specific device. The caller must first acquire a handle for
 313  *              the desired device. The resource data is passed to the routine
 314  *              the buffer pointed to by the InBuffer variable.
 315  *
 316  ******************************************************************************/
 317 
 318 ACPI_STATUS
 319 AcpiSetCurrentResources (
 320     ACPI_HANDLE             DeviceHandle,
 321     ACPI_BUFFER             *InBuffer)
 322 {
 323     ACPI_STATUS             Status;
 324     ACPI_NAMESPACE_NODE     *Node;
 325 
 326 
 327     ACPI_FUNCTION_TRACE (AcpiSetCurrentResources);
 328 
 329 
 330     /* Validate the buffer, don't allow zero length */
 331 
 332     if ((!InBuffer) ||
 333         (!InBuffer->Pointer) ||
 334         (!InBuffer->Length))
 335     {
 336         return_ACPI_STATUS (AE_BAD_PARAMETER);
 337     }
 338 
 339     /* Validate parameters then dispatch to internal routine */
 340 
 341     Status = AcpiRsValidateParameters (DeviceHandle, InBuffer, &Node);
 342     if (ACPI_FAILURE (Status))
 343     {
 344         return_ACPI_STATUS (Status);
 345     }
 346 
 347     Status = AcpiRsSetSrsMethodData (Node, InBuffer);
 348     return_ACPI_STATUS (Status);
 349 }
 350 
 351 ACPI_EXPORT_SYMBOL (AcpiSetCurrentResources)
 352 
 353 
 354 /******************************************************************************
 355  *
 356  * FUNCTION:    AcpiResourceToAddress64
 357  *
 358  * PARAMETERS:  Resource        - Pointer to a resource
 359  *              Out             - Pointer to the users's return buffer
 360  *                                (a struct acpi_resource_address64)
 361  *
 362  * RETURN:      Status
 363  *
 364  * DESCRIPTION: If the resource is an address16, address32, or address64,
 365  *              copy it to the address64 return buffer. This saves the
 366  *              caller from having to duplicate code for different-sized
 367  *              addresses.
 368  *
 369  ******************************************************************************/
 370 
 371 ACPI_STATUS
 372 AcpiResourceToAddress64 (
 373     ACPI_RESOURCE               *Resource,
 374     ACPI_RESOURCE_ADDRESS64     *Out)
 375 {
 376     ACPI_RESOURCE_ADDRESS16     *Address16;
 377     ACPI_RESOURCE_ADDRESS32     *Address32;
 378 
 379 
 380     if (!Resource || !Out)
 381     {
 382         return (AE_BAD_PARAMETER);
 383     }
 384 
 385     /* Convert 16 or 32 address descriptor to 64 */
 386 
 387     switch (Resource->Type)
 388     {
 389     case ACPI_RESOURCE_TYPE_ADDRESS16:
 390 
 391         Address16 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS16, &Resource->Data);
 392         ACPI_COPY_ADDRESS (Out, Address16);
 393         break;
 394 
 395     case ACPI_RESOURCE_TYPE_ADDRESS32:
 396 
 397         Address32 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS32, &Resource->Data);
 398         ACPI_COPY_ADDRESS (Out, Address32);
 399         break;
 400 
 401     case ACPI_RESOURCE_TYPE_ADDRESS64:
 402 
 403         /* Simple copy for 64 bit source */
 404 
 405         ACPI_MEMCPY (Out, &Resource->Data, sizeof (ACPI_RESOURCE_ADDRESS64));
 406         break;
 407 
 408     default:
 409         return (AE_BAD_PARAMETER);
 410     }
 411 
 412     return (AE_OK);
 413 }
 414 
 415 ACPI_EXPORT_SYMBOL (AcpiResourceToAddress64)
 416 
 417 
 418 /*******************************************************************************
 419  *
 420  * FUNCTION:    AcpiGetVendorResource
 421  *
 422  * PARAMETERS:  DeviceHandle    - Handle for the parent device object
 423  *              Name            - Method name for the parent resource
 424  *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
 425  *              Uuid            - Pointer to the UUID to be matched.
 426  *                                includes both subtype and 16-byte UUID
 427  *              RetBuffer       - Where the vendor resource is returned
 428  *
 429  * RETURN:      Status
 430  *
 431  * DESCRIPTION: Walk a resource template for the specified evice to find a
 432  *              vendor-defined resource that matches the supplied UUID and
 433  *              UUID subtype. Returns a ACPI_RESOURCE of type Vendor.
 434  *
 435  ******************************************************************************/
 436 
 437 ACPI_STATUS
 438 AcpiGetVendorResource (
 439     ACPI_HANDLE             DeviceHandle,
 440     char                    *Name,
 441     ACPI_VENDOR_UUID        *Uuid,
 442     ACPI_BUFFER             *RetBuffer)
 443 {
 444     ACPI_VENDOR_WALK_INFO   Info;
 445     ACPI_STATUS             Status;
 446 
 447 
 448     /* Other parameters are validated by AcpiWalkResources */
 449 
 450     if (!Uuid || !RetBuffer)
 451     {
 452         return (AE_BAD_PARAMETER);
 453     }
 454 
 455     Info.Uuid = Uuid;
 456     Info.Buffer = RetBuffer;
 457     Info.Status = AE_NOT_EXIST;
 458 
 459     /* Walk the _CRS or _PRS resource list for this device */
 460 
 461     Status = AcpiWalkResources (DeviceHandle, Name, AcpiRsMatchVendorResource,
 462                 &Info);
 463     if (ACPI_FAILURE (Status))
 464     {
 465         return (Status);
 466     }
 467 
 468     return (Info.Status);
 469 }
 470 
 471 ACPI_EXPORT_SYMBOL (AcpiGetVendorResource)
 472 
 473 
 474 /*******************************************************************************
 475  *
 476  * FUNCTION:    AcpiRsMatchVendorResource
 477  *
 478  * PARAMETERS:  ACPI_WALK_RESOURCE_CALLBACK
 479  *
 480  * RETURN:      Status
 481  *
 482  * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
 483  *
 484  ******************************************************************************/
 485 
 486 static ACPI_STATUS
 487 AcpiRsMatchVendorResource (
 488     ACPI_RESOURCE           *Resource,
 489     void                    *Context)
 490 {
 491     ACPI_VENDOR_WALK_INFO       *Info = Context;
 492     ACPI_RESOURCE_VENDOR_TYPED  *Vendor;
 493     ACPI_BUFFER                 *Buffer;
 494     ACPI_STATUS                 Status;
 495 
 496 
 497     /* Ignore all descriptors except Vendor */
 498 
 499     if (Resource->Type != ACPI_RESOURCE_TYPE_VENDOR)
 500     {
 501         return (AE_OK);
 502     }
 503 
 504     Vendor = &Resource->Data.VendorTyped;
 505 
 506     /*
 507      * For a valid match, these conditions must hold:
 508      *
 509      * 1) Length of descriptor data must be at least as long as a UUID struct
 510      * 2) The UUID subtypes must match
 511      * 3) The UUID data must match
 512      */
 513     if ((Vendor->ByteLength < (ACPI_UUID_LENGTH + 1)) ||
 514         (Vendor->UuidSubtype != Info->Uuid->Subtype)  ||
 515         (ACPI_MEMCMP (Vendor->Uuid, Info->Uuid->Data, ACPI_UUID_LENGTH)))
 516     {
 517         return (AE_OK);
 518     }
 519 
 520     /* Validate/Allocate/Clear caller buffer */
 521 
 522     Buffer = Info->Buffer;
 523     Status = AcpiUtInitializeBuffer (Buffer, Resource->Length);
 524     if (ACPI_FAILURE (Status))
 525     {
 526         return (Status);
 527     }
 528 
 529     /* Found the correct resource, copy and return it */
 530 
 531     ACPI_MEMCPY (Buffer->Pointer, Resource, Resource->Length);
 532     Buffer->Length = Resource->Length;
 533 
 534     /* Found the desired descriptor, terminate resource walk */
 535 
 536     Info->Status = AE_OK;
 537     return (AE_CTRL_TERMINATE);
 538 }
 539 
 540 
 541 /*******************************************************************************
 542  *
 543  * FUNCTION:    AcpiWalkResources
 544  *
 545  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
 546  *                                device we are querying
 547  *              Name            - Method name of the resources we want
 548  *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
 549  *              UserFunction    - Called for each resource
 550  *              Context         - Passed to UserFunction
 551  *
 552  * RETURN:      Status
 553  *
 554  * DESCRIPTION: Retrieves the current or possible resource list for the
 555  *              specified device. The UserFunction is called once for
 556  *              each resource in the list.
 557  *
 558  ******************************************************************************/
 559 
 560 ACPI_STATUS
 561 AcpiWalkResources (
 562     ACPI_HANDLE                 DeviceHandle,
 563     char                        *Name,
 564     ACPI_WALK_RESOURCE_CALLBACK UserFunction,
 565     void                        *Context)
 566 {
 567     ACPI_STATUS                 Status;
 568     ACPI_BUFFER                 Buffer;
 569     ACPI_RESOURCE               *Resource;
 570     ACPI_RESOURCE               *ResourceEnd;
 571 
 572 
 573     ACPI_FUNCTION_TRACE (AcpiWalkResources);
 574 
 575 
 576     /* Parameter validation */
 577 
 578     if (!DeviceHandle || !UserFunction || !Name ||
 579         (!ACPI_COMPARE_NAME (Name, METHOD_NAME__CRS) &&
 580          !ACPI_COMPARE_NAME (Name, METHOD_NAME__PRS)))
 581     {
 582         return_ACPI_STATUS (AE_BAD_PARAMETER);
 583     }
 584 
 585     /* Get the _CRS or _PRS resource list */
 586 
 587     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
 588     Status = AcpiRsGetMethodData (DeviceHandle, Name, &Buffer);
 589     if (ACPI_FAILURE (Status))
 590     {
 591         return_ACPI_STATUS (Status);
 592     }
 593 
 594     /* Buffer now contains the resource list */
 595 
 596     Resource = ACPI_CAST_PTR (ACPI_RESOURCE, Buffer.Pointer);
 597     ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Buffer.Pointer, Buffer.Length);
 598 
 599     /* Walk the resource list until the EndTag is found (or buffer end) */
 600 
 601     while (Resource < ResourceEnd)
 602     {
 603         /* Sanity check the resource */
 604 
 605         if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
 606         {
 607             Status = AE_AML_INVALID_RESOURCE_TYPE;
 608             break;
 609         }
 610 
 611         /* Invoke the user function, abort on any error returned */
 612 
 613         Status = UserFunction (Resource, Context);
 614         if (ACPI_FAILURE (Status))
 615         {
 616             if (Status == AE_CTRL_TERMINATE)
 617             {
 618                 /* This is an OK termination by the user function */
 619 
 620                 Status = AE_OK;
 621             }
 622             break;
 623         }
 624 
 625         /* EndTag indicates end-of-list */
 626 
 627         if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
 628         {
 629             break;
 630         }
 631 
 632         /* Get the next resource descriptor */
 633 
 634         Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length);
 635     }
 636 
 637     ACPI_FREE (Buffer.Pointer);
 638     return_ACPI_STATUS (Status);
 639 }
 640 
 641 ACPI_EXPORT_SYMBOL (AcpiWalkResources)