linux/drivers/acpi/acpica/rsutils.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/*******************************************************************************
   3 *
   4 * Module Name: rsutils - Utilities for the resource manager
   5 *
   6 ******************************************************************************/
   7
   8#include <acpi/acpi.h>
   9#include "accommon.h"
  10#include "acnamesp.h"
  11#include "acresrc.h"
  12
  13#define _COMPONENT          ACPI_RESOURCES
  14ACPI_MODULE_NAME("rsutils")
  15
  16/*******************************************************************************
  17 *
  18 * FUNCTION:    acpi_rs_decode_bitmask
  19 *
  20 * PARAMETERS:  mask            - Bitmask to decode
  21 *              list            - Where the converted list is returned
  22 *
  23 * RETURN:      Count of bits set (length of list)
  24 *
  25 * DESCRIPTION: Convert a bit mask into a list of values
  26 *
  27 ******************************************************************************/
  28u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
  29{
  30        u8 i;
  31        u8 bit_count;
  32
  33        ACPI_FUNCTION_ENTRY();
  34
  35        /* Decode the mask bits */
  36
  37        for (i = 0, bit_count = 0; mask; i++) {
  38                if (mask & 0x0001) {
  39                        list[bit_count] = i;
  40                        bit_count++;
  41                }
  42
  43                mask >>= 1;
  44        }
  45
  46        return (bit_count);
  47}
  48
  49/*******************************************************************************
  50 *
  51 * FUNCTION:    acpi_rs_encode_bitmask
  52 *
  53 * PARAMETERS:  list            - List of values to encode
  54 *              count           - Length of list
  55 *
  56 * RETURN:      Encoded bitmask
  57 *
  58 * DESCRIPTION: Convert a list of values to an encoded bitmask
  59 *
  60 ******************************************************************************/
  61
  62u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
  63{
  64        u32 i;
  65        u16 mask;
  66
  67        ACPI_FUNCTION_ENTRY();
  68
  69        /* Encode the list into a single bitmask */
  70
  71        for (i = 0, mask = 0; i < count; i++) {
  72                mask |= (0x1 << list[i]);
  73        }
  74
  75        return (mask);
  76}
  77
  78/*******************************************************************************
  79 *
  80 * FUNCTION:    acpi_rs_move_data
  81 *
  82 * PARAMETERS:  destination         - Pointer to the destination descriptor
  83 *              source              - Pointer to the source descriptor
  84 *              item_count          - How many items to move
  85 *              move_type           - Byte width
  86 *
  87 * RETURN:      None
  88 *
  89 * DESCRIPTION: Move multiple data items from one descriptor to another. Handles
  90 *              alignment issues and endian issues if necessary, as configured
  91 *              via the ACPI_MOVE_* macros. (This is why a memcpy is not used)
  92 *
  93 ******************************************************************************/
  94
  95void
  96acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
  97{
  98        u32 i;
  99
 100        ACPI_FUNCTION_ENTRY();
 101
 102        /* One move per item */
 103
 104        for (i = 0; i < item_count; i++) {
 105                switch (move_type) {
 106                        /*
 107                         * For the 8-bit case, we can perform the move all at once
 108                         * since there are no alignment or endian issues
 109                         */
 110                case ACPI_RSC_MOVE8:
 111                case ACPI_RSC_MOVE_GPIO_RES:
 112                case ACPI_RSC_MOVE_SERIAL_VEN:
 113                case ACPI_RSC_MOVE_SERIAL_RES:
 114
 115                        memcpy(destination, source, item_count);
 116                        return;
 117
 118                        /*
 119                         * 16-, 32-, and 64-bit cases must use the move macros that perform
 120                         * endian conversion and/or accommodate hardware that cannot perform
 121                         * misaligned memory transfers
 122                         */
 123                case ACPI_RSC_MOVE16:
 124                case ACPI_RSC_MOVE_GPIO_PIN:
 125
 126                        ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i],
 127                                           &ACPI_CAST_PTR(u16, source)[i]);
 128                        break;
 129
 130                case ACPI_RSC_MOVE32:
 131
 132                        ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i],
 133                                           &ACPI_CAST_PTR(u32, source)[i]);
 134                        break;
 135
 136                case ACPI_RSC_MOVE64:
 137
 138                        ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i],
 139                                           &ACPI_CAST_PTR(u64, source)[i]);
 140                        break;
 141
 142                default:
 143
 144                        return;
 145                }
 146        }
 147}
 148
 149/*******************************************************************************
 150 *
 151 * FUNCTION:    acpi_rs_set_resource_length
 152 *
 153 * PARAMETERS:  total_length        - Length of the AML descriptor, including
 154 *                                    the header and length fields.
 155 *              aml                 - Pointer to the raw AML descriptor
 156 *
 157 * RETURN:      None
 158 *
 159 * DESCRIPTION: Set the resource_length field of an AML
 160 *              resource descriptor, both Large and Small descriptors are
 161 *              supported automatically. Note: Descriptor Type field must
 162 *              be valid.
 163 *
 164 ******************************************************************************/
 165
 166void
 167acpi_rs_set_resource_length(acpi_rsdesc_size total_length,
 168                            union aml_resource *aml)
 169{
 170        acpi_rs_length resource_length;
 171
 172        ACPI_FUNCTION_ENTRY();
 173
 174        /* Length is the total descriptor length minus the header length */
 175
 176        resource_length = (acpi_rs_length)
 177            (total_length - acpi_ut_get_resource_header_length(aml));
 178
 179        /* Length is stored differently for large and small descriptors */
 180
 181        if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
 182
 183                /* Large descriptor -- bytes 1-2 contain the 16-bit length */
 184
 185                ACPI_MOVE_16_TO_16(&aml->large_header.resource_length,
 186                                   &resource_length);
 187        } else {
 188                /*
 189                 * Small descriptor -- bits 2:0 of byte 0 contain the length
 190                 * Clear any existing length, preserving descriptor type bits
 191                 */
 192                aml->small_header.descriptor_type = (u8)
 193                    ((aml->small_header.descriptor_type &
 194                      ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK)
 195                     | resource_length);
 196        }
 197}
 198
 199/*******************************************************************************
 200 *
 201 * FUNCTION:    acpi_rs_set_resource_header
 202 *
 203 * PARAMETERS:  descriptor_type     - Byte to be inserted as the type
 204 *              total_length        - Length of the AML descriptor, including
 205 *                                    the header and length fields.
 206 *              aml                 - Pointer to the raw AML descriptor
 207 *
 208 * RETURN:      None
 209 *
 210 * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML
 211 *              resource descriptor, both Large and Small descriptors are
 212 *              supported automatically
 213 *
 214 ******************************************************************************/
 215
 216void
 217acpi_rs_set_resource_header(u8 descriptor_type,
 218                            acpi_rsdesc_size total_length,
 219                            union aml_resource *aml)
 220{
 221        ACPI_FUNCTION_ENTRY();
 222
 223        /* Set the Resource Type */
 224
 225        aml->small_header.descriptor_type = descriptor_type;
 226
 227        /* Set the Resource Length */
 228
 229        acpi_rs_set_resource_length(total_length, aml);
 230}
 231
 232/*******************************************************************************
 233 *
 234 * FUNCTION:    acpi_rs_strcpy
 235 *
 236 * PARAMETERS:  destination         - Pointer to the destination string
 237 *              source              - Pointer to the source string
 238 *
 239 * RETURN:      String length, including NULL terminator
 240 *
 241 * DESCRIPTION: Local string copy that returns the string length, saving a
 242 *              strcpy followed by a strlen.
 243 *
 244 ******************************************************************************/
 245
 246static u16 acpi_rs_strcpy(char *destination, char *source)
 247{
 248        u16 i;
 249
 250        ACPI_FUNCTION_ENTRY();
 251
 252        for (i = 0; source[i]; i++) {
 253                destination[i] = source[i];
 254        }
 255
 256        destination[i] = 0;
 257
 258        /* Return string length including the NULL terminator */
 259
 260        return ((u16) (i + 1));
 261}
 262
 263/*******************************************************************************
 264 *
 265 * FUNCTION:    acpi_rs_get_resource_source
 266 *
 267 * PARAMETERS:  resource_length     - Length field of the descriptor
 268 *              minimum_length      - Minimum length of the descriptor (minus
 269 *                                    any optional fields)
 270 *              resource_source     - Where the resource_source is returned
 271 *              aml                 - Pointer to the raw AML descriptor
 272 *              string_ptr          - (optional) where to store the actual
 273 *                                    resource_source string
 274 *
 275 * RETURN:      Length of the string plus NULL terminator, rounded up to native
 276 *              word boundary
 277 *
 278 * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor
 279 *              to an internal resource descriptor
 280 *
 281 ******************************************************************************/
 282
 283acpi_rs_length
 284acpi_rs_get_resource_source(acpi_rs_length resource_length,
 285                            acpi_rs_length minimum_length,
 286                            struct acpi_resource_source * resource_source,
 287                            union aml_resource * aml, char *string_ptr)
 288{
 289        acpi_rsdesc_size total_length;
 290        u8 *aml_resource_source;
 291
 292        ACPI_FUNCTION_ENTRY();
 293
 294        total_length =
 295            resource_length + sizeof(struct aml_resource_large_header);
 296        aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
 297
 298        /*
 299         * resource_source is present if the length of the descriptor is longer
 300         * than the minimum length.
 301         *
 302         * Note: Some resource descriptors will have an additional null, so
 303         * we add 1 to the minimum length.
 304         */
 305        if (total_length > (acpi_rsdesc_size)(minimum_length + 1)) {
 306
 307                /* Get the resource_source_index */
 308
 309                resource_source->index = aml_resource_source[0];
 310
 311                resource_source->string_ptr = string_ptr;
 312                if (!string_ptr) {
 313                        /*
 314                         * String destination pointer is not specified; Set the String
 315                         * pointer to the end of the current resource_source structure.
 316                         */
 317                        resource_source->string_ptr =
 318                            ACPI_ADD_PTR(char, resource_source,
 319                                         sizeof(struct acpi_resource_source));
 320                }
 321
 322                /*
 323                 * In order for the Resource length to be a multiple of the native
 324                 * word, calculate the length of the string (+1 for NULL terminator)
 325                 * and expand to the next word multiple.
 326                 *
 327                 * Zero the entire area of the buffer.
 328                 */
 329                total_length =
 330                    (u32)strlen(ACPI_CAST_PTR(char, &aml_resource_source[1])) +
 331                    1;
 332
 333                total_length = (u32)ACPI_ROUND_UP_TO_NATIVE_WORD(total_length);
 334
 335                memset(resource_source->string_ptr, 0, total_length);
 336
 337                /* Copy the resource_source string to the destination */
 338
 339                resource_source->string_length =
 340                    acpi_rs_strcpy(resource_source->string_ptr,
 341                                   ACPI_CAST_PTR(char,
 342                                                 &aml_resource_source[1]));
 343
 344                return ((acpi_rs_length)total_length);
 345        }
 346
 347        /* resource_source is not present */
 348
 349        resource_source->index = 0;
 350        resource_source->string_length = 0;
 351        resource_source->string_ptr = NULL;
 352        return (0);
 353}
 354
 355/*******************************************************************************
 356 *
 357 * FUNCTION:    acpi_rs_set_resource_source
 358 *
 359 * PARAMETERS:  aml                 - Pointer to the raw AML descriptor
 360 *              minimum_length      - Minimum length of the descriptor (minus
 361 *                                    any optional fields)
 362 *              resource_source     - Internal resource_source
 363
 364 *
 365 * RETURN:      Total length of the AML descriptor
 366 *
 367 * DESCRIPTION: Convert an optional resource_source from internal format to a
 368 *              raw AML resource descriptor
 369 *
 370 ******************************************************************************/
 371
 372acpi_rsdesc_size
 373acpi_rs_set_resource_source(union aml_resource *aml,
 374                            acpi_rs_length minimum_length,
 375                            struct acpi_resource_source *resource_source)
 376{
 377        u8 *aml_resource_source;
 378        acpi_rsdesc_size descriptor_length;
 379
 380        ACPI_FUNCTION_ENTRY();
 381
 382        descriptor_length = minimum_length;
 383
 384        /* Non-zero string length indicates presence of a resource_source */
 385
 386        if (resource_source->string_length) {
 387
 388                /* Point to the end of the AML descriptor */
 389
 390                aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
 391
 392                /* Copy the resource_source_index */
 393
 394                aml_resource_source[0] = (u8) resource_source->index;
 395
 396                /* Copy the resource_source string */
 397
 398                strcpy(ACPI_CAST_PTR(char, &aml_resource_source[1]),
 399                       resource_source->string_ptr);
 400
 401                /*
 402                 * Add the length of the string (+ 1 for null terminator) to the
 403                 * final descriptor length
 404                 */
 405                descriptor_length += ((acpi_rsdesc_size)
 406                                      resource_source->string_length + 1);
 407        }
 408
 409        /* Return the new total length of the AML descriptor */
 410
 411        return (descriptor_length);
 412}
 413
 414/*******************************************************************************
 415 *
 416 * FUNCTION:    acpi_rs_get_prt_method_data
 417 *
 418 * PARAMETERS:  node            - Device node
 419 *              ret_buffer      - Pointer to a buffer structure for the
 420 *                                results
 421 *
 422 * RETURN:      Status
 423 *
 424 * DESCRIPTION: This function is called to get the _PRT value of an object
 425 *              contained in an object specified by the handle passed in
 426 *
 427 *              If the function fails an appropriate status will be returned
 428 *              and the contents of the callers buffer is undefined.
 429 *
 430 ******************************************************************************/
 431
 432acpi_status
 433acpi_rs_get_prt_method_data(struct acpi_namespace_node *node,
 434                            struct acpi_buffer *ret_buffer)
 435{
 436        union acpi_operand_object *obj_desc;
 437        acpi_status status;
 438
 439        ACPI_FUNCTION_TRACE(rs_get_prt_method_data);
 440
 441        /* Parameters guaranteed valid by caller */
 442
 443        /* Execute the method, no parameters */
 444
 445        status =
 446            acpi_ut_evaluate_object(node, METHOD_NAME__PRT, ACPI_BTYPE_PACKAGE,
 447                                    &obj_desc);
 448        if (ACPI_FAILURE(status)) {
 449                return_ACPI_STATUS(status);
 450        }
 451
 452        /*
 453         * Create a resource linked list from the byte stream buffer that comes
 454         * back from the _CRS method execution.
 455         */
 456        status = acpi_rs_create_pci_routing_table(obj_desc, ret_buffer);
 457
 458        /* On exit, we must delete the object returned by evaluate_object */
 459
 460        acpi_ut_remove_reference(obj_desc);
 461        return_ACPI_STATUS(status);
 462}
 463
 464/*******************************************************************************
 465 *
 466 * FUNCTION:    acpi_rs_get_crs_method_data
 467 *
 468 * PARAMETERS:  node            - Device node
 469 *              ret_buffer      - Pointer to a buffer structure for the
 470 *                                results
 471 *
 472 * RETURN:      Status
 473 *
 474 * DESCRIPTION: This function is called to get the _CRS value of an object
 475 *              contained in an object specified by the handle passed in
 476 *
 477 *              If the function fails an appropriate status will be returned
 478 *              and the contents of the callers buffer is undefined.
 479 *
 480 ******************************************************************************/
 481
 482acpi_status
 483acpi_rs_get_crs_method_data(struct acpi_namespace_node *node,
 484                            struct acpi_buffer *ret_buffer)
 485{
 486        union acpi_operand_object *obj_desc;
 487        acpi_status status;
 488
 489        ACPI_FUNCTION_TRACE(rs_get_crs_method_data);
 490
 491        /* Parameters guaranteed valid by caller */
 492
 493        /* Execute the method, no parameters */
 494
 495        status =
 496            acpi_ut_evaluate_object(node, METHOD_NAME__CRS, ACPI_BTYPE_BUFFER,
 497                                    &obj_desc);
 498        if (ACPI_FAILURE(status)) {
 499                return_ACPI_STATUS(status);
 500        }
 501
 502        /*
 503         * Make the call to create a resource linked list from the
 504         * byte stream buffer that comes back from the _CRS method
 505         * execution.
 506         */
 507        status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
 508
 509        /* On exit, we must delete the object returned by evaluateObject */
 510
 511        acpi_ut_remove_reference(obj_desc);
 512        return_ACPI_STATUS(status);
 513}
 514
 515/*******************************************************************************
 516 *
 517 * FUNCTION:    acpi_rs_get_prs_method_data
 518 *
 519 * PARAMETERS:  node            - Device node
 520 *              ret_buffer      - Pointer to a buffer structure for the
 521 *                                results
 522 *
 523 * RETURN:      Status
 524 *
 525 * DESCRIPTION: This function is called to get the _PRS value of an object
 526 *              contained in an object specified by the handle passed in
 527 *
 528 *              If the function fails an appropriate status will be returned
 529 *              and the contents of the callers buffer is undefined.
 530 *
 531 ******************************************************************************/
 532
 533acpi_status
 534acpi_rs_get_prs_method_data(struct acpi_namespace_node *node,
 535                            struct acpi_buffer *ret_buffer)
 536{
 537        union acpi_operand_object *obj_desc;
 538        acpi_status status;
 539
 540        ACPI_FUNCTION_TRACE(rs_get_prs_method_data);
 541
 542        /* Parameters guaranteed valid by caller */
 543
 544        /* Execute the method, no parameters */
 545
 546        status =
 547            acpi_ut_evaluate_object(node, METHOD_NAME__PRS, ACPI_BTYPE_BUFFER,
 548                                    &obj_desc);
 549        if (ACPI_FAILURE(status)) {
 550                return_ACPI_STATUS(status);
 551        }
 552
 553        /*
 554         * Make the call to create a resource linked list from the
 555         * byte stream buffer that comes back from the _CRS method
 556         * execution.
 557         */
 558        status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
 559
 560        /* On exit, we must delete the object returned by evaluateObject */
 561
 562        acpi_ut_remove_reference(obj_desc);
 563        return_ACPI_STATUS(status);
 564}
 565
 566/*******************************************************************************
 567 *
 568 * FUNCTION:    acpi_rs_get_aei_method_data
 569 *
 570 * PARAMETERS:  node            - Device node
 571 *              ret_buffer      - Pointer to a buffer structure for the
 572 *                                results
 573 *
 574 * RETURN:      Status
 575 *
 576 * DESCRIPTION: This function is called to get the _AEI value of an object
 577 *              contained in an object specified by the handle passed in
 578 *
 579 *              If the function fails an appropriate status will be returned
 580 *              and the contents of the callers buffer is undefined.
 581 *
 582 ******************************************************************************/
 583
 584acpi_status
 585acpi_rs_get_aei_method_data(struct acpi_namespace_node *node,
 586                            struct acpi_buffer *ret_buffer)
 587{
 588        union acpi_operand_object *obj_desc;
 589        acpi_status status;
 590
 591        ACPI_FUNCTION_TRACE(rs_get_aei_method_data);
 592
 593        /* Parameters guaranteed valid by caller */
 594
 595        /* Execute the method, no parameters */
 596
 597        status =
 598            acpi_ut_evaluate_object(node, METHOD_NAME__AEI, ACPI_BTYPE_BUFFER,
 599                                    &obj_desc);
 600        if (ACPI_FAILURE(status)) {
 601                return_ACPI_STATUS(status);
 602        }
 603
 604        /*
 605         * Make the call to create a resource linked list from the
 606         * byte stream buffer that comes back from the _CRS method
 607         * execution.
 608         */
 609        status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
 610
 611        /* On exit, we must delete the object returned by evaluateObject */
 612
 613        acpi_ut_remove_reference(obj_desc);
 614        return_ACPI_STATUS(status);
 615}
 616
 617/*******************************************************************************
 618 *
 619 * FUNCTION:    acpi_rs_get_method_data
 620 *
 621 * PARAMETERS:  handle          - Handle to the containing object
 622 *              path            - Path to method, relative to Handle
 623 *              ret_buffer      - Pointer to a buffer structure for the
 624 *                                results
 625 *
 626 * RETURN:      Status
 627 *
 628 * DESCRIPTION: This function is called to get the _CRS or _PRS value of an
 629 *              object contained in an object specified by the handle passed in
 630 *
 631 *              If the function fails an appropriate status will be returned
 632 *              and the contents of the callers buffer is undefined.
 633 *
 634 ******************************************************************************/
 635
 636acpi_status
 637acpi_rs_get_method_data(acpi_handle handle,
 638                        const char *path, struct acpi_buffer *ret_buffer)
 639{
 640        union acpi_operand_object *obj_desc;
 641        acpi_status status;
 642
 643        ACPI_FUNCTION_TRACE(rs_get_method_data);
 644
 645        /* Parameters guaranteed valid by caller */
 646
 647        /* Execute the method, no parameters */
 648
 649        status =
 650            acpi_ut_evaluate_object(ACPI_CAST_PTR
 651                                    (struct acpi_namespace_node, handle), path,
 652                                    ACPI_BTYPE_BUFFER, &obj_desc);
 653        if (ACPI_FAILURE(status)) {
 654                return_ACPI_STATUS(status);
 655        }
 656
 657        /*
 658         * Make the call to create a resource linked list from the
 659         * byte stream buffer that comes back from the method
 660         * execution.
 661         */
 662        status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
 663
 664        /* On exit, we must delete the object returned by evaluate_object */
 665
 666        acpi_ut_remove_reference(obj_desc);
 667        return_ACPI_STATUS(status);
 668}
 669
 670/*******************************************************************************
 671 *
 672 * FUNCTION:    acpi_rs_set_srs_method_data
 673 *
 674 * PARAMETERS:  node            - Device node
 675 *              in_buffer       - Pointer to a buffer structure of the
 676 *                                parameter
 677 *
 678 * RETURN:      Status
 679 *
 680 * DESCRIPTION: This function is called to set the _SRS of an object contained
 681 *              in an object specified by the handle passed in
 682 *
 683 *              If the function fails an appropriate status will be returned
 684 *              and the contents of the callers buffer is undefined.
 685 *
 686 * Note: Parameters guaranteed valid by caller
 687 *
 688 ******************************************************************************/
 689
 690acpi_status
 691acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
 692                            struct acpi_buffer *in_buffer)
 693{
 694        struct acpi_evaluate_info *info;
 695        union acpi_operand_object *args[2];
 696        acpi_status status;
 697        struct acpi_buffer buffer;
 698
 699        ACPI_FUNCTION_TRACE(rs_set_srs_method_data);
 700
 701        /* Allocate and initialize the evaluation information block */
 702
 703        info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
 704        if (!info) {
 705                return_ACPI_STATUS(AE_NO_MEMORY);
 706        }
 707
 708        info->prefix_node = node;
 709        info->relative_pathname = METHOD_NAME__SRS;
 710        info->parameters = args;
 711        info->flags = ACPI_IGNORE_RETURN_VALUE;
 712
 713        /*
 714         * The in_buffer parameter will point to a linked list of
 715         * resource parameters. It needs to be formatted into a
 716         * byte stream to be sent in as an input parameter to _SRS
 717         *
 718         * Convert the linked list into a byte stream
 719         */
 720        buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 721        status = acpi_rs_create_aml_resources(in_buffer, &buffer);
 722        if (ACPI_FAILURE(status)) {
 723                goto cleanup;
 724        }
 725
 726        /* Create and initialize the method parameter object */
 727
 728        args[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
 729        if (!args[0]) {
 730                /*
 731                 * Must free the buffer allocated above (otherwise it is freed
 732                 * later)
 733                 */
 734                ACPI_FREE(buffer.pointer);
 735                status = AE_NO_MEMORY;
 736                goto cleanup;
 737        }
 738
 739        args[0]->buffer.length = (u32) buffer.length;
 740        args[0]->buffer.pointer = buffer.pointer;
 741        args[0]->common.flags = AOPOBJ_DATA_VALID;
 742        args[1] = NULL;
 743
 744        /* Execute the method, no return value is expected */
 745
 746        status = acpi_ns_evaluate(info);
 747
 748        /* Clean up and return the status from acpi_ns_evaluate */
 749
 750        acpi_ut_remove_reference(args[0]);
 751
 752cleanup:
 753        ACPI_FREE(info);
 754        return_ACPI_STATUS(status);
 755}
 756