1 /******************************************************************************* 2 * 3 * Module Name: rsxface - Public interfaces to the resource manager 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, 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 return (AE_BAD_PARAMETER); 406 } 407 408 return (AE_OK); 409 } 410 411 ACPI_EXPORT_SYMBOL(acpi_resource_to_address64) 412 413 /******************************************************************************* 414 * 415 * FUNCTION: acpi_get_vendor_resource 416 * 417 * PARAMETERS: device_handle - Handle for the parent device object 418 * name - Method name for the parent resource 419 * (METHOD_NAME__CRS or METHOD_NAME__PRS) 420 * uuid - Pointer to the UUID to be matched. 421 * includes both subtype and 16-byte UUID 422 * ret_buffer - Where the vendor resource is returned 423 * 424 * RETURN: Status 425 * 426 * DESCRIPTION: Walk a resource template for the specified evice to find a 427 * vendor-defined resource that matches the supplied UUID and 428 * UUID subtype. Returns a struct acpi_resource of type Vendor. 429 * 430 ******************************************************************************/ 431 acpi_status 432 acpi_get_vendor_resource(acpi_handle device_handle, 433 char *name, 434 struct acpi_vendor_uuid * uuid, 435 struct acpi_buffer * ret_buffer) 436 { 437 struct acpi_vendor_walk_info info; 438 acpi_status status; 439 440 /* Other parameters are validated by acpi_walk_resources */ 441 442 if (!uuid || !ret_buffer) { 443 return (AE_BAD_PARAMETER); 444 } 445 446 info.uuid = uuid; 447 info.buffer = ret_buffer; 448 info.status = AE_NOT_EXIST; 449 450 /* Walk the _CRS or _PRS resource list for this device */ 451 452 status = 453 acpi_walk_resources(device_handle, name, 454 acpi_rs_match_vendor_resource, &info); 455 if (ACPI_FAILURE(status)) { 456 return (status); 457 } 458 459 return (info.status); 460 } 461 462 ACPI_EXPORT_SYMBOL(acpi_get_vendor_resource) 463 464 /******************************************************************************* 465 * 466 * FUNCTION: acpi_rs_match_vendor_resource 467 * 468 * PARAMETERS: acpi_walk_resource_callback 469 * 470 * RETURN: Status 471 * 472 * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID 473 * 474 ******************************************************************************/ 475 static acpi_status 476 acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context) 477 { 478 struct acpi_vendor_walk_info *info = context; 479 struct acpi_resource_vendor_typed *vendor; 480 struct acpi_buffer *buffer; 481 acpi_status status; 482 483 /* Ignore all descriptors except Vendor */ 484 485 if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) { 486 return (AE_OK); 487 } 488 489 vendor = &resource->data.vendor_typed; 490 491 /* 492 * For a valid match, these conditions must hold: 493 * 494 * 1) Length of descriptor data must be at least as long as a UUID struct 495 * 2) The UUID subtypes must match 496 * 3) The UUID data must match 497 */ 498 if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) || 499 (vendor->uuid_subtype != info->uuid->subtype) || 500 (ACPI_MEMCMP(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) { 501 return (AE_OK); 502 } 503 504 /* Validate/Allocate/Clear caller buffer */ 505 506 buffer = info->buffer; 507 status = acpi_ut_initialize_buffer(buffer, resource->length); 508 if (ACPI_FAILURE(status)) { 509 return (status); 510 } 511 512 /* Found the correct resource, copy and return it */ 513 514 ACPI_MEMCPY(buffer->pointer, resource, resource->length); 515 buffer->length = resource->length; 516 517 /* Found the desired descriptor, terminate resource walk */ 518 519 info->status = AE_OK; 520 return (AE_CTRL_TERMINATE); 521 } 522 523 /******************************************************************************* 524 * 525 * FUNCTION: acpi_walk_resources 526 * 527 * PARAMETERS: device_handle - Handle to the device object for the 528 * device we are querying 529 * name - Method name of the resources we want. 530 * (METHOD_NAME__CRS, METHOD_NAME__PRS, or 531 * METHOD_NAME__AEI) 532 * user_function - Called for each resource 533 * context - Passed to user_function 534 * 535 * RETURN: Status 536 * 537 * DESCRIPTION: Retrieves the current or possible resource list for the 538 * specified device. The user_function is called once for 539 * each resource in the list. 540 * 541 ******************************************************************************/ 542 acpi_status 543 acpi_walk_resources(acpi_handle device_handle, 544 char *name, 545 acpi_walk_resource_callback user_function, void *context) 546 { 547 acpi_status status; 548 struct acpi_buffer buffer; 549 struct acpi_resource *resource; 550 struct acpi_resource *resource_end; 551 552 ACPI_FUNCTION_TRACE(acpi_walk_resources); 553 554 /* Parameter validation */ 555 556 if (!device_handle || !user_function || !name || 557 (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) && 558 !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS) && 559 !ACPI_COMPARE_NAME(name, METHOD_NAME__AEI))) { 560 return_ACPI_STATUS(AE_BAD_PARAMETER); 561 } 562 563 /* Get the _CRS/_PRS/_AEI resource list */ 564 565 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; 566 status = acpi_rs_get_method_data(device_handle, name, &buffer); 567 if (ACPI_FAILURE(status)) { 568 return_ACPI_STATUS(status); 569 } 570 571 /* Buffer now contains the resource list */ 572 573 resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer); 574 resource_end = 575 ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length); 576 577 /* Walk the resource list until the end_tag is found (or buffer end) */ 578 579 while (resource < resource_end) { 580 581 /* Sanity check the resource */ 582 583 if (resource->type > ACPI_RESOURCE_TYPE_MAX) { 584 status = AE_AML_INVALID_RESOURCE_TYPE; 585 break; 586 } 587 588 /* Invoke the user function, abort on any error returned */ 589 590 status = user_function(resource, context); 591 if (ACPI_FAILURE(status)) { 592 if (status == AE_CTRL_TERMINATE) { 593 594 /* This is an OK termination by the user function */ 595 596 status = AE_OK; 597 } 598 break; 599 } 600 601 /* end_tag indicates end-of-list */ 602 603 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { 604 break; 605 } 606 607 /* Get the next resource descriptor */ 608 609 resource = 610 ACPI_ADD_PTR(struct acpi_resource, resource, 611 resource->length); 612 } 613 614 ACPI_FREE(buffer.pointer); 615 return_ACPI_STATUS(status); 616 } 617 618 ACPI_EXPORT_SYMBOL(acpi_walk_resources) 619