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)