1118611Snjl/****************************************************************************** 2118611Snjl * 3218590Sjkim * Module Name: aslanalyze.c - Support functions for parse tree walks 4118611Snjl * 5118611Snjl *****************************************************************************/ 6118611Snjl 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 9118611Snjl * All rights reserved. 10118611Snjl * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25118611Snjl * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29118611Snjl * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43118611Snjl 44118611Snjl 45151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 46118611Snjl#include "aslcompiler.y.h" 47218590Sjkim#include <string.h> 48118611Snjl 49218590Sjkim 50118611Snjl#define _COMPONENT ACPI_COMPILER 51118611Snjl ACPI_MODULE_NAME ("aslanalyze") 52118611Snjl 53118611Snjl 54118611Snjl/******************************************************************************* 55118611Snjl * 56167802Sjkim * FUNCTION: AnIsInternalMethod 57167802Sjkim * 58218590Sjkim * PARAMETERS: Op - Current op 59167802Sjkim * 60167802Sjkim * RETURN: Boolean 61167802Sjkim * 62167802Sjkim * DESCRIPTION: Check for an internal control method. 63167802Sjkim * 64167802Sjkim ******************************************************************************/ 65167802Sjkim 66218590SjkimBOOLEAN 67167802SjkimAnIsInternalMethod ( 68167802Sjkim ACPI_PARSE_OBJECT *Op) 69167802Sjkim{ 70167802Sjkim 71167802Sjkim if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) || 72167802Sjkim (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI"))) 73167802Sjkim { 74167802Sjkim return (TRUE); 75167802Sjkim } 76167802Sjkim 77167802Sjkim return (FALSE); 78167802Sjkim} 79167802Sjkim 80167802Sjkim 81167802Sjkim/******************************************************************************* 82167802Sjkim * 83167802Sjkim * FUNCTION: AnGetInternalMethodReturnType 84167802Sjkim * 85218590Sjkim * PARAMETERS: Op - Current op 86167802Sjkim * 87167802Sjkim * RETURN: Btype 88167802Sjkim * 89167802Sjkim * DESCRIPTION: Get the return type of an internal method 90167802Sjkim * 91167802Sjkim ******************************************************************************/ 92167802Sjkim 93218590SjkimUINT32 94167802SjkimAnGetInternalMethodReturnType ( 95167802Sjkim ACPI_PARSE_OBJECT *Op) 96167802Sjkim{ 97167802Sjkim 98167802Sjkim if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) || 99167802Sjkim (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI"))) 100167802Sjkim { 101167802Sjkim return (ACPI_BTYPE_STRING); 102167802Sjkim } 103167802Sjkim 104167802Sjkim return (0); 105167802Sjkim} 106167802Sjkim 107167802Sjkim 108167802Sjkim/******************************************************************************* 109167802Sjkim * 110213806Sjkim * FUNCTION: AnCheckId 111213806Sjkim * 112213806Sjkim * PARAMETERS: Op - Current parse op 113213806Sjkim * Type - HID or CID 114213806Sjkim * 115213806Sjkim * RETURN: None 116213806Sjkim * 117213806Sjkim * DESCRIPTION: Perform various checks on _HID and _CID strings. Only limited 118213806Sjkim * checks can be performed on _CID strings. 119213806Sjkim * 120213806Sjkim ******************************************************************************/ 121213806Sjkim 122218590Sjkimvoid 123213806SjkimAnCheckId ( 124213806Sjkim ACPI_PARSE_OBJECT *Op, 125213806Sjkim ACPI_NAME Type) 126213806Sjkim{ 127213806Sjkim UINT32 i; 128213806Sjkim ACPI_SIZE Length; 129213806Sjkim 130213806Sjkim 131216471Sjkim /* Only care about string versions of _HID/_CID (integers are legal) */ 132216471Sjkim 133213806Sjkim if (Op->Asl.ParseOpcode != PARSEOP_STRING_LITERAL) 134213806Sjkim { 135213806Sjkim return; 136213806Sjkim } 137213806Sjkim 138216471Sjkim /* For both _HID and _CID, the string must be non-null */ 139216471Sjkim 140213806Sjkim Length = strlen (Op->Asl.Value.String); 141216471Sjkim if (!Length) 142216471Sjkim { 143216471Sjkim AslError (ASL_ERROR, ASL_MSG_NULL_STRING, 144216471Sjkim Op, NULL); 145216471Sjkim return; 146216471Sjkim } 147213806Sjkim 148213806Sjkim /* 149216471Sjkim * One of the things we want to catch here is the use of a leading 150216471Sjkim * asterisk in the string -- an odd construct that certain platform 151216471Sjkim * manufacturers are fond of. Technically, a leading asterisk is OK 152216471Sjkim * for _CID, but a valid use of this has not been seen. 153213806Sjkim */ 154216471Sjkim if (*Op->Asl.Value.String == '*') 155216471Sjkim { 156216471Sjkim AslError (ASL_ERROR, ASL_MSG_LEADING_ASTERISK, 157216471Sjkim Op, Op->Asl.Value.String); 158216471Sjkim return; 159216471Sjkim } 160216471Sjkim 161216471Sjkim /* _CID strings are bus-specific, no more checks can be performed */ 162216471Sjkim 163216471Sjkim if (Type == ASL_TYPE_CID) 164216471Sjkim { 165216471Sjkim return; 166216471Sjkim } 167216471Sjkim 168216471Sjkim /* For _HID, all characters must be alphanumeric */ 169216471Sjkim 170213806Sjkim for (i = 0; Op->Asl.Value.String[i]; i++) 171213806Sjkim { 172213806Sjkim if (!isalnum ((int) Op->Asl.Value.String[i])) 173213806Sjkim { 174213806Sjkim AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING, 175213806Sjkim Op, Op->Asl.Value.String); 176228110Sjkim return; 177213806Sjkim } 178213806Sjkim } 179213806Sjkim 180228110Sjkim /* 181228110Sjkim * _HID String must be one of these forms: 182228110Sjkim * 183228110Sjkim * "AAA####" A is an uppercase letter and # is a hex digit 184228110Sjkim * "ACPI####" # is a hex digit 185228110Sjkim * "NNNN####" N is an uppercase letter or decimal digit (0-9) 186228110Sjkim * # is a hex digit (ACPI 5.0) 187228110Sjkim */ 188213806Sjkim if ((Length < 7) || (Length > 8)) 189213806Sjkim { 190213806Sjkim AslError (ASL_ERROR, ASL_MSG_HID_LENGTH, 191213806Sjkim Op, Op->Asl.Value.String); 192213806Sjkim return; 193213806Sjkim } 194213806Sjkim 195228110Sjkim /* _HID Length is valid (7 or 8), now check the prefix (first 3 or 4 chars) */ 196213806Sjkim 197228110Sjkim if (Length == 7) 198213806Sjkim { 199228110Sjkim /* AAA####: Ensure the alphabetic prefix is all uppercase */ 200228110Sjkim 201228110Sjkim for (i = 0; i < 3; i++) 202228110Sjkim { 203228110Sjkim if (!isupper ((int) Op->Asl.Value.String[i])) 204228110Sjkim { 205228110Sjkim AslError (ASL_ERROR, ASL_MSG_UPPER_CASE, 206228110Sjkim Op, &Op->Asl.Value.String[i]); 207228110Sjkim return; 208228110Sjkim } 209228110Sjkim } 210213806Sjkim } 211228110Sjkim else /* Length == 8 */ 212228110Sjkim { 213228110Sjkim /* 214228110Sjkim * ACPI#### or NNNN####: 215228110Sjkim * Ensure the prefix contains only uppercase alpha or decimal digits 216228110Sjkim */ 217228110Sjkim for (i = 0; i < 4; i++) 218228110Sjkim { 219228110Sjkim if (!isupper ((int) Op->Asl.Value.String[i]) && 220228110Sjkim !isdigit ((int) Op->Asl.Value.String[i])) 221228110Sjkim { 222228110Sjkim AslError (ASL_ERROR, ASL_MSG_HID_PREFIX, 223228110Sjkim Op, &Op->Asl.Value.String[i]); 224228110Sjkim return; 225228110Sjkim } 226228110Sjkim } 227228110Sjkim } 228213806Sjkim 229228110Sjkim /* Remaining characters (suffix) must be hex digits */ 230213806Sjkim 231228110Sjkim for (; i < Length; i++) 232213806Sjkim { 233228110Sjkim if (!isxdigit ((int) Op->Asl.Value.String[i])) 234213806Sjkim { 235228110Sjkim AslError (ASL_ERROR, ASL_MSG_HID_SUFFIX, 236228110Sjkim Op, &Op->Asl.Value.String[i]); 237213806Sjkim break; 238213806Sjkim } 239213806Sjkim } 240213806Sjkim} 241213806Sjkim 242213806Sjkim 243213806Sjkim/******************************************************************************* 244213806Sjkim * 245118611Snjl * FUNCTION: AnLastStatementIsReturn 246118611Snjl * 247218590Sjkim * PARAMETERS: Op - A method parse node 248118611Snjl * 249167802Sjkim * RETURN: TRUE if last statement is an ASL RETURN. False otherwise 250118611Snjl * 251118611Snjl * DESCRIPTION: Walk down the list of top level statements within a method 252167802Sjkim * to find the last one. Check if that last statement is in 253118611Snjl * fact a RETURN statement. 254118611Snjl * 255118611Snjl ******************************************************************************/ 256118611Snjl 257218590SjkimBOOLEAN 258118611SnjlAnLastStatementIsReturn ( 259118611Snjl ACPI_PARSE_OBJECT *Op) 260118611Snjl{ 261118611Snjl ACPI_PARSE_OBJECT *Next; 262118611Snjl 263118611Snjl 264218590Sjkim /* Check if last statement is a return */ 265218590Sjkim 266118611Snjl Next = ASL_GET_CHILD_NODE (Op); 267118611Snjl while (Next) 268118611Snjl { 269118611Snjl if ((!Next->Asl.Next) && 270118611Snjl (Next->Asl.ParseOpcode == PARSEOP_RETURN)) 271118611Snjl { 272218590Sjkim return (TRUE); 273118611Snjl } 274118611Snjl 275118611Snjl Next = ASL_GET_PEER_NODE (Next); 276118611Snjl } 277118611Snjl 278218590Sjkim return (FALSE); 279118611Snjl} 280118611Snjl 281118611Snjl 282118611Snjl/******************************************************************************* 283118611Snjl * 284118611Snjl * FUNCTION: AnCheckMethodReturnValue 285118611Snjl * 286118611Snjl * PARAMETERS: Op - Parent 287118611Snjl * OpInfo - Parent info 288118611Snjl * ArgOp - Method invocation op 289118611Snjl * RequiredBtypes - What caller requires 290118611Snjl * ThisNodeBtype - What this node returns (if anything) 291118611Snjl * 292118611Snjl * RETURN: None 293118611Snjl * 294118611Snjl * DESCRIPTION: Check a method invocation for 1) A return value and if it does 295118611Snjl * in fact return a value, 2) check the type of the return value. 296118611Snjl * 297118611Snjl ******************************************************************************/ 298118611Snjl 299218590Sjkimvoid 300118611SnjlAnCheckMethodReturnValue ( 301118611Snjl ACPI_PARSE_OBJECT *Op, 302118611Snjl const ACPI_OPCODE_INFO *OpInfo, 303118611Snjl ACPI_PARSE_OBJECT *ArgOp, 304118611Snjl UINT32 RequiredBtypes, 305118611Snjl UINT32 ThisNodeBtype) 306118611Snjl{ 307118611Snjl ACPI_PARSE_OBJECT *OwningOp; 308118611Snjl ACPI_NAMESPACE_NODE *Node; 309118611Snjl 310118611Snjl 311118611Snjl Node = ArgOp->Asl.Node; 312118611Snjl 313118611Snjl 314118611Snjl /* Examine the parent op of this method */ 315118611Snjl 316151937Sjkim OwningOp = Node->Op; 317118611Snjl if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL) 318118611Snjl { 319151937Sjkim /* Method NEVER returns a value */ 320151937Sjkim 321118611Snjl AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName); 322118611Snjl } 323118611Snjl else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL) 324118611Snjl { 325151937Sjkim /* Method SOMETIMES returns a value, SOMETIMES not */ 326151937Sjkim 327118611Snjl AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName); 328118611Snjl } 329118611Snjl else if (!(ThisNodeBtype & RequiredBtypes)) 330118611Snjl { 331151937Sjkim /* Method returns a value, but the type is wrong */ 332151937Sjkim 333118611Snjl AnFormatBtype (StringBuffer, ThisNodeBtype); 334118611Snjl AnFormatBtype (StringBuffer2, RequiredBtypes); 335118611Snjl 336118611Snjl /* 337118611Snjl * The case where the method does not return any value at all 338118611Snjl * was already handled in the namespace cross reference 339118611Snjl * -- Only issue an error if the method in fact returns a value, 340118611Snjl * but it is of the wrong type 341118611Snjl */ 342118611Snjl if (ThisNodeBtype != 0) 343118611Snjl { 344151937Sjkim sprintf (MsgBuffer, 345151937Sjkim "Method returns [%s], %s operator requires [%s]", 346151937Sjkim StringBuffer, OpInfo->Name, StringBuffer2); 347118611Snjl 348118611Snjl AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer); 349118611Snjl } 350118611Snjl } 351118611Snjl} 352118611Snjl 353118611Snjl 354118611Snjl/******************************************************************************* 355118611Snjl * 356167802Sjkim * FUNCTION: AnIsResultUsed 357167802Sjkim * 358218590Sjkim * PARAMETERS: Op - Parent op for the operator 359167802Sjkim * 360167802Sjkim * RETURN: TRUE if result from this operation is actually consumed 361167802Sjkim * 362167802Sjkim * DESCRIPTION: Determine if the function result value from an operator is 363167802Sjkim * used. 364167802Sjkim * 365167802Sjkim ******************************************************************************/ 366167802Sjkim 367218590SjkimBOOLEAN 368167802SjkimAnIsResultUsed ( 369167802Sjkim ACPI_PARSE_OBJECT *Op) 370167802Sjkim{ 371167802Sjkim ACPI_PARSE_OBJECT *Parent; 372167802Sjkim 373167802Sjkim 374167802Sjkim switch (Op->Asl.ParseOpcode) 375167802Sjkim { 376167802Sjkim case PARSEOP_INCREMENT: 377167802Sjkim case PARSEOP_DECREMENT: 378167802Sjkim 379167802Sjkim /* These are standalone operators, no return value */ 380167802Sjkim 381167802Sjkim return (TRUE); 382167802Sjkim 383167802Sjkim default: 384250838Sjkim 385167802Sjkim break; 386167802Sjkim } 387167802Sjkim 388167802Sjkim /* Examine parent to determine if the return value is used */ 389167802Sjkim 390167802Sjkim Parent = Op->Asl.Parent; 391167802Sjkim switch (Parent->Asl.ParseOpcode) 392167802Sjkim { 393167802Sjkim /* If/While - check if the operator is the predicate */ 394167802Sjkim 395167802Sjkim case PARSEOP_IF: 396167802Sjkim case PARSEOP_WHILE: 397167802Sjkim 398167802Sjkim /* First child is the predicate */ 399167802Sjkim 400167802Sjkim if (Parent->Asl.Child == Op) 401167802Sjkim { 402167802Sjkim return (TRUE); 403167802Sjkim } 404167802Sjkim return (FALSE); 405167802Sjkim 406167802Sjkim /* Not used if one of these is the parent */ 407167802Sjkim 408167802Sjkim case PARSEOP_METHOD: 409167802Sjkim case PARSEOP_DEFINITIONBLOCK: 410167802Sjkim case PARSEOP_ELSE: 411167802Sjkim 412167802Sjkim return (FALSE); 413167802Sjkim 414167802Sjkim default: 415250838Sjkim 416167802Sjkim /* Any other type of parent means that the result is used */ 417167802Sjkim 418167802Sjkim return (TRUE); 419167802Sjkim } 420167802Sjkim} 421167802Sjkim 422167802Sjkim 423167802Sjkim/******************************************************************************* 424167802Sjkim * 425218590Sjkim * FUNCTION: ApCheckForGpeNameConflict 426118611Snjl * 427218590Sjkim * PARAMETERS: Op - Current parse op 428118611Snjl * 429218590Sjkim * RETURN: None 430118611Snjl * 431218590Sjkim * DESCRIPTION: Check for a conflict between GPE names within this scope. 432218590Sjkim * Conflict means two GPE names with the same GPE number, but 433218590Sjkim * different types -- such as _L1C and _E1C. 434118611Snjl * 435118611Snjl ******************************************************************************/ 436118611Snjl 437218590Sjkimvoid 438218590SjkimApCheckForGpeNameConflict ( 439218590Sjkim ACPI_PARSE_OBJECT *Op) 440118611Snjl{ 441218590Sjkim ACPI_PARSE_OBJECT *NextOp; 442218590Sjkim UINT32 GpeNumber; 443218590Sjkim char Name[ACPI_NAME_SIZE + 1]; 444218590Sjkim char Target[ACPI_NAME_SIZE]; 445118611Snjl 446167802Sjkim 447218590Sjkim /* Need a null-terminated string version of NameSeg */ 448167802Sjkim 449218590Sjkim ACPI_MOVE_32_TO_32 (Name, &Op->Asl.NameSeg); 450218590Sjkim Name[ACPI_NAME_SIZE] = 0; 451218590Sjkim 452167802Sjkim /* 453218590Sjkim * For a GPE method: 454218590Sjkim * 1st char must be underscore 455218590Sjkim * 2nd char must be L or E 456218590Sjkim * 3rd/4th chars must be a hex number 457167802Sjkim */ 458218590Sjkim if ((Name[0] != '_') || 459218590Sjkim ((Name[1] != 'L') && (Name[1] != 'E'))) 460167802Sjkim { 461218590Sjkim return; 462218590Sjkim } 463167802Sjkim 464218590Sjkim /* Verify 3rd/4th chars are a valid hex value */ 465167802Sjkim 466218590Sjkim GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16); 467218590Sjkim if (GpeNumber == ACPI_UINT32_MAX) 468218590Sjkim { 469218590Sjkim return; 470167802Sjkim } 471167802Sjkim 472167802Sjkim /* 473218590Sjkim * We are now sure we have an _Lxx or _Exx. 474218590Sjkim * Create the target name that would cause collision (Flip E/L) 475167802Sjkim */ 476218590Sjkim ACPI_MOVE_32_TO_32 (Target, Name); 477167802Sjkim 478218590Sjkim /* Inject opposite letter ("L" versus "E") */ 479167802Sjkim 480218590Sjkim if (Name[1] == 'L') 481218590Sjkim { 482218590Sjkim Target[1] = 'E'; 483218590Sjkim } 484218590Sjkim else /* Name[1] == 'E' */ 485218590Sjkim { 486218590Sjkim Target[1] = 'L'; 487218590Sjkim } 488167802Sjkim 489218590Sjkim /* Search all peers (objects within this scope) for target match */ 490167802Sjkim 491218590Sjkim NextOp = Op->Asl.Next; 492218590Sjkim while (NextOp) 493218590Sjkim { 494167802Sjkim /* 495218590Sjkim * We mostly care about methods, but check Name() constructs also, 496218590Sjkim * even though they will get another error for not being a method. 497218590Sjkim * All GPE names must be defined as control methods. 498167802Sjkim */ 499218590Sjkim if ((NextOp->Asl.ParseOpcode == PARSEOP_METHOD) || 500218590Sjkim (NextOp->Asl.ParseOpcode == PARSEOP_NAME)) 501167802Sjkim { 502218590Sjkim if (ACPI_COMPARE_NAME (Target, NextOp->Asl.NameSeg)) 503218590Sjkim { 504218590Sjkim /* Found both _Exy and _Lxy in the same scope, error */ 505167802Sjkim 506218590Sjkim AslError (ASL_ERROR, ASL_MSG_GPE_NAME_CONFLICT, NextOp, 507218590Sjkim Name); 508218590Sjkim return; 509218590Sjkim } 510167802Sjkim } 511167802Sjkim 512218590Sjkim NextOp = NextOp->Asl.Next; 513167802Sjkim } 514167802Sjkim 515218590Sjkim /* OK, no conflict found */ 516118611Snjl 517218590Sjkim return; 518118611Snjl} 519220663Sjkim 520220663Sjkim 521220663Sjkim/******************************************************************************* 522220663Sjkim * 523220663Sjkim * FUNCTION: ApCheckRegMethod 524220663Sjkim * 525220663Sjkim * PARAMETERS: Op - Current parse op 526220663Sjkim * 527220663Sjkim * RETURN: None 528220663Sjkim * 529220663Sjkim * DESCRIPTION: Ensure that a _REG method has a corresponding Operation 530220663Sjkim * Region declaration within the same scope. Note: _REG is defined 531220663Sjkim * to have two arguments and must therefore be defined as a 532220663Sjkim * control method. 533220663Sjkim * 534220663Sjkim ******************************************************************************/ 535220663Sjkim 536220663Sjkimvoid 537220663SjkimApCheckRegMethod ( 538220663Sjkim ACPI_PARSE_OBJECT *Op) 539220663Sjkim{ 540220663Sjkim ACPI_PARSE_OBJECT *Next; 541220663Sjkim ACPI_PARSE_OBJECT *Parent; 542220663Sjkim 543220663Sjkim 544220663Sjkim /* We are only interested in _REG methods */ 545220663Sjkim 546220663Sjkim if (!ACPI_COMPARE_NAME (METHOD_NAME__REG, &Op->Asl.NameSeg)) 547220663Sjkim { 548220663Sjkim return; 549220663Sjkim } 550220663Sjkim 551220663Sjkim /* Get the start of the current scope */ 552220663Sjkim 553220663Sjkim Parent = Op->Asl.Parent; 554220663Sjkim Next = Parent->Asl.Child; 555220663Sjkim 556220663Sjkim /* Search entire scope for an operation region declaration */ 557220663Sjkim 558220663Sjkim while (Next) 559220663Sjkim { 560220663Sjkim if (Next->Asl.ParseOpcode == PARSEOP_OPERATIONREGION) 561220663Sjkim { 562220663Sjkim return; /* Found region, OK */ 563220663Sjkim } 564220663Sjkim 565220663Sjkim Next = Next->Asl.Next; 566220663Sjkim } 567220663Sjkim 568220663Sjkim /* No region found, issue warning */ 569220663Sjkim 570220663Sjkim AslError (ASL_WARNING, ASL_MSG_NO_REGION, Op, NULL); 571220663Sjkim} 572