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