xref: /dflybsd-src/sys/contrib/dev/acpica/source/components/hardware/hwvalid.c (revision fe7b5cb4c90e398c6bb35082299e03f913b608d1)
10d02842fSSascha Wildner /******************************************************************************
20d02842fSSascha Wildner  *
30d02842fSSascha Wildner  * Module Name: hwvalid - I/O request validation
40d02842fSSascha Wildner  *
50d02842fSSascha Wildner  *****************************************************************************/
60d02842fSSascha Wildner 
70d02842fSSascha Wildner /*
8*fe7b5cb4SSascha Wildner  * Copyright (C) 2000 - 2015, Intel Corp.
90d02842fSSascha Wildner  * All rights reserved.
100d02842fSSascha Wildner  *
110d02842fSSascha Wildner  * Redistribution and use in source and binary forms, with or without
120d02842fSSascha Wildner  * modification, are permitted provided that the following conditions
130d02842fSSascha Wildner  * are met:
140d02842fSSascha Wildner  * 1. Redistributions of source code must retain the above copyright
150d02842fSSascha Wildner  *    notice, this list of conditions, and the following disclaimer,
160d02842fSSascha Wildner  *    without modification.
170d02842fSSascha Wildner  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
180d02842fSSascha Wildner  *    substantially similar to the "NO WARRANTY" disclaimer below
190d02842fSSascha Wildner  *    ("Disclaimer") and any redistribution must be conditioned upon
200d02842fSSascha Wildner  *    including a substantially similar Disclaimer requirement for further
210d02842fSSascha Wildner  *    binary redistribution.
220d02842fSSascha Wildner  * 3. Neither the names of the above-listed copyright holders nor the names
230d02842fSSascha Wildner  *    of any contributors may be used to endorse or promote products derived
240d02842fSSascha Wildner  *    from this software without specific prior written permission.
250d02842fSSascha Wildner  *
260d02842fSSascha Wildner  * Alternatively, this software may be distributed under the terms of the
270d02842fSSascha Wildner  * GNU General Public License ("GPL") version 2 as published by the Free
280d02842fSSascha Wildner  * Software Foundation.
290d02842fSSascha Wildner  *
300d02842fSSascha Wildner  * NO WARRANTY
310d02842fSSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
320d02842fSSascha Wildner  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
330d02842fSSascha Wildner  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
340d02842fSSascha Wildner  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
350d02842fSSascha Wildner  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
360d02842fSSascha Wildner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
370d02842fSSascha Wildner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
380d02842fSSascha Wildner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
390d02842fSSascha Wildner  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
400d02842fSSascha Wildner  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
410d02842fSSascha Wildner  * POSSIBILITY OF SUCH DAMAGES.
420d02842fSSascha Wildner  */
430d02842fSSascha Wildner 
440d02842fSSascha Wildner #include "acpi.h"
450d02842fSSascha Wildner #include "accommon.h"
460d02842fSSascha Wildner 
470d02842fSSascha Wildner #define _COMPONENT          ACPI_HARDWARE
480d02842fSSascha Wildner         ACPI_MODULE_NAME    ("hwvalid")
490d02842fSSascha Wildner 
500d02842fSSascha Wildner /* Local prototypes */
510d02842fSSascha Wildner 
520d02842fSSascha Wildner static ACPI_STATUS
530d02842fSSascha Wildner AcpiHwValidateIoRequest (
540d02842fSSascha Wildner     ACPI_IO_ADDRESS         Address,
550d02842fSSascha Wildner     UINT32                  BitWidth);
560d02842fSSascha Wildner 
570d02842fSSascha Wildner 
580d02842fSSascha Wildner /*
590d02842fSSascha Wildner  * Protected I/O ports. Some ports are always illegal, and some are
600d02842fSSascha Wildner  * conditionally illegal. This table must remain ordered by port address.
610d02842fSSascha Wildner  *
620d02842fSSascha Wildner  * The table is used to implement the Microsoft port access rules that
630d02842fSSascha Wildner  * first appeared in Windows XP. Some ports are always illegal, and some
640d02842fSSascha Wildner  * ports are only illegal if the BIOS calls _OSI with a WinXP string or
650d02842fSSascha Wildner  * later (meaning that the BIOS itelf is post-XP.)
660d02842fSSascha Wildner  *
670d02842fSSascha Wildner  * This provides ACPICA with the desired port protections and
680d02842fSSascha Wildner  * Microsoft compatibility.
690d02842fSSascha Wildner  *
700d02842fSSascha Wildner  * Description of port entries:
710d02842fSSascha Wildner  *  DMA:   DMA controller
720d02842fSSascha Wildner  *  PIC0:  Programmable Interrupt Controller (8259A)
730d02842fSSascha Wildner  *  PIT1:  System Timer 1
740d02842fSSascha Wildner  *  PIT2:  System Timer 2 failsafe
750d02842fSSascha Wildner  *  RTC:   Real-time clock
760d02842fSSascha Wildner  *  CMOS:  Extended CMOS
770d02842fSSascha Wildner  *  DMA1:  DMA 1 page registers
780d02842fSSascha Wildner  *  DMA1L: DMA 1 Ch 0 low page
790d02842fSSascha Wildner  *  DMA2:  DMA 2 page registers
800d02842fSSascha Wildner  *  DMA2L: DMA 2 low page refresh
810d02842fSSascha Wildner  *  ARBC:  Arbitration control
820d02842fSSascha Wildner  *  SETUP: Reserved system board setup
830d02842fSSascha Wildner  *  POS:   POS channel select
840d02842fSSascha Wildner  *  PIC1:  Cascaded PIC
850d02842fSSascha Wildner  *  IDMA:  ISA DMA
860d02842fSSascha Wildner  *  ELCR:  PIC edge/level registers
870d02842fSSascha Wildner  *  PCI:   PCI configuration space
880d02842fSSascha Wildner  */
890d02842fSSascha Wildner static const ACPI_PORT_INFO     AcpiProtectedPorts[] =
900d02842fSSascha Wildner {
910d02842fSSascha Wildner     {"DMA",     0x0000, 0x000F, ACPI_OSI_WIN_XP},
920d02842fSSascha Wildner     {"PIC0",    0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL},
930d02842fSSascha Wildner     {"PIT1",    0x0040, 0x0043, ACPI_OSI_WIN_XP},
940d02842fSSascha Wildner     {"PIT2",    0x0048, 0x004B, ACPI_OSI_WIN_XP},
950d02842fSSascha Wildner     {"RTC",     0x0070, 0x0071, ACPI_OSI_WIN_XP},
960d02842fSSascha Wildner     {"CMOS",    0x0074, 0x0076, ACPI_OSI_WIN_XP},
970d02842fSSascha Wildner     {"DMA1",    0x0081, 0x0083, ACPI_OSI_WIN_XP},
980d02842fSSascha Wildner     {"DMA1L",   0x0087, 0x0087, ACPI_OSI_WIN_XP},
990d02842fSSascha Wildner     {"DMA2",    0x0089, 0x008B, ACPI_OSI_WIN_XP},
1000d02842fSSascha Wildner     {"DMA2L",   0x008F, 0x008F, ACPI_OSI_WIN_XP},
1010d02842fSSascha Wildner     {"ARBC",    0x0090, 0x0091, ACPI_OSI_WIN_XP},
1020d02842fSSascha Wildner     {"SETUP",   0x0093, 0x0094, ACPI_OSI_WIN_XP},
1030d02842fSSascha Wildner     {"POS",     0x0096, 0x0097, ACPI_OSI_WIN_XP},
1040d02842fSSascha Wildner     {"PIC1",    0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL},
1050d02842fSSascha Wildner     {"IDMA",    0x00C0, 0x00DF, ACPI_OSI_WIN_XP},
1060d02842fSSascha Wildner     {"ELCR",    0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL},
1070d02842fSSascha Wildner     {"PCI",     0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP}
1080d02842fSSascha Wildner };
1090d02842fSSascha Wildner 
1100d02842fSSascha Wildner #define ACPI_PORT_INFO_ENTRIES  ACPI_ARRAY_LENGTH (AcpiProtectedPorts)
1110d02842fSSascha Wildner 
1120d02842fSSascha Wildner 
1130d02842fSSascha Wildner /******************************************************************************
1140d02842fSSascha Wildner  *
1150d02842fSSascha Wildner  * FUNCTION:    AcpiHwValidateIoRequest
1160d02842fSSascha Wildner  *
1170d02842fSSascha Wildner  * PARAMETERS:  Address             Address of I/O port/register
1180d02842fSSascha Wildner  *              BitWidth            Number of bits (8,16,32)
1190d02842fSSascha Wildner  *
1200d02842fSSascha Wildner  * RETURN:      Status
1210d02842fSSascha Wildner  *
1220d02842fSSascha Wildner  * DESCRIPTION: Validates an I/O request (address/length). Certain ports are
1230d02842fSSascha Wildner  *              always illegal and some ports are only illegal depending on
1240d02842fSSascha Wildner  *              the requests the BIOS AML code makes to the predefined
1250d02842fSSascha Wildner  *              _OSI method.
1260d02842fSSascha Wildner  *
1270d02842fSSascha Wildner  ******************************************************************************/
1280d02842fSSascha Wildner 
1290d02842fSSascha Wildner static ACPI_STATUS
1300d02842fSSascha Wildner AcpiHwValidateIoRequest (
1310d02842fSSascha Wildner     ACPI_IO_ADDRESS         Address,
1320d02842fSSascha Wildner     UINT32                  BitWidth)
1330d02842fSSascha Wildner {
1340d02842fSSascha Wildner     UINT32                  i;
1350d02842fSSascha Wildner     UINT32                  ByteWidth;
1360d02842fSSascha Wildner     ACPI_IO_ADDRESS         LastAddress;
1370d02842fSSascha Wildner     const ACPI_PORT_INFO    *PortInfo;
1380d02842fSSascha Wildner 
1390d02842fSSascha Wildner 
1400d02842fSSascha Wildner     ACPI_FUNCTION_TRACE (HwValidateIoRequest);
1410d02842fSSascha Wildner 
1420d02842fSSascha Wildner 
1430d02842fSSascha Wildner     /* Supported widths are 8/16/32 */
1440d02842fSSascha Wildner 
1450d02842fSSascha Wildner     if ((BitWidth != 8) &&
1460d02842fSSascha Wildner         (BitWidth != 16) &&
1470d02842fSSascha Wildner         (BitWidth != 32))
1480d02842fSSascha Wildner     {
1490d02842fSSascha Wildner         ACPI_ERROR ((AE_INFO,
1500d02842fSSascha Wildner             "Bad BitWidth parameter: %8.8X", BitWidth));
1510d02842fSSascha Wildner         return (AE_BAD_PARAMETER);
1520d02842fSSascha Wildner     }
1530d02842fSSascha Wildner 
1540d02842fSSascha Wildner     PortInfo = AcpiProtectedPorts;
1550d02842fSSascha Wildner     ByteWidth = ACPI_DIV_8 (BitWidth);
1560d02842fSSascha Wildner     LastAddress = Address + ByteWidth - 1;
1570d02842fSSascha Wildner 
1580d02842fSSascha Wildner     ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Address %p LastAddress %p Length %X",
1590d02842fSSascha Wildner         ACPI_CAST_PTR (void, Address), ACPI_CAST_PTR (void, LastAddress),
1600d02842fSSascha Wildner         ByteWidth));
1610d02842fSSascha Wildner 
1620d02842fSSascha Wildner     /* Maximum 16-bit address in I/O space */
1630d02842fSSascha Wildner 
1640d02842fSSascha Wildner     if (LastAddress > ACPI_UINT16_MAX)
1650d02842fSSascha Wildner     {
1660d02842fSSascha Wildner         ACPI_ERROR ((AE_INFO,
1670d02842fSSascha Wildner             "Illegal I/O port address/length above 64K: %p/0x%X",
1680d02842fSSascha Wildner             ACPI_CAST_PTR (void, Address), ByteWidth));
1690d02842fSSascha Wildner         return_ACPI_STATUS (AE_LIMIT);
1700d02842fSSascha Wildner     }
1710d02842fSSascha Wildner 
1720d02842fSSascha Wildner     /* Exit if requested address is not within the protected port table */
1730d02842fSSascha Wildner 
1740d02842fSSascha Wildner     if (Address > AcpiProtectedPorts[ACPI_PORT_INFO_ENTRIES - 1].End)
1750d02842fSSascha Wildner     {
1760d02842fSSascha Wildner         return_ACPI_STATUS (AE_OK);
1770d02842fSSascha Wildner     }
1780d02842fSSascha Wildner 
1790d02842fSSascha Wildner     /* Check request against the list of protected I/O ports */
1800d02842fSSascha Wildner 
1810d02842fSSascha Wildner     for (i = 0; i < ACPI_PORT_INFO_ENTRIES; i++, PortInfo++)
1820d02842fSSascha Wildner     {
1830d02842fSSascha Wildner         /*
1840d02842fSSascha Wildner          * Check if the requested address range will write to a reserved
1850d02842fSSascha Wildner          * port. Four cases to consider:
1860d02842fSSascha Wildner          *
1870d02842fSSascha Wildner          * 1) Address range is contained completely in the port address range
1880d02842fSSascha Wildner          * 2) Address range overlaps port range at the port range start
1890d02842fSSascha Wildner          * 3) Address range overlaps port range at the port range end
1900d02842fSSascha Wildner          * 4) Address range completely encompasses the port range
1910d02842fSSascha Wildner          */
1920d02842fSSascha Wildner         if ((Address <= PortInfo->End) && (LastAddress >= PortInfo->Start))
1930d02842fSSascha Wildner         {
1940d02842fSSascha Wildner             /* Port illegality may depend on the _OSI calls made by the BIOS */
1950d02842fSSascha Wildner 
1960d02842fSSascha Wildner             if (AcpiGbl_OsiData >= PortInfo->OsiDependency)
1970d02842fSSascha Wildner             {
1980d02842fSSascha Wildner                 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
1990d02842fSSascha Wildner                     "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
2000d02842fSSascha Wildner                     ACPI_CAST_PTR (void, Address), ByteWidth, PortInfo->Name,
2010d02842fSSascha Wildner                     PortInfo->Start, PortInfo->End));
2020d02842fSSascha Wildner 
2030d02842fSSascha Wildner                 return_ACPI_STATUS (AE_AML_ILLEGAL_ADDRESS);
2040d02842fSSascha Wildner             }
2050d02842fSSascha Wildner         }
2060d02842fSSascha Wildner 
2070d02842fSSascha Wildner         /* Finished if address range ends before the end of this port */
2080d02842fSSascha Wildner 
2090d02842fSSascha Wildner         if (LastAddress <= PortInfo->End)
2100d02842fSSascha Wildner         {
2110d02842fSSascha Wildner             break;
2120d02842fSSascha Wildner         }
2130d02842fSSascha Wildner     }
2140d02842fSSascha Wildner 
2150d02842fSSascha Wildner     return_ACPI_STATUS (AE_OK);
2160d02842fSSascha Wildner }
2170d02842fSSascha Wildner 
2180d02842fSSascha Wildner 
2190d02842fSSascha Wildner /******************************************************************************
2200d02842fSSascha Wildner  *
2210d02842fSSascha Wildner  * FUNCTION:    AcpiHwReadPort
2220d02842fSSascha Wildner  *
2230d02842fSSascha Wildner  * PARAMETERS:  Address             Address of I/O port/register to read
2240d02842fSSascha Wildner  *              Value               Where value is placed
2250d02842fSSascha Wildner  *              Width               Number of bits
2260d02842fSSascha Wildner  *
2270d02842fSSascha Wildner  * RETURN:      Status and value read from port
2280d02842fSSascha Wildner  *
2290d02842fSSascha Wildner  * DESCRIPTION: Read data from an I/O port or register. This is a front-end
2300d02842fSSascha Wildner  *              to AcpiOsReadPort that performs validation on both the port
2310d02842fSSascha Wildner  *              address and the length.
2320d02842fSSascha Wildner  *
2330d02842fSSascha Wildner  *****************************************************************************/
2340d02842fSSascha Wildner 
2350d02842fSSascha Wildner ACPI_STATUS
2360d02842fSSascha Wildner AcpiHwReadPort (
2370d02842fSSascha Wildner     ACPI_IO_ADDRESS         Address,
2380d02842fSSascha Wildner     UINT32                  *Value,
2390d02842fSSascha Wildner     UINT32                  Width)
2400d02842fSSascha Wildner {
2410d02842fSSascha Wildner     ACPI_STATUS             Status;
2420d02842fSSascha Wildner     UINT32                  OneByte;
2430d02842fSSascha Wildner     UINT32                  i;
2440d02842fSSascha Wildner 
2450d02842fSSascha Wildner 
2460d02842fSSascha Wildner     /* Truncate address to 16 bits if requested */
2470d02842fSSascha Wildner 
2480d02842fSSascha Wildner     if (AcpiGbl_TruncateIoAddresses)
2490d02842fSSascha Wildner     {
2500d02842fSSascha Wildner         Address &= ACPI_UINT16_MAX;
2510d02842fSSascha Wildner     }
2520d02842fSSascha Wildner 
2530d02842fSSascha Wildner     /* Validate the entire request and perform the I/O */
2540d02842fSSascha Wildner 
2550d02842fSSascha Wildner     Status = AcpiHwValidateIoRequest (Address, Width);
2560d02842fSSascha Wildner     if (ACPI_SUCCESS (Status))
2570d02842fSSascha Wildner     {
2580d02842fSSascha Wildner         Status = AcpiOsReadPort (Address, Value, Width);
2590d02842fSSascha Wildner         return (Status);
2600d02842fSSascha Wildner     }
2610d02842fSSascha Wildner 
2620d02842fSSascha Wildner     if (Status != AE_AML_ILLEGAL_ADDRESS)
2630d02842fSSascha Wildner     {
2640d02842fSSascha Wildner         return (Status);
2650d02842fSSascha Wildner     }
2660d02842fSSascha Wildner 
2670d02842fSSascha Wildner     /*
2680d02842fSSascha Wildner      * There has been a protection violation within the request. Fall
2690d02842fSSascha Wildner      * back to byte granularity port I/O and ignore the failing bytes.
2700d02842fSSascha Wildner      * This provides Windows compatibility.
2710d02842fSSascha Wildner      */
2720d02842fSSascha Wildner     for (i = 0, *Value = 0; i < Width; i += 8)
2730d02842fSSascha Wildner     {
2740d02842fSSascha Wildner         /* Validate and read one byte */
2750d02842fSSascha Wildner 
2760d02842fSSascha Wildner         if (AcpiHwValidateIoRequest (Address, 8) == AE_OK)
2770d02842fSSascha Wildner         {
2780d02842fSSascha Wildner             Status = AcpiOsReadPort (Address, &OneByte, 8);
2790d02842fSSascha Wildner             if (ACPI_FAILURE (Status))
2800d02842fSSascha Wildner             {
2810d02842fSSascha Wildner                 return (Status);
2820d02842fSSascha Wildner             }
2830d02842fSSascha Wildner 
2840d02842fSSascha Wildner             *Value |= (OneByte << i);
2850d02842fSSascha Wildner         }
2860d02842fSSascha Wildner 
2870d02842fSSascha Wildner         Address++;
2880d02842fSSascha Wildner     }
2890d02842fSSascha Wildner 
2900d02842fSSascha Wildner     return (AE_OK);
2910d02842fSSascha Wildner }
2920d02842fSSascha Wildner 
2930d02842fSSascha Wildner 
2940d02842fSSascha Wildner /******************************************************************************
2950d02842fSSascha Wildner  *
2960d02842fSSascha Wildner  * FUNCTION:    AcpiHwWritePort
2970d02842fSSascha Wildner  *
2980d02842fSSascha Wildner  * PARAMETERS:  Address             Address of I/O port/register to write
2990d02842fSSascha Wildner  *              Value               Value to write
3000d02842fSSascha Wildner  *              Width               Number of bits
3010d02842fSSascha Wildner  *
3020d02842fSSascha Wildner  * RETURN:      Status
3030d02842fSSascha Wildner  *
3040d02842fSSascha Wildner  * DESCRIPTION: Write data to an I/O port or register. This is a front-end
3050d02842fSSascha Wildner  *              to AcpiOsWritePort that performs validation on both the port
3060d02842fSSascha Wildner  *              address and the length.
3070d02842fSSascha Wildner  *
3080d02842fSSascha Wildner  *****************************************************************************/
3090d02842fSSascha Wildner 
3100d02842fSSascha Wildner ACPI_STATUS
3110d02842fSSascha Wildner AcpiHwWritePort (
3120d02842fSSascha Wildner     ACPI_IO_ADDRESS         Address,
3130d02842fSSascha Wildner     UINT32                  Value,
3140d02842fSSascha Wildner     UINT32                  Width)
3150d02842fSSascha Wildner {
3160d02842fSSascha Wildner     ACPI_STATUS             Status;
3170d02842fSSascha Wildner     UINT32                  i;
3180d02842fSSascha Wildner 
3190d02842fSSascha Wildner 
3200d02842fSSascha Wildner     /* Truncate address to 16 bits if requested */
3210d02842fSSascha Wildner 
3220d02842fSSascha Wildner     if (AcpiGbl_TruncateIoAddresses)
3230d02842fSSascha Wildner     {
3240d02842fSSascha Wildner         Address &= ACPI_UINT16_MAX;
3250d02842fSSascha Wildner     }
3260d02842fSSascha Wildner 
3270d02842fSSascha Wildner     /* Validate the entire request and perform the I/O */
3280d02842fSSascha Wildner 
3290d02842fSSascha Wildner     Status = AcpiHwValidateIoRequest (Address, Width);
3300d02842fSSascha Wildner     if (ACPI_SUCCESS (Status))
3310d02842fSSascha Wildner     {
3320d02842fSSascha Wildner         Status = AcpiOsWritePort (Address, Value, Width);
3330d02842fSSascha Wildner         return (Status);
3340d02842fSSascha Wildner     }
3350d02842fSSascha Wildner 
3360d02842fSSascha Wildner     if (Status != AE_AML_ILLEGAL_ADDRESS)
3370d02842fSSascha Wildner     {
3380d02842fSSascha Wildner         return (Status);
3390d02842fSSascha Wildner     }
3400d02842fSSascha Wildner 
3410d02842fSSascha Wildner     /*
3420d02842fSSascha Wildner      * There has been a protection violation within the request. Fall
3430d02842fSSascha Wildner      * back to byte granularity port I/O and ignore the failing bytes.
3440d02842fSSascha Wildner      * This provides Windows compatibility.
3450d02842fSSascha Wildner      */
3460d02842fSSascha Wildner     for (i = 0; i < Width; i += 8)
3470d02842fSSascha Wildner     {
3480d02842fSSascha Wildner         /* Validate and write one byte */
3490d02842fSSascha Wildner 
3500d02842fSSascha Wildner         if (AcpiHwValidateIoRequest (Address, 8) == AE_OK)
3510d02842fSSascha Wildner         {
3520d02842fSSascha Wildner             Status = AcpiOsWritePort (Address, (Value >> i) & 0xFF, 8);
3530d02842fSSascha Wildner             if (ACPI_FAILURE (Status))
3540d02842fSSascha Wildner             {
3550d02842fSSascha Wildner                 return (Status);
3560d02842fSSascha Wildner             }
3570d02842fSSascha Wildner         }
3580d02842fSSascha Wildner 
3590d02842fSSascha Wildner         Address++;
3600d02842fSSascha Wildner     }
3610d02842fSSascha Wildner 
3620d02842fSSascha Wildner     return (AE_OK);
3630d02842fSSascha Wildner }
364