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