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