root/drivers/acpi/acpica/rsxface.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. acpi_rs_validate_parameters
  2. acpi_get_irq_routing_table
  3. ACPI_EXPORT_SYMBOL
  4. ACPI_EXPORT_SYMBOL
  5. ACPI_EXPORT_SYMBOL
  6. ACPI_EXPORT_SYMBOL
  7. ACPI_EXPORT_SYMBOL
  8. ACPI_EXPORT_SYMBOL
  9. ACPI_EXPORT_SYMBOL
  10. acpi_walk_resource_buffer
  11. ACPI_EXPORT_SYMBOL

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

/* [<][>][^][v][top][bottom][index][help] */