linux/drivers/acpi/namespace/nspredef.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: nspredef - Validation of ACPI predefined methods and objects
   4 *              $Revision: 1.1 $
   5 *
   6 *****************************************************************************/
   7
   8/*
   9 * Copyright (C) 2000 - 2008, Intel Corp.
  10 * All rights reserved.
  11 *
  12 * Redistribution and use in source and binary forms, with or without
  13 * modification, are permitted provided that the following conditions
  14 * are met:
  15 * 1. Redistributions of source code must retain the above copyright
  16 *    notice, this list of conditions, and the following disclaimer,
  17 *    without modification.
  18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  19 *    substantially similar to the "NO WARRANTY" disclaimer below
  20 *    ("Disclaimer") and any redistribution must be conditioned upon
  21 *    including a substantially similar Disclaimer requirement for further
  22 *    binary redistribution.
  23 * 3. Neither the names of the above-listed copyright holders nor the names
  24 *    of any contributors may be used to endorse or promote products derived
  25 *    from this software without specific prior written permission.
  26 *
  27 * Alternatively, this software may be distributed under the terms of the
  28 * GNU General Public License ("GPL") version 2 as published by the Free
  29 * Software Foundation.
  30 *
  31 * NO WARRANTY
  32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42 * POSSIBILITY OF SUCH DAMAGES.
  43 */
  44
  45#include <acpi/acpi.h>
  46#include <acpi/acnamesp.h>
  47#include <acpi/acpredef.h>
  48
  49#define _COMPONENT          ACPI_NAMESPACE
  50ACPI_MODULE_NAME("nspredef")
  51
  52/*******************************************************************************
  53 *
  54 * This module validates predefined ACPI objects that appear in the namespace,
  55 * at the time they are evaluated (via acpi_evaluate_object). The purpose of this
  56 * validation is to detect problems with BIOS-exposed predefined ACPI objects
  57 * before the results are returned to the ACPI-related drivers.
  58 *
  59 * There are several areas that are validated:
  60 *
  61 *  1) The number of input arguments as defined by the method/object in the
  62 *      ASL is validated against the ACPI specification.
  63 *  2) The type of the return object (if any) is validated against the ACPI
  64 *      specification.
  65 *  3) For returned package objects, the count of package elements is
  66 *      validated, as well as the type of each package element. Nested
  67 *      packages are supported.
  68 *
  69 * For any problems found, a warning message is issued.
  70 *
  71 ******************************************************************************/
  72/* Local prototypes */
  73static acpi_status
  74acpi_ns_check_package(char *pathname,
  75                      union acpi_operand_object *return_object,
  76                      const union acpi_predefined_info *predefined);
  77
  78static acpi_status
  79acpi_ns_check_package_elements(char *pathname,
  80                               union acpi_operand_object **elements,
  81                               u8 type1, u32 count1, u8 type2, u32 count2);
  82
  83static acpi_status
  84acpi_ns_check_object_type(char *pathname,
  85                          union acpi_operand_object *return_object,
  86                          u32 expected_btypes, u32 package_index);
  87
  88static acpi_status
  89acpi_ns_check_reference(char *pathname,
  90                        union acpi_operand_object *return_object);
  91
  92/*
  93 * Names for the types that can be returned by the predefined objects.
  94 * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
  95 */
  96static const char *acpi_rtype_names[] = {
  97        "/Integer",
  98        "/String",
  99        "/Buffer",
 100        "/Package",
 101        "/Reference",
 102};
 103
 104#define ACPI_NOT_PACKAGE    ACPI_UINT32_MAX
 105
 106/*******************************************************************************
 107 *
 108 * FUNCTION:    acpi_ns_check_predefined_names
 109 *
 110 * PARAMETERS:  Node            - Namespace node for the method/object
 111 *              return_object   - Object returned from the evaluation of this
 112 *                                method/object
 113 *
 114 * RETURN:      Status
 115 *
 116 * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
 117 *
 118 ******************************************************************************/
 119
 120acpi_status
 121acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
 122                               union acpi_operand_object *return_object)
 123{
 124        acpi_status status = AE_OK;
 125        const union acpi_predefined_info *predefined;
 126        char *pathname;
 127
 128        /* Match the name for this method/object against the predefined list */
 129
 130        predefined = acpi_ns_check_for_predefined_name(node);
 131        if (!predefined) {
 132
 133                /* Name was not one of the predefined names */
 134
 135                return (AE_OK);
 136        }
 137
 138        /* Get the full pathname to the object, for use in error messages */
 139
 140        pathname = acpi_ns_get_external_pathname(node);
 141        if (!pathname) {
 142                pathname = ACPI_CAST_PTR(char, predefined->info.name);
 143        }
 144
 145        /*
 146         * Check that the parameter count for this method is in accordance
 147         * with the ACPI specification.
 148         */
 149        acpi_ns_check_parameter_count(pathname, node, predefined);
 150
 151        /*
 152         * If there is no return value, check if we require a return value for
 153         * this predefined name. Either one return value is expected, or none,
 154         * for both methods and other objects.
 155         *
 156         * Exit now if there is no return object. Warning if one was expected.
 157         */
 158        if (!return_object) {
 159                if ((predefined->info.expected_btypes) &&
 160                    (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) {
 161                        ACPI_ERROR((AE_INFO,
 162                                    "%s: Missing expected return value",
 163                                    pathname));
 164
 165                        status = AE_AML_NO_RETURN_VALUE;
 166                }
 167                goto exit;
 168        }
 169
 170        /*
 171         * We have a return value, but if one wasn't expected, just exit, this is
 172         * not a problem
 173         *
 174         * For example, if "Implicit return value" is enabled, methods will
 175         * always return a value
 176         */
 177        if (!predefined->info.expected_btypes) {
 178                goto exit;
 179        }
 180
 181        /*
 182         * Check that the type of the return object is what is expected for
 183         * this predefined name
 184         */
 185        status = acpi_ns_check_object_type(pathname, return_object,
 186                                           predefined->info.expected_btypes,
 187                                           ACPI_NOT_PACKAGE);
 188        if (ACPI_FAILURE(status)) {
 189                goto exit;
 190        }
 191
 192        /* For returned Package objects, check the type of all sub-objects */
 193
 194        if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
 195                status =
 196                    acpi_ns_check_package(pathname, return_object, predefined);
 197        }
 198
 199      exit:
 200        if (pathname) {
 201                ACPI_FREE(pathname);
 202        }
 203
 204        return (status);
 205}
 206
 207/*******************************************************************************
 208 *
 209 * FUNCTION:    acpi_ns_check_parameter_count
 210 *
 211 * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
 212 *              Node            - Namespace node for the method/object
 213 *              Predefined      - Pointer to entry in predefined name table
 214 *
 215 * RETURN:      None
 216 *
 217 * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
 218 *              predefined name is what is expected (i.e., what is defined in
 219 *              the ACPI specification for this predefined name.)
 220 *
 221 ******************************************************************************/
 222
 223void
 224acpi_ns_check_parameter_count(char *pathname,
 225                              struct acpi_namespace_node *node,
 226                              const union acpi_predefined_info *predefined)
 227{
 228        u32 param_count;
 229        u32 required_params_current;
 230        u32 required_params_old;
 231
 232        /*
 233         * Check that the ASL-defined parameter count is what is expected for
 234         * this predefined name.
 235         *
 236         * Methods have 0-7 parameters. All other types have zero.
 237         */
 238        param_count = 0;
 239        if (node->type == ACPI_TYPE_METHOD) {
 240                param_count = node->object->method.param_count;
 241        }
 242
 243        /* Validate parameter count - allow two different legal counts (_SCP) */
 244
 245        required_params_current = predefined->info.param_count & 0x0F;
 246        required_params_old = predefined->info.param_count >> 4;
 247
 248        if ((param_count != required_params_current) &&
 249            (param_count != required_params_old)) {
 250                ACPI_WARNING((AE_INFO,
 251                              "%s: Parameter count mismatch - ASL declared %d, expected %d",
 252                              pathname, param_count, required_params_current));
 253        }
 254}
 255
 256/*******************************************************************************
 257 *
 258 * FUNCTION:    acpi_ns_check_for_predefined_name
 259 *
 260 * PARAMETERS:  Node            - Namespace node for the method/object
 261 *
 262 * RETURN:      Pointer to entry in predefined table. NULL indicates not found.
 263 *
 264 * DESCRIPTION: Check an object name against the predefined object list.
 265 *
 266 ******************************************************************************/
 267
 268const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct
 269                                                                    acpi_namespace_node
 270                                                                    *node)
 271{
 272        const union acpi_predefined_info *this_name;
 273
 274        /* Quick check for a predefined name, first character must be underscore */
 275
 276        if (node->name.ascii[0] != '_') {
 277                return (NULL);
 278        }
 279
 280        /* Search info table for a predefined method/object name */
 281
 282        this_name = predefined_names;
 283        while (this_name->info.name[0]) {
 284                if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) {
 285
 286                        /* Return pointer to this table entry */
 287
 288                        return (this_name);
 289                }
 290
 291                /*
 292                 * Skip next entry in the table if this name returns a Package
 293                 * (next entry contains the package info)
 294                 */
 295                if (this_name->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
 296                        this_name++;
 297                }
 298
 299                this_name++;
 300        }
 301
 302        return (NULL);
 303}
 304
 305/*******************************************************************************
 306 *
 307 * FUNCTION:    acpi_ns_check_package
 308 *
 309 * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
 310 *              return_object   - Object returned from the evaluation of a
 311 *                                method or object
 312 *              Predefined      - Pointer to entry in predefined name table
 313 *
 314 * RETURN:      Status
 315 *
 316 * DESCRIPTION: Check a returned package object for the correct count and
 317 *              correct type of all sub-objects.
 318 *
 319 ******************************************************************************/
 320
 321static acpi_status
 322acpi_ns_check_package(char *pathname,
 323                      union acpi_operand_object *return_object,
 324                      const union acpi_predefined_info *predefined)
 325{
 326        const union acpi_predefined_info *package;
 327        union acpi_operand_object *sub_package;
 328        union acpi_operand_object **elements;
 329        union acpi_operand_object **sub_elements;
 330        acpi_status status;
 331        u32 expected_count;
 332        u32 count;
 333        u32 i;
 334        u32 j;
 335
 336        ACPI_FUNCTION_NAME(ns_check_package);
 337
 338        /* The package info for this name is in the next table entry */
 339
 340        package = predefined + 1;
 341
 342        ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 343                          "%s Validating return Package of Type %X, Count %X\n",
 344                          pathname, package->ret_info.type,
 345                          return_object->package.count));
 346
 347        /* Extract package count and elements array */
 348
 349        elements = return_object->package.elements;
 350        count = return_object->package.count;
 351
 352        /* The package must have at least one element, else invalid */
 353
 354        if (!count) {
 355                ACPI_WARNING((AE_INFO,
 356                              "%s: Return Package has no elements (empty)",
 357                              pathname));
 358
 359                return (AE_AML_OPERAND_VALUE);
 360        }
 361
 362        /*
 363         * Decode the type of the expected package contents
 364         *
 365         * PTYPE1 packages contain no subpackages
 366         * PTYPE2 packages contain sub-packages
 367         */
 368        switch (package->ret_info.type) {
 369        case ACPI_PTYPE1_FIXED:
 370
 371                /*
 372                 * The package count is fixed and there are no sub-packages
 373                 *
 374                 * If package is too small, exit.
 375                 * If package is larger than expected, issue warning but continue
 376                 */
 377                expected_count =
 378                    package->ret_info.count1 + package->ret_info.count2;
 379                if (count < expected_count) {
 380                        goto package_too_small;
 381                } else if (count > expected_count) {
 382                        ACPI_WARNING((AE_INFO,
 383                                      "%s: Return Package is larger than needed - "
 384                                      "found %u, expected %u", pathname, count,
 385                                      expected_count));
 386                }
 387
 388                /* Validate all elements of the returned package */
 389
 390                status = acpi_ns_check_package_elements(pathname, elements,
 391                                                        package->ret_info.
 392                                                        object_type1,
 393                                                        package->ret_info.
 394                                                        count1,
 395                                                        package->ret_info.
 396                                                        object_type2,
 397                                                        package->ret_info.
 398                                                        count2);
 399                if (ACPI_FAILURE(status)) {
 400                        return (status);
 401                }
 402                break;
 403
 404        case ACPI_PTYPE1_VAR:
 405
 406                /*
 407                 * The package count is variable, there are no sub-packages, and all
 408                 * elements must be of the same type
 409                 */
 410                for (i = 0; i < count; i++) {
 411                        status = acpi_ns_check_object_type(pathname, *elements,
 412                                                           package->ret_info.
 413                                                           object_type1, i);
 414                        if (ACPI_FAILURE(status)) {
 415                                return (status);
 416                        }
 417                        elements++;
 418                }
 419                break;
 420
 421        case ACPI_PTYPE1_OPTION:
 422
 423                /*
 424                 * The package count is variable, there are no sub-packages. There are
 425                 * a fixed number of required elements, and a variable number of
 426                 * optional elements.
 427                 *
 428                 * Check if package is at least as large as the minimum required
 429                 */
 430                expected_count = package->ret_info3.count;
 431                if (count < expected_count) {
 432                        goto package_too_small;
 433                }
 434
 435                /* Variable number of sub-objects */
 436
 437                for (i = 0; i < count; i++) {
 438                        if (i < package->ret_info3.count) {
 439
 440                                /* These are the required package elements (0, 1, or 2) */
 441
 442                                status =
 443                                    acpi_ns_check_object_type(pathname,
 444                                                              *elements,
 445                                                              package->
 446                                                              ret_info3.
 447                                                              object_type[i],
 448                                                              i);
 449                                if (ACPI_FAILURE(status)) {
 450                                        return (status);
 451                                }
 452                        } else {
 453                                /* These are the optional package elements */
 454
 455                                status =
 456                                    acpi_ns_check_object_type(pathname,
 457                                                              *elements,
 458                                                              package->
 459                                                              ret_info3.
 460                                                              tail_object_type,
 461                                                              i);
 462                                if (ACPI_FAILURE(status)) {
 463                                        return (status);
 464                                }
 465                        }
 466                        elements++;
 467                }
 468                break;
 469
 470        case ACPI_PTYPE2_PKG_COUNT:
 471
 472                /* First element is the (Integer) count of sub-packages to follow */
 473
 474                status = acpi_ns_check_object_type(pathname, *elements,
 475                                                   ACPI_RTYPE_INTEGER, 0);
 476                if (ACPI_FAILURE(status)) {
 477                        return (status);
 478                }
 479
 480                /*
 481                 * Count cannot be larger than the parent package length, but allow it
 482                 * to be smaller. The >= accounts for the Integer above.
 483                 */
 484                expected_count = (u32) (*elements)->integer.value;
 485                if (expected_count >= count) {
 486                        goto package_too_small;
 487                }
 488
 489                count = expected_count;
 490                elements++;
 491
 492                /* Now we can walk the sub-packages */
 493
 494                /*lint -fallthrough */
 495
 496        case ACPI_PTYPE2:
 497        case ACPI_PTYPE2_FIXED:
 498        case ACPI_PTYPE2_MIN:
 499        case ACPI_PTYPE2_COUNT:
 500
 501                /*
 502                 * These types all return a single package that consists of a variable
 503                 * number of sub-packages
 504                 */
 505                for (i = 0; i < count; i++) {
 506                        sub_package = *elements;
 507                        sub_elements = sub_package->package.elements;
 508
 509                        /* Each sub-object must be of type Package */
 510
 511                        status =
 512                            acpi_ns_check_object_type(pathname, sub_package,
 513                                                      ACPI_RTYPE_PACKAGE, i);
 514                        if (ACPI_FAILURE(status)) {
 515                                return (status);
 516                        }
 517
 518                        /* Examine the different types of sub-packages */
 519
 520                        switch (package->ret_info.type) {
 521                        case ACPI_PTYPE2:
 522                        case ACPI_PTYPE2_PKG_COUNT:
 523
 524                                /* Each subpackage has a fixed number of elements */
 525
 526                                expected_count =
 527                                    package->ret_info.count1 +
 528                                    package->ret_info.count2;
 529                                if (sub_package->package.count !=
 530                                    expected_count) {
 531                                        count = sub_package->package.count;
 532                                        goto package_too_small;
 533                                }
 534
 535                                status =
 536                                    acpi_ns_check_package_elements(pathname,
 537                                                                   sub_elements,
 538                                                                   package->
 539                                                                   ret_info.
 540                                                                   object_type1,
 541                                                                   package->
 542                                                                   ret_info.
 543                                                                   count1,
 544                                                                   package->
 545                                                                   ret_info.
 546                                                                   object_type2,
 547                                                                   package->
 548                                                                   ret_info.
 549                                                                   count2);
 550                                if (ACPI_FAILURE(status)) {
 551                                        return (status);
 552                                }
 553                                break;
 554
 555                        case ACPI_PTYPE2_FIXED:
 556
 557                                /* Each sub-package has a fixed length */
 558
 559                                expected_count = package->ret_info2.count;
 560                                if (sub_package->package.count < expected_count) {
 561                                        count = sub_package->package.count;
 562                                        goto package_too_small;
 563                                }
 564
 565                                /* Check the type of each sub-package element */
 566
 567                                for (j = 0; j < expected_count; j++) {
 568                                        status =
 569                                            acpi_ns_check_object_type(pathname,
 570                                                                      sub_elements
 571                                                                      [j],
 572                                                                      package->
 573                                                                      ret_info2.
 574                                                                      object_type
 575                                                                      [j], j);
 576                                        if (ACPI_FAILURE(status)) {
 577                                                return (status);
 578                                        }
 579                                }
 580                                break;
 581
 582                        case ACPI_PTYPE2_MIN:
 583
 584                                /* Each sub-package has a variable but minimum length */
 585
 586                                expected_count = package->ret_info.count1;
 587                                if (sub_package->package.count < expected_count) {
 588                                        count = sub_package->package.count;
 589                                        goto package_too_small;
 590                                }
 591
 592                                /* Check the type of each sub-package element */
 593
 594                                status =
 595                                    acpi_ns_check_package_elements(pathname,
 596                                                                   sub_elements,
 597                                                                   package->
 598                                                                   ret_info.
 599                                                                   object_type1,
 600                                                                   sub_package->
 601                                                                   package.
 602                                                                   count, 0, 0);
 603                                if (ACPI_FAILURE(status)) {
 604                                        return (status);
 605                                }
 606                                break;
 607
 608                        case ACPI_PTYPE2_COUNT:
 609
 610                                /* First element is the (Integer) count of elements to follow */
 611
 612                                status =
 613                                    acpi_ns_check_object_type(pathname,
 614                                                              *sub_elements,
 615                                                              ACPI_RTYPE_INTEGER,
 616                                                              0);
 617                                if (ACPI_FAILURE(status)) {
 618                                        return (status);
 619                                }
 620
 621                                /* Make sure package is large enough for the Count */
 622
 623                                expected_count =
 624                                    (u32) (*sub_elements)->integer.value;
 625                                if (sub_package->package.count < expected_count) {
 626                                        count = sub_package->package.count;
 627                                        goto package_too_small;
 628                                }
 629
 630                                /* Check the type of each sub-package element */
 631
 632                                status =
 633                                    acpi_ns_check_package_elements(pathname,
 634                                                                   (sub_elements
 635                                                                    + 1),
 636                                                                   package->
 637                                                                   ret_info.
 638                                                                   object_type1,
 639                                                                   (expected_count
 640                                                                    - 1), 0, 0);
 641                                if (ACPI_FAILURE(status)) {
 642                                        return (status);
 643                                }
 644                                break;
 645
 646                        default:
 647                                break;
 648                        }
 649
 650                        elements++;
 651                }
 652                break;
 653
 654        default:
 655
 656                /* Should not get here if predefined info table is correct */
 657
 658                ACPI_WARNING((AE_INFO,
 659                              "%s: Invalid internal return type in table entry: %X",
 660                              pathname, package->ret_info.type));
 661
 662                return (AE_AML_INTERNAL);
 663        }
 664
 665        return (AE_OK);
 666
 667      package_too_small:
 668
 669        /* Error exit for the case with an incorrect package count */
 670
 671        ACPI_WARNING((AE_INFO, "%s: Return Package is too small - "
 672                      "found %u, expected %u", pathname, count,
 673                      expected_count));
 674
 675        return (AE_AML_OPERAND_VALUE);
 676}
 677
 678/*******************************************************************************
 679 *
 680 * FUNCTION:    acpi_ns_check_package_elements
 681 *
 682 * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
 683 *              Elements        - Pointer to the package elements array
 684 *              Type1           - Object type for first group
 685 *              Count1          - Count for first group
 686 *              Type2           - Object type for second group
 687 *              Count2          - Count for second group
 688 *
 689 * RETURN:      Status
 690 *
 691 * DESCRIPTION: Check that all elements of a package are of the correct object
 692 *              type. Supports up to two groups of different object types.
 693 *
 694 ******************************************************************************/
 695
 696static acpi_status
 697acpi_ns_check_package_elements(char *pathname,
 698                               union acpi_operand_object **elements,
 699                               u8 type1, u32 count1, u8 type2, u32 count2)
 700{
 701        union acpi_operand_object **this_element = elements;
 702        acpi_status status;
 703        u32 i;
 704
 705        /*
 706         * Up to two groups of package elements are supported by the data
 707         * structure. All elements in each group must be of the same type.
 708         * The second group can have a count of zero.
 709         */
 710        for (i = 0; i < count1; i++) {
 711                status = acpi_ns_check_object_type(pathname, *this_element,
 712                                                   type1, i);
 713                if (ACPI_FAILURE(status)) {
 714                        return (status);
 715                }
 716                this_element++;
 717        }
 718
 719        for (i = 0; i < count2; i++) {
 720                status = acpi_ns_check_object_type(pathname, *this_element,
 721                                                   type2, (i + count1));
 722                if (ACPI_FAILURE(status)) {
 723                        return (status);
 724                }
 725                this_element++;
 726        }
 727
 728        return (AE_OK);
 729}
 730
 731/*******************************************************************************
 732 *
 733 * FUNCTION:    acpi_ns_check_object_type
 734 *
 735 * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
 736 *              return_object   - Object return from the execution of this
 737 *                                method/object
 738 *              expected_btypes - Bitmap of expected return type(s)
 739 *              package_index   - Index of object within parent package (if
 740 *                                applicable - ACPI_NOT_PACKAGE otherwise)
 741 *
 742 * RETURN:      Status
 743 *
 744 * DESCRIPTION: Check the type of the return object against the expected object
 745 *              type(s). Use of Btype allows multiple expected object types.
 746 *
 747 ******************************************************************************/
 748
 749static acpi_status
 750acpi_ns_check_object_type(char *pathname,
 751                          union acpi_operand_object *return_object,
 752                          u32 expected_btypes, u32 package_index)
 753{
 754        acpi_status status = AE_OK;
 755        u32 return_btype;
 756        char type_buffer[48];   /* Room for 5 types */
 757        u32 this_rtype;
 758        u32 i;
 759        u32 j;
 760
 761        /*
 762         * If we get a NULL return_object here, it is a NULL package element,
 763         * and this is always an error.
 764         */
 765        if (!return_object) {
 766                goto type_error_exit;
 767        }
 768
 769        /* A Namespace node should not get here, but make sure */
 770
 771        if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) {
 772                ACPI_WARNING((AE_INFO,
 773                              "%s: Invalid return type - Found a Namespace node [%4.4s] type %s",
 774                              pathname, return_object->node.name.ascii,
 775                              acpi_ut_get_type_name(return_object->node.type)));
 776                return (AE_AML_OPERAND_TYPE);
 777        }
 778
 779        /*
 780         * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
 781         * The bitmapped type allows multiple possible return types.
 782         *
 783         * Note, the cases below must handle all of the possible types returned
 784         * from all of the predefined names (including elements of returned
 785         * packages)
 786         */
 787        switch (ACPI_GET_OBJECT_TYPE(return_object)) {
 788        case ACPI_TYPE_INTEGER:
 789                return_btype = ACPI_RTYPE_INTEGER;
 790                break;
 791
 792        case ACPI_TYPE_BUFFER:
 793                return_btype = ACPI_RTYPE_BUFFER;
 794                break;
 795
 796        case ACPI_TYPE_STRING:
 797                return_btype = ACPI_RTYPE_STRING;
 798                break;
 799
 800        case ACPI_TYPE_PACKAGE:
 801                return_btype = ACPI_RTYPE_PACKAGE;
 802                break;
 803
 804        case ACPI_TYPE_LOCAL_REFERENCE:
 805                return_btype = ACPI_RTYPE_REFERENCE;
 806                break;
 807
 808        default:
 809                /* Not one of the supported objects, must be incorrect */
 810
 811                goto type_error_exit;
 812        }
 813
 814        /* Is the object one of the expected types? */
 815
 816        if (!(return_btype & expected_btypes)) {
 817                goto type_error_exit;
 818        }
 819
 820        /* For reference objects, check that the reference type is correct */
 821
 822        if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) {
 823                status = acpi_ns_check_reference(pathname, return_object);
 824        }
 825
 826        return (status);
 827
 828      type_error_exit:
 829
 830        /* Create a string with all expected types for this predefined object */
 831
 832        j = 1;
 833        type_buffer[0] = 0;
 834        this_rtype = ACPI_RTYPE_INTEGER;
 835
 836        for (i = 0; i < ACPI_NUM_RTYPES; i++) {
 837
 838                /* If one of the expected types, concatenate the name of this type */
 839
 840                if (expected_btypes & this_rtype) {
 841                        ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]);
 842                        j = 0;  /* Use name separator from now on */
 843                }
 844                this_rtype <<= 1;       /* Next Rtype */
 845        }
 846
 847        if (package_index == ACPI_NOT_PACKAGE) {
 848                ACPI_WARNING((AE_INFO,
 849                              "%s: Return type mismatch - found %s, expected %s",
 850                              pathname,
 851                              acpi_ut_get_object_type_name(return_object),
 852                              type_buffer));
 853        } else {
 854                ACPI_WARNING((AE_INFO,
 855                              "%s: Return Package type mismatch at index %u - "
 856                              "found %s, expected %s", pathname, package_index,
 857                              acpi_ut_get_object_type_name(return_object),
 858                              type_buffer));
 859        }
 860
 861        return (AE_AML_OPERAND_TYPE);
 862}
 863
 864/*******************************************************************************
 865 *
 866 * FUNCTION:    acpi_ns_check_reference
 867 *
 868 * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
 869 *              return_object   - Object returned from the evaluation of a
 870 *                                method or object
 871 *
 872 * RETURN:      Status
 873 *
 874 * DESCRIPTION: Check a returned reference object for the correct reference
 875 *              type. The only reference type that can be returned from a
 876 *              predefined method is a named reference. All others are invalid.
 877 *
 878 ******************************************************************************/
 879
 880static acpi_status
 881acpi_ns_check_reference(char *pathname,
 882                        union acpi_operand_object *return_object)
 883{
 884
 885        /*
 886         * Check the reference object for the correct reference type (opcode).
 887         * The only type of reference that can be converted to an union acpi_object is
 888         * a reference to a named object (reference class: NAME)
 889         */
 890        if (return_object->reference.class == ACPI_REFCLASS_NAME) {
 891                return (AE_OK);
 892        }
 893
 894        ACPI_WARNING((AE_INFO,
 895                      "%s: Return type mismatch - unexpected reference object type [%s] %2.2X",
 896                      pathname, acpi_ut_get_reference_name(return_object),
 897                      return_object->reference.class));
 898
 899        return (AE_AML_OPERAND_TYPE);
 900}
 901
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.