1*0d02842fSSascha Wildner /****************************************************************************** 2*0d02842fSSascha Wildner * 3*0d02842fSSascha Wildner * Module Name: hwvalid - I/O request validation 4*0d02842fSSascha Wildner * 5*0d02842fSSascha Wildner *****************************************************************************/ 6*0d02842fSSascha Wildner 7*0d02842fSSascha Wildner /* 8*0d02842fSSascha Wildner * Copyright (C) 2000 - 2013, Intel Corp. 9*0d02842fSSascha Wildner * All rights reserved. 10*0d02842fSSascha Wildner * 11*0d02842fSSascha Wildner * Redistribution and use in source and binary forms, with or without 12*0d02842fSSascha Wildner * modification, are permitted provided that the following conditions 13*0d02842fSSascha Wildner * are met: 14*0d02842fSSascha Wildner * 1. Redistributions of source code must retain the above copyright 15*0d02842fSSascha Wildner * notice, this list of conditions, and the following disclaimer, 16*0d02842fSSascha Wildner * without modification. 17*0d02842fSSascha Wildner * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*0d02842fSSascha Wildner * substantially similar to the "NO WARRANTY" disclaimer below 19*0d02842fSSascha Wildner * ("Disclaimer") and any redistribution must be conditioned upon 20*0d02842fSSascha Wildner * including a substantially similar Disclaimer requirement for further 21*0d02842fSSascha Wildner * binary redistribution. 22*0d02842fSSascha Wildner * 3. Neither the names of the above-listed copyright holders nor the names 23*0d02842fSSascha Wildner * of any contributors may be used to endorse or promote products derived 24*0d02842fSSascha Wildner * from this software without specific prior written permission. 25*0d02842fSSascha Wildner * 26*0d02842fSSascha Wildner * Alternatively, this software may be distributed under the terms of the 27*0d02842fSSascha Wildner * GNU General Public License ("GPL") version 2 as published by the Free 28*0d02842fSSascha Wildner * Software Foundation. 29*0d02842fSSascha Wildner * 30*0d02842fSSascha Wildner * NO WARRANTY 31*0d02842fSSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*0d02842fSSascha Wildner * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*0d02842fSSascha Wildner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*0d02842fSSascha Wildner * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*0d02842fSSascha Wildner * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*0d02842fSSascha Wildner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*0d02842fSSascha Wildner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*0d02842fSSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*0d02842fSSascha Wildner * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*0d02842fSSascha Wildner * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*0d02842fSSascha Wildner * POSSIBILITY OF SUCH DAMAGES. 42*0d02842fSSascha Wildner */ 43*0d02842fSSascha Wildner 44*0d02842fSSascha Wildner #define __HWVALID_C__ 45*0d02842fSSascha Wildner 46*0d02842fSSascha Wildner #include "acpi.h" 47*0d02842fSSascha Wildner #include "accommon.h" 48*0d02842fSSascha Wildner 49*0d02842fSSascha Wildner #define _COMPONENT ACPI_HARDWARE 50*0d02842fSSascha Wildner ACPI_MODULE_NAME ("hwvalid") 51*0d02842fSSascha Wildner 52*0d02842fSSascha Wildner /* Local prototypes */ 53*0d02842fSSascha Wildner 54*0d02842fSSascha Wildner static ACPI_STATUS 55*0d02842fSSascha Wildner AcpiHwValidateIoRequest ( 56*0d02842fSSascha Wildner ACPI_IO_ADDRESS Address, 57*0d02842fSSascha Wildner UINT32 BitWidth); 58*0d02842fSSascha Wildner 59*0d02842fSSascha Wildner 60*0d02842fSSascha Wildner /* 61*0d02842fSSascha Wildner * Protected I/O ports. Some ports are always illegal, and some are 62*0d02842fSSascha Wildner * conditionally illegal. This table must remain ordered by port address. 63*0d02842fSSascha Wildner * 64*0d02842fSSascha Wildner * The table is used to implement the Microsoft port access rules that 65*0d02842fSSascha Wildner * first appeared in Windows XP. Some ports are always illegal, and some 66*0d02842fSSascha Wildner * ports are only illegal if the BIOS calls _OSI with a WinXP string or 67*0d02842fSSascha Wildner * later (meaning that the BIOS itelf is post-XP.) 68*0d02842fSSascha Wildner * 69*0d02842fSSascha Wildner * This provides ACPICA with the desired port protections and 70*0d02842fSSascha Wildner * Microsoft compatibility. 71*0d02842fSSascha Wildner * 72*0d02842fSSascha Wildner * Description of port entries: 73*0d02842fSSascha Wildner * DMA: DMA controller 74*0d02842fSSascha Wildner * PIC0: Programmable Interrupt Controller (8259A) 75*0d02842fSSascha Wildner * PIT1: System Timer 1 76*0d02842fSSascha Wildner * PIT2: System Timer 2 failsafe 77*0d02842fSSascha Wildner * RTC: Real-time clock 78*0d02842fSSascha Wildner * CMOS: Extended CMOS 79*0d02842fSSascha Wildner * DMA1: DMA 1 page registers 80*0d02842fSSascha Wildner * DMA1L: DMA 1 Ch 0 low page 81*0d02842fSSascha Wildner * DMA2: DMA 2 page registers 82*0d02842fSSascha Wildner * DMA2L: DMA 2 low page refresh 83*0d02842fSSascha Wildner * ARBC: Arbitration control 84*0d02842fSSascha Wildner * SETUP: Reserved system board setup 85*0d02842fSSascha Wildner * POS: POS channel select 86*0d02842fSSascha Wildner * PIC1: Cascaded PIC 87*0d02842fSSascha Wildner * IDMA: ISA DMA 88*0d02842fSSascha Wildner * ELCR: PIC edge/level registers 89*0d02842fSSascha Wildner * PCI: PCI configuration space 90*0d02842fSSascha Wildner */ 91*0d02842fSSascha Wildner static const ACPI_PORT_INFO AcpiProtectedPorts[] = 92*0d02842fSSascha Wildner { 93*0d02842fSSascha Wildner {"DMA", 0x0000, 0x000F, ACPI_OSI_WIN_XP}, 94*0d02842fSSascha Wildner {"PIC0", 0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL}, 95*0d02842fSSascha Wildner {"PIT1", 0x0040, 0x0043, ACPI_OSI_WIN_XP}, 96*0d02842fSSascha Wildner {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP}, 97*0d02842fSSascha Wildner {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP}, 98*0d02842fSSascha Wildner {"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP}, 99*0d02842fSSascha Wildner {"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP}, 100*0d02842fSSascha Wildner {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP}, 101*0d02842fSSascha Wildner {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP}, 102*0d02842fSSascha Wildner {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP}, 103*0d02842fSSascha Wildner {"ARBC", 0x0090, 0x0091, ACPI_OSI_WIN_XP}, 104*0d02842fSSascha Wildner {"SETUP", 0x0093, 0x0094, ACPI_OSI_WIN_XP}, 105*0d02842fSSascha Wildner {"POS", 0x0096, 0x0097, ACPI_OSI_WIN_XP}, 106*0d02842fSSascha Wildner {"PIC1", 0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL}, 107*0d02842fSSascha Wildner {"IDMA", 0x00C0, 0x00DF, ACPI_OSI_WIN_XP}, 108*0d02842fSSascha Wildner {"ELCR", 0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL}, 109*0d02842fSSascha Wildner {"PCI", 0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP} 110*0d02842fSSascha Wildner }; 111*0d02842fSSascha Wildner 112*0d02842fSSascha Wildner #define ACPI_PORT_INFO_ENTRIES ACPI_ARRAY_LENGTH (AcpiProtectedPorts) 113*0d02842fSSascha Wildner 114*0d02842fSSascha Wildner 115*0d02842fSSascha Wildner /****************************************************************************** 116*0d02842fSSascha Wildner * 117*0d02842fSSascha Wildner * FUNCTION: AcpiHwValidateIoRequest 118*0d02842fSSascha Wildner * 119*0d02842fSSascha Wildner * PARAMETERS: Address Address of I/O port/register 120*0d02842fSSascha Wildner * BitWidth Number of bits (8,16,32) 121*0d02842fSSascha Wildner * 122*0d02842fSSascha Wildner * RETURN: Status 123*0d02842fSSascha Wildner * 124*0d02842fSSascha Wildner * DESCRIPTION: Validates an I/O request (address/length). Certain ports are 125*0d02842fSSascha Wildner * always illegal and some ports are only illegal depending on 126*0d02842fSSascha Wildner * the requests the BIOS AML code makes to the predefined 127*0d02842fSSascha Wildner * _OSI method. 128*0d02842fSSascha Wildner * 129*0d02842fSSascha Wildner ******************************************************************************/ 130*0d02842fSSascha Wildner 131*0d02842fSSascha Wildner static ACPI_STATUS 132*0d02842fSSascha Wildner AcpiHwValidateIoRequest ( 133*0d02842fSSascha Wildner ACPI_IO_ADDRESS Address, 134*0d02842fSSascha Wildner UINT32 BitWidth) 135*0d02842fSSascha Wildner { 136*0d02842fSSascha Wildner UINT32 i; 137*0d02842fSSascha Wildner UINT32 ByteWidth; 138*0d02842fSSascha Wildner ACPI_IO_ADDRESS LastAddress; 139*0d02842fSSascha Wildner const ACPI_PORT_INFO *PortInfo; 140*0d02842fSSascha Wildner 141*0d02842fSSascha Wildner 142*0d02842fSSascha Wildner ACPI_FUNCTION_TRACE (HwValidateIoRequest); 143*0d02842fSSascha Wildner 144*0d02842fSSascha Wildner 145*0d02842fSSascha Wildner /* Supported widths are 8/16/32 */ 146*0d02842fSSascha Wildner 147*0d02842fSSascha Wildner if ((BitWidth != 8) && 148*0d02842fSSascha Wildner (BitWidth != 16) && 149*0d02842fSSascha Wildner (BitWidth != 32)) 150*0d02842fSSascha Wildner { 151*0d02842fSSascha Wildner ACPI_ERROR ((AE_INFO, 152*0d02842fSSascha Wildner "Bad BitWidth parameter: %8.8X", BitWidth)); 153*0d02842fSSascha Wildner return (AE_BAD_PARAMETER); 154*0d02842fSSascha Wildner } 155*0d02842fSSascha Wildner 156*0d02842fSSascha Wildner PortInfo = AcpiProtectedPorts; 157*0d02842fSSascha Wildner ByteWidth = ACPI_DIV_8 (BitWidth); 158*0d02842fSSascha Wildner LastAddress = Address + ByteWidth - 1; 159*0d02842fSSascha Wildner 160*0d02842fSSascha Wildner ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Address %p LastAddress %p Length %X", 161*0d02842fSSascha Wildner ACPI_CAST_PTR (void, Address), ACPI_CAST_PTR (void, LastAddress), 162*0d02842fSSascha Wildner ByteWidth)); 163*0d02842fSSascha Wildner 164*0d02842fSSascha Wildner /* Maximum 16-bit address in I/O space */ 165*0d02842fSSascha Wildner 166*0d02842fSSascha Wildner if (LastAddress > ACPI_UINT16_MAX) 167*0d02842fSSascha Wildner { 168*0d02842fSSascha Wildner ACPI_ERROR ((AE_INFO, 169*0d02842fSSascha Wildner "Illegal I/O port address/length above 64K: %p/0x%X", 170*0d02842fSSascha Wildner ACPI_CAST_PTR (void, Address), ByteWidth)); 171*0d02842fSSascha Wildner return_ACPI_STATUS (AE_LIMIT); 172*0d02842fSSascha Wildner } 173*0d02842fSSascha Wildner 174*0d02842fSSascha Wildner /* Exit if requested address is not within the protected port table */ 175*0d02842fSSascha Wildner 176*0d02842fSSascha Wildner if (Address > AcpiProtectedPorts[ACPI_PORT_INFO_ENTRIES - 1].End) 177*0d02842fSSascha Wildner { 178*0d02842fSSascha Wildner return_ACPI_STATUS (AE_OK); 179*0d02842fSSascha Wildner } 180*0d02842fSSascha Wildner 181*0d02842fSSascha Wildner /* Check request against the list of protected I/O ports */ 182*0d02842fSSascha Wildner 183*0d02842fSSascha Wildner for (i = 0; i < ACPI_PORT_INFO_ENTRIES; i++, PortInfo++) 184*0d02842fSSascha Wildner { 185*0d02842fSSascha Wildner /* 186*0d02842fSSascha Wildner * Check if the requested address range will write to a reserved 187*0d02842fSSascha Wildner * port. Four cases to consider: 188*0d02842fSSascha Wildner * 189*0d02842fSSascha Wildner * 1) Address range is contained completely in the port address range 190*0d02842fSSascha Wildner * 2) Address range overlaps port range at the port range start 191*0d02842fSSascha Wildner * 3) Address range overlaps port range at the port range end 192*0d02842fSSascha Wildner * 4) Address range completely encompasses the port range 193*0d02842fSSascha Wildner */ 194*0d02842fSSascha Wildner if ((Address <= PortInfo->End) && (LastAddress >= PortInfo->Start)) 195*0d02842fSSascha Wildner { 196*0d02842fSSascha Wildner /* Port illegality may depend on the _OSI calls made by the BIOS */ 197*0d02842fSSascha Wildner 198*0d02842fSSascha Wildner if (AcpiGbl_OsiData >= PortInfo->OsiDependency) 199*0d02842fSSascha Wildner { 200*0d02842fSSascha Wildner ACPI_DEBUG_PRINT ((ACPI_DB_IO, 201*0d02842fSSascha Wildner "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)", 202*0d02842fSSascha Wildner ACPI_CAST_PTR (void, Address), ByteWidth, PortInfo->Name, 203*0d02842fSSascha Wildner PortInfo->Start, PortInfo->End)); 204*0d02842fSSascha Wildner 205*0d02842fSSascha Wildner return_ACPI_STATUS (AE_AML_ILLEGAL_ADDRESS); 206*0d02842fSSascha Wildner } 207*0d02842fSSascha Wildner } 208*0d02842fSSascha Wildner 209*0d02842fSSascha Wildner /* Finished if address range ends before the end of this port */ 210*0d02842fSSascha Wildner 211*0d02842fSSascha Wildner if (LastAddress <= PortInfo->End) 212*0d02842fSSascha Wildner { 213*0d02842fSSascha Wildner break; 214*0d02842fSSascha Wildner } 215*0d02842fSSascha Wildner } 216*0d02842fSSascha Wildner 217*0d02842fSSascha Wildner return_ACPI_STATUS (AE_OK); 218*0d02842fSSascha Wildner } 219*0d02842fSSascha Wildner 220*0d02842fSSascha Wildner 221*0d02842fSSascha Wildner /****************************************************************************** 222*0d02842fSSascha Wildner * 223*0d02842fSSascha Wildner * FUNCTION: AcpiHwReadPort 224*0d02842fSSascha Wildner * 225*0d02842fSSascha Wildner * PARAMETERS: Address Address of I/O port/register to read 226*0d02842fSSascha Wildner * Value Where value is placed 227*0d02842fSSascha Wildner * Width Number of bits 228*0d02842fSSascha Wildner * 229*0d02842fSSascha Wildner * RETURN: Status and value read from port 230*0d02842fSSascha Wildner * 231*0d02842fSSascha Wildner * DESCRIPTION: Read data from an I/O port or register. This is a front-end 232*0d02842fSSascha Wildner * to AcpiOsReadPort that performs validation on both the port 233*0d02842fSSascha Wildner * address and the length. 234*0d02842fSSascha Wildner * 235*0d02842fSSascha Wildner *****************************************************************************/ 236*0d02842fSSascha Wildner 237*0d02842fSSascha Wildner ACPI_STATUS 238*0d02842fSSascha Wildner AcpiHwReadPort ( 239*0d02842fSSascha Wildner ACPI_IO_ADDRESS Address, 240*0d02842fSSascha Wildner UINT32 *Value, 241*0d02842fSSascha Wildner UINT32 Width) 242*0d02842fSSascha Wildner { 243*0d02842fSSascha Wildner ACPI_STATUS Status; 244*0d02842fSSascha Wildner UINT32 OneByte; 245*0d02842fSSascha Wildner UINT32 i; 246*0d02842fSSascha Wildner 247*0d02842fSSascha Wildner 248*0d02842fSSascha Wildner /* Truncate address to 16 bits if requested */ 249*0d02842fSSascha Wildner 250*0d02842fSSascha Wildner if (AcpiGbl_TruncateIoAddresses) 251*0d02842fSSascha Wildner { 252*0d02842fSSascha Wildner Address &= ACPI_UINT16_MAX; 253*0d02842fSSascha Wildner } 254*0d02842fSSascha Wildner 255*0d02842fSSascha Wildner /* Validate the entire request and perform the I/O */ 256*0d02842fSSascha Wildner 257*0d02842fSSascha Wildner Status = AcpiHwValidateIoRequest (Address, Width); 258*0d02842fSSascha Wildner if (ACPI_SUCCESS (Status)) 259*0d02842fSSascha Wildner { 260*0d02842fSSascha Wildner Status = AcpiOsReadPort (Address, Value, Width); 261*0d02842fSSascha Wildner return (Status); 262*0d02842fSSascha Wildner } 263*0d02842fSSascha Wildner 264*0d02842fSSascha Wildner if (Status != AE_AML_ILLEGAL_ADDRESS) 265*0d02842fSSascha Wildner { 266*0d02842fSSascha Wildner return (Status); 267*0d02842fSSascha Wildner } 268*0d02842fSSascha Wildner 269*0d02842fSSascha Wildner /* 270*0d02842fSSascha Wildner * There has been a protection violation within the request. Fall 271*0d02842fSSascha Wildner * back to byte granularity port I/O and ignore the failing bytes. 272*0d02842fSSascha Wildner * This provides Windows compatibility. 273*0d02842fSSascha Wildner */ 274*0d02842fSSascha Wildner for (i = 0, *Value = 0; i < Width; i += 8) 275*0d02842fSSascha Wildner { 276*0d02842fSSascha Wildner /* Validate and read one byte */ 277*0d02842fSSascha Wildner 278*0d02842fSSascha Wildner if (AcpiHwValidateIoRequest (Address, 8) == AE_OK) 279*0d02842fSSascha Wildner { 280*0d02842fSSascha Wildner Status = AcpiOsReadPort (Address, &OneByte, 8); 281*0d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 282*0d02842fSSascha Wildner { 283*0d02842fSSascha Wildner return (Status); 284*0d02842fSSascha Wildner } 285*0d02842fSSascha Wildner 286*0d02842fSSascha Wildner *Value |= (OneByte << i); 287*0d02842fSSascha Wildner } 288*0d02842fSSascha Wildner 289*0d02842fSSascha Wildner Address++; 290*0d02842fSSascha Wildner } 291*0d02842fSSascha Wildner 292*0d02842fSSascha Wildner return (AE_OK); 293*0d02842fSSascha Wildner } 294*0d02842fSSascha Wildner 295*0d02842fSSascha Wildner 296*0d02842fSSascha Wildner /****************************************************************************** 297*0d02842fSSascha Wildner * 298*0d02842fSSascha Wildner * FUNCTION: AcpiHwWritePort 299*0d02842fSSascha Wildner * 300*0d02842fSSascha Wildner * PARAMETERS: Address Address of I/O port/register to write 301*0d02842fSSascha Wildner * Value Value to write 302*0d02842fSSascha Wildner * Width Number of bits 303*0d02842fSSascha Wildner * 304*0d02842fSSascha Wildner * RETURN: Status 305*0d02842fSSascha Wildner * 306*0d02842fSSascha Wildner * DESCRIPTION: Write data to an I/O port or register. This is a front-end 307*0d02842fSSascha Wildner * to AcpiOsWritePort that performs validation on both the port 308*0d02842fSSascha Wildner * address and the length. 309*0d02842fSSascha Wildner * 310*0d02842fSSascha Wildner *****************************************************************************/ 311*0d02842fSSascha Wildner 312*0d02842fSSascha Wildner ACPI_STATUS 313*0d02842fSSascha Wildner AcpiHwWritePort ( 314*0d02842fSSascha Wildner ACPI_IO_ADDRESS Address, 315*0d02842fSSascha Wildner UINT32 Value, 316*0d02842fSSascha Wildner UINT32 Width) 317*0d02842fSSascha Wildner { 318*0d02842fSSascha Wildner ACPI_STATUS Status; 319*0d02842fSSascha Wildner UINT32 i; 320*0d02842fSSascha Wildner 321*0d02842fSSascha Wildner 322*0d02842fSSascha Wildner /* Truncate address to 16 bits if requested */ 323*0d02842fSSascha Wildner 324*0d02842fSSascha Wildner if (AcpiGbl_TruncateIoAddresses) 325*0d02842fSSascha Wildner { 326*0d02842fSSascha Wildner Address &= ACPI_UINT16_MAX; 327*0d02842fSSascha Wildner } 328*0d02842fSSascha Wildner 329*0d02842fSSascha Wildner /* Validate the entire request and perform the I/O */ 330*0d02842fSSascha Wildner 331*0d02842fSSascha Wildner Status = AcpiHwValidateIoRequest (Address, Width); 332*0d02842fSSascha Wildner if (ACPI_SUCCESS (Status)) 333*0d02842fSSascha Wildner { 334*0d02842fSSascha Wildner Status = AcpiOsWritePort (Address, Value, Width); 335*0d02842fSSascha Wildner return (Status); 336*0d02842fSSascha Wildner } 337*0d02842fSSascha Wildner 338*0d02842fSSascha Wildner if (Status != AE_AML_ILLEGAL_ADDRESS) 339*0d02842fSSascha Wildner { 340*0d02842fSSascha Wildner return (Status); 341*0d02842fSSascha Wildner } 342*0d02842fSSascha Wildner 343*0d02842fSSascha Wildner /* 344*0d02842fSSascha Wildner * There has been a protection violation within the request. Fall 345*0d02842fSSascha Wildner * back to byte granularity port I/O and ignore the failing bytes. 346*0d02842fSSascha Wildner * This provides Windows compatibility. 347*0d02842fSSascha Wildner */ 348*0d02842fSSascha Wildner for (i = 0; i < Width; i += 8) 349*0d02842fSSascha Wildner { 350*0d02842fSSascha Wildner /* Validate and write one byte */ 351*0d02842fSSascha Wildner 352*0d02842fSSascha Wildner if (AcpiHwValidateIoRequest (Address, 8) == AE_OK) 353*0d02842fSSascha Wildner { 354*0d02842fSSascha Wildner Status = AcpiOsWritePort (Address, (Value >> i) & 0xFF, 8); 355*0d02842fSSascha Wildner if (ACPI_FAILURE (Status)) 356*0d02842fSSascha Wildner { 357*0d02842fSSascha Wildner return (Status); 358*0d02842fSSascha Wildner } 359*0d02842fSSascha Wildner } 360*0d02842fSSascha Wildner 361*0d02842fSSascha Wildner Address++; 362*0d02842fSSascha Wildner } 363*0d02842fSSascha Wildner 364*0d02842fSSascha Wildner return (AE_OK); 365*0d02842fSSascha Wildner } 366