1 /****************************************************************************** 2 * 3 * Module Name: nsprepkg - Validation of package objects for predefined names 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2019, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpi.h" 45 #include "accommon.h" 46 #include "acnamesp.h" 47 #include "acpredef.h" 48 49 50 #define _COMPONENT ACPI_NAMESPACE 51 ACPI_MODULE_NAME ("nsprepkg") 52 53 54 /* Local prototypes */ 55 56 static ACPI_STATUS 57 AcpiNsCheckPackageList ( 58 ACPI_EVALUATE_INFO *Info, 59 const ACPI_PREDEFINED_INFO *Package, 60 ACPI_OPERAND_OBJECT **Elements, 61 UINT32 Count); 62 63 static ACPI_STATUS 64 AcpiNsCheckPackageElements ( 65 ACPI_EVALUATE_INFO *Info, 66 ACPI_OPERAND_OBJECT **Elements, 67 UINT8 Type1, 68 UINT32 Count1, 69 UINT8 Type2, 70 UINT32 Count2, 71 UINT32 StartIndex); 72 73 static ACPI_STATUS 74 AcpiNsCustomPackage ( 75 ACPI_EVALUATE_INFO *Info, 76 ACPI_OPERAND_OBJECT **Elements, 77 UINT32 Count); 78 79 80 /******************************************************************************* 81 * 82 * FUNCTION: AcpiNsCheckPackage 83 * 84 * PARAMETERS: Info - Method execution information block 85 * ReturnObjectPtr - Pointer to the object returned from the 86 * evaluation of a method or object 87 * 88 * RETURN: Status 89 * 90 * DESCRIPTION: Check a returned package object for the correct count and 91 * correct type of all sub-objects. 92 * 93 ******************************************************************************/ 94 95 ACPI_STATUS 96 AcpiNsCheckPackage ( 97 ACPI_EVALUATE_INFO *Info, 98 ACPI_OPERAND_OBJECT **ReturnObjectPtr) 99 { 100 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; 101 const ACPI_PREDEFINED_INFO *Package; 102 ACPI_OPERAND_OBJECT **Elements; 103 ACPI_STATUS Status = AE_OK; 104 UINT32 ExpectedCount; 105 UINT32 Count; 106 UINT32 i; 107 108 109 ACPI_FUNCTION_NAME (NsCheckPackage); 110 111 112 /* The package info for this name is in the next table entry */ 113 114 Package = Info->Predefined + 1; 115 116 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 117 "%s Validating return Package of Type %X, Count %X\n", 118 Info->FullPathname, Package->RetInfo.Type, 119 ReturnObject->Package.Count)); 120 121 /* 122 * For variable-length Packages, we can safely remove all embedded 123 * and trailing NULL package elements 124 */ 125 AcpiNsRemoveNullElements (Info, Package->RetInfo.Type, ReturnObject); 126 127 /* Extract package count and elements array */ 128 129 Elements = ReturnObject->Package.Elements; 130 Count = ReturnObject->Package.Count; 131 132 /* 133 * Most packages must have at least one element. The only exception 134 * is the variable-length package (ACPI_PTYPE1_VAR). 135 */ 136 if (!Count) 137 { 138 if (Package->RetInfo.Type == ACPI_PTYPE1_VAR) 139 { 140 return (AE_OK); 141 } 142 143 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 144 "Return Package has no elements (empty)")); 145 146 return (AE_AML_OPERAND_VALUE); 147 } 148 149 /* 150 * Decode the type of the expected package contents 151 * 152 * PTYPE1 packages contain no subpackages 153 * PTYPE2 packages contain subpackages 154 */ 155 switch (Package->RetInfo.Type) 156 { 157 case ACPI_PTYPE_CUSTOM: 158 159 Status = AcpiNsCustomPackage (Info, Elements, Count); 160 break; 161 162 case ACPI_PTYPE1_FIXED: 163 /* 164 * The package count is fixed and there are no subpackages 165 * 166 * If package is too small, exit. 167 * If package is larger than expected, issue warning but continue 168 */ 169 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 170 if (Count < ExpectedCount) 171 { 172 goto PackageTooSmall; 173 } 174 else if (Count > ExpectedCount) 175 { 176 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 177 "%s: Return Package is larger than needed - " 178 "found %u, expected %u\n", 179 Info->FullPathname, Count, ExpectedCount)); 180 } 181 182 /* Validate all elements of the returned package */ 183 184 Status = AcpiNsCheckPackageElements (Info, Elements, 185 Package->RetInfo.ObjectType1, Package->RetInfo.Count1, 186 Package->RetInfo.ObjectType2, Package->RetInfo.Count2, 0); 187 break; 188 189 case ACPI_PTYPE1_VAR: 190 /* 191 * The package count is variable, there are no subpackages, and all 192 * elements must be of the same type 193 */ 194 for (i = 0; i < Count; i++) 195 { 196 Status = AcpiNsCheckObjectType (Info, Elements, 197 Package->RetInfo.ObjectType1, i); 198 if (ACPI_FAILURE (Status)) 199 { 200 return (Status); 201 } 202 203 Elements++; 204 } 205 break; 206 207 case ACPI_PTYPE1_OPTION: 208 /* 209 * The package count is variable, there are no subpackages. There are 210 * a fixed number of required elements, and a variable number of 211 * optional elements. 212 * 213 * Check if package is at least as large as the minimum required 214 */ 215 ExpectedCount = Package->RetInfo3.Count; 216 if (Count < ExpectedCount) 217 { 218 goto PackageTooSmall; 219 } 220 221 /* Variable number of sub-objects */ 222 223 for (i = 0; i < Count; i++) 224 { 225 if (i < Package->RetInfo3.Count) 226 { 227 /* These are the required package elements (0, 1, or 2) */ 228 229 Status = AcpiNsCheckObjectType (Info, Elements, 230 Package->RetInfo3.ObjectType[i], i); 231 if (ACPI_FAILURE (Status)) 232 { 233 return (Status); 234 } 235 } 236 else 237 { 238 /* These are the optional package elements */ 239 240 Status = AcpiNsCheckObjectType (Info, Elements, 241 Package->RetInfo3.TailObjectType, i); 242 if (ACPI_FAILURE (Status)) 243 { 244 return (Status); 245 } 246 } 247 248 Elements++; 249 } 250 break; 251 252 case ACPI_PTYPE2_REV_FIXED: 253 254 /* First element is the (Integer) revision */ 255 256 Status = AcpiNsCheckObjectType ( 257 Info, Elements, ACPI_RTYPE_INTEGER, 0); 258 if (ACPI_FAILURE (Status)) 259 { 260 return (Status); 261 } 262 263 Elements++; 264 Count--; 265 266 /* Examine the subpackages */ 267 268 Status = AcpiNsCheckPackageList (Info, Package, Elements, Count); 269 break; 270 271 case ACPI_PTYPE2_PKG_COUNT: 272 273 /* First element is the (Integer) count of subpackages to follow */ 274 275 Status = AcpiNsCheckObjectType ( 276 Info, Elements, ACPI_RTYPE_INTEGER, 0); 277 if (ACPI_FAILURE (Status)) 278 { 279 return (Status); 280 } 281 282 /* 283 * Count cannot be larger than the parent package length, but allow it 284 * to be smaller. The >= accounts for the Integer above. 285 */ 286 ExpectedCount = (UINT32) (*Elements)->Integer.Value; 287 if (ExpectedCount >= Count) 288 { 289 goto PackageTooSmall; 290 } 291 292 Count = ExpectedCount; 293 Elements++; 294 295 /* Examine the subpackages */ 296 297 Status = AcpiNsCheckPackageList (Info, Package, Elements, Count); 298 break; 299 300 case ACPI_PTYPE2: 301 case ACPI_PTYPE2_FIXED: 302 case ACPI_PTYPE2_MIN: 303 case ACPI_PTYPE2_COUNT: 304 case ACPI_PTYPE2_FIX_VAR: 305 /* 306 * These types all return a single Package that consists of a 307 * variable number of subpackages. 308 * 309 * First, ensure that the first element is a subpackage. If not, 310 * the BIOS may have incorrectly returned the object as a single 311 * package instead of a Package of Packages (a common error if 312 * there is only one entry). We may be able to repair this by 313 * wrapping the returned Package with a new outer Package. 314 */ 315 if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE)) 316 { 317 /* Create the new outer package and populate it */ 318 319 Status = AcpiNsWrapWithPackage ( 320 Info, ReturnObject, ReturnObjectPtr); 321 if (ACPI_FAILURE (Status)) 322 { 323 return (Status); 324 } 325 326 /* Update locals to point to the new package (of 1 element) */ 327 328 ReturnObject = *ReturnObjectPtr; 329 Elements = ReturnObject->Package.Elements; 330 Count = 1; 331 } 332 333 /* Examine the subpackages */ 334 335 Status = AcpiNsCheckPackageList (Info, Package, Elements, Count); 336 break; 337 338 case ACPI_PTYPE2_VAR_VAR: 339 /* 340 * Returns a variable list of packages, each with a variable list 341 * of objects. 342 */ 343 break; 344 345 case ACPI_PTYPE2_UUID_PAIR: 346 347 /* The package must contain pairs of (UUID + type) */ 348 349 if (Count & 1) 350 { 351 ExpectedCount = Count + 1; 352 goto PackageTooSmall; 353 } 354 355 while (Count > 0) 356 { 357 Status = AcpiNsCheckObjectType(Info, Elements, 358 Package->RetInfo.ObjectType1, 0); 359 if (ACPI_FAILURE(Status)) 360 { 361 return (Status); 362 } 363 364 /* Validate length of the UUID buffer */ 365 366 if ((*Elements)->Buffer.Length != 16) 367 { 368 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, 369 Info->NodeFlags, "Invalid length for UUID Buffer")); 370 return (AE_AML_OPERAND_VALUE); 371 } 372 373 Status = AcpiNsCheckObjectType(Info, Elements + 1, 374 Package->RetInfo.ObjectType2, 0); 375 if (ACPI_FAILURE(Status)) 376 { 377 return (Status); 378 } 379 380 Elements += 2; 381 Count -= 2; 382 } 383 break; 384 385 default: 386 387 /* Should not get here if predefined info table is correct */ 388 389 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 390 "Invalid internal return type in table entry: %X", 391 Package->RetInfo.Type)); 392 393 return (AE_AML_INTERNAL); 394 } 395 396 return (Status); 397 398 399 PackageTooSmall: 400 401 /* Error exit for the case with an incorrect package count */ 402 403 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 404 "Return Package is too small - found %u elements, expected %u", 405 Count, ExpectedCount)); 406 407 return (AE_AML_OPERAND_VALUE); 408 } 409 410 411 /******************************************************************************* 412 * 413 * FUNCTION: AcpiNsCheckPackageList 414 * 415 * PARAMETERS: Info - Method execution information block 416 * Package - Pointer to package-specific info for method 417 * Elements - Element list of parent package. All elements 418 * of this list should be of type Package. 419 * Count - Count of subpackages 420 * 421 * RETURN: Status 422 * 423 * DESCRIPTION: Examine a list of subpackages 424 * 425 ******************************************************************************/ 426 427 static ACPI_STATUS 428 AcpiNsCheckPackageList ( 429 ACPI_EVALUATE_INFO *Info, 430 const ACPI_PREDEFINED_INFO *Package, 431 ACPI_OPERAND_OBJECT **Elements, 432 UINT32 Count) 433 { 434 ACPI_OPERAND_OBJECT *SubPackage; 435 ACPI_OPERAND_OBJECT **SubElements; 436 ACPI_STATUS Status; 437 UINT32 ExpectedCount; 438 UINT32 i; 439 UINT32 j; 440 441 442 /* 443 * Validate each subpackage in the parent Package 444 * 445 * NOTE: assumes list of subpackages contains no NULL elements. 446 * Any NULL elements should have been removed by earlier call 447 * to AcpiNsRemoveNullElements. 448 */ 449 for (i = 0; i < Count; i++) 450 { 451 SubPackage = *Elements; 452 SubElements = SubPackage->Package.Elements; 453 Info->ParentPackage = SubPackage; 454 455 /* Each sub-object must be of type Package */ 456 457 Status = AcpiNsCheckObjectType (Info, &SubPackage, 458 ACPI_RTYPE_PACKAGE, i); 459 if (ACPI_FAILURE (Status)) 460 { 461 return (Status); 462 } 463 464 /* Examine the different types of expected subpackages */ 465 466 Info->ParentPackage = SubPackage; 467 switch (Package->RetInfo.Type) 468 { 469 case ACPI_PTYPE2: 470 case ACPI_PTYPE2_PKG_COUNT: 471 case ACPI_PTYPE2_REV_FIXED: 472 473 /* Each subpackage has a fixed number of elements */ 474 475 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 476 if (SubPackage->Package.Count < ExpectedCount) 477 { 478 goto PackageTooSmall; 479 } 480 481 Status = AcpiNsCheckPackageElements (Info, SubElements, 482 Package->RetInfo.ObjectType1, 483 Package->RetInfo.Count1, 484 Package->RetInfo.ObjectType2, 485 Package->RetInfo.Count2, 0); 486 if (ACPI_FAILURE (Status)) 487 { 488 return (Status); 489 } 490 break; 491 492 case ACPI_PTYPE2_FIX_VAR: 493 /* 494 * Each subpackage has a fixed number of elements and an 495 * optional element 496 */ 497 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2; 498 if (SubPackage->Package.Count < ExpectedCount) 499 { 500 goto PackageTooSmall; 501 } 502 503 Status = AcpiNsCheckPackageElements (Info, SubElements, 504 Package->RetInfo.ObjectType1, 505 Package->RetInfo.Count1, 506 Package->RetInfo.ObjectType2, 507 SubPackage->Package.Count - Package->RetInfo.Count1, 0); 508 if (ACPI_FAILURE (Status)) 509 { 510 return (Status); 511 } 512 break; 513 514 case ACPI_PTYPE2_VAR_VAR: 515 /* 516 * Each subpackage has a fixed or variable number of elements 517 */ 518 break; 519 520 case ACPI_PTYPE2_FIXED: 521 522 /* Each subpackage has a fixed length */ 523 524 ExpectedCount = Package->RetInfo2.Count; 525 if (SubPackage->Package.Count < ExpectedCount) 526 { 527 goto PackageTooSmall; 528 } 529 530 /* Check the type of each subpackage element */ 531 532 for (j = 0; j < ExpectedCount; j++) 533 { 534 Status = AcpiNsCheckObjectType (Info, &SubElements[j], 535 Package->RetInfo2.ObjectType[j], j); 536 if (ACPI_FAILURE (Status)) 537 { 538 return (Status); 539 } 540 } 541 break; 542 543 case ACPI_PTYPE2_MIN: 544 545 /* Each subpackage has a variable but minimum length */ 546 547 ExpectedCount = Package->RetInfo.Count1; 548 if (SubPackage->Package.Count < ExpectedCount) 549 { 550 goto PackageTooSmall; 551 } 552 553 /* Check the type of each subpackage element */ 554 555 Status = AcpiNsCheckPackageElements (Info, SubElements, 556 Package->RetInfo.ObjectType1, 557 SubPackage->Package.Count, 0, 0, 0); 558 if (ACPI_FAILURE (Status)) 559 { 560 return (Status); 561 } 562 break; 563 564 case ACPI_PTYPE2_COUNT: 565 /* 566 * First element is the (Integer) count of elements, including 567 * the count field (the ACPI name is NumElements) 568 */ 569 Status = AcpiNsCheckObjectType (Info, SubElements, 570 ACPI_RTYPE_INTEGER, 0); 571 if (ACPI_FAILURE (Status)) 572 { 573 return (Status); 574 } 575 576 /* 577 * Make sure package is large enough for the Count and is 578 * is as large as the minimum size 579 */ 580 ExpectedCount = (UINT32) (*SubElements)->Integer.Value; 581 if (SubPackage->Package.Count < ExpectedCount) 582 { 583 goto PackageTooSmall; 584 } 585 586 if (SubPackage->Package.Count < Package->RetInfo.Count1) 587 { 588 ExpectedCount = Package->RetInfo.Count1; 589 goto PackageTooSmall; 590 } 591 592 if (ExpectedCount == 0) 593 { 594 /* 595 * Either the NumEntries element was originally zero or it was 596 * a NULL element and repaired to an Integer of value zero. 597 * In either case, repair it by setting NumEntries to be the 598 * actual size of the subpackage. 599 */ 600 ExpectedCount = SubPackage->Package.Count; 601 (*SubElements)->Integer.Value = ExpectedCount; 602 } 603 604 /* Check the type of each subpackage element */ 605 606 Status = AcpiNsCheckPackageElements (Info, (SubElements + 1), 607 Package->RetInfo.ObjectType1, 608 (ExpectedCount - 1), 0, 0, 1); 609 if (ACPI_FAILURE (Status)) 610 { 611 return (Status); 612 } 613 break; 614 615 default: /* Should not get here, type was validated by caller */ 616 617 ACPI_ERROR ((AE_INFO, "Invalid Package type: %X", 618 Package->RetInfo.Type)); 619 return (AE_AML_INTERNAL); 620 } 621 622 Elements++; 623 } 624 625 return (AE_OK); 626 627 628 PackageTooSmall: 629 630 /* The subpackage count was smaller than required */ 631 632 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 633 "Return SubPackage[%u] is too small - found %u elements, expected %u", 634 i, SubPackage->Package.Count, ExpectedCount)); 635 636 return (AE_AML_OPERAND_VALUE); 637 } 638 639 640 /******************************************************************************* 641 * 642 * FUNCTION: AcpiNsCustomPackage 643 * 644 * PARAMETERS: Info - Method execution information block 645 * Elements - Pointer to the package elements array 646 * Count - Element count for the package 647 * 648 * RETURN: Status 649 * 650 * DESCRIPTION: Check a returned package object for the correct count and 651 * correct type of all sub-objects. 652 * 653 * NOTE: Currently used for the _BIX method only. When needed for two or more 654 * methods, probably a detect/dispatch mechanism will be required. 655 * 656 ******************************************************************************/ 657 658 static ACPI_STATUS 659 AcpiNsCustomPackage ( 660 ACPI_EVALUATE_INFO *Info, 661 ACPI_OPERAND_OBJECT **Elements, 662 UINT32 Count) 663 { 664 UINT32 ExpectedCount; 665 UINT32 Version; 666 ACPI_STATUS Status = AE_OK; 667 668 669 ACPI_FUNCTION_NAME (NsCustomPackage); 670 671 672 /* Get version number, must be Integer */ 673 674 if ((*Elements)->Common.Type != ACPI_TYPE_INTEGER) 675 { 676 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 677 "Return Package has invalid object type for version number")); 678 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 679 } 680 681 Version = (UINT32) (*Elements)->Integer.Value; 682 ExpectedCount = 21; /* Version 1 */ 683 684 if (Version == 0) 685 { 686 ExpectedCount = 20; /* Version 0 */ 687 } 688 689 if (Count < ExpectedCount) 690 { 691 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, Info->NodeFlags, 692 "Return Package is too small - found %u elements, expected %u", 693 Count, ExpectedCount)); 694 return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 695 } 696 else if (Count > ExpectedCount) 697 { 698 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, 699 "%s: Return Package is larger than needed - " 700 "found %u, expected %u\n", 701 Info->FullPathname, Count, ExpectedCount)); 702 } 703 704 /* Validate all elements of the returned package */ 705 706 Status = AcpiNsCheckPackageElements (Info, Elements, 707 ACPI_RTYPE_INTEGER, 16, 708 ACPI_RTYPE_STRING, 4, 0); 709 if (ACPI_FAILURE (Status)) 710 { 711 return_ACPI_STATUS (Status); 712 } 713 714 /* Version 1 has a single trailing integer */ 715 716 if (Version > 0) 717 { 718 Status = AcpiNsCheckPackageElements (Info, Elements + 20, 719 ACPI_RTYPE_INTEGER, 1, 0, 0, 20); 720 } 721 722 return_ACPI_STATUS (Status); 723 } 724 725 726 /******************************************************************************* 727 * 728 * FUNCTION: AcpiNsCheckPackageElements 729 * 730 * PARAMETERS: Info - Method execution information block 731 * Elements - Pointer to the package elements array 732 * Type1 - Object type for first group 733 * Count1 - Count for first group 734 * Type2 - Object type for second group 735 * Count2 - Count for second group 736 * StartIndex - Start of the first group of elements 737 * 738 * RETURN: Status 739 * 740 * DESCRIPTION: Check that all elements of a package are of the correct object 741 * type. Supports up to two groups of different object types. 742 * 743 ******************************************************************************/ 744 745 static ACPI_STATUS 746 AcpiNsCheckPackageElements ( 747 ACPI_EVALUATE_INFO *Info, 748 ACPI_OPERAND_OBJECT **Elements, 749 UINT8 Type1, 750 UINT32 Count1, 751 UINT8 Type2, 752 UINT32 Count2, 753 UINT32 StartIndex) 754 { 755 ACPI_OPERAND_OBJECT **ThisElement = Elements; 756 ACPI_STATUS Status; 757 UINT32 i; 758 759 760 /* 761 * Up to two groups of package elements are supported by the data 762 * structure. All elements in each group must be of the same type. 763 * The second group can have a count of zero. 764 */ 765 for (i = 0; i < Count1; i++) 766 { 767 Status = AcpiNsCheckObjectType (Info, ThisElement, 768 Type1, i + StartIndex); 769 if (ACPI_FAILURE (Status)) 770 { 771 return (Status); 772 } 773 774 ThisElement++; 775 } 776 777 for (i = 0; i < Count2; i++) 778 { 779 Status = AcpiNsCheckObjectType (Info, ThisElement, 780 Type2, (i + Count1 + StartIndex)); 781 if (ACPI_FAILURE (Status)) 782 { 783 return (Status); 784 } 785 786 ThisElement++; 787 } 788 789 return (AE_OK); 790 } 791