Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / drivers / storage / ide / uniata / id_ata.cpp
diff --git a/reactos/drivers/storage/ide/uniata/id_ata.cpp b/reactos/drivers/storage/ide/uniata/id_ata.cpp
deleted file mode 100644 (file)
index f823e4f..0000000
+++ /dev/null
@@ -1,11527 +0,0 @@
-/*++
-
-Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter)
-
-Module Name:
-    id_ata.cpp
-
-Abstract:
-    This is the miniport driver for ATA/ATAPI IDE/SATA/AHCI controllers
-    with Busmaster DMA and Serial ATA support
-
-Author:
-    Alexander A. Telyatnikov (Alter)
-
-Environment:
-    kernel mode only
-
-Notes:
-
-    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Revision History:
-
-    The skeleton was taken from standard ATAPI.SYS from NT4 DDK by
-         Mike Glass (MGlass)
-         Chuck Park (ChuckP)
-
-    Some parts of code were taken from FreeBSD 4.3-6.1 ATA driver by
-         Søren Schmidt, Copyright (c) 1998-2007
-
-    All parts of code are significantly changed/updated by
-         Alter, Copyright (c) 2002-2014:
-
-    1. Internal command queueing/reordering
-    2. Drive identification
-    3. Support for 2 _independent_ channels in a single PCI device
-    4. Smart host<->drive transfer rate slowdown (for bad cable)
-    5. W2k support (binary compatibility)
-    6. HDD hot swap under NT4
-    7. XP support (binary compatibility)
-    8. Serial ATA (SATA/SATA2/SATA3) support
-    9. NT 3.51 support (binary compatibility)
-    10. AHCI support
-
-    etc. (See todo.txt)
-
-Licence:
-    GPLv2
-
---*/
-
-#include "stdafx.h"
-
-#ifndef UNIATA_CORE
-
-static const CHAR ver_string[] = "\n\nATAPI IDE MiniPort Driver (UniATA) v 0." UNIATA_VER_STR "\n";
-
-static const CHAR uniata_comm_name[] = UNIATA_COMM_PORT_VENDOR_STR "    \n";
-
-UNICODE_STRING SavedRegPath;
-WCHAR SavedRegPathBuffer[256];
-
-#endif //UNIATA_CORE
-
-//UCHAR AtaCommands48[256];
-//UCHAR AtaCommandFlags[256];
-
-ULONG  SkipRaids = 1;
-ULONG  ForceSimplex = 0;
-
-LONGLONG g_Perf = 0;
-ULONG    g_PerfDt = 0;
-
-#ifdef _DEBUG
-ULONG  g_LogToDisplay = 0;
-#endif //_DEBUG
-
-ULONG  g_WaitBusyInISR = 1;
-
-ULONG  g_opt_WaitBusyResetCount = 10000; // 20000
-ULONG  g_opt_WaitBusyCount = 200; // 20000
-ULONG  g_opt_WaitBusyDelay = 10;  // 150
-ULONG  g_opt_WaitDrqDelay  = 10; // 100
-ULONG  g_opt_WaitBusyLongCount = 2000; // 2000
-ULONG  g_opt_WaitBusyLongDelay = 250;  // 250
-ULONG  g_opt_MaxIsrWait = 40;
-
-ULONG  g_opt_DriveSelectNanoDelay = 0; // 400; // ns
-
-BOOLEAN g_opt_AtapiSendDisableIntr = 0; // 0
-BOOLEAN g_opt_AtapiDmaRawRead = 1; // 0
-BOOLEAN g_opt_AtapiNoDma = FALSE;
-BOOLEAN g_opt_BochsDmaReadWorkaround = FALSE;
-BOOLEAN hasPCI = FALSE;
-
-ULONG g_opt_VirtualMachine = 0; // Auto
-
-BOOLEAN InDriverEntry = TRUE;
-BOOLEAN g_Dump = FALSE;
-
-BOOLEAN g_opt_Verbose = 0;
-
-BOOLEAN WinVer_WDM_Model = FALSE;
-ULONG CPU_num = 1;
-
-//UCHAR EnableDma = FALSE;
-//UCHAR EnableReorder = FALSE;
-
-UCHAR g_foo = 0;
-
-BOOLEAN
-NTAPI
-AtapiResetController__(
-    IN PVOID HwDeviceExtension,
-    IN ULONG PathId,
-    IN UCHAR CompleteType
-    );
-
-VOID
-NTAPI
-AtapiHwInitialize__(
-    IN PHW_DEVICE_EXTENSION deviceExtension,
-    IN ULONG lChannel
-    );
-
-VOID
-NTAPI
-UniataUserDeviceReset(
-    PHW_DEVICE_EXTENSION deviceExtension,
-    PHW_LU_EXTENSION LunExt,
-    ULONG lChannel
-    );
-
-#define RESET_COMPLETE_CURRENT  0x00
-#define RESET_COMPLETE_ALL      0x01
-#define RESET_COMPLETE_NONE     0x02
-
-#ifndef UNIATA_CORE
-
-VOID
-NTAPI
-AtapiCallBack_X(
-    IN PVOID HwDeviceExtension
-    );
-
-#ifdef UNIATA_USE_XXableInterrupts
-  #define RETTYPE_XXableInterrupts   BOOLEAN
-  #define RETVAL_XXableInterrupts    TRUE
-#else
-  #define RETTYPE_XXableInterrupts   VOID
-  #define RETVAL_XXableInterrupts
-#endif
-
-RETTYPE_XXableInterrupts
-NTAPI
-AtapiInterruptDpc(
-    IN PVOID HwDeviceExtension
-    );
-
-RETTYPE_XXableInterrupts
-NTAPI
-AtapiEnableInterrupts__(
-    IN PVOID HwDeviceExtension
-    );
-
-VOID
-NTAPI
-AtapiQueueTimerDpc(
-    IN PVOID HwDeviceExtension,
-    IN ULONG lChannel,
-    IN PHW_TIMER HwScsiTimer,
-    IN ULONG MiniportTimerValue
-    );
-
-SCSI_ADAPTER_CONTROL_STATUS
-NTAPI
-AtapiAdapterControl(
-    IN PVOID HwDeviceExtension,
-    IN SCSI_ADAPTER_CONTROL_TYPE ControlType,
-    IN PVOID Parameters
-    );
-
-#endif //UNIATA_CORE
-
-#ifndef UNIATA_CORE
-
-BOOLEAN
-NTAPI
-AtapiRegGetStringParameterValue(
-    IN PWSTR RegistryPath,
-    IN PWSTR Name,
-    IN PWCHAR Str,
-    IN ULONG MaxLen
-    )
-{
-#define ITEMS_TO_QUERY 2 // always 1 greater than what is searched 
-    NTSTATUS          status;
-    RTL_QUERY_REGISTRY_TABLE parameters[ITEMS_TO_QUERY];
-    UNICODE_STRING ustr;
-
-    ustr.Buffer = Str;
-    ustr.Length =
-    ustr.MaximumLength = (USHORT)MaxLen;
-    RtlZeroMemory(parameters, (sizeof(RTL_QUERY_REGISTRY_TABLE)*ITEMS_TO_QUERY));
-
-    parameters[0].Flags         = RTL_QUERY_REGISTRY_DIRECT;
-    parameters[0].Name          = Name;
-    parameters[0].EntryContext  = &ustr;
-    parameters[0].DefaultType   = REG_SZ;
-    parameters[0].DefaultData   = Str;
-    parameters[0].DefaultLength = MaxLen;
-
-    status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
-                                    RegistryPath, parameters, NULL, NULL);
-
-    if(!NT_SUCCESS(status))
-        return FALSE;
-
-    return TRUE;
-
-#undef ITEMS_TO_QUERY
-} // end AtapiRegGetStringParameterValue()
-
-
-#endif //UNIATA_CORE
-
-VOID
-DDKFASTAPI
-UniataNanoSleep(
-    ULONG nano
-    )
-{
-    LONGLONG t;
-    LARGE_INTEGER t0;
-
-#ifdef NAVO_TEST
-    return;
-#endif //NAVO_TEST
-
-    if(!nano || !g_Perf || !g_PerfDt)
-        return;
-    t = (g_Perf * nano) / g_PerfDt / 1000;
-    if(!t) {
-        t = 1;
-    }
-    do {
-        KeQuerySystemTime(&t0);
-        t--;
-    } while(t);
-} // end UniataNanoSleep()
-
-#define AtapiWritePortN_template(_type, _Type, sz) \
-VOID \
-DDKFASTAPI \
-AtapiWritePort##sz( \
-    IN PHW_CHANNEL chan, \
-    IN ULONGIO_PTR _port, \
-    IN _type  data \
-    ) \
-{ \
-    PIORES res; \
-    if(_port >= IDX_MAX_REG) { \
-        res = (PIORES)(_port);  \
-    } else \
-    if(chan) { \
-        res = &chan->RegTranslation[_port];  \
-    } else {                                     \
-        KdPrint(("invalid io write request @ ch %x, res* %x\n", chan, _port)); \
-        return; \
-    } \
-    if(res->Proc) {             \
-        KdPrint(("PROC io write request @ ch %x, res* %x\n", chan, _port)); \
-        ASSERT(FALSE); /* We should never get here */ \
-    } \
-    if(!res->MemIo) {             \
-        ScsiPortWritePort##_Type((_type*)(res->Addr), data); \
-    } else {                                      \
-        /*KdPrint(("r_mem @ (%x) %x\n", _port, port));*/ \
-        ScsiPortWriteRegister##_Type((_type*)(res->Addr), data); \
-    }                                                        \
-    return;                                                  \
-}
-
-AtapiWritePortN_template(ULONG,  Ulong,  4);
-AtapiWritePortN_template(USHORT, Ushort, 2);
-AtapiWritePortN_template(UCHAR,  Uchar,  1);
-
-#define AtapiWritePortExN_template(_type, _Type, sz) \
-VOID \
-DDKFASTAPI \
-AtapiWritePortEx##sz( \
-    IN PHW_CHANNEL chan, \
-    IN ULONGIO_PTR _port, \
-    IN ULONG offs, \
-    IN _type  data \
-    ) \
-{ \
-    PIORES res; \
-    if(_port >= IDX_MAX_REG) { \
-        res = (PIORES)(_port);  \
-    } else \
-    if(chan) { \
-        res = &chan->RegTranslation[_port];  \
-    } else {                                     \
-        KdPrint(("invalid io write request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \
-        return; \
-    } \
-    if(res->Proc) {             \
-        KdPrint(("PROC io write request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \
-        ASSERT(FALSE); /* We should never get here */ \
-    } \
-    if(!res->MemIo) {             \
-        ScsiPortWritePort##_Type((_type*)(res->Addr+offs), data); \
-    } else {                                      \
-        /*KdPrint(("r_mem @ (%x) %x\n", _port, port));*/ \
-        ScsiPortWriteRegister##_Type((_type*)(res->Addr+offs), data); \
-    }                                                        \
-    return;                                                  \
-}
-
-AtapiWritePortExN_template(ULONG,  Ulong,  4);
-//AtapiWritePortExN_template(USHORT, Ushort, 2);
-AtapiWritePortExN_template(UCHAR,  Uchar,  1);
-
-#define AtapiReadPortN_template(_type, _Type, sz) \
-_type \
-DDKFASTAPI \
-AtapiReadPort##sz( \
-    IN PHW_CHANNEL chan, \
-    IN ULONGIO_PTR _port \
-    ) \
-{ \
-    PIORES res; \
-    if(_port >= IDX_MAX_REG) { \
-        res = (PIORES)(_port);  \
-    } else \
-    if(chan) { \
-        res = &chan->RegTranslation[_port];  \
-    } else {                                     \
-        KdPrint(("invalid io read request @ ch %x, res* %x\n", chan, _port)); \
-        return (_type)(-1); \
-    } \
-    if(res->Proc) {             \
-        KdPrint(("PROC io read request @ ch %x, res* %x\n", chan, _port)); \
-        ASSERT(FALSE); /* We should never get here */ \
-    } \
-    if(!res->MemIo) {             \
-        /*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \
-        return ScsiPortReadPort##_Type((_type*)(res->Addr)); \
-    } else {                                      \
-        /*KdPrint(("r_mem @ (%x) %x\n", _port, res->Addr));*/ \
-        return ScsiPortReadRegister##_Type((_type*)(res->Addr)); \
-    }                                                        \
-}
-
-AtapiReadPortN_template(ULONG,  Ulong,  4);
-AtapiReadPortN_template(USHORT, Ushort, 2);
-AtapiReadPortN_template(UCHAR,  Uchar,  1);
-
-#define AtapiReadPortExN_template(_type, _Type, sz) \
-_type \
-DDKFASTAPI \
-AtapiReadPortEx##sz( \
-    IN PHW_CHANNEL chan, \
-    IN ULONGIO_PTR _port, \
-    IN ULONG offs \
-    ) \
-{ \
-    PIORES res; \
-    if(_port >= IDX_MAX_REG) { \
-        res = (PIORES)(_port);  \
-    } else \
-    if(chan) { \
-        res = &chan->RegTranslation[_port];  \
-    } else {                                     \
-        KdPrint(("invalid io read request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \
-        return (_type)(-1); \
-    } \
-    if(res->Proc) {             \
-        KdPrint(("PROC io read request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \
-        ASSERT(FALSE); /* We should never get here */ \
-    } \
-    if(!res->MemIo) {             \
-        return ScsiPortReadPort##_Type((_type*)(res->Addr+offs)); \
-    } else {                                      \
-        /*KdPrint(("r_mem @ (%x) %x\n", _port, port));*/ \
-        return ScsiPortReadRegister##_Type((_type*)(res->Addr+offs)); \
-    }                                                        \
-}
-
-AtapiReadPortExN_template(ULONG,  Ulong,  4);
-//AtapiReadPortExN_template(USHORT, Ushort, 2);
-AtapiReadPortExN_template(UCHAR,  Uchar,  1);
-
-#define AtapiReadPortBufferN_template(_type, _Type, sz) \
-VOID \
-DDKFASTAPI \
-AtapiReadBuffer##sz( \
-    IN PHW_CHANNEL chan, \
-    IN ULONGIO_PTR _port, \
-    IN PVOID Buffer, \
-    IN ULONG Count,   \
-    IN ULONG Timing   \
-    ) \
-{ \
-    PIORES res; \
-                 \
-    if(Timing) { \
-        while(Count) { \
-            (*((_type*)Buffer)) = AtapiReadPort##sz(chan, _port); \
-            Count--; \
-            Buffer = ((_type*)Buffer)+1; \
-            UniataNanoSleep(Timing); \
-        } \
-        return; \
-    } \
-           \
-    if(_port >= IDX_MAX_REG) { \
-        res = (PIORES)(_port);  \
-    } else \
-    if(chan) { \
-        res = &chan->RegTranslation[_port];  \
-    } else {                                     \
-        KdPrint(("invalid io read request @ ch %x, res* %x\n", chan, _port)); \
-        return; \
-    } \
-    if(!res->MemIo) {             \
-        /*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \
-        ScsiPortReadPortBuffer##_Type((_type*)(res->Addr), (_type*)Buffer, Count); \
-        return; \
-    }                                                        \
-    while(Count) { \
-        (*((_type*)Buffer)) = ScsiPortReadRegister##_Type((_type*)(res->Addr)); \
-        Count--; \
-        Buffer = ((_type*)Buffer)+1; \
-    } \
-    return;                                                  \
-}
-
-#define AtapiWritePortBufferN_template(_type, _Type, sz) \
-VOID \
-DDKFASTAPI \
-AtapiWriteBuffer##sz( \
-    IN PHW_CHANNEL chan, \
-    IN ULONGIO_PTR _port, \
-    IN PVOID Buffer, \
-    IN ULONG Count,   \
-    IN ULONG Timing   \
-    ) \
-{ \
-    PIORES res; \
-                 \
-    if(Timing) { \
-        while(Count) { \
-            AtapiWritePort##sz(chan, _port, *((_type*)Buffer)); \
-            Buffer = ((_type*)Buffer)+1; \
-            Count--; \
-            UniataNanoSleep(Timing); \
-        } \
-        return;                                                  \
-    } \
-           \
-    if(_port >= IDX_MAX_REG) { \
-        res = (PIORES)(_port);  \
-    } else \
-    if(chan) { \
-        res = &chan->RegTranslation[_port];  \
-    } else {                                     \
-        KdPrint(("invalid io write request @ ch %x, res* %x\n", chan, _port)); \
-        return; \
-    } \
-    if(!res->MemIo) {             \
-        /*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \
-        ScsiPortWritePortBuffer##_Type((_type*)(res->Addr), (_type*)Buffer, Count); \
-        return; \
-    }                                                        \
-    while(Count) { \
-        ScsiPortWriteRegister##_Type((_type*)(res->Addr), *((_type*)Buffer)); \
-        Count--; \
-        Buffer = ((_type*)Buffer)+1; \
-    } \
-    return;                                                  \
-}
-
-AtapiWritePortBufferN_template(ULONG,  Ulong,  4);
-AtapiWritePortBufferN_template(USHORT, Ushort, 2);
-
-AtapiReadPortBufferN_template(ULONG,  Ulong,  4);
-AtapiReadPortBufferN_template(USHORT, Ushort, 2);
-
-
-UCHAR
-DDKFASTAPI
-AtapiSuckPort2(
-    IN PHW_CHANNEL chan
-    )
-{
-    UCHAR statusByte;
-    ULONG i;
-
-    // Assume, proper drive is already seleted
-    WaitOnBusyLong(chan);
-    for (i = 0; i < 0x10000; i++) {
-
-        GetStatus(chan, statusByte);
-        if (statusByte & IDE_STATUS_DRQ) {
-            // Suck out any remaining bytes and throw away.
-            AtapiReadPort2(chan, IDX_IO1_i_Data);
-            UniataNanoSleep(PIO0_TIMING);
-        } else {
-            break;
-        }
-    }
-    if(i) {
-        KdPrint2((PRINT_PREFIX "AtapiSuckPort2: overrun detected (%#x words)\n", i ));
-    }
-    return statusByte;
-} // AtapiSuckPort2()
-
-ULONG
-DDKFASTAPI
-AtapiSuckPortBuffer2(
-    IN PHW_CHANNEL chan,
-    IN PUSHORT Buffer,
-    IN ULONG Count
-    )
-{
-    UCHAR statusByte;
-    ULONG i;
-    USHORT data;
-    BOOLEAN retry = FALSE;
-
-    // Assume, proper drive is already seleted
-    WaitOnBusyLong(chan);
-    for (i = 0; i < Count; i++) {
-
-        GetStatus(chan, statusByte);
-        if (statusByte & IDE_STATUS_DRQ) {
-            // Suck out any remaining bytes and throw away.
-            data = AtapiReadPort2(chan, IDX_IO1_i_Data);
-            (*Buffer) = data;
-            Count--;
-            Buffer++;
-            UniataNanoSleep(PIO0_TIMING);
-            retry = FALSE;
-        } else {
-            if(i<Count && !retry) {
-                KdPrint2((PRINT_PREFIX "  wait...\n"));
-                WaitForDrq(chan);
-                retry = TRUE;
-            }
-            break;
-        }
-    }
-    if(i) {
-        KdPrint2((PRINT_PREFIX "AtapiSuckPortBuffer2: %#x words\n", i ));
-        if(i==Count) {
-            AtapiSuckPort2(chan);
-        }
-    }
-    return i;
-} // AtapiSuckPortBuffer2()
-
-UCHAR
-DDKFASTAPI
-SelectDrive(
-    IN PHW_CHANNEL   chan,
-    IN ULONG         DeviceNumber
-    )
-{
-    if(!chan) {
-        return 0;
-    }
-/*
-    if(chan->lun[DeviceNumber] &&
-       (chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_CHANGER)) {
-        KdPrint3(("  Select %d\n", DeviceNumber));
-    }
-*/
-    if(chan->last_devsel == DeviceNumber) {
-        //KdPrint3(("  Selected %d\n", DeviceNumber));
-        return 1;
-    }
-    AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1); \
-    chan->last_devsel = DeviceNumber ? 1 : 0;
-    if(!g_opt_DriveSelectNanoDelay) {
-        //KdPrint3(("  Select %d\n", DeviceNumber));
-        return 2;
-    }
-    //KdPrint3(("  Select %d (%d ns)\n", DeviceNumber, g_opt_DriveSelectNanoDelay));
-    UniataNanoSleep(g_opt_DriveSelectNanoDelay);
-    return 2;
-} // end SelectDrive()
-
-UCHAR
-DDKFASTAPI
-WaitOnBusy(
-    IN PHW_CHANNEL   chan
-    )
-{
-    ULONG i;
-    UCHAR Status;
-
-    GetStatus(chan, Status);
-    for (i=0; i<g_opt_WaitBusyCount; i++) {
-        if (Status & IDE_STATUS_BUSY) {
-            AtapiStallExecution(g_opt_WaitBusyDelay);
-            GetStatus(chan, Status);
-            continue;
-        } else {
-            break;
-        }
-    }
-    return Status;
-} // end WaitOnBusy()
-
-UCHAR
-DDKFASTAPI
-WaitOnBusyLong(
-    IN PHW_CHANNEL   chan
-    )
-{
-    ULONG i;
-    UCHAR Status;
-
-    Status = WaitOnBusy(chan);
-    if(!(Status & IDE_STATUS_BUSY))
-        return Status;
-    for (i=0; i<g_opt_WaitBusyLongCount; i++) {
-        GetStatus(chan, Status);
-        if (Status & IDE_STATUS_BUSY) {
-            AtapiStallExecution(g_opt_WaitBusyLongDelay);
-            continue;
-        } else {
-            break;
-        }
-    }
-    return Status;
-} // end WaitOnBusyLong()
-
-UCHAR
-DDKFASTAPI
-WaitOnBaseBusy(
-    IN PHW_CHANNEL   chan
-    )
-{
-    ULONG i;
-    UCHAR Status = IDE_STATUS_WRONG;
-    for (i=0; i<g_opt_WaitBusyCount; i++) {
-        GetBaseStatus(chan, Status);
-        if (Status & IDE_STATUS_BUSY) {
-            AtapiStallExecution(g_opt_WaitBusyDelay);
-            continue;
-        } else {
-            break;
-        }
-    }
-    return Status;
-} // end WaitOnBaseBusy()
-
-UCHAR
-DDKFASTAPI
-WaitOnBaseBusyLong(
-    IN PHW_CHANNEL   chan
-    )
-{
-    ULONG i;
-    UCHAR Status;
-
-    Status = WaitOnBaseBusy(chan);
-    if(!(Status & IDE_STATUS_BUSY))
-        return Status;
-    for (i=0; i<2000; i++) {
-        GetBaseStatus(chan, Status);
-        if (Status & IDE_STATUS_BUSY) {
-            AtapiStallExecution(250);
-            continue;
-        } else {
-            break;
-        }
-    }
-    return Status;
-} // end WaitOnBaseBusyLong()
-
-UCHAR
-DDKFASTAPI
-UniataIsIdle(
-    IN struct _HW_DEVICE_EXTENSION* deviceExtension,
-    IN UCHAR Status
-    )
-{
-    UCHAR Status2;
-
-    if(Status == IDE_STATUS_WRONG) {
-        return IDE_STATUS_WRONG;
-    }
-    if(Status & IDE_STATUS_BUSY) {
-        return Status;
-    }
-//    if(deviceExtension->HwFlags & UNIATA_SATA) {
-    if(UniataIsSATARangeAvailable(deviceExtension, 0)) {
-        if(Status & (IDE_STATUS_BUSY | IDE_STATUS_ERROR)) {
-            return Status;
-        }
-    } else {
-        Status2 = Status & ~(IDE_STATUS_ERROR | IDE_STATUS_INDEX);
-        if ((Status & IDE_STATUS_BUSY) ||
-            (Status2 != IDE_STATUS_IDLE && Status2 != IDE_STATUS_DRDY)) {
-            return Status;
-        }
-    }
-    return IDE_STATUS_IDLE;
-} // end UniataIsIdle()
-
-UCHAR
-DDKFASTAPI
-WaitForIdleLong(
-    IN PHW_CHANNEL   chan
-    )
-{
-    ULONG i;
-    UCHAR Status;
-    UCHAR Status2;
-    for (i=0; i<20000; i++) {
-        GetStatus(chan, Status);
-        Status2 = UniataIsIdle(chan->DeviceExtension, Status);
-        if(Status2 == IDE_STATUS_WRONG) {
-            // no drive ?
-            break;
-        } else
-        if(Status2 & IDE_STATUS_BUSY) {
-            AtapiStallExecution(10);
-            continue;
-        } else {
-            break;
-        }
-    }
-    return Status;
-} // end WaitForIdleLong()
-
-UCHAR
-DDKFASTAPI
-WaitForDrq(
-    IN PHW_CHANNEL   chan
-    )
-{
-    ULONG i;
-    UCHAR Status;
-    for (i=0; i<1000; i++) {
-        GetStatus(chan, Status);
-        if (Status & IDE_STATUS_BUSY) {
-            AtapiStallExecution(g_opt_WaitDrqDelay);
-        } else if (Status & IDE_STATUS_DRQ) {
-            break;
-        } else {
-            AtapiStallExecution(g_opt_WaitDrqDelay*2);
-        }
-    }
-    return Status;
-} // end WaitForDrq()
-
-UCHAR
-DDKFASTAPI
-WaitShortForDrq(
-    IN PHW_CHANNEL   chan
-    )
-{
-    ULONG i;
-    UCHAR Status;
-    for (i=0; i<2; i++) {
-        GetStatus(chan, Status);
-        if (Status & IDE_STATUS_BUSY) {
-            AtapiStallExecution(g_opt_WaitDrqDelay);
-        } else if (Status & IDE_STATUS_DRQ) {
-            break;
-        } else {
-            AtapiStallExecution(g_opt_WaitDrqDelay);
-        }
-    }
-    return Status;
-} // end WaitShortForDrq()
-
-VOID
-DDKFASTAPI
-AtapiSoftReset(
-    IN PHW_CHANNEL   chan,
-    IN ULONG         DeviceNumber
-    )
-{
-    //ULONG c = chan->lChannel;
-    ULONG i = 30 * 1000;
-    UCHAR dma_status = 0;
-    KdPrint2((PRINT_PREFIX "AtapiSoftReset:\n"));
-    UCHAR statusByte0, statusByte2;
-
-    if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
-        UniataAhciSoftReset(chan->DeviceExtension, chan->lChannel, DeviceNumber);
-        return;
-    }
-
-    GetBaseStatus(chan, statusByte2);
-    KdPrint2((PRINT_PREFIX "  statusByte2 %x:\n", statusByte2));
-    SelectDrive(chan, DeviceNumber);
-    if(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_MANUAL_CHS) {
-        // For ESDI/MFM
-        KdPrint2((PRINT_PREFIX "  ESDI/MFM\n"));
-        AtapiStallExecution(10000);
-        for (i = 0; i < 1000; i++) {
-            AtapiStallExecution(999);
-        }
-/*    } else
-    // Seems to be unnecessary, verified by KtP
-    if(!hasPCI) {
-        // original atapi.sys behavior for old ISA-only hardware
-        AtapiStallExecution(10000);
-        AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_RESET);
-        for (i = 0; i < 1000; i++) {
-            AtapiStallExecution(999);
-        } */
-    } else {
-        AtapiStallExecution(500);
-        GetBaseStatus(chan, statusByte2);
-        statusByte0 = statusByte2;
-        AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_RESET);
-
-        // Do not wait for BUSY assertion if it was initially set, jump to
-        // BUSY release wait loop
-        if(!(statusByte0 & IDE_STATUS_BUSY)) {
-            // Wait for BUSY assertion, in some cases delay may occure
-            // 100ms should be enough
-            if(g_opt_VirtualMachine == VM_BOCHS) {
-                i = 100;
-            } else {
-                i = 10*1000;
-            }
-            statusByte2 = AtapiReadPort1(chan, IDX_IO1_i_Status);
-            while (!(statusByte2 & IDE_STATUS_BUSY) &&
-                   i--)
-            {
-                if(!(statusByte0 & IDE_STATUS_ERROR) && (statusByte2 & IDE_STATUS_ERROR)) {
-                    KdPrint2((PRINT_PREFIX "  Command aborted, statusByte2 %x:\n", statusByte2));
-                    break;
-                }
-                AtapiStallExecution(10);
-            }
-        }
-
-        i = 30 * 1000;
-        // ReactOS modification: Already stop looping when we know that the drive has finished resetting.
-        // Not all controllers clear the IDE_STATUS_BUSY flag (e.g. not the VMware one), so ensure that
-        // the maximum waiting time (30 * i = 0.9 seconds) does not exceed the one of the original
-        // implementation. (which is around 1 second)
-        while ((AtapiReadPort1(chan, IDX_IO1_i_Status) & IDE_STATUS_BUSY) &&
-               i--)
-        {
-            AtapiStallExecution(30);
-        }
-        KdPrint2((PRINT_PREFIX " set DFLAGS_REINIT_DMA\n"));
-        chan->lun[DeviceNumber]->DeviceFlags |= DFLAGS_REINIT_DMA;
-    }
-
-    chan->last_devsel = -1; // make sure proper drive would be selected
-    SelectDrive(chan, DeviceNumber);
-    WaitOnBusy(chan);
-    GetBaseStatus(chan, statusByte2);
-    AtapiStallExecution(500);
-
-    GetBaseStatus(chan, statusByte2);
-    if(chan && chan->DeviceExtension) {
-        dma_status = GetDmaStatus(chan->DeviceExtension, chan->lChannel);
-        KdPrint2((PRINT_PREFIX "  DMA status %#x\n", dma_status));
-    } else {
-        KdPrint2((PRINT_PREFIX "  can't get DMA status\n"));
-    }
-    if(dma_status & BM_STATUS_INTR) {
-        // bullshit, we have DMA interrupt, but had never initiate DMA operation
-        KdPrint2((PRINT_PREFIX "  clear unexpected DMA intr on ATAPI reset\n"));
-        AtapiDmaDone(chan->DeviceExtension, DeviceNumber, chan->lChannel, NULL);
-        GetBaseStatus(chan, statusByte2);
-    }
-    if(chan->DeviceExtension->HwFlags & UNIATA_SATA) {
-        UniataSataClearErr(chan->DeviceExtension, chan->lChannel, UNIATA_SATA_IGNORE_CONNECT, DeviceNumber);
-/*        if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
-            UniataSataClearErr(chan->DeviceExtension, chan->lChannel, UNIATA_SATA_IGNORE_CONNECT, 1);
-        }*/
-    }
-    return;
-
-} // end AtapiSoftReset()
-
-VOID
-DDKFASTAPI
-AtapiHardReset(
-    IN struct _HW_CHANNEL*   chan,
-    IN BOOLEAN               DisableInterrupts,
-    IN ULONG                 Delay
-    )
-{
-    KdPrint2((PRINT_PREFIX "AtapiHardReset: %d, dis=%d\n", Delay, DisableInterrupts));
-    AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER |
-                              (DisableInterrupts ? IDE_DC_DISABLE_INTERRUPTS : 0));
-    chan->last_devsel = -1;
-    AtapiStallExecution(Delay);
-    AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER);
-} // end AtapiHardReset()
-
-/*
-    Send command to device.
-    Translate to 48-Lba form if required
-*/
-UCHAR
-NTAPI
-AtaCommand48(
-    IN PHW_DEVICE_EXTENSION deviceExtension,
-    IN ULONG DeviceNumber,
-    IN ULONG lChannel,
-    IN UCHAR command,
-    IN ULONGLONG lba,
-    IN USHORT count,
-    IN USHORT feature,
-    IN ULONG wait_flags
-    )
-{
-    PHW_CHANNEL          chan = &(deviceExtension->chan[lChannel]);
-    UCHAR                statusByte;
-    ULONG i;
-    PUCHAR plba;
-
-    KdPrint2((PRINT_PREFIX "AtaCommand48: cntrlr %#x:%#x dev %#x, cmd %#x, lba %#I64x count %#x feature %#x\n",
-                 deviceExtension->DevIndex, deviceExtension->Channel, DeviceNumber, command, lba, count, feature ));
-
-    if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        //PIDE_AHCI_CMD  AHCI_CMD = &(chan->AhciCtlBlock->cmd);
-
-        KdPrint3(("  (ahci)\n"));
-
-        statusByte = UniataAhciSendPIOCommand(deviceExtension, lChannel, DeviceNumber,
-            (PSCSI_REQUEST_BLOCK)NULL,
-            NULL,
-            0,
-            command,
-            lba, count,
-            feature,
-            0 /* ahci flags */ ,
-            wait_flags,
-            1000 /* timeout 1 sec */
-            );
-
-        return statusByte;
-    }
-
-    SelectDrive(chan, DeviceNumber);
-
-    statusByte = WaitOnBusy(chan);
-
-    /* ready to issue command ? */
-    if (statusByte & IDE_STATUS_BUSY) {
-        KdPrint2((PRINT_PREFIX "  Returning BUSY status\n"));
-        return statusByte;
-    }
-    // !!! We should not check ERROR condition here
-    // ERROR bit may be asserted durring previous operation
-    // and not cleared after SELECT
-
-    //>>>>>> NV: 2006/08/03
-    if(((AtaCommandFlags[command] & (ATA_CMD_FLAG_LBAIOsupp|ATA_CMD_FLAG_FUA)) == ATA_CMD_FLAG_LBAIOsupp) &&
-       CheckIfBadBlock(chan->lun[DeviceNumber], lba, count)) {
-        KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
-        return IDE_STATUS_ERROR;
-        //return SRB_STATUS_ERROR;
-    }
-    //<<<<<< NV:  2006/08/03
-
-    /* only use 48bit addressing if needed because of the overhead */
-    if (UniAta_need_lba48(command, lba, count,
-        chan->lun[DeviceNumber]->IdentifyData.FeaturesSupport.Address48)) {
-
-        KdPrint2((PRINT_PREFIX "  dev %#x USE_LBA_48\n", DeviceNumber ));
-        /* translate command into 48bit version */
-        if(AtaCommandFlags[command] & ATA_CMD_FLAG_48supp) {
-            command = AtaCommands48[command];
-        } else {
-            KdPrint2((PRINT_PREFIX "  unhandled LBA48 command\n"));
-                       return (UCHAR)-1;
-        }
-
-        chan->ChannelCtrlFlags |= CTRFLAGS_LBA48;
-        plba = (PUCHAR)&lba;
-
-        AtapiWritePort1(chan, IDX_IO1_o_Feature,      (UCHAR)(feature>>8));
-        AtapiWritePort1(chan, IDX_IO1_o_Feature,      (UCHAR)feature);
-        AtapiWritePort1(chan, IDX_IO1_o_BlockCount,   (UCHAR)(count>>8));
-        AtapiWritePort1(chan, IDX_IO1_o_BlockCount,   (UCHAR)count);
-        AtapiWritePort1(chan, IDX_IO1_o_BlockNumber,  (UCHAR)(plba[3]));
-        AtapiWritePort1(chan, IDX_IO1_o_BlockNumber,  (UCHAR)(plba[0]));
-        AtapiWritePort1(chan, IDX_IO1_o_CylinderLow,  (UCHAR)(plba[4]));
-        AtapiWritePort1(chan, IDX_IO1_o_CylinderLow,  (UCHAR)(plba[1]));
-        AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)(plba[5]));
-        AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)(plba[2]));
-
-        //KdPrint2((PRINT_PREFIX "AtaCommand48: dev %#x USE_LBA48 (2)\n", DeviceNumber ));
-        AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1) );
-    } else {
-
-        plba = (PUCHAR)&lba; //ktp
-        chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
-        
-        //if(feature ||
-        //   (chan->lun[DeviceNumber]->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_TAPE_DEVICE | DFLAGS_LBA_ENABLED))) {
-            AtapiWritePort1(chan, IDX_IO1_o_Feature,      (UCHAR)feature);
-        //}
-        AtapiWritePort1(chan, IDX_IO1_o_BlockCount,   (UCHAR)count);
-        AtapiWritePort1(chan, IDX_IO1_o_BlockNumber,  (UCHAR)plba[0]);
-        AtapiWritePort1(chan, IDX_IO1_o_CylinderLow,  (UCHAR)plba[1]);
-        AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)plba[2]);
-        if(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_LBA_ENABLED) {
-            //KdPrint2((PRINT_PREFIX "AtaCommand28: dev %#x USE_LBA\n", DeviceNumber ));
-            AtapiWritePort1(chan, IDX_IO1_o_DriveSelect,  (UCHAR)(plba[3] & 0xf) | IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1) );
-        } else {
-            //KdPrint2((PRINT_PREFIX "AtaCommand28: dev %#x USE_CHS\n", DeviceNumber ));
-            AtapiWritePort1(chan, IDX_IO1_o_DriveSelect,  (UCHAR)(plba[3] & 0xf) | (DeviceNumber ? IDE_DRIVE_SELECT_2 : IDE_DRIVE_SELECT_1) );
-        }
-    }
-
-    // write command code to device
-    AtapiWritePort1(chan, IDX_IO1_o_Command, command);
-
-    switch (wait_flags) {
-    case ATA_WAIT_INTR:
-
-        // caller requested wait for interrupt
-        for(i=0;i<4;i++) {
-            WaitOnBusy(chan);
-            statusByte = WaitForDrq(chan);
-            if (statusByte & IDE_STATUS_DRQ)
-                break;
-            AtapiStallExecution(500);
-            KdPrint2((PRINT_PREFIX "  retry waiting DRQ, status %#x\n", statusByte));
-        }
-
-        return statusByte;
-
-    case ATA_WAIT_IDLE:
-
-        // caller requested wait for entering Wait state
-        for (i=0; i<30 * 1000; i++) {
-
-            GetStatus(chan, statusByte);
-            statusByte = UniataIsIdle(deviceExtension, statusByte);
-            if(statusByte == IDE_STATUS_WRONG) {
-                // no drive ?
-                break;
-            } else
-            if(statusByte & IDE_STATUS_ERROR) {
-                break;
-            } else
-            if(statusByte & IDE_STATUS_BUSY) {
-                AtapiStallExecution(100);
-                continue;
-            } else
-            if((statusByte & ~IDE_STATUS_INDEX) == IDE_STATUS_IDLE) {
-                break;
-            } else {
-                //if(deviceExtension->HwFlags & UNIATA_SATA) {
-                if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
-                    break;
-                }
-                AtapiStallExecution(100);
-            }
-        }
-        //statusByte |= IDE_STATUS_BUSY;
-        break;
-
-    case ATA_WAIT_READY:
-        statusByte = WaitOnBusyLong(chan);
-        break;
-    case ATA_WAIT_BASE_READY:
-        statusByte = WaitOnBaseBusyLong(chan);
-        break;
-    case ATA_IMMEDIATE:
-        GetStatus(chan, statusByte);
-        if (statusByte & IDE_STATUS_ERROR) {
-            KdPrint2((PRINT_PREFIX "  Warning: Immed Status %#x :(\n", statusByte));
-            if(statusByte == (IDE_STATUS_IDLE | IDE_STATUS_ERROR)) {
-                break;
-            }
-            KdPrint2((PRINT_PREFIX "  try to continue\n"));
-            statusByte &= ~IDE_STATUS_ERROR;
-
-        } else {
-            //KdPrint2((PRINT_PREFIX "  send Status %#x\n", statusByte));
-        }
-        UniataExpectChannelInterrupt(chan, TRUE);
-        // !!!!!
-        InterlockedExchange(&(chan->CheckIntr),
-                                      CHECK_INTR_IDLE);
-
-        statusByte = IDE_STATUS_SUCCESS;
-        break;
-    }
-
-    //KdPrint2((PRINT_PREFIX "  Status %#x\n", statusByte));
-
-    return statusByte;
-} // end AtaCommand48()
-
-/*
-    Send command to device.
-    This is simply wrapper for AtaCommand48()
-*/
-UCHAR
-NTAPI
-AtaCommand(
-    IN PHW_DEVICE_EXTENSION deviceExtension,
-    IN ULONG DeviceNumber,
-    IN ULONG lChannel,
-    IN UCHAR command,
-    IN USHORT cylinder,
-    IN UCHAR head,
-    IN UCHAR sector,
-    IN UCHAR count,
-    IN UCHAR feature,
-    IN ULONG wait_flags
-    )
-{
-    if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
-        return AtaCommand48(deviceExtension, DeviceNumber, lChannel,
-                            command,
-                            (ULONG)sector | ((ULONG)cylinder << 8) | ((ULONG)(head & 0x0f) << 24),
-                            count, feature, wait_flags);
-    } else {
-        return UniataAhciSendPIOCommand(deviceExtension, lChannel, DeviceNumber,
-            (PSCSI_REQUEST_BLOCK)NULL,
-            NULL,
-            0,
-            command,
-            (ULONG)sector | ((ULONG)cylinder << 8) | ((ULONG)(head & 0x0f) << 24),
-            count,
-            feature,
-            0 /* ahci flags */ ,
-            wait_flags,
-            1000 /* timeout 1 sec */
-            );
-
-    }
-} // end AtaCommand()
-
-LONG
-NTAPI
-AtaPio2Mode(LONG pio)
-{
-    switch (pio) {
-    default: return ATA_PIO;
-    case 0: return ATA_PIO0;
-    case 1: return ATA_PIO1;
-    case 2: return ATA_PIO2;
-    case 3: return ATA_PIO3;
-    case 4: return ATA_PIO4;
-    case 5: return ATA_PIO5;
-    }
-} // end AtaPio2Mode()
-
-LONG
-NTAPI
-AtaPioMode(PIDENTIFY_DATA2 ident)
-{
-    if (ident->PioTimingsValid) {
-        if (ident->AdvancedPIOModes & AdvancedPIOModes_5)
-            return 5;
-        if (ident->AdvancedPIOModes & AdvancedPIOModes_4)
-            return 4;
-        if (ident->AdvancedPIOModes & AdvancedPIOModes_3)
-            return 3;
-    }
-    if (ident->PioCycleTimingMode == 2)
-        return 2;
-    if (ident->PioCycleTimingMode == 1)
-        return 1;
-    if (ident->PioCycleTimingMode == 0)
-        return 0;
-    return IOMODE_NOT_SPECIFIED;
-} // end AtaPioMode()
-
-LONG
-NTAPI
-AtaWmode(PIDENTIFY_DATA2 ident)
-{
-    if (ident->MultiWordDMASupport & 0x04)
-        return 2;
-    if (ident->MultiWordDMASupport & 0x02)
-        return 1;
-    if (ident->MultiWordDMASupport & 0x01)
-        return 0;
-    return IOMODE_NOT_SPECIFIED;
-} // end AtaWmode()
-
-LONG
-NTAPI
-AtaUmode(PIDENTIFY_DATA2 ident)
-{
-    if (!ident->UdmaModesValid)
-        return IOMODE_NOT_SPECIFIED;
-    if (ident->UltraDMASupport & 0x40)
-        return 6;
-    if (ident->UltraDMASupport & 0x20)
-        return 5;
-    if (ident->UltraDMASupport & 0x10)
-        return 4;
-    if (ident->UltraDMASupport & 0x08)
-        return 3;
-    if (ident->UltraDMASupport & 0x04)
-        return 2;
-    if (ident->UltraDMASupport & 0x02)
-        return 1;
-    if (ident->UltraDMASupport & 0x01)
-        return 0;
-    return IOMODE_NOT_SPECIFIED;
-} // end AtaUmode()
-
-LONG
-NTAPI
-AtaSAmode(PIDENTIFY_DATA2 ident) {
-    if(!ident->SataCapabilities || 
-       ident->SataCapabilities == 0xffff) {
-        return IOMODE_NOT_SPECIFIED;
-    }
-    if(ident->SataCapabilities & ATA_SATA_GEN3) {
-        return ATA_SA600;
-    } else
-    if(ident->SataCapabilities & ATA_SATA_GEN2) {
-        return ATA_SA300;
-    } else
-    if(ident->SataCapabilities & ATA_SATA_GEN1) {
-        return ATA_SA150;
-    }
-    return IOMODE_NOT_SPECIFIED;
-} // end AtaSAmode()
-
-#ifndef UNIATA_CORE
-
-VOID
-NTAPI
-AtapiTimerDpc(
-    IN PVOID HwDeviceExtension
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PHW_TIMER HwScsiTimer;
-    LARGE_INTEGER time;
-    ULONG MiniportTimerValue;
-    BOOLEAN recall = FALSE;
-    ULONG lChannel;
-    PHW_CHANNEL chan;
-
-    KdPrint2((PRINT_PREFIX "AtapiTimerDpc:\n"));
-
-    lChannel = deviceExtension->ActiveDpcChan = deviceExtension->FirstDpcChan;
-    if(lChannel == CHAN_NOT_SPECIFIED) {
-        KdPrint2((PRINT_PREFIX "AtapiTimerDpc: no items\n"));
-        return;
-    }
-    chan = &(deviceExtension->chan[lChannel]);
-
-    while(TRUE) {
-
-        HwScsiTimer = chan->HwScsiTimer;
-        chan->HwScsiTimer = NULL;
-
-        deviceExtension->FirstDpcChan = chan->NextDpcChan;
-        if(deviceExtension->FirstDpcChan != CHAN_NOT_SPECIFIED) {
-            recall = TRUE;
-        }
-
-        HwScsiTimer(HwDeviceExtension);
-
-        chan->NextDpcChan = CHAN_NOT_SPECIFIED;
-
-        lChannel = deviceExtension->ActiveDpcChan = deviceExtension->FirstDpcChan;
-        if(lChannel == CHAN_NOT_SPECIFIED) {
-            KdPrint2((PRINT_PREFIX "AtapiTimerDpc: no more items\n"));
-            deviceExtension->FirstDpcChan =
-            deviceExtension->ActiveDpcChan = CHAN_NOT_SPECIFIED;
-            return;
-        }
-
-        KeQuerySystemTime(&time);
-        KdPrint2((PRINT_PREFIX "AtapiTimerDpc: KeQuerySystemTime=%#x%#x\n", time.HighPart, time.LowPart));
-
-        chan = &deviceExtension->chan[lChannel];
-        if(time.QuadPart >= chan->DpcTime - 10) {
-            // call now
-            KdPrint2((PRINT_PREFIX "AtapiTimerDpc: get next DPC, DpcTime1=%#x%#x\n",
-                         (ULONG)(chan->DpcTime >> 32), (ULONG)(chan->DpcTime)));
-            continue;
-        }
-        break;
-    }
-
-    if(recall) {
-        deviceExtension->ActiveDpcChan = CHAN_NOT_SPECIFIED;
-        MiniportTimerValue = (ULONG)(time.QuadPart - chan->DpcTime)/10;
-        if(!MiniportTimerValue)
-            MiniportTimerValue = 1;
-
-        KdPrint2((PRINT_PREFIX "AtapiTimerDpc: recall AtapiTimerDpc\n"));
-        ScsiPortNotification(RequestTimerCall, HwDeviceExtension,
-                             AtapiTimerDpc,
-                             MiniportTimerValue
-                             );
-    }
-    return;
-
-} // end AtapiTimerDpc()
-
-/*
-    Wrapper for ScsiPort, that implements smart Dpc
-    queueing. We need it to allow parallel functioning
-    of IDE channels with shared interrupt. Standard Dpc mechanism
-    cancels previous Dpc request (if any), but we need Dpc queue.
-*/
-VOID
-NTAPI
-AtapiQueueTimerDpc(
-    IN PVOID HwDeviceExtension,
-    IN ULONG lChannel,
-    IN PHW_TIMER HwScsiTimer,
-    IN ULONG MiniportTimerValue
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    LARGE_INTEGER time;
-    LARGE_INTEGER time2;
-    ULONG i;
-    PHW_CHANNEL prev_chan;
-    PHW_CHANNEL chan;
-//    BOOLEAN UseRequestTimerCall = TRUE;
-
-    KdPrint2((PRINT_PREFIX "AtapiQueueTimerDpc: dt=%d for lChn %#x\n", MiniportTimerValue, lChannel));
-    KeQuerySystemTime(&time);
-    time2 = time;
-    KdPrint2((PRINT_PREFIX "AtapiQueueTimerDpc: KeQuerySystemTime=%#x%#x\n", time.HighPart, time.LowPart));
-    time.QuadPart += MiniportTimerValue*10;
-    KdPrint2((PRINT_PREFIX "AtapiQueueTimerDpc: KeQuerySystemTime2=%#x%#x\n", time.HighPart, time.LowPart));
-
-    KdPrint2((PRINT_PREFIX "  ActiveDpcChan=%d, FirstDpcChan=%d\n", deviceExtension->ActiveDpcChan, deviceExtension->FirstDpcChan));
-
-    i = deviceExtension->FirstDpcChan;
-    chan = prev_chan = NULL;
-    while(i != CHAN_NOT_SPECIFIED) {
-        prev_chan = chan;
-        chan = &(deviceExtension->chan[i]);
-        if(chan->DpcTime > time.QuadPart) {
-            break;
-        }
-        i = chan->NextDpcChan;
-    }
-    chan = &(deviceExtension->chan[lChannel]);
-    if(!prev_chan) {
-        deviceExtension->FirstDpcChan = lChannel;
-    } else {
-        prev_chan->NextDpcChan = lChannel;
-    }
-    chan->NextDpcChan = i;
-    chan->HwScsiTimer = HwScsiTimer;
-    chan->DpcTime     = time.QuadPart;
-
-    KdPrint2((PRINT_PREFIX "AtapiQueueTimerDpc: KeQuerySystemTime3=%#x%#x\n", time2.HighPart, time2.LowPart));
-    if(time.QuadPart <= time2.QuadPart) {
-        MiniportTimerValue = 1;
-    } else {
-        MiniportTimerValue = (ULONG)((time.QuadPart - time2.QuadPart) / 10);
-    }
-
-    KdPrint2((PRINT_PREFIX "AtapiQueueTimerDpc: dt=%d for lChn %#x\n", MiniportTimerValue, lChannel));
-    ScsiPortNotification(RequestTimerCall, HwDeviceExtension,
-                         AtapiTimerDpc,
-                         MiniportTimerValue);
-
-} // end AtapiQueueTimerDpc()
-
-#endif //UNIATA_CORE
-
-#ifdef _DEBUG
-VOID
-NTAPI
-UniataDumpATARegs(
-    IN PHW_CHANNEL chan
-    )
-{
-    ULONG                j;
-    UCHAR                statusByteAlt;
-
-    GetStatus(chan, statusByteAlt);
-    KdPrint2((PRINT_PREFIX "  AltStatus (%#x)\n", statusByteAlt));
-
-    for(j=1; j<IDX_IO1_SZ; j++) {
-        statusByteAlt = AtapiReadPort1(chan, IDX_IO1+j);
-        KdPrint2((PRINT_PREFIX
-                   "  Reg_%#x (%#x) = %#x\n",
-                   j,
-                   chan->RegTranslation[IDX_IO1+j].Addr,
-                   statusByteAlt));
-    }
-    if(!chan->RegTranslation[IDX_BM_IO].Addr) {
-        return;
-    }
-    for(j=0; j<IDX_BM_IO_SZ-1; j++) {
-        statusByteAlt = AtapiReadPort1(chan, IDX_BM_IO+j);
-        KdPrint2((PRINT_PREFIX
-                   "  BM_%#x (%#x) = %#x\n",
-                   j,
-                   chan->RegTranslation[IDX_BM_IO+j].Addr,
-                   statusByteAlt));
-    }
-    return;
-} // end UniataDumpATARegs()
-#endif //_DEBUG
-
-VOID
-NTAPI
-UniataSnapAtaRegs(
-    IN PHW_CHANNEL chan,
-    IN ULONG DeviceNumber,
- IN OUT PIDEREGS_EX regs
-    )
-{
-    if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
-        // AHCI
-        UniataAhciSnapAtaRegs(chan, DeviceNumber, regs);
-    } else {
-        // SATA/PATA, assume drive is selected
-        ULONG                j;
-        UCHAR                statusByteAlt;
-
-        if((regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) == 0) {
-            for(j=IDX_IO1_i_Error; j<=IDX_IO1_i_Status; j++) {
-                statusByteAlt = AtapiReadPort1(chan, IDX_IO1+j);
-                ((PUCHAR)regs)[j-1] = statusByteAlt;
-            }
-            regs->bOpFlags = 0;
-        } else {
-            regs->bDriveHeadReg    = AtapiReadPort1(chan, IDX_IO1_i_DriveSelect);
-            for(j=IDX_IO1_i_Error; j<IDX_IO1_i_DriveSelect; j++) {
-                statusByteAlt = AtapiReadPort1(chan, IDX_IO1+j);
-                ((PUCHAR)regs)[j-1] = statusByteAlt;
-                statusByteAlt = AtapiReadPort1(chan, IDX_IO1+j);
-                ((PUCHAR)regs)[j+8-1] = statusByteAlt;
-            }
-            regs->bCommandReg      = AtapiReadPort1(chan, IDX_IO1_i_Status);
-        }
-    }
-    return;
-} // end UniataSnapAtaRegs()
-
-/*++
-
-Routine Description:
-
-    Issue IDENTIFY command to a device.
-
-Arguments:
-
-    HwDeviceExtension - HBA miniport driver's adapter data storage
-    DeviceNumber - Indicates which device.
-    Command - Either the standard (EC) or the ATAPI packet (A1) IDENTIFY.
-
-Return Value:
-
-    TRUE if all goes well.
-
---*/
-BOOLEAN
-NTAPI
-IssueIdentify(
-    IN PVOID HwDeviceExtension,
-    IN ULONG DeviceNumber,
-    IN ULONG lChannel,
-    IN UCHAR Command,
-    IN BOOLEAN NoSetup
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PHW_CHANNEL          chan = &(deviceExtension->chan[lChannel]);
-    ULONG                waitCount = 50000;
-    ULONG                j;
-    UCHAR                statusByte;
-    //UCHAR                statusByte2;
-    UCHAR                signatureLow,
-                         signatureHigh;
-    BOOLEAN              atapiDev = FALSE;
-    BOOLEAN              use_ahci = FALSE;
-    PHW_LU_EXTENSION     LunExt = chan->lun[DeviceNumber];
-
-    use_ahci = UniataIsSATARangeAvailable(deviceExtension, lChannel) &&
-        (deviceExtension->HwFlags & UNIATA_AHCI);
-
-    if(chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) {
-        if(chan->PmLunMap & (1 << DeviceNumber)) {
-            // OK
-        } else {
-            KdPrint2((PRINT_PREFIX "IssueIdentify: PM empty port\n"));
-            return FALSE;
-        }
-    } else
-    if(DeviceNumber && (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
-        KdPrint2((PRINT_PREFIX "IssueIdentify: NO SLAVE\n"));
-        return FALSE;
-    }
-    if(LunExt->DeviceFlags & DFLAGS_HIDDEN) {
-        KdPrint2((PRINT_PREFIX "IssueIdentify: HIDDEN\n"));
-        return FALSE;
-    }
-
-    if(use_ahci) {
-        statusByte = WaitOnBusyLong(chan);
-#ifdef _DEBUG
-        if(!chan->AhciInternalAtaReq) {
-            KdPrint2((PRINT_PREFIX "!AhciInternalAtaReq\n"));
-        }
-#endif
-    } else {
-        SelectDrive(chan, DeviceNumber);
-        AtapiStallExecution(10);
-        statusByte = WaitOnBusyLong(chan);
-        // Check that the status register makes sense.
-        GetBaseStatus(chan, statusByte);
-        /*
-        // unnecessary
-        if(!hasPCI) {
-            // original atapi.sys behavior for old ISA-only hardware
-            AtapiStallExecution(100);
-        }
-        */
-    }
-
-    if (Command == IDE_COMMAND_IDENTIFY) {
-        // Mask status byte ERROR bits.
-        statusByte = UniataIsIdle(deviceExtension, statusByte & ~(IDE_STATUS_ERROR | IDE_STATUS_INDEX));
-        KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for IDE. Status (%#x)\n", statusByte));
-        // Check if register value is reasonable.
-
-        if(statusByte != IDE_STATUS_IDLE) {
-
-            // No reset here !!!
-            KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte != IDE_STATUS_IDLE\n"));
-
-            //if(!(deviceExtension->HwFlags & UNIATA_SATA)) {
-            if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
-                SelectDrive(chan, DeviceNumber);
-                WaitOnBusyLong(chan);
-
-                signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
-                signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
-
-                if (signatureLow == ATAPI_MAGIC_LSB &&
-                    signatureHigh == ATAPI_MAGIC_MSB) {
-                    // Device is Atapi.
-                    KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (dev %d)\n", DeviceNumber));
-                    return FALSE;
-                }
-
-                // We really should wait up to 31 seconds
-                // The ATA spec. allows device 0 to come back from BUSY in 31 seconds!
-                // (30 seconds for device 1)
-                do {
-                    // Wait for Busy to drop.
-                    AtapiStallExecution(100);
-                    GetStatus(chan, statusByte);
-                    if(statusByte == IDE_STATUS_WRONG) {
-                        KdPrint2((PRINT_PREFIX "IssueIdentify: IDE_STATUS_WRONG (dev %d)\n", DeviceNumber));
-                        return FALSE;
-                    }
-
-                } while ((statusByte & IDE_STATUS_BUSY) && waitCount--);
-                GetBaseStatus(chan, statusByte);
-
-                SelectDrive(chan, DeviceNumber);
-            } else {
-                GetBaseStatus(chan, statusByte);
-            }
-            // Another check for signature, to deal with one model Atapi that doesn't assert signature after
-            // a soft reset.
-            signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
-            signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
-
-            if (signatureLow == ATAPI_MAGIC_LSB &&
-                signatureHigh == ATAPI_MAGIC_MSB) {
-                KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (2) (dev %d)\n", DeviceNumber));
-                // Device is Atapi.
-                return FALSE;
-            }
-
-            statusByte = UniataIsIdle(deviceExtension, statusByte) & ~IDE_STATUS_INDEX;
-            if (statusByte != IDE_STATUS_IDLE) {
-                // Give up on this.
-                KdPrint2((PRINT_PREFIX "IssueIdentify: no dev (dev %d)\n", DeviceNumber));
-                return FALSE;
-            }
-        }
-    } else {
-        KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for ATAPI. Status (%#x)\n", statusByte));
-        if(statusByte == IDE_STATUS_WRONG) {
-            return FALSE;
-        }
-        //if(!(deviceExtension->HwFlags & UNIATA_SATA)) {
-        if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
-            statusByte = WaitForIdleLong(chan);
-            KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for ATAPI (2). Status (%#x)\n", statusByte));
-        }
-        atapiDev = TRUE;
-    }
-
-//    if(deviceExtension->HwFlags & UNIATA_SATA) {
-    if(use_ahci) {
-        statusByte = UniataAhciSendPIOCommand(HwDeviceExtension, lChannel, DeviceNumber,
-            (PSCSI_REQUEST_BLOCK)NULL,
-            (PUCHAR)(&deviceExtension->FullIdentifyData),
-            DEV_BSIZE,
-            Command,
-            0, 0,
-            0,
-            0 /* ahci flags */ ,
-            ATA_WAIT_INTR,
-            1000 /* timeout 1 sec */
-            );
-        j = 9; // AHCI is rather different, skip loop at all
-    } else
-    if(LunExt->DeviceFlags & DFLAGS_MANUAL_CHS) {
-        j = 9; // don't send IDENTIFY, assume it is not supported
-        KdPrint2((PRINT_PREFIX "IssueIdentify: Manual CHS\n"));
-        RtlZeroMemory(&(deviceExtension->FullIdentifyData), sizeof(deviceExtension->FullIdentifyData));
-        RtlCopyMemory(&(deviceExtension->FullIdentifyData), &(LunExt->IdentifyData), sizeof(LunExt->IdentifyData));
-    } else
-    if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
-        j = 4; // skip old-style checks
-    } else {
-        j = 0;
-    }
-    for (; j < 4*2; j++) {
-        // Send IDENTIFY command.
-
-        // Load CylinderHigh and CylinderLow with number bytes to transfer for old devices, use 0 for newer.
-        
-        statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, Command, (j < 4) ? DEV_BSIZE : 0 /* cyl */, 0, 0, 0, 0, ATA_WAIT_INTR);
-        // Clear interrupt
-
-        if (!statusByte) {
-            KdPrint2((PRINT_PREFIX "IssueIdentify: 0-status, not present\n"));
-            return FALSE;
-        } else
-        if (statusByte & IDE_STATUS_DRQ) {
-            // Read status to acknowledge any interrupts generated.
-            KdPrint2((PRINT_PREFIX "IssueIdentify: IDE_STATUS_DRQ (%#x)\n", statusByte));
-            GetBaseStatus(chan, statusByte);
-            // One last check for Atapi.
-            if (Command == IDE_COMMAND_IDENTIFY) {
-                signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
-                signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
-
-                if (signatureLow == ATAPI_MAGIC_LSB &&
-                    signatureHigh == ATAPI_MAGIC_MSB) {
-                    KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (3) (dev %d)\n", DeviceNumber));
-                    // Device is Atapi.
-                    return FALSE;
-                }
-            }
-            break;
-        } else {
-            KdPrint2((PRINT_PREFIX "IssueIdentify: !IDE_STATUS_DRQ (%#x)\n", statusByte));
-            if (Command == IDE_COMMAND_IDENTIFY) {
-                // Check the signature. If DRQ didn't come up it's likely Atapi.
-                signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
-                signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
-
-                if (signatureLow == ATAPI_MAGIC_LSB &&
-                    signatureHigh == ATAPI_MAGIC_MSB) {
-                    // Device is Atapi.
-                    KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (4) (dev %d)\n", DeviceNumber));
-                    return FALSE;
-                }
-            } else {
-                if(!(statusByte & IDE_STATUS_ERROR) && (statusByte & IDE_STATUS_BUSY)) {
-                    KdPrint2((PRINT_PREFIX "IssueIdentify: DRQ not asserted immediately, BUSY -> WaitForDrq\n"));
-                    break;
-                }
-            }
-            // Device didn't respond correctly. It will be given one more chance.
-            KdPrint2((PRINT_PREFIX "IssueIdentify: DRQ never asserted (%#x). Error reg (%#x)\n",
-                        statusByte, AtapiReadPort1(chan, IDX_IO1_i_Error)));
-            GetBaseStatus(chan, statusByte);
-            AtapiSoftReset(chan,DeviceNumber);
-
-            AtapiDisableInterrupts(deviceExtension, lChannel);
-            AtapiEnableInterrupts(deviceExtension, lChannel);
-
-            GetBaseStatus(chan, statusByte);
-            //GetStatus(chan, statusByte);
-            KdPrint2((PRINT_PREFIX "IssueIdentify: Status after soft reset (%#x)\n", statusByte));
-        }
-    }
-    // Check for error on really stupid master devices that assert random
-    // patterns of bits in the status register at the slave address.
-    if ((Command == IDE_COMMAND_IDENTIFY) && (statusByte & IDE_STATUS_ERROR)) {
-        KdPrint2((PRINT_PREFIX "IssueIdentify: Exit on error (%#x)\n", statusByte));
-        return FALSE;
-    }
-
-    if(use_ahci) {
-        // everything should already be done by controller
-    } else
-    if(LunExt->DeviceFlags & DFLAGS_MANUAL_CHS) {
-        j = 9; // don't send IDENTIFY, assume it is not supported
-        KdPrint2((PRINT_PREFIX "IssueIdentify: Manual CHS (2)\n"));
-        statusByte = WaitForDrq(chan);
-        statusByte = WaitOnBusyLong(chan);
-            KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
-        GetBaseStatus(chan, statusByte);
-    } else {
-
-        KdPrint2((PRINT_PREFIX "IssueIdentify: Status before read words %#x\n", statusByte));
-        // Suck out 256 words. After waiting for one model that asserts busy
-        // after receiving the Packet Identify command.
-        statusByte = WaitForDrq(chan);
-        statusByte = WaitOnBusyLong(chan);
-            KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
-
-        if (!(statusByte & IDE_STATUS_DRQ)) {
-            KdPrint2((PRINT_PREFIX "IssueIdentify: !IDE_STATUS_DRQ (2) (%#x)\n", statusByte));
-            GetBaseStatus(chan, statusByte);
-            return FALSE;
-        }
-        GetBaseStatus(chan, statusByte);
-        KdPrint2((PRINT_PREFIX "IssueIdentify: BASE statusByte %#x\n", statusByte));
-
-#ifdef _DEBUG
-        if(atapiDev) {
-          j = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
-          KdPrint3((PRINT_PREFIX "IssueIdentify: iReason %x\n", j));
-
-          j =
-              AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountLow);
-
-          j |=
-              (USHORT)AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountHigh) << 8;
-          KdPrint3((PRINT_PREFIX "IssueIdentify: wCount %x\n", j));
-
-        }
-#endif //_DEBUG
-
-        if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) {
-
-            KdPrint2((PRINT_PREFIX "  use 16bit IO\n"));
-            // ATI/SII chipsets with memory-mapped IO hangs when
-            // I call ReadBuffer(), probably due to PCI burst/prefetch enabled
-            // Unfortunately, I don't know yet how to workaround it except
-            // spacifying manual delay in the way you see below.
-            ReadBuffer(chan, (PUSHORT)&deviceExtension->FullIdentifyData, 256, PIO0_TIMING);
-
-            // Work around for some IDE and one model Atapi that will present more than
-            // 256 bytes for the Identify data.
-            KdPrint2((PRINT_PREFIX "IssueIdentify: suck data port\n", statusByte));
-            statusByte = AtapiSuckPort2(chan);
-        } else {
-            KdPrint2((PRINT_PREFIX "  use 32bit IO\n"));
-            ReadBuffer2(chan, (PULONG)&deviceExtension->FullIdentifyData, 256/2, PIO0_TIMING);
-        }
-
-        KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
-        statusByte = WaitForDrq(chan);
-        KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
-        GetBaseStatus(chan, statusByte);
-    }
-    KdPrint2((PRINT_PREFIX "IssueIdentify: Status after read words %#x\n", statusByte));
-
-    if(NoSetup) {
-        KdPrint2((PRINT_PREFIX "IssueIdentify: no setup, exiting\n"));
-        return TRUE;
-    }
-
-    KdPrint2((PRINT_PREFIX "Model: %20.20s\n", deviceExtension->FullIdentifyData.ModelNumber));
-    KdPrint2((PRINT_PREFIX "FW:    %4.4s\n", deviceExtension->FullIdentifyData.FirmwareRevision));
-    KdPrint2((PRINT_PREFIX "S/N:   %20.20s\n", deviceExtension->FullIdentifyData.SerialNumber));
-    if(g_opt_VirtualMachine == VM_AUTO) {
-        if((deviceExtension->FullIdentifyData.FirmwareRevision[0] == 0 ||
-           deviceExtension->FullIdentifyData.FirmwareRevision[0] == ' ') &&
-           (deviceExtension->FullIdentifyData.FirmwareRevision[1] == 0 ||
-           deviceExtension->FullIdentifyData.FirmwareRevision[1] == ' ')) {
-            // Check for BOCHS VM signature. If no additional PCI devices (e.g. VGA)
-            // are declared BOCHS looks like regular PC
-            if (!atapiDev && !AtapiStringCmp ((PCCHAR)(deviceExtension->FullIdentifyData.SerialNumber), "XBDH00", 6)) {
-                KdPrint2((PRINT_PREFIX "IssueIdentify: BOCHS HDD\n"));
-                g_opt_VirtualMachine = VM_BOCHS;
-            } else
-            if (atapiDev && !AtapiStringCmp ((PCCHAR)(deviceExtension->FullIdentifyData.SerialNumber), "XBDC00", 6)) {
-                KdPrint2((PRINT_PREFIX "IssueIdentify: BOCHS CD\n"));
-                g_opt_VirtualMachine = VM_BOCHS;
-            }
-        }
-    }
-
-    KdPrint2((PRINT_PREFIX "Pio:   %x\n", deviceExtension->FullIdentifyData.PioCycleTimingMode));
-    if(deviceExtension->FullIdentifyData.PioTimingsValid) {
-        KdPrint2((PRINT_PREFIX "APio:  %x\n", deviceExtension->FullIdentifyData.AdvancedPIOModes));
-    }
-    KdPrint2((PRINT_PREFIX "SWDMA: %x\n", deviceExtension->FullIdentifyData.SingleWordDMAActive));
-    KdPrint2((PRINT_PREFIX "MWDMA: %x\n", deviceExtension->FullIdentifyData.MultiWordDMAActive));
-    if(deviceExtension->FullIdentifyData.UdmaModesValid) {
-        KdPrint2((PRINT_PREFIX "UDMA:  %x/%x\n", deviceExtension->FullIdentifyData.UltraDMAActive, deviceExtension->FullIdentifyData.UltraDMASupport));
-    }
-    KdPrint2((PRINT_PREFIX "SATA:  %x\n", deviceExtension->FullIdentifyData.SataEnable));
-    KdPrint2((PRINT_PREFIX "SATA support: %x, CAPs %#x\n",
-        deviceExtension->FullIdentifyData.SataSupport,
-        deviceExtension->FullIdentifyData.SataCapabilities));
-
-    LunExt->LimitedTransferMode =
-    LunExt->OrigTransferMode =
-        (UCHAR)ata_cur_mode_from_ident(&(deviceExtension->FullIdentifyData), IDENT_MODE_MAX);
-    LunExt->TransferMode =
-        (UCHAR)ata_cur_mode_from_ident(&(deviceExtension->FullIdentifyData), IDENT_MODE_ACTIVE);
-
-    KdPrint2((PRINT_PREFIX "OrigTransferMode: %x, Active: %x\n", LunExt->OrigTransferMode, LunExt->TransferMode));
-    KdPrint2((PRINT_PREFIX "Accoustic %d, cur %d\n",
-        deviceExtension->FullIdentifyData.VendorAcoustic,
-        deviceExtension->FullIdentifyData.CurrentAcoustic
-        ));
-    KdPrint2((PRINT_PREFIX "AdvPowerMode %d\n",
-        deviceExtension->FullIdentifyData.CfAdvPowerMode
-        ));
-
-    KdPrint2((PRINT_PREFIX "PowerMngt %d/%d, APM %d/%d\n",
-        deviceExtension->FullIdentifyData.FeaturesEnabled.PowerMngt,
-        deviceExtension->FullIdentifyData.FeaturesSupport.PowerMngt,
-        deviceExtension->FullIdentifyData.FeaturesEnabled.APM,
-        deviceExtension->FullIdentifyData.FeaturesSupport.APM
-        ));
-
-    // Check out a few capabilities / limitations of the device.
-    if (deviceExtension->FullIdentifyData.RemovableStatus & 1) {
-        // Determine if this drive supports the MSN functions.
-        KdPrint2((PRINT_PREFIX "IssueIdentify: Marking drive %d as removable. SFE = %d\n",
-                    DeviceNumber,
-                    deviceExtension->FullIdentifyData.RemovableStatus));
-        LunExt->DeviceFlags |= DFLAGS_REMOVABLE_DRIVE;
-    }
-    if(use_ahci) {
-        // AHCI doesn't recommend using PIO and multiblock
-        LunExt->MaximumBlockXfer = 0;
-    } else
-    if (deviceExtension->FullIdentifyData.MaximumBlockTransfer) {
-        // Determine max. block transfer for this device.
-        LunExt->MaximumBlockXfer =
-            (UCHAR)(deviceExtension->FullIdentifyData.MaximumBlockTransfer & 0xFF);
-    }
-    LunExt->NumOfSectors = 0;
-    if (Command == IDE_COMMAND_IDENTIFY) {
-        ULONGLONG NumOfSectors=0;
-        ULONGLONG NativeNumOfSectors=0;
-        ULONGLONG cylinders=0;
-        ULONGLONG tmp_cylinders=0;
-
-        KdPrint2((PRINT_PREFIX "PhysLogSectorSize %#x, %#x, offset %#x\n", 
-                deviceExtension->FullIdentifyData.PhysLogSectorSize,
-                deviceExtension->FullIdentifyData.LargeSectorSize,
-                deviceExtension->FullIdentifyData.LogicalSectorOffset
-                ));
-
-        KdPrint2((PRINT_PREFIX "NV PM_Sup %d, PM_En %d, En %d, PM ver %#x ver %#x\n", 
-                deviceExtension->FullIdentifyData.NVCache_PM_Supported,
-                deviceExtension->FullIdentifyData.NVCache_PM_Enabled,
-                deviceExtension->FullIdentifyData.NVCache_Enabled,
-                deviceExtension->FullIdentifyData.NVCache_PM_Version,
-                deviceExtension->FullIdentifyData.NVCache_Version
-                ));
-
-        KdPrint2((PRINT_PREFIX "R-rate %d\n",
-                deviceExtension->FullIdentifyData.NominalMediaRotationRate
-                ));
-        KdPrint2((PRINT_PREFIX "WC %d/%d, LA %d/%d, WB %d/%d, RB %d/%d, Q %d/%d\n",
-                deviceExtension->FullIdentifyData.FeaturesEnabled.WriteCache,
-                deviceExtension->FullIdentifyData.FeaturesSupport.WriteCache,
-                deviceExtension->FullIdentifyData.FeaturesEnabled.LookAhead,
-                deviceExtension->FullIdentifyData.FeaturesSupport.LookAhead,
-                deviceExtension->FullIdentifyData.FeaturesEnabled.WriteBuffer,
-                deviceExtension->FullIdentifyData.FeaturesSupport.WriteBuffer,
-                deviceExtension->FullIdentifyData.FeaturesEnabled.ReadBuffer,
-                deviceExtension->FullIdentifyData.FeaturesSupport.ReadBuffer,
-                deviceExtension->FullIdentifyData.FeaturesEnabled.Queued,
-                deviceExtension->FullIdentifyData.FeaturesSupport.Queued
-                ));
-
-        KdPrint2((PRINT_PREFIX "Protected %d/%d status %#x, rev %#x\n",
-                deviceExtension->FullIdentifyData.FeaturesEnabled.Protected,
-                deviceExtension->FullIdentifyData.FeaturesSupport.Protected,
-                deviceExtension->FullIdentifyData.SecurityStatus,
-                deviceExtension->FullIdentifyData.MasterPasswdRevision
-                ));
-
-        // Read very-old-style drive geometry
-        KdPrint2((PRINT_PREFIX "CHS %#x:%#x:%#x\n", 
-                deviceExtension->FullIdentifyData.NumberOfCylinders,
-                deviceExtension->FullIdentifyData.NumberOfHeads,
-                deviceExtension->FullIdentifyData.SectorsPerTrack
-                ));
-        NumOfSectors = deviceExtension->FullIdentifyData.NumberOfCylinders *
-                       deviceExtension->FullIdentifyData.NumberOfHeads *
-                       deviceExtension->FullIdentifyData.SectorsPerTrack;
-        KdPrint2((PRINT_PREFIX "NumOfSectors %#I64x\n", NumOfSectors));
-        // Check for HDDs > 8Gb
-        if ((deviceExtension->FullIdentifyData.NumberOfCylinders == 0x3fff) &&
-/*            (deviceExtension->FullIdentifyData.TranslationFieldsValid) &&*/
-             deviceExtension->FullIdentifyData.NumberOfHeads &&
-             deviceExtension->FullIdentifyData.SectorsPerTrack &&
-            (NumOfSectors < deviceExtension->FullIdentifyData.UserAddressableSectors)) {
-            KdPrint2((PRINT_PREFIX "NumberOfCylinders == 0x3fff\n"));
-            cylinders = 
-                (deviceExtension->FullIdentifyData.UserAddressableSectors /
-                    (deviceExtension->FullIdentifyData.NumberOfHeads *
-                       deviceExtension->FullIdentifyData.SectorsPerTrack));
-
-            KdPrint2((PRINT_PREFIX "cylinders %#I64x\n", cylinders));
-
-            NumOfSectors = cylinders *
-                           deviceExtension->FullIdentifyData.NumberOfHeads *
-                           deviceExtension->FullIdentifyData.SectorsPerTrack;
-
-            KdPrint2((PRINT_PREFIX "NumOfSectors %#I64x\n", NumOfSectors));
-        } else {
-
-        }
-        // Check for LBA mode
-        KdPrint2((PRINT_PREFIX "SupportLba flag %#x\n", deviceExtension->FullIdentifyData.SupportLba));
-        KdPrint2((PRINT_PREFIX "SupportDMA flag %#x\n", deviceExtension->FullIdentifyData.SupportDma));
-        KdPrint2((PRINT_PREFIX "SoftReset %#x\n", deviceExtension->FullIdentifyData.SoftReset));
-        KdPrint2((PRINT_PREFIX "SupportIordy %#x, DisableIordy %#x\n",
-            deviceExtension->FullIdentifyData.SupportIordy,
-            deviceExtension->FullIdentifyData.DisableIordy
-            ));
-        KdPrint2((PRINT_PREFIX "MajorRevision %#x\n", deviceExtension->FullIdentifyData.MajorRevision));
-        KdPrint2((PRINT_PREFIX "UserAddressableSectors %#x\n", deviceExtension->FullIdentifyData.UserAddressableSectors));
-        if ( deviceExtension->FullIdentifyData.SupportLba
-                            ||
-            (deviceExtension->FullIdentifyData.MajorRevision &&
-/*             deviceExtension->FullIdentifyData.TranslationFieldsValid &&*/
-             deviceExtension->FullIdentifyData.UserAddressableSectors)) {
-            KdPrint2((PRINT_PREFIX "LBA mode\n"));
-            LunExt->DeviceFlags |= DFLAGS_LBA_ENABLED;
-        } else {
-            KdPrint2((PRINT_PREFIX "Keep orig geometry\n"));
-            LunExt->DeviceFlags |= DFLAGS_ORIG_GEOMETRY;
-            goto skip_lba_staff;
-        }
-        // Check for LBA48 support
-        if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
-            if(deviceExtension->FullIdentifyData.FeaturesSupport.Address48 &&
-               deviceExtension->FullIdentifyData.FeaturesEnabled.Address48 &&
-               deviceExtension->FullIdentifyData.NumberOfHeads &&
-               deviceExtension->FullIdentifyData.SectorsPerTrack &&
-               (deviceExtension->FullIdentifyData.UserAddressableSectors48 > NumOfSectors)
-               ) {
-                KdPrint2((PRINT_PREFIX "LBA48\n"));
-                cylinders = 
-                    (deviceExtension->FullIdentifyData.UserAddressableSectors48 /
-                        (deviceExtension->FullIdentifyData.NumberOfHeads *
-                           deviceExtension->FullIdentifyData.SectorsPerTrack));
-
-                KdPrint2((PRINT_PREFIX "cylinders %#I64x\n", cylinders));
-                
-                NativeNumOfSectors = cylinders *
-                               deviceExtension->FullIdentifyData.NumberOfHeads *
-                               deviceExtension->FullIdentifyData.SectorsPerTrack;
-
-                KdPrint2((PRINT_PREFIX "NativeNumOfSectors %#I64x\n", NativeNumOfSectors));
-
-                if(NativeNumOfSectors > NumOfSectors) {
-                    KdPrint2((PRINT_PREFIX "Update NumOfSectors to %#I64x\n", NativeNumOfSectors));
-                    NumOfSectors = NativeNumOfSectors;
-                }
-            }
-
-            // Check drive capacity report for LBA48-capable drives.
-            if(deviceExtension->FullIdentifyData.FeaturesSupport.Address48) {
-                ULONG hNativeNumOfSectors;
-                KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_READ_NATIVE_SIZE48\n"));
-
-                statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
-                             IDE_COMMAND_READ_NATIVE_SIZE48, 0, 0, 0, ATA_WAIT_READY);
-
-                if(!(statusByte & IDE_STATUS_ERROR)) {
-                    if(use_ahci) {
-                        NativeNumOfSectors = chan->AhciInternalAtaReq->ahci.in_lba;
-                    } else {
-                        NativeNumOfSectors = (ULONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber) |
-                                            ((ULONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderLow)  << 8) |
-                                            ((ULONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh) << 16) ;
-
-                        AtapiWritePort1(chan, IDX_IO2_o_Control,
-                                               IDE_DC_USE_HOB );
-
-                        KdPrint2((PRINT_PREFIX "Read high order bytes\n"));
-                        NativeNumOfSectors |=
-                                            (ULONG)((ULONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber)  << 24 );
-                        hNativeNumOfSectors= 
-                                             (ULONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) |
-                                            ((ULONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh) << 8) ;
-                        ((PULONG)&NativeNumOfSectors)[1] = hNativeNumOfSectors;
-                    }
-                    KdPrint2((PRINT_PREFIX "NativeNumOfSectors %#I64x\n", NativeNumOfSectors));
-
-                    // Some drives report LBA48 capability while has capacity below 128Gb
-                    // Probably they support large block-counters.
-                    // But the problem is that some of them reports higher part of Max LBA equal to lower part.
-                    // Here we check this
-                    if((NativeNumOfSectors & 0xffffff) == ((NativeNumOfSectors >> 24) & 0xffffff)) {
-                        KdPrint2((PRINT_PREFIX "High-order bytes == Low-order bytes !!!\n"));
-
-                        statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
-                                     IDE_COMMAND_READ_NATIVE_SIZE48, 0, 0, 0, ATA_WAIT_READY);
-
-                        if(!(statusByte & IDE_STATUS_ERROR)) {
-                            if(use_ahci) {
-                                NativeNumOfSectors = chan->AhciInternalAtaReq->ahci.in_lba;
-                            } else {
-                                NativeNumOfSectors = (ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber) |
-                                                ((ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber)  << 24) |
-                                                ((ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderLow)  << 8 ) |
-                                                ((ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderLow)  << 32) |
-                                                ((ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh) << 16) |
-                                                ((ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh) << 40) 
-                                                ;
-                            }
-                        }
-
-                        if((NativeNumOfSectors & 0xffffff) == ((NativeNumOfSectors >> 24) & 0xffffff)) {
-                            KdPrint2((PRINT_PREFIX "High-order bytes == Low-order bytes !!! (2)\n"));
-                            NativeNumOfSectors = 0;
-                        }
-                    }
-
-                    if(NumOfSectors <= ATA_MAX_LBA28 &&
-                       NativeNumOfSectors > NumOfSectors) {
-
-                        KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_SET_NATIVE_SIZE48\n"));
-                        KdPrint2((PRINT_PREFIX "Update NumOfSectors to %#I64x\n", NativeNumOfSectors));
-
-                        statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
-                                     IDE_COMMAND_SET_NATIVE_SIZE, NativeNumOfSectors, 0, 0, ATA_WAIT_READY);
-                        if(!(statusByte & IDE_STATUS_ERROR)) {
-                            NumOfSectors = NativeNumOfSectors;
-                        }
-                    }
-                } // !error
-            }
-    
-            if(NumOfSectors < 0x2100000 /*&& NumOfSectors > 31*1000*1000*/) {
-                // check for native LBA size
-                // some drives report ~32Gb in Identify Block
-                KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_READ_NATIVE_SIZE\n"));
-
-                statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_READ_NATIVE_SIZE,
-                             0, IDE_USE_LBA, 0, 0, 0, ATA_WAIT_READY);
-
-                if(!(statusByte & IDE_STATUS_ERROR)) {
-                    if(use_ahci) {
-                        NativeNumOfSectors = chan->AhciInternalAtaReq->ahci.in_lba;
-                    } else {
-                        NativeNumOfSectors = (ULONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber) |
-                                            ((ULONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) << 8) |
-                                            ((ULONG)AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh) << 16) |
-                                           (((ULONG)AtapiReadPort1(chan, IDX_IO1_i_DriveSelect) & 0xf) << 24);
-                    }
-                    KdPrint2((PRINT_PREFIX "NativeNumOfSectors %#I64x\n", NativeNumOfSectors));
-
-                    if(NativeNumOfSectors > NumOfSectors) {
-
-                        KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_SET_NATIVE_SIZE\n"));
-                        KdPrint2((PRINT_PREFIX "Update NumOfSectors to %#I64x\n", NativeNumOfSectors));
-
-                        statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
-                                     IDE_COMMAND_SET_NATIVE_SIZE, NativeNumOfSectors, 0, 0, ATA_WAIT_READY);
-                        if(!(statusByte & IDE_STATUS_ERROR)) {
-                            NumOfSectors = NativeNumOfSectors;
-                        }
-                    }
-                }
-            }
-
-        } // if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED)
-
-        // fill IdentifyData with bogus geometry
-        KdPrint2((PRINT_PREFIX "requested LunExt->GeomType=%x\n", LunExt->opt_GeomType));
-        if(deviceExtension->FullIdentifyData.CurrentSectorsPerTrack &&
-           deviceExtension->FullIdentifyData.NumberOfCurrentHeads) {
-          tmp_cylinders = NumOfSectors / (deviceExtension->FullIdentifyData.CurrentSectorsPerTrack *
-                                          deviceExtension->FullIdentifyData.NumberOfCurrentHeads);
-        } else
-        if(deviceExtension->FullIdentifyData.SectorsPerTrack &&
-           deviceExtension->FullIdentifyData.NumberOfHeads) {
-            KdPrint2((PRINT_PREFIX "Current C/H = %#I64x/%#I64x\n",
-                deviceExtension->FullIdentifyData.CurrentSectorsPerTrack,
-                deviceExtension->FullIdentifyData.NumberOfCurrentHeads));
-            tmp_cylinders = NumOfSectors / (deviceExtension->FullIdentifyData.SectorsPerTrack *
-                                            deviceExtension->FullIdentifyData.NumberOfHeads);
-        } else {
-            tmp_cylinders = 0;
-        }
-        KdPrint2((PRINT_PREFIX "tmp_cylinders = %#I64x\n", tmp_cylinders));
-        if((tmp_cylinders < 0xffff) || (LunExt->opt_GeomType == GEOM_ORIG)) {
-            // ok, we can keep original values
-            if(LunExt->opt_GeomType == GEOM_AUTO) {
-                LunExt->opt_GeomType = GEOM_ORIG;
-            }
-        } else {
-            tmp_cylinders = NumOfSectors / (255*63);
-            if(tmp_cylinders < 0xffff) {
-                // we can use generic values for H/S for generic geometry approach
-                if(LunExt->opt_GeomType == GEOM_AUTO) {
-                    LunExt->opt_GeomType = GEOM_STD;
-                }
-            } else {
-                // we should use UNIATA geometry approach
-                if(LunExt->opt_GeomType == GEOM_AUTO) {
-                    LunExt->opt_GeomType = GEOM_UNIATA;
-                }
-            }
-        }
-
-        if(!deviceExtension->FullIdentifyData.SectorsPerTrack ||
-           !deviceExtension->FullIdentifyData.NumberOfHeads) {
-            KdPrint2((PRINT_PREFIX "Zero S/H -> Force Use GEOM_STD\n"));
-        }
-
-        if(LunExt->opt_GeomType == GEOM_STD) {
-            deviceExtension->FullIdentifyData.CurrentSectorsPerTrack =
-            deviceExtension->FullIdentifyData.SectorsPerTrack = 63;
-
-            deviceExtension->FullIdentifyData.NumberOfCurrentHeads =
-            deviceExtension->FullIdentifyData.NumberOfHeads   = 255;
-
-            cylinders = NumOfSectors / (255*63);
-            KdPrint2((PRINT_PREFIX "Use GEOM_STD, CHS=%I64x/%x/%x\n", cylinders, 255, 63));
-        } else
-        if(LunExt->opt_GeomType == GEOM_UNIATA) {
-            while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.SectorsPerTrack < 0x80)) {
-                cylinders /= 2;
-                KdPrint2((PRINT_PREFIX "cylinders /= 2\n"));
-                deviceExtension->FullIdentifyData.SectorsPerTrack *= 2;
-                deviceExtension->FullIdentifyData.CurrentSectorsPerTrack *= 2;
-            }
-            while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.NumberOfHeads < 0x80)) {
-                cylinders /= 2;
-                KdPrint2((PRINT_PREFIX "cylinders /= 2 (2)\n"));
-                deviceExtension->FullIdentifyData.NumberOfHeads *= 2;
-                deviceExtension->FullIdentifyData.NumberOfCurrentHeads *= 2;
-            }
-            while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.SectorsPerTrack < 0x8000)) {
-                cylinders /= 2;
-                KdPrint2((PRINT_PREFIX "cylinders /= 2 (3)\n"));
-                deviceExtension->FullIdentifyData.SectorsPerTrack *= 2;
-                deviceExtension->FullIdentifyData.CurrentSectorsPerTrack *= 2;
-            }
-            while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.NumberOfHeads < 0x8000)) {
-                cylinders /= 2;
-                KdPrint2((PRINT_PREFIX "cylinders /= 2 (4)\n"));
-                deviceExtension->FullIdentifyData.NumberOfHeads *= 2;
-                deviceExtension->FullIdentifyData.NumberOfCurrentHeads *= 2;
-            }
-            KdPrint2((PRINT_PREFIX "Use GEOM_UNIATA, CHS=%I64x/%x/%x\n", cylinders,
-                deviceExtension->FullIdentifyData.NumberOfCurrentHeads,
-                deviceExtension->FullIdentifyData.CurrentSectorsPerTrack));
-        }
-        if(!cylinders) {
-            KdPrint2((PRINT_PREFIX "cylinders = tmp_cylinders (%x = %x)\n", cylinders, tmp_cylinders));
-            cylinders = tmp_cylinders;
-        }
-        deviceExtension->FullIdentifyData.NumberOfCurrentCylinders =
-        deviceExtension->FullIdentifyData.NumberOfCylinders = (USHORT)cylinders;
-
-skip_lba_staff:
-
-        KdPrint2((PRINT_PREFIX "Geometry: C %#x (%#x)\n",
-                  deviceExtension->FullIdentifyData.NumberOfCylinders,
-                  deviceExtension->FullIdentifyData.NumberOfCurrentCylinders
-                  ));
-        KdPrint2((PRINT_PREFIX "Geometry: H %#x (%#x)\n",
-                  deviceExtension->FullIdentifyData.NumberOfHeads,
-                  deviceExtension->FullIdentifyData.NumberOfCurrentHeads
-                  ));
-        KdPrint2((PRINT_PREFIX "Geometry: S %#x (%#x)\n",
-                  deviceExtension->FullIdentifyData.SectorsPerTrack,
-                  deviceExtension->FullIdentifyData.CurrentSectorsPerTrack
-                  ));
-
-        if(NumOfSectors) {
-            LunExt->NumOfSectors = NumOfSectors;
-        }
-        if(deviceExtension->FullIdentifyData.MajorRevision &&
-           deviceExtension->FullIdentifyData.DoubleWordIo) {
-            LunExt->DeviceFlags |= DFLAGS_DWORDIO_ENABLED;
-            KdPrint2((PRINT_PREFIX "IssueIdentify: DWORDIO supported\n"));
-        }
-    } else {
-        // ATAPI
-        if(deviceExtension->FullIdentifyData.MajorRevision &&
-           deviceExtension->FullIdentifyData.DoubleWordIo) {
-            LunExt->DeviceFlags |= DFLAGS_DWORDIO_ENABLED;
-            KdPrint2((PRINT_PREFIX "IssueIdentify: DFLAGS_DWORDIO_ENABLED.\n"));
-        }
-        if(deviceExtension->FullIdentifyData.AtapiDMA.DMADirRequired) {
-            KdPrint2((PRINT_PREFIX "DMADirRequired.\n"));
-        }
-        if(deviceExtension->FullIdentifyData.AtapiByteCount0) {
-            KdPrint2((PRINT_PREFIX "AtapiByteCount0=%x\n", deviceExtension->FullIdentifyData.AtapiByteCount0));
-        }
-    }
-
-    ScsiPortMoveMemory(&LunExt->IdentifyData,
-                       &deviceExtension->FullIdentifyData,sizeof(IDENTIFY_DATA2));
-
-    InitBadBlocks(LunExt);
-
-    if ((LunExt->IdentifyData.DrqType & ATAPI_DRQT_INTR) &&
-        (Command != IDE_COMMAND_IDENTIFY)) {
-
-        // This device interrupts with the assertion of DRQ after receiving
-        // Atapi Packet Command
-        LunExt->DeviceFlags |= DFLAGS_INT_DRQ;
-        KdPrint2((PRINT_PREFIX "IssueIdentify: Device interrupts on assertion of DRQ.\n"));
-
-    } else {
-        KdPrint2((PRINT_PREFIX "IssueIdentify: Device does not interrupt on assertion of DRQ.\n"));
-    }
-
-    if(Command != IDE_COMMAND_IDENTIFY) {
-        // ATAPI branch
-        if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_TAPE) {
-            // This is a tape.
-            LunExt->DeviceFlags |= DFLAGS_TAPE_DEVICE;
-            KdPrint2((PRINT_PREFIX "IssueIdentify: Device is a tape drive.\n"));
-        } else
-        if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM ||
-            LunExt->IdentifyData.DeviceType == ATAPI_TYPE_OPTICAL) {
-            KdPrint2((PRINT_PREFIX "IssueIdentify: Device is CD/Optical drive.\n"));
-            // set CD default costs
-            LunExt->RwSwitchCost  = REORDER_COST_SWITCH_RW_CD;
-            LunExt->RwSwitchMCost = REORDER_MCOST_SWITCH_RW_CD;
-            LunExt->SeekBackMCost = REORDER_MCOST_SEEK_BACK_CD;
-            statusByte = WaitForDrq(chan);
-        } else {
-            KdPrint2((PRINT_PREFIX "IssueIdentify: ATAPI drive type %#x.\n",
-                LunExt->IdentifyData.DeviceType));
-        }
-        KdPrint2((PRINT_PREFIX "IssueIdentify: AtapiCmdSize %#x\n", deviceExtension->FullIdentifyData.AtapiCmdSize));
-    } else {
-        KdPrint2((PRINT_PREFIX "IssueIdentify: hard drive.\n"));
-    }
-
-    GetBaseStatus(chan, statusByte);
-    KdPrint2((PRINT_PREFIX "IssueIdentify: final Status on exit (%#x)\n", statusByte));
-    return TRUE;
-
-} // end IssueIdentify()
-
-
-/*++
-
-Routine Description:
-    Set drive parameters using the IDENTIFY data.
-
-Arguments:
-    HwDeviceExtension - HBA miniport driver's adapter data storage
-    DeviceNumber - Indicates which device.
-
-Return Value:
-    TRUE if all goes well.
-
---*/
-BOOLEAN
-NTAPI
-SetDriveParameters(
-    IN PVOID HwDeviceExtension,
-    IN ULONG DeviceNumber,
-    IN ULONG lChannel
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PIDENTIFY_DATA2      identifyData;
-    PHW_LU_EXTENSION     LunExt;
-//    ULONG i;
-    UCHAR statusByte;
-    UCHAR errorByte;
-
-    LunExt = deviceExtension->chan[lChannel].lun[DeviceNumber];
-    identifyData = &(LunExt->IdentifyData);
-
-    if(LunExt->DeviceFlags &
-          (DFLAGS_LBA_ENABLED | DFLAGS_ORIG_GEOMETRY))
-       return TRUE;
-
-    KdPrint2((PRINT_PREFIX "SetDriveParameters: Number of heads %#x\n", identifyData->NumberOfHeads));
-    KdPrint2((PRINT_PREFIX "SetDriveParameters: Sectors per track %#x\n", identifyData->SectorsPerTrack));
-
-    // Send SET PARAMETER command.
-    statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel,
-                            IDE_COMMAND_SET_DRIVE_PARAMETERS, 0,
-                            (identifyData->NumberOfHeads - 1), 0,
-                            (UCHAR)identifyData->SectorsPerTrack, 0, ATA_WAIT_IDLE);
-
-    statusByte = UniataIsIdle(deviceExtension, statusByte);
-    if(statusByte & IDE_STATUS_ERROR) {
-        errorByte = AtapiReadPort1(&deviceExtension->chan[lChannel], IDX_IO1_i_Error);
-        KdPrint2((PRINT_PREFIX "SetDriveParameters: Error bit set. Status %#x, error %#x\n",
-                    errorByte, statusByte));
-        return FALSE;
-    }
-
-    if(statusByte == IDE_STATUS_IDLE) {
-        return TRUE;
-    }
-
-    return FALSE;
-
-} // end SetDriveParameters()
-
-VOID
-NTAPI
-UniataForgetDevice(
-    PHW_LU_EXTENSION   LunExt
-    )
-{
-    // keep only DFLAGS_HIDDEN flag
-    LunExt->DeviceFlags &= DFLAGS_HIDDEN;
-    LunExt->AtapiReadyWaitDelay = 0;
-} // end UniataForgetDevice()
-
-
-/*++
-
-Routine Description:
-    Reset IDE controller and/or Atapi device.
-    ->HwResetBus
-
-Arguments:
-    HwDeviceExtension - HBA miniport driver's adapter data storage
-
-Return Value:
-    Nothing.
-
-
---*/
-BOOLEAN
-NTAPI
-AtapiResetController(
-    IN PVOID HwDeviceExtension,
-    IN ULONG PathId
-    )
-{
-    KdPrint2((PRINT_PREFIX "AtapiResetController(%x)\n", PathId));
-    return AtapiResetController__(HwDeviceExtension, PathId, RESET_COMPLETE_ALL);
-} // end AtapiResetController()
-
-BOOLEAN
-NTAPI
-AtapiResetController__(
-    IN PVOID HwDeviceExtension,
-    IN ULONG PathId,
-    IN BOOLEAN CompleteType
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    ULONG                numberChannels  = deviceExtension->NumberChannels;
-    PHW_CHANNEL          chan = NULL;
-    ULONG i,j;
-    ULONG MaxLuns;
-    UCHAR statusByte;
-    PSCSI_REQUEST_BLOCK CurSrb;
-    ULONG ChannelCtrlFlags;
-    UCHAR dma_status = 0;
-
-    ULONG slotNumber = deviceExtension->slotNumber;
-    ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
-    ULONG VendorID =  deviceExtension->DevID        & 0xffff;
-#ifdef _DEBUG
-    ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
-#endif
-    //ULONG RevID    =  deviceExtension->RevID;
-    ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
-    //UCHAR tmp8;
-    USHORT tmp16;
-
-    KdPrint2((PRINT_PREFIX "AtapiResetController: Reset IDE %#x/%#x @ %#x\n", VendorID, DeviceID, slotNumber));
-    KdPrint2((PRINT_PREFIX "simplexOnly %d, VM %x\n", deviceExtension->simplexOnly, g_opt_VirtualMachine));
-
-    if(!deviceExtension->simplexOnly && (PathId != CHAN_NOT_SPECIFIED)) {
-        // we shall reset both channels on SimplexOnly devices,
-        // It's not worth doing so on normal controllers
-        j = PathId;
-        numberChannels = min(j+1, deviceExtension->NumberChannels);
-    } else {
-        j=0;
-        numberChannels = deviceExtension->NumberChannels;
-    }
-
-    for (; j < numberChannels; j++) {
-
-        KdPrint2((PRINT_PREFIX "AtapiResetController: Reset lchannel %d[%d]\n", j, deviceExtension->Channel));
-        chan = &(deviceExtension->chan[j]);
-        MaxLuns = chan->NumberLuns;
-        // Save control flags
-        ChannelCtrlFlags = chan->ChannelCtrlFlags;
-        KdPrint2((PRINT_PREFIX "  CompleteType %#x, Luns %d, chan %#x, sptr %#x, flags %#x\n", CompleteType, MaxLuns, chan, &chan, ChannelCtrlFlags));
-        //MaxLuns = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : 2;
-        if(CompleteType != RESET_COMPLETE_NONE) {
-#ifndef UNIATA_CORE
-            while((CurSrb = UniataGetCurRequest(chan))) {
-
-                PHW_LU_EXTENSION     LunExt;
-                PATA_REQ AtaReq = (PATA_REQ)(CurSrb->SrbExtension);
-
-                i = GET_CDEV(CurSrb);
-                KdPrint2((PRINT_PREFIX "  Lun %x\n", i));
-                LunExt = chan->lun[i];
-
-                KdPrint2((PRINT_PREFIX "AtapiResetController: pending SRB %#x, chan %#x\n", CurSrb, chan));
-                if(CurSrb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
-                    KdPrint2((PRINT_PREFIX "  was MechStatus\n"));
-
-                    if(!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED)) {
-                        LunExt->DeviceFlags |= DFLAGS_CHANGER_INITED;
-                        KdPrint2((PRINT_PREFIX "  set DFLAGS_CHANGER_INITED\n"));
-                    }
-                }
-                // Check and see if we are processing an internal srb
-                if (AtaReq->OriginalSrb) {
-                    KdPrint2((PRINT_PREFIX "  restore original SRB %#x\n", AtaReq->OriginalSrb));
-                    AtaReq->Srb = AtaReq->OriginalSrb;
-                    CurSrb->SrbExtension = NULL;
-                    AtaReq->OriginalSrb = NULL;
-                    // NOTE: internal SRB doesn't get to SRB queue !!!
-                    CurSrb = AtaReq->Srb;
-                }
-
-                // Remove current request from queue
-                UniataRemoveRequest(chan, CurSrb);
-
-                // Check if request is in progress.
-                ASSERT(AtaReq->Srb == CurSrb);
-                if (CurSrb) {
-                    // Complete outstanding request with SRB_STATUS_BUS_RESET.
-                    UCHAR CurPathId = CurSrb->PathId;
-                    UCHAR TargetId = CurSrb->TargetId;
-                    UCHAR Lun = CurSrb->Lun;
-
-                    CurSrb->SrbStatus = ((CompleteType == RESET_COMPLETE_ALL) ? SRB_STATUS_BUS_RESET : SRB_STATUS_ABORTED) | SRB_STATUS_AUTOSENSE_VALID;
-                    CurSrb->ScsiStatus = SCSISTAT_CHECK_CONDITION;
-
-                    if (CurSrb->SenseInfoBuffer) {
-
-                        PSENSE_DATA  senseBuffer = (PSENSE_DATA)CurSrb->SenseInfoBuffer;
-                        KdPrint2((PRINT_PREFIX "  senseBuffer %#x, chan %#x, ReqFlags %#x\n", senseBuffer, chan, AtaReq->Flags));
-
-                        senseBuffer->ErrorCode = 0x70;
-                        senseBuffer->Valid     = 1;
-                        senseBuffer->AdditionalSenseLength = 0xb;
-                        if(CompleteType == RESET_COMPLETE_ALL) {
-                            KdPrint2((PRINT_PREFIX "AtapiResetController: report SCSI_SENSE_UNIT_ATTENTION + SCSI_ADSENSE_BUS_RESET\n"));
-                            senseBuffer->SenseKey = SCSI_SENSE_UNIT_ATTENTION;
-                            senseBuffer->AdditionalSenseCode = SCSI_ADSENSE_BUS_RESET;
-                            senseBuffer->AdditionalSenseCodeQualifier = SCSI_SENSEQ_SCSI_BUS;
-                        } else {
-                            KdPrint2((PRINT_PREFIX "AtapiResetController: report SCSI_SENSE_ABORTED_COMMAND\n"));
-                            senseBuffer->SenseKey = SCSI_SENSE_ABORTED_COMMAND;
-                            senseBuffer->AdditionalSenseCode = 0;
-                            senseBuffer->AdditionalSenseCodeQualifier = 0;
-                        }
-                    }
-
-                    if(!ATAPI_DEVICE(chan, i) && AtaReq->bcount && AtaReq->retry < MAX_RETRIES) {
-                        KdPrint2((PRINT_PREFIX "Save IDE retry status %d\n", AtaReq->retry));
-                        LunExt->errLastLba = AtaReq->lba;
-                        LunExt->errBCount = AtaReq->bcount;
-                        LunExt->errRetry = AtaReq->retry+1;
-                        //KdPrint2((PRINT_PREFIX "AtaReq->Flags & REQ_FLAG_RW_MASK = %x (%x)\n", (AtaReq->Flags & REQ_FLAG_RW_MASK), REQ_FLAG_READ));
-                        //KdPrint2((PRINT_PREFIX "ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION = %x (%x)\n", ChannelCtrlFlags & CTRFLAGS_DMA_ACTIVE, CTRFLAGS_DMA_OPERATION));
-                        //KdPrint2((PRINT_PREFIX "g_opt_VirtualMachine = %x (%x)\n", g_opt_VirtualMachine, VM_BOCHS));
-                        if(((AtaReq->Flags & REQ_FLAG_RW_MASK) == REQ_FLAG_READ) &&
-                           (ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) &&
-                           (g_opt_VirtualMachine == VM_BOCHS)) {
-                            KdPrint2((PRINT_PREFIX "set CTRFLAGS_DMA_BEFORE_R on BOCHS\n"));
-                            g_opt_BochsDmaReadWorkaround = TRUE;
-                            g_opt_AtapiNoDma = TRUE;
-                        } else {
-                            KdPrint2((PRINT_PREFIX "do nothing\n"));
-                        }
-                    } else
-                    if(ATAPI_DEVICE(chan, i) && AtaReq->bcount && !AtaReq->retry) {
-                        KdPrint2((PRINT_PREFIX "Save ATAPI retry status %d\n", AtaReq->retry));
-                        LunExt->errLastLba = AtaReq->lba;
-                        LunExt->errBCount = AtaReq->bcount;
-                        LunExt->errRetry = AtaReq->retry+1;
-                        if(((AtaReq->Flags & REQ_FLAG_RW_MASK) == REQ_FLAG_READ) &&
-                           (ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) &&
-                           (g_opt_VirtualMachine == VM_BOCHS)) {
-                            KdPrint2((PRINT_PREFIX "set CTRFLAGS_DMA_BEFORE_R on BOCHS ATAPI\n"));
-                            //g_opt_BochsDmaReadWorkaround = TRUE;
-                            g_opt_AtapiNoDma = TRUE;
-                        } else {
-                            KdPrint2((PRINT_PREFIX "do nothing\n"));
-                        }
-                    } else {
-                        LunExt->errRetry = 0;
-                    }
-
-                    // Clear request tracking fields.
-                    AtaReq->WordsLeft = 0;
-                    AtaReq->DataBuffer = NULL;
-                    AtaReq->TransferLength = 0;
-                    KdPrint2((PRINT_PREFIX "chan %#x\n", chan));
-
-                    ScsiPortNotification(RequestComplete,
-                                         deviceExtension,
-                                         CurSrb);
-
-                    // Indicate ready for next request.
-                    ScsiPortNotification(NextLuRequest,
-                                         deviceExtension, 
-                                         CurPathId,
-                                         TargetId,
-                                         Lun);
-                }
-                if(CompleteType != RESET_COMPLETE_ALL)
-                    break;
-            } // end while()
-#endif //UNIATA_CORE
-        } // end if (!CompleteType != RESET_COMPLETE_NONE)
-
-        // Clear expecting interrupt flag.
-        UniataExpectChannelInterrupt(chan, FALSE);
-        chan->RDP = FALSE;
-        chan->ChannelCtrlFlags = ChannelCtrlFlags & CTRFLAGS_PERMANENT;
-        InterlockedExchange(&(chan->CheckIntr),
-                                      CHECK_INTR_IDLE);
-        
-        for (i = 0; i < MaxLuns; i++) {
-            chan->lun[i]->PowerState = 0;
-        }
-        // Reset controller
-        if(ChipFlags & UNIATA_AHCI) {
-            KdPrint2((PRINT_PREFIX "  AHCI path\n"));
-            if(UniataAhciChanImplemented(deviceExtension, j)) {
-#ifdef _DEBUG
-                UniataDumpAhciPortRegs(chan);
-#endif
-                AtapiDisableInterrupts(deviceExtension, j);
-                UniataAhciReset(HwDeviceExtension, j);
-            } else {
-                KdPrint2((PRINT_PREFIX "  skip not implemented\n"));
-                continue;
-            }
-        } else {
-            KdPrint2((PRINT_PREFIX "  ATA path, chan %#x\n", chan));
-            KdPrint2((PRINT_PREFIX "  disable intr (0)\n"));
-            AtapiDisableInterrupts(deviceExtension, j);
-            KdPrint2((PRINT_PREFIX "  done\n"));
-            switch(VendorID) {
-            case ATA_INTEL_ID: {
-                ULONG mask;
-                ULONG pshift;
-                ULONG timeout;
-                if(!(ChipFlags & UNIATA_SATA)) {
-                    goto default_reset;
-                }
-                if(!UniataIsSATARangeAvailable(deviceExtension, j)) {
-                    goto default_reset;
-                }
-
-#if 0
-                /* ICH6 & ICH7 in compat mode has 4 SATA ports as master/slave on 2 ch's */
-                if(ChipFlags & UNIATA_AHCI) {
-                    mask = 0x0005 << j;
-                } else {
-                    /* ICH5 in compat mode has SATA ports as master/slave on 1 channel */
-                    GetPciConfig1(0x90, tmp8);
-                    if(tmp8 & 0x04) {
-                        mask = 0x0003;
-                    } else {
-                        mask = 0x0001 << j;
-                    }
-                }
-#else
-                mask = 1 << chan->lun[0]->SATA_lun_map;
-                if (MaxLuns > 1) {
-                    mask |= (1 << chan->lun[1]->SATA_lun_map);
-                }
-#endif
-                ChangePciConfig2(0x92, a & ~mask);
-                AtapiStallExecution(10);
-                ChangePciConfig2(0x92, a | mask);
-                timeout = 100;
-
-                /* Wait up to 1 sec for "connect well". */
-                if (ChipFlags & (I6CH | I6CH2)) {
-                    pshift = 8;
-                } else {
-                    pshift = 4;
-                }
-                while (timeout--) {
-                    GetPciConfig2(0x92, tmp16);
-                    if (((tmp16 >> pshift) & mask) == mask) {
-                        GetBaseStatus(chan, statusByte);
-                        if(statusByte != IDE_STATUS_WRONG) {
-                            break;
-                        }
-                    }
-                    AtapiStallExecution(10000);
-                }
-                break; }
-            case ATA_SIS_ID: {
-                KdPrint2((PRINT_PREFIX "  SIS\n"));
-                if(!(ChipFlags & UNIATA_SATA))
-                    goto default_reset;
-                break; }
-#if 0
-            case ATA_NVIDIA_ID: {
-                KdPrint2((PRINT_PREFIX "  nVidia\n"));
-                if(!(ChipFlags & UNIATA_SATA))
-                    goto default_reset;
-                break; }
-#else
-            case ATA_NVIDIA_ID: {
-                ULONG offs;
-                ULONG Channel = deviceExtension->Channel + j;
-                KdPrint2((PRINT_PREFIX "  nVidia\n"));
-                if(!(ChipFlags & UNIATA_SATA)) {
-                    goto default_reset;
-                }
-                offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010;
-
-                KdPrint2((PRINT_PREFIX "  disable Phy intr, offs %#x, c %u\n", offs, Channel));
-                /* disable device and PHY state change interrupts */
-                if(ChipFlags & NVQ) {
-                    KdPrint2((PRINT_PREFIX "  NVQ, 32bits reg\n"));
-                    AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4, 
-                        AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4) & ((~(ULONG)0x0000000d) << (!Channel*16)) );
-                } else {
-                    AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1, 
-                        AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1) & ((~(UCHAR)0x0d) << (!Channel*4)) );
-                }
-                tmp16 = UniataSataPhyEnable(HwDeviceExtension, j, 0/* dev0*/, UNIATA_SATA_RESET_ENABLE);
-
-                KdPrint2((PRINT_PREFIX "  enable Phy intr, offs %#x\n", offs));
-                /* enable device and PHY state change interrupts */
-                if(ChipFlags & NVQ) {
-                    AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4, 
-                        AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4) | (((ULONG)0x0000000d) << (!Channel*16)) );
-                } else {
-                    AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1, 
-                        AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1) | (((UCHAR)0x0d) << (!Channel*4)) );
-                }
-
-                KdPrint2((PRINT_PREFIX "  dev status %#x\n", tmp16));
-                if(tmp16 != IDE_STATUS_WRONG) {
-                    goto default_reset;
-                }
-                break; }
-#endif //0
-            case ATA_SILICON_IMAGE_ID: {
-                ULONG offset;
-                ULONG Channel = deviceExtension->Channel + j;
-                if(!(ChipFlags & UNIATA_SATA))
-                    goto default_reset;
-                offset = ((Channel & 1) << 7) + ((Channel & 2) << 8);
-                /* disable PHY state change interrupt */
-                AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x148 + offset, 0);
-
-                UniataSataClearErr(HwDeviceExtension, j, UNIATA_SATA_IGNORE_CONNECT, 0);
-
-                /* reset controller part for this channel */
-                AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x48,
-                     AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x48) | (0xc0 >> Channel));
-                AtapiStallExecution(1000);
-                AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x48,
-                     AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x48) & ~(0xc0 >> Channel));
-
-
-                break; }
-            case ATA_PROMISE_ID: {
-                break; }
-            default:
-                if(ChipFlags & UNIATA_SATA) {
-                    KdPrint2((PRINT_PREFIX "  SATA generic reset\n"));
-                    UniataSataClearErr(HwDeviceExtension, j, UNIATA_SATA_IGNORE_CONNECT, 0);
-                }
-default_reset:
-/*
-                AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_DISABLE_INTERRUPTS |
-                                                                        IDE_DC_RESET_CONTROLLER );
-                chan->last_devsel = -1;
-                KdPrint2((PRINT_PREFIX "  wait a little\n"));
-                AtapiStallExecution(10000);
-                // Disable interrupts
-                KdPrint2((PRINT_PREFIX "  disable intr\n"));
-                AtapiDisableInterrupts(deviceExtension, j);
-                AtapiStallExecution(100);
-                KdPrint2((PRINT_PREFIX "  re-enable intr\n"));
-                AtapiEnableInterrupts(deviceExtension, j);
-                KdPrint2((PRINT_PREFIX "  wait a little (2)\n"));
-                AtapiStallExecution(100000);
-*/
-                AtapiHardReset(chan, TRUE, 100000);
-                KdPrint2((PRINT_PREFIX "  disable intr\n"));
-                AtapiDisableInterrupts(deviceExtension, j);
-                AtapiStallExecution(100);
-                KdPrint2((PRINT_PREFIX "  re-enable intr\n"));
-                AtapiEnableInterrupts(deviceExtension, j);
-                KdPrint2((PRINT_PREFIX "  done\n"));
-
-                break;
-            } // end switch()
-
-            //if(!(ChipFlags & UNIATA_SATA)) {}
-            if(!UniataIsSATARangeAvailable(deviceExtension, j)) {
-                // Reset DMA engine if active
-                KdPrint2((PRINT_PREFIX "  check DMA engine\n"));
-                dma_status = GetDmaStatus(chan->DeviceExtension, chan->lChannel);
-                KdPrint2((PRINT_PREFIX "  DMA status %#x\n", dma_status));
-                if((ChannelCtrlFlags & CTRFLAGS_DMA_ACTIVE) ||
-                   (dma_status & BM_STATUS_INTR)) {
-                    AtapiDmaDone(HwDeviceExtension, 0, j, NULL);
-                }
-            }
-        } // ATA vs AHCI
-
-        // all these shall be performed inside AtapiHwInitialize__() ?
-#if 1
-        KdPrint2((PRINT_PREFIX "  process connected devices 0 - %d\n", MaxLuns-1));
-        // Do special processing for ATAPI and IDE disk devices.
-        for (i = 0; i < MaxLuns; i++) {
-
-            // Check if device present.
-            KdPrint2((PRINT_PREFIX "  Chan %#x\n", chan));
-            KdPrint2((PRINT_PREFIX "  Lun %#x\n", i));
-            KdPrint2((PRINT_PREFIX "  Lun ptr %#x\n", chan->lun[i]));
-            if (!(chan->lun[i]->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
-                if(ChipFlags & UNIATA_AHCI) {
-                    // everything is done in UniataAhciReset()
-                    KdPrint2((PRINT_PREFIX "  device have gone\n"));
-                    continue;
-                }
-#ifdef NAVO_TEST
-                continue;
-#else //NAVO_TEST
-                //if(!CheckDevice(HwDeviceExtension, i, j, FALSE))
-                if(!UniataAnybodyHome(HwDeviceExtension, j, i)) {
-                    continue;
-                }
-                if(!CheckDevice(HwDeviceExtension, j, i, TRUE)) {
-                    continue;
-                }
-            } else {
-                if(ChipFlags & UNIATA_AHCI) {
-                    // everything is done in UniataAhciReset()
-                    KdPrint2((PRINT_PREFIX "  found some device\n"));
-
-                    if(!IssueIdentify(HwDeviceExtension,
-                                  i, j,
-                             ATAPI_DEVICE(chan, i) ?
-                                  IDE_COMMAND_ATAPI_IDENTIFY : IDE_COMMAND_IDENTIFY,
-                                  FALSE)) {
-                        KdPrint2((PRINT_PREFIX "  identify failed !\n"));
-                        UniataForgetDevice(chan->lun[i]);
-                    }
-                    continue;
-                }
-                if(!UniataAnybodyHome(HwDeviceExtension, j, i)) {
-                    KdPrint2((PRINT_PREFIX "  device have gone\n"));
-                    UniataForgetDevice(chan->lun[i]);
-                }
-#endif //NAVO_TEST
-            }
-
-            SelectDrive(chan, i);
-            AtapiStallExecution(10);
-            statusByte = WaitOnBusyLong(chan);
-            statusByte = UniataIsIdle(deviceExtension, statusByte);
-            if(statusByte == IDE_STATUS_WRONG) {
-                KdPrint2((PRINT_PREFIX 
-                           "no drive, status %#x\n",
-                           statusByte));
-                UniataForgetDevice(chan->lun[i]);
-            } else
-            // Check for ATAPI disk.
-            if (ATAPI_DEVICE(chan, i)) {
-                // Issue soft reset and issue identify.
-                GetStatus(chan, statusByte);
-                KdPrint2((PRINT_PREFIX "AtapiResetController: Status before Atapi reset (%#x).\n",
-                            statusByte));
-
-                AtapiDisableInterrupts(deviceExtension, j);
-                AtapiSoftReset(chan, i);
-                AtapiEnableInterrupts(deviceExtension, j);
-
-                GetStatus(chan, statusByte);
-
-                if(statusByte != IDE_STATUS_SUCCESS) {
-                    ULONG k;
-                    k = UniataAnybodyHome(deviceExtension, j, i);
-                    if(k == ATA_AT_HOME_HDD) {
-                        // device reset in progress, perform additional wait
-                        KdPrint2((PRINT_PREFIX "  long reset, wait up to 4.5 s\n"));
-                        k = 30 * 1000;
-                        while ((AtapiReadPort1(chan, IDX_IO1_i_Status) & IDE_STATUS_BUSY) &&
-                               k--)
-                        {
-                            AtapiStallExecution(150);
-                        }
-                        KdPrint2((PRINT_PREFIX " exit after %u loops\n", k));
-                        GetStatus(chan, statusByte);
-                    }
-                }
-                if(statusByte == IDE_STATUS_SUCCESS) {
-
-                    IssueIdentify(HwDeviceExtension,
-                                  i, j,
-                                  IDE_COMMAND_ATAPI_IDENTIFY, FALSE);
-                } else {
-
-                    KdPrint2((PRINT_PREFIX 
-                               "AtapiResetController: Status after soft reset %#x\n",
-                               statusByte));
-                }
-                GetBaseStatus(chan, statusByte);
-
-            } else {
-                // Issue identify and reinit after channel reset.
-
-                if (statusByte != IDE_STATUS_IDLE &&
-                    statusByte != IDE_STATUS_SUCCESS &&
-                    statusByte != IDE_STATUS_DRDY) {
-//                    result2 = FALSE;
-                    KdPrint2((PRINT_PREFIX "AtapiResetController: IdeHardReset failed\n"));
-                } else
-                if(!IssueIdentify(HwDeviceExtension,
-                                  i, j,
-                                  IDE_COMMAND_IDENTIFY, FALSE)) {
-//                    result2 = FALSE;
-                    KdPrint2((PRINT_PREFIX "AtapiResetController: IDE IssueIdentify failed\n"));
-                } else
-                // Set disk geometry parameters.
-                if (!SetDriveParameters(HwDeviceExtension, i, j)) {
-                    KdPrint2((PRINT_PREFIX "AtapiResetController: SetDriveParameters failed\n"));
-                }
-                GetBaseStatus(chan, statusByte);
-            }
-            // force DMA mode reinit
-            KdPrint2((PRINT_PREFIX " set DFLAGS_REINIT_DMA\n"));
-            chan->lun[i]->DeviceFlags |= DFLAGS_REINIT_DMA;
-        }
-#endif //0
-
-        // Enable interrupts, note, we can have here recursive disable
-        AtapiStallExecution(10);
-        KdPrint2((PRINT_PREFIX "AtapiResetController: deviceExtension->chan[%d].DisableIntr %d -> 1\n",
-            j,
-            chan->DisableIntr));
-        AtapiEnableInterrupts(deviceExtension, j);
-
-        // Call the HwInitialize routine to setup multi-block.
-        AtapiHwInitialize__(deviceExtension, j);
-    } // for(channel)
-    ScsiPortNotification(NextRequest, deviceExtension, NULL);
-
-    return TRUE;
-
-} // end AtapiResetController__()
-
-
-/*++
-
-Routine Description:
-    This routine maps ATAPI and IDE errors to specific SRB statuses.
-
-Arguments:
-    HwDeviceExtension - HBA miniport driver's adapter data storage
-    Srb - IO request packet
-
-Return Value:
-    SRB status
-
---*/
-ULONG
-NTAPI
-MapError(
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    ULONG lChannel = GET_CHANNEL(Srb);
-    PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
-//    ULONG i;
-    UCHAR errorByte = 0;
-    UCHAR srbStatus = SRB_STATUS_SUCCESS;
-    UCHAR scsiStatus;
-    ULONG DeviceNumber = GET_CDEV(Srb);
-    PHW_LU_EXTENSION     LunExt = chan->lun[DeviceNumber];
-
-    // Read the error register.
-
-    if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
-        if(AtaReq) {
-            errorByte = AtaReq->ahci.in_error;
-        } else {
-        }
-    } else {
-        errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
-    }
-    KdPrint2((PRINT_PREFIX 
-               "MapError: Error register is %#x\n",
-               errorByte));
-
-    if (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
-
-        switch (errorByte >> 4) {
-        case SCSI_SENSE_NO_SENSE:
-
-            KdPrint2((PRINT_PREFIX 
-                       "ATAPI: No sense information\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-            break;
-
-        case SCSI_SENSE_RECOVERED_ERROR:
-
-            KdPrint2((PRINT_PREFIX 
-                       "ATAPI: Recovered error\n"));
-            scsiStatus = 0;
-            srbStatus = SRB_STATUS_SUCCESS;
-            break;
-
-        case SCSI_SENSE_NOT_READY:
-
-            KdPrint2((PRINT_PREFIX 
-                       "ATAPI: Device not ready\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-            break;
-
-        case SCSI_SENSE_MEDIUM_ERROR:
-
-            KdPrint2((PRINT_PREFIX 
-                       "ATAPI: Media error\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-            break;
-
-        case SCSI_SENSE_HARDWARE_ERROR:
-
-            KdPrint2((PRINT_PREFIX 
-                       "ATAPI: Hardware error\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-            break;
-
-        case SCSI_SENSE_ILLEGAL_REQUEST:
-
-            KdPrint2((PRINT_PREFIX 
-                       "ATAPI: Illegal request\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-            break;
-
-        case SCSI_SENSE_UNIT_ATTENTION:
-
-            KdPrint2((PRINT_PREFIX 
-                       "ATAPI: Unit attention\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-            break;
-
-        case SCSI_SENSE_DATA_PROTECT:
-
-            KdPrint2((PRINT_PREFIX 
-                       "ATAPI: Data protect\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-            break;
-
-        case SCSI_SENSE_BLANK_CHECK:
-
-            KdPrint2((PRINT_PREFIX 
-                       "ATAPI: Blank check\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-            break;
-
-        case SCSI_SENSE_ABORTED_COMMAND:
-            KdPrint2((PRINT_PREFIX 
-                        "Atapi: Command Aborted\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-            break;
-
-        default:
-
-            KdPrint2((PRINT_PREFIX 
-                       "ATAPI: Invalid sense information\n"));
-            scsiStatus = 0;
-            srbStatus = SRB_STATUS_ERROR;
-            break;
-        }
-
-    } else {
-
-        scsiStatus = 0;
-
-        // Save errorByte,to be used by SCSIOP_REQUEST_SENSE.
-        chan->ReturningMediaStatus = errorByte;
-
-        if (errorByte & IDE_ERROR_MEDIA_CHANGE_REQ) {
-            KdPrint2((PRINT_PREFIX 
-                       "IDE: Media change\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-
-            if (Srb->SenseInfoBuffer) {
-
-                PSENSE_DATA  senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
-
-                senseBuffer->ErrorCode = 0x70;
-                senseBuffer->Valid     = 1;
-                senseBuffer->AdditionalSenseLength = 0xb;
-                senseBuffer->SenseKey =  SCSI_SENSE_UNIT_ATTENTION;
-                senseBuffer->AdditionalSenseCode = SCSI_ADSENSE_MEDIUM_CHANGED;
-                senseBuffer->AdditionalSenseCodeQualifier = 0;
-
-                srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
-            }
-
-        } else if (errorByte & IDE_ERROR_COMMAND_ABORTED) {
-            KdPrint2((PRINT_PREFIX 
-                       "IDE: Command abort\n"));
-            srbStatus = SRB_STATUS_ABORTED;
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-
-            if (Srb->SenseInfoBuffer) {
-
-                PSENSE_DATA  senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
-
-                senseBuffer->ErrorCode = 0x70;
-                senseBuffer->Valid     = 1;
-                senseBuffer->AdditionalSenseLength = 0xb;
-                senseBuffer->SenseKey =  SCSI_SENSE_ABORTED_COMMAND;
-                senseBuffer->AdditionalSenseCode = 0;
-                senseBuffer->AdditionalSenseCodeQualifier = 0;
-
-                srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
-            }
-
-            LunExt->ErrorCount++;
-
-        } else if (errorByte & IDE_ERROR_END_OF_MEDIA) {
-
-            KdPrint2((PRINT_PREFIX 
-                       "IDE: End of media\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-
-            if (Srb->SenseInfoBuffer) {
-
-                PSENSE_DATA  senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
-
-                senseBuffer->ErrorCode = 0x70;
-                senseBuffer->Valid     = 1;
-                senseBuffer->AdditionalSenseLength = 0xb;
-                senseBuffer->SenseKey =  SCSI_SENSE_UNIT_ATTENTION;
-                senseBuffer->AdditionalSenseCode = SCSI_ADSENSE_MEDIA_STATE;
-                senseBuffer->AdditionalSenseCodeQualifier = SCSI_SENSEQ_END_OF_MEDIUM;
-                senseBuffer->EndOfMedia = 1;
-
-                srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
-            }
-
-            if (!(LunExt->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED)){
-                LunExt->ErrorCount++;
-            }
-
-        } else if (errorByte & IDE_ERROR_ILLEGAL_LENGTH) {
-
-            KdPrint2((PRINT_PREFIX 
-                       "IDE: Illegal length\n"));
-            srbStatus = SRB_STATUS_INVALID_REQUEST;
-
-            if (Srb->SenseInfoBuffer) {
-
-                PSENSE_DATA  senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
-
-                senseBuffer->ErrorCode = 0x70;
-                senseBuffer->Valid     = 1;
-                senseBuffer->AdditionalSenseLength = 0xb;
-                senseBuffer->SenseKey =  SCSI_SENSE_ILLEGAL_REQUEST;
-                senseBuffer->AdditionalSenseCode = SCSI_ADSENSE_INVALID_VALUE;
-                senseBuffer->AdditionalSenseCodeQualifier = SCSI_SENSEQ_PARAM_INVALID_VALUE;
-                senseBuffer->IncorrectLength = 1;
-
-                srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
-            }
-
-        } else if (errorByte & IDE_ERROR_BAD_BLOCK) {
-
-            KdPrint2((PRINT_PREFIX 
-                       "IDE: Bad block\n"));
-            srbStatus = SRB_STATUS_ERROR;
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            if (Srb->SenseInfoBuffer) {
-
-                PSENSE_DATA  senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
-
-                senseBuffer->ErrorCode = 0x70;
-                senseBuffer->Valid     = 1;
-                senseBuffer->AdditionalSenseLength = 0xb;
-                senseBuffer->SenseKey =  SCSI_SENSE_MEDIUM_ERROR;
-                senseBuffer->AdditionalSenseCode = 0;
-                senseBuffer->AdditionalSenseCodeQualifier = 0;
-
-                srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
-            }
-
-        } else if (errorByte & IDE_ERROR_ID_NOT_FOUND) {
-
-            KdPrint2((PRINT_PREFIX 
-                       "IDE: Id not found\n"));
-            srbStatus = SRB_STATUS_ERROR;
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-
-            if (Srb->SenseInfoBuffer) {
-
-                PSENSE_DATA  senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
-
-                senseBuffer->ErrorCode = 0x70;
-                senseBuffer->Valid     = 1;
-                senseBuffer->AdditionalSenseLength = 0xb;
-                senseBuffer->SenseKey =  SCSI_SENSE_MEDIUM_ERROR;
-                senseBuffer->AdditionalSenseCode = 0;
-                senseBuffer->AdditionalSenseCodeQualifier = 0;
-
-                srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
-            }
-
-            LunExt->ErrorCount++;
-
-        } else if (errorByte & IDE_ERROR_MEDIA_CHANGE) {
-
-            KdPrint2((PRINT_PREFIX 
-                       "IDE: Media change\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-
-            if (Srb->SenseInfoBuffer) {
-
-                PSENSE_DATA  senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
-
-                senseBuffer->ErrorCode = 0x70;
-                senseBuffer->Valid     = 1;
-                senseBuffer->AdditionalSenseLength = 0xb;
-                senseBuffer->SenseKey =  SCSI_SENSE_UNIT_ATTENTION;
-                senseBuffer->AdditionalSenseCode = SCSI_ADSENSE_MEDIUM_CHANGED;
-                senseBuffer->AdditionalSenseCodeQualifier = 0;
-
-                srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
-            }
-
-        } else if (errorByte & IDE_ERROR_DATA_ERROR) {
-
-            KdPrint2((PRINT_PREFIX 
-                   "IDE: Data error\n"));
-            scsiStatus = SCSISTAT_CHECK_CONDITION;
-            srbStatus = SRB_STATUS_ERROR;
-
-            if (!(LunExt->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED)){
-                LunExt->ErrorCount++;
-            }
-
-            // Build sense buffer
-            if (Srb->SenseInfoBuffer) {
-
-                PSENSE_DATA  senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
-
-                senseBuffer->ErrorCode = 0x70;
-                senseBuffer->Valid     = 1;
-                senseBuffer->AdditionalSenseLength = 0xb;
-                senseBuffer->SenseKey =  SCSI_SENSE_MEDIUM_ERROR;
-                senseBuffer->AdditionalSenseCode = 0;
-                senseBuffer->AdditionalSenseCodeQualifier = 0;
-
-                srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
-            }
-        }
-
-        if (LunExt->ErrorCount >= MAX_ERRORS) {
-//            deviceExtension->DWordIO = FALSE;
-
-            KdPrint2((PRINT_PREFIX 
-                        "MapError: ErrorCount >= MAX_ERRORS\n"));
-
-            LunExt->DeviceFlags &= ~DFLAGS_DWORDIO_ENABLED;
-            LunExt->MaximumBlockXfer = 0;
-            BrutePoint();
-
-            KdPrint2((PRINT_PREFIX 
-                        "MapError: Disabling 32-bit PIO and Multi-sector IOs\n"));
-
-            // Log the error.
-            KdPrint2((PRINT_PREFIX 
-                        "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d)\n",
-                              HwDeviceExtension,
-                              Srb,
-                              Srb->PathId,
-                              Srb->TargetId,
-                              Srb->Lun,
-                              SP_BAD_FW_WARNING,
-                              4
-                        ));
-            ScsiPortLogError( HwDeviceExtension,
-                              Srb,
-                              Srb->PathId,
-                              Srb->TargetId,
-                              Srb->Lun,
-                              SP_BAD_FW_WARNING,
-                              4);
-
-            // Reprogram to not use Multi-sector.
-            UCHAR statusByte;
-
-            if (LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT &&
-                 !(LunExt->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_MANUAL_CHS))) {
-
-                statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_SET_MULTIPLE, 0, 0, 0, 0, 0, ATA_WAIT_BASE_READY);
-
-                // Check for errors. Reset the value to 0 (disable MultiBlock) if the
-                // command was aborted.
-                if (statusByte & IDE_STATUS_ERROR) {
-
-                    // Read the error register.
-                    errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
-
-                    KdPrint2((PRINT_PREFIX "MapError: Error setting multiple mode. Status %#x, error byte %#x\n",
-                                statusByte,
-                                errorByte));
-
-                    // Adjust the devExt. value, if necessary.
-                    LunExt->MaximumBlockXfer = 0;
-                    BrutePoint();
-
-                }
-            }
-        }
-    }
-
-    // Set SCSI status to indicate a check condition.
-    Srb->ScsiStatus = scsiStatus;
-
-    return srbStatus;
-
-} // end MapError()
-
-
-/*++
-
-Routine Description:
-
-Arguments:
-    HwDeviceExtension - HBA miniport driver's adapter data storage
-    ->HwInitialize
-
-Return Value:
-    TRUE - if initialization successful.
-    FALSE - if initialization unsuccessful.
-
---*/
-BOOLEAN
-NTAPI
-AtapiHwInitialize(
-    IN PVOID HwDeviceExtension
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    ULONG                numberChannels  = deviceExtension->NumberChannels;
-    ULONG c;
-
-    KdPrint2((PRINT_PREFIX "AtapiHwInitialize: (base)\n"));
-
-    if(WinVer_WDM_Model) {
-        AtapiResetController__(HwDeviceExtension, CHAN_NOT_SPECIFIED, RESET_COMPLETE_ALL);
-    }
-    if(deviceExtension->MasterDev) {
-        KdPrint2((PRINT_PREFIX "  mark chan %d of master controller [%x] as inited\n",
-            deviceExtension->Channel, deviceExtension->DevIndex));
-        BMList[deviceExtension->DevIndex].ChanInitOk |= 0x01 << deviceExtension->Channel;
-    }
-
-    /* do extra chipset specific setups */
-    AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, CHAN_NOT_SPECIFIED);
-/*
-    if(deviceExtension->Isr2DevObj && (deviceExtension->HwFlags & UNIATA_SATA)) {
-        KdPrint2((PRINT_PREFIX " enable ISR2 to catch unexpected interrupts\n"));
-        BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
-    }
-*/
-    for (c = 0; c < numberChannels; c++) {
-        AtapiHwInitialize__(deviceExtension, c);
-    }
-    KdPrint2((PRINT_PREFIX "AtapiHwInitialize: (base) done\n"));
-    return TRUE;
-} // end AtapiHwInitialize()
-
-VOID
-NTAPI
-AtapiHwInitialize__(
-    IN PHW_DEVICE_EXTENSION deviceExtension,
-    IN ULONG lChannel
-    )
-{
-    ULONG i;
-    UCHAR statusByte, errorByte;
-    PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
-    PHW_LU_EXTENSION     LunExt;
-//    ULONG tmp32;
-    ULONG PreferedMode = 0xffffffff;
-
-    if((deviceExtension->HwFlags & UNIATA_AHCI) &&
-       !UniataAhciChanImplemented(deviceExtension, lChannel)) {
-        return;
-    }
-
-    AtapiChipInit(deviceExtension, DEVNUM_NOT_SPECIFIED, lChannel);
-    FindDevices(deviceExtension, 0, lChannel);
-
-    for (i = 0; i < chan->NumberLuns; i++) {
-
-        KdPrint3((PRINT_PREFIX "AtapiHwInitialize: lChannel %#x, dev %x\n", lChannel, i));
-
-        LunExt = chan->lun[i];
-        // skip empty slots
-        if (!(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
-            continue;
-        }
-
-        AtapiDisableInterrupts(deviceExtension, lChannel);
-        AtapiStallExecution(1);
-
-        if (!(LunExt->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_MANUAL_CHS))) {
-
-            KdPrint2((PRINT_PREFIX "AtapiHwInitialize: IDE branch\n"));
-            // Enable media status notification
-            IdeMediaStatus(TRUE,deviceExtension,lChannel,(UCHAR)i);
-
-            // If supported, setup Multi-block transfers.
-            statusByte = AtaCommand(deviceExtension, i, lChannel,
-                                IDE_COMMAND_SET_MULTIPLE, 0, 0, 0,
-                                LunExt->MaximumBlockXfer, 0, ATA_WAIT_BASE_READY);
-
-            // Check for errors. Reset the value to 0 (disable MultiBlock) if the
-            // command was aborted.
-            if (statusByte & IDE_STATUS_ERROR) {
-
-                // Read the error register.
-                errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
-
-                KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error setting multiple mode. Status %#x, error byte %#x\n",
-                            statusByte,
-                            errorByte));
-
-                statusByte = AtaCommand(deviceExtension, i, lChannel,
-                                    IDE_COMMAND_SET_MULTIPLE, 0, 0, 0,
-                                    0, 0, ATA_WAIT_BASE_READY);
-
-                if (statusByte & IDE_STATUS_ERROR) {
-                    // Read the error register.
-                    errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
-
-                    KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error disabling multiple mode. Status %#x, error byte %#x\n",
-                                statusByte,
-                                errorByte));
-                }
-                // Adjust the devExt. value, if necessary.
-                LunExt->MaximumBlockXfer = 0;
-
-            } else {
-                KdPrint2((PRINT_PREFIX 
-                            "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n",
-                            i,
-                            LunExt->MaximumBlockXfer));
-            }
-
-            if(LunExt->IdentifyData.MajorRevision) {
-            
-                if(LunExt->opt_ReadCacheEnable) {
-                    KdPrint2((PRINT_PREFIX "  Try Enable Read Cache\n"));
-                    // If supported, setup read/write cacheing
-                    statusByte = AtaCommand(deviceExtension, i, lChannel,
-                                        IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                        0, ATA_C_F_ENAB_RCACHE, ATA_WAIT_BASE_READY);
-
-                    // Check for errors.
-                    if (statusByte & IDE_STATUS_ERROR) {
-                        KdPrint2((PRINT_PREFIX 
-                                    "AtapiHwInitialize: Enable read/write cacheing on Device %d failed\n",
-                                    i));
-                        LunExt->DeviceFlags &= ~DFLAGS_RCACHE_ENABLED;
-                    } else {
-                        LunExt->DeviceFlags |= DFLAGS_RCACHE_ENABLED;
-                    }
-                } else {
-                    KdPrint2((PRINT_PREFIX "  Disable Read Cache\n"));
-                    statusByte = AtaCommand(deviceExtension, i, lChannel,
-                                        IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                        0, ATA_C_F_DIS_RCACHE, ATA_WAIT_BASE_READY);
-                    LunExt->DeviceFlags &= ~DFLAGS_RCACHE_ENABLED;
-                }
-                if(LunExt->IdentifyData.FeaturesSupport.WriteCache) {
-                    if(LunExt->opt_WriteCacheEnable) {
-                        KdPrint2((PRINT_PREFIX "  Try Enable Write Cache\n"));
-                        // If supported & allowed, setup write cacheing
-                        statusByte = AtaCommand(deviceExtension, i, lChannel,
-                                            IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                            0, ATA_C_F_ENAB_WCACHE, ATA_WAIT_BASE_READY);
-                        // Check for errors.
-                        if (statusByte & IDE_STATUS_ERROR) {
-                            KdPrint2((PRINT_PREFIX 
-                                        "AtapiHwInitialize: Enable write cacheing on Device %d failed\n",
-                                        i));
-                            LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
-                        } else {
-                            LunExt->DeviceFlags |= DFLAGS_WCACHE_ENABLED;
-                        }
-                    } else {
-                        KdPrint2((PRINT_PREFIX "  Disable Write Cache\n"));
-                        statusByte = AtaCommand(deviceExtension, i, lChannel,
-                                            IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                            0, ATA_C_F_DIS_WCACHE, ATA_WAIT_BASE_READY);
-                        LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
-                    }
-                }
-
-                if(/*LunExt->IdentifyData.FeaturesSupport.PowerMngt ||*/
-                   LunExt->IdentifyData.FeaturesSupport.APM) {
-
-                    if(LunExt->opt_AdvPowerMode) {
-                        KdPrint2((PRINT_PREFIX "  Try Enable Adv. Power Mgmt\n"));
-                        // setup APM
-                        statusByte = AtaCommand(deviceExtension, i, lChannel,
-                                            IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                            LunExt->opt_AdvPowerMode, ATA_C_F_ENAB_APM, ATA_WAIT_BASE_READY);
-                        // Check for errors.
-                        if (statusByte & IDE_STATUS_ERROR) {
-                            KdPrint2((PRINT_PREFIX 
-                                        "AtapiHwInitialize: Enable APM on Device %d failed\n",
-                                        i));
-                        }
-                    } else {
-                        KdPrint2((PRINT_PREFIX "  Disable Adv. Power Mgmt\n"));
-                        statusByte = AtaCommand(deviceExtension, i, lChannel,
-                                            IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                            0, ATA_C_F_DIS_APM, ATA_WAIT_BASE_READY);
-                    }
-                }
-                if(LunExt->IdentifyData.FeaturesSupport.AutoAcoustic) {
-                    if(LunExt->opt_AcousticMode) {
-                        KdPrint2((PRINT_PREFIX "  Try Enable Acoustic Mgmt\n"));
-                        // setup acoustic mgmt
-                        statusByte = AtaCommand(deviceExtension, i, lChannel,
-                                            IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                            LunExt->opt_AcousticMode, ATA_C_F_ENAB_ACOUSTIC, ATA_WAIT_BASE_READY);
-                        // Check for errors.
-                        if (statusByte & IDE_STATUS_ERROR) {
-                            KdPrint2((PRINT_PREFIX 
-                                        "AtapiHwInitialize: Enable Acoustic Mgmt on Device %d failed\n",
-                                        i));
-                        }
-                    } else {
-                        KdPrint2((PRINT_PREFIX "  Disable Acoustic Mgmt\n"));
-                        statusByte = AtaCommand(deviceExtension, i, lChannel,
-                                            IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                            0, ATA_C_F_DIS_ACOUSTIC, ATA_WAIT_BASE_READY);
-                    }
-                }
-                if(LunExt->IdentifyData.FeaturesSupport.Standby) {
-                    KdPrint2((PRINT_PREFIX "  Try init standby timer: %d\n"));
-                    // setup standby timer
-                    statusByte = AtaCommand(deviceExtension, i, lChannel,
-                                        IDE_COMMAND_IDLE, 0, 0, 0,
-                                        LunExt->opt_StandbyTimer, 0, ATA_WAIT_BASE_READY);
-                    // Check for errors.
-                    if (statusByte & IDE_STATUS_ERROR) {
-                        KdPrint2((PRINT_PREFIX 
-                                    "AtapiHwInitialize: standby timer on Device %d failed\n",
-                                    i));
-                    }
-                }
-            }
-
-        } else if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED)){
-
-            ULONG j;
-            //BOOLEAN isSanyo = FALSE;
-            CCHAR vendorId[26];
-
-            KdPrint2((PRINT_PREFIX "AtapiHwInitialize: ATAPI/Changer branch\n"));
-
-            // Attempt to identify any special-case devices - psuedo-atapi changers, atapi changers, etc.
-            for (j = 0; j < 26; j += 2) {
-
-                // Build a buffer based on the identify data.
-                MOV_DW_SWP(vendorId[j], ((PUCHAR)LunExt->IdentifyData.ModelNumber)[j]);
-            }
-
-            if (!AtapiStringCmp (vendorId, "CD-ROM  CDR", 11)) {
-
-                // Inquiry string for older model had a '-', newer is '_'
-                if (vendorId[12] == 'C') {
-
-                    // Torisan changer. Set the bit. This will be used in several places
-                    // acting like 1) a multi-lun device and 2) building the 'special' TUR's.
-                    LunExt->DeviceFlags |= (DFLAGS_CHANGER_INITED | DFLAGS_SANYO_ATAPI_CHANGER);
-                    LunExt->DiscsPresent = 3;
-                    //isSanyo = TRUE;
-                }
-            }
-        }
-
-        PreferedMode = LunExt->opt_MaxTransferMode;
-        if((PreferedMode == 0xffffffff) || (PreferedMode > chan->MaxTransferMode)) {
-            KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", chan->MaxTransferMode));
-            PreferedMode = chan->MaxTransferMode;
-        }
-
-        if(LunExt->opt_PreferedTransferMode != 0xffffffff) {
-            KdPrint2((PRINT_PREFIX "PreferedTransferMode: %#x\n", PreferedMode));
-            PreferedMode = min(LunExt->opt_PreferedTransferMode, PreferedMode);
-        }
-
-        KdPrint2((PRINT_PREFIX "  try mode %#x\n", PreferedMode));
-        LunExt->LimitedTransferMode =
-        LunExt->TransferMode =
-            (CHAR)PreferedMode;
-
-        AtapiDmaInit__(deviceExtension, LunExt);
-
-        LunExt->LimitedTransferMode =
-            LunExt->TransferMode;
-        KdPrint2((PRINT_PREFIX "Using %#x mode\n", LunExt->TransferMode));
-
-        // We need to get our device ready for action before
-        // returning from this function
-
-        // According to the atapi spec 2.5 or 2.6, an atapi device
-        // clears its status BSY bit when it is ready for atapi commands.
-        // However, some devices (Panasonic SQ-TC500N) are still
-        // not ready even when the status BSY is clear.  They don't react
-        // to atapi commands.
-        //
-        // Since there is really no other indication that tells us
-        // the drive is really ready for action.  We are going to check BSY
-        // is clear and then just wait for an arbitrary amount of time!
-        //
-        if (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
-            ULONG waitCount;
-
-            // have to get out of the loop sometime!
-            // 10000 * 100us = 1000,000us = 1000ms = 1s
-            waitCount = 10000;
-            GetStatus(chan, statusByte);
-            if(statusByte == IDE_STATUS_WRONG) {
-                waitCount = 0;
-            }
-            while ((statusByte & IDE_STATUS_BUSY) && waitCount) {
-
-                KdPrint2((PRINT_PREFIX "Wait for ATAPI (status %x)\n", statusByte));
-                // Wait for Busy to drop.
-                AtapiStallExecution(100);
-                GetStatus(chan, statusByte);
-                waitCount--;
-            }
-
-            // 5000 * 100us = 500,000us = 500ms = 0.5s
-            if(statusByte != IDE_STATUS_WRONG) {
-                waitCount = 5000;
-                do {
-                    AtapiStallExecution(100);
-                } while (waitCount--);
-            }
-        }
-        GetBaseStatus(chan, statusByte);
-        AtapiEnableInterrupts(deviceExtension, lChannel);
-        AtapiStallExecution(10);
-    }
-
-    return;
-
-} // end AtapiHwInitialize__()
-
-
-#ifndef UNIATA_CORE
-
-VOID
-NTAPI
-AtapiHwInitializeChanger(
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb,
-    IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus)
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    ULONG lChannel = GET_CHANNEL(Srb);
-    PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
-    ULONG DeviceNumber = GET_CDEV(Srb);
-    PHW_LU_EXTENSION     LunExt = chan->lun[DeviceNumber];
-
-    if (MechanismStatus) {
-        LunExt->DiscsPresent = MechanismStatus->NumberAvailableSlots;
-        if (LunExt->DiscsPresent > 1) {
-            LunExt->DeviceFlags |= DFLAGS_ATAPI_CHANGER;
-        }
-    }
-    return;
-} // end AtapiHwInitializeChanger()
-
-
-/*++
-
-Routine Description:
-    This routine will parse the string for a match on the keyword, then
-    calculate the value for the keyword and return it to the caller.
-
-Arguments:
-    String - The ASCII string to parse.
-    KeyWord - The keyword for the value desired.
-
-Return Values:
-    Zero if value not found
-    Value converted from ASCII to binary.
-
---*/
-ULONG
-NTAPI
-AtapiParseArgumentString(
-    IN PCCH String,
-    IN PCCH KeyWord
-    )
-{
-    PCCH cptr;
-    PCCH kptr;
-    ULONG value;
-    ULONG stringLength = 0;
-    ULONG keyWordLength = 0;
-    ULONG index;
-
-    if (!String) {
-        return 0;
-    }
-    if (!KeyWord) {
-        return 0;
-    }
-
-    // Calculate the string length and lower case all characters.
-    cptr = String;
-    while (*cptr++) {
-        stringLength++;
-    }
-
-    // Calculate the keyword length.
-    kptr = KeyWord;
-    while (*kptr++) {
-        keyWordLength++;
-    }
-
-    if (keyWordLength > stringLength) {
-
-        // Can't possibly have a match.
-        return 0;
-    }
-
-    // Now setup and start the compare.
-    cptr = String;
-
-ContinueSearch:
-
-    // The input string may start with white space.  Skip it.
-    while (*cptr == ' ' || *cptr == '\t') {
-        cptr++;
-    }
-
-    if (*cptr == '\0') {
-        // end of string.
-        return 0;
-    }
-
-    kptr = KeyWord;
-    while ((*cptr == *kptr) ||
-           (*cptr >= 'A' && *cptr <= 'Z' && *cptr + ('a' - 'A') == *kptr) ||
-           (*cptr >= 'a' && *cptr <= 'z' && *cptr - ('a' - 'A') == *kptr)) {
-        cptr++;
-        kptr++;
-
-        if (*cptr == '\0') {
-            // end of string
-            return 0;
-        }
-    }
-
-    if (*kptr == '\0') {
-
-        // May have a match backup and check for blank or equals.
-        while (*cptr == ' ' || *cptr == '\t') {
-            cptr++;
-        }
-
-        // Found a match.  Make sure there is an equals.
-        if (*cptr != '=') {
-
-            // Not a match so move to the next semicolon.
-            while (*cptr) {
-                if (*cptr++ == ';') {
-                    goto ContinueSearch;
-                }
-            }
-            return 0;
-        }
-        // Skip the equals sign.
-        cptr++;
-
-        // Skip white space.
-        while ((*cptr == ' ') || (*cptr == '\t')) {
-            cptr++;
-        }
-
-        if (*cptr == '\0') {
-            // Early end of string, return not found
-            return 0;
-        }
-
-        if (*cptr == ';') {
-            // This isn't it either.
-            cptr++;
-            goto ContinueSearch;
-        }
-
-        value = 0;
-        if ((*cptr == '0') && ((*(cptr + 1) == 'x') || (*(cptr + 1) == 'X'))) {
-            // Value is in Hex.  Skip the "0x"
-            cptr += 2;
-            for (index = 0; *(cptr + index); index++) {
-
-                if (*(cptr + index) == ' ' ||
-                    *(cptr + index) == '\t' ||
-                    *(cptr + index) == ';') {
-                     break;
-                }
-
-                if ((*(cptr + index) >= '0') && (*(cptr + index) <= '9')) {
-                    value = (16 * value) + (*(cptr + index) - '0');
-                } else {
-                    if ((*(cptr + index) >= 'a') && (*(cptr + index) <= 'f')) {
-                        value = (16 * value) + (*(cptr + index) - 'a' + 10);
-                    } else if ((*(cptr + index) >= 'A') && (*(cptr + index) <= 'F')) {
-                        value = (16 * value) + (*(cptr + index) - 'A' + 10);
-                    } else {
-                        // Syntax error, return not found.
-                        return 0;
-                    }
-                }
-            }
-        } else {
-
-            // Value is in Decimal.
-            for (index = 0; *(cptr + index); index++) {
-
-                if (*(cptr + index) == ' ' ||
-                    *(cptr + index) == '\t' ||
-                    *(cptr + index) == ';') {
-                     break;
-                }
-
-                if ((*(cptr + index) >= '0') && (*(cptr + index) <= '9')) {
-                    value = (10 * value) + (*(cptr + index) - '0');
-                } else {
-
-                    // Syntax error return not found.
-                    return 0;
-                }
-            }
-        }
-
-        return value;
-    } else {
-
-        // Not a match check for ';' to continue search.
-        while (*cptr) {
-            if (*cptr++ == ';') {
-                goto ContinueSearch;
-            }
-        }
-
-        return 0;
-    }
-} // end AtapiParseArgumentString()_
-
-/*
-    Timer callback
-*/
-VOID
-NTAPI
-AtapiCallBack__(
-    IN PVOID HwDeviceExtension,
-    IN UCHAR lChannel
-    )
-{
-
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
-    ULONG c, _c;
-
-    PSCSI_REQUEST_BLOCK  srb = UniataGetCurRequest(chan);
-    UCHAR statusByte;
-
-    KdPrint2((PRINT_PREFIX "AtapiCallBack:\n"));
-    // If the last command was DSC restrictive, see if it's set. If so, the device is
-    // ready for a new request. Otherwise, reset the timer and come back to here later.
-
-    // If ISR decided to wait for BUSY or DRQ in DPC, we shall also get here.
-    // In this case chan->ExpectingInterrupt == TRUE, but interrupts are disabled, thus,
-    // we shall have no problem with interrupt handler.
-    if (!srb || chan->ExpectingInterrupt) {
-        KdPrint2((PRINT_PREFIX "AtapiCallBack: Calling ISR directly due to BUSY\n"));
-        chan->DpcState = DPC_STATE_TIMER;
-        if(!AtapiInterrupt__(HwDeviceExtension, lChannel)) {
-            InterlockedExchange(&(chan->CheckIntr), CHECK_INTR_IDLE);
-            KdPrint2((PRINT_PREFIX "AtapiCallBack: What's fucking this ???\n"));
-        }
-        goto ReturnCallback;
-    }
-
-#ifdef _DEBUG
-    if (!IS_RDP((srb->Cdb[0]))) {
-        KdPrint2((PRINT_PREFIX "AtapiCallBack: Invalid CDB marked as RDP - %#x\n", srb->Cdb[0]));
-    }
-#endif
-    if(!(chan->RDP)) {
-        goto ReturnEnableIntr;
-    }
-    GetStatus(chan, statusByte);
-    if (statusByte & IDE_STATUS_DSC) {
-
-        UCHAR PathId   = srb->PathId;
-        UCHAR TargetId = srb->TargetId;
-        UCHAR Lun      = srb->Lun;
-
-        KdPrint2((PRINT_PREFIX "AtapiCallBack: Found DSC for RDP - %#x\n", srb->Cdb[0]));
-        AtapiDmaDBSync(chan, srb);
-        UniataRemoveRequest(chan, srb);
-        ScsiPortNotification(RequestComplete, deviceExtension, srb);
-        // Clear current SRB.
-        if(!deviceExtension->simplexOnly) {
-            srb = UniataGetCurRequest(chan);
-        } else {
-            srb = NULL;
-        }
-        chan->RDP = FALSE;
-
-        // Ask for next request.
-        ScsiPortNotification(NextLuRequest,
-                             deviceExtension, 
-                             PathId,
-                             TargetId,
-                             Lun);
-        ScsiPortNotification(NextRequest, deviceExtension, NULL);
-
-        if(srb) {
-            AtapiStartIo__(HwDeviceExtension, srb, FALSE);
-        }
-
-    } else {
-        KdPrint2((PRINT_PREFIX "AtapiCallBack: Requesting another timer for Op %#x\n",
-                    srb->Cdb[0]));
-
-        AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
-                             AtapiCallBack_X,
-                             1000);
-
-        goto ReturnCallback;
-    }
-
-ReturnEnableIntr:
-
-    if(CrNtInterlockedExchangeAdd(&(chan->DisableIntr), 0)) {
-        KdPrint2((PRINT_PREFIX "AtapiCallBack: CallDisableInterrupts\n"));
-        //ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
-#ifdef UNIATA_USE_XXableInterrupts
-        chan->ChannelCtrlFlags |= CTRFLAGS_ENABLE_INTR_REQ;
-        // must be called on DISPATCH_LEVEL
-        ScsiPortNotification(CallDisableInterrupts, HwDeviceExtension,
-                             AtapiEnableInterrupts__);
-#else
-        AtapiEnableInterrupts(HwDeviceExtension, lChannel);
-        InterlockedExchange(&(chan->CheckIntr),
-                                      CHECK_INTR_IDLE);
-        // Will raise IRQL to DIRQL
-        AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
-                             AtapiEnableInterrupts__,
-                             1);
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
-#endif // UNIATA_USE_XXableInterrupts
-    } else {
-        //ASSERT(!deviceExtension->simplexOnly);
-    }
-
-ReturnCallback:
-
-    // Check other channel
-    // In simplex mode no interrupts must appear on other channels
-    for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
-        c = (_c+deviceExtension->FirstChannelToCheck) % deviceExtension->NumberChannels;
-
-        if(c == lChannel) {
-            continue;
-        }
-
-        chan = &(deviceExtension->chan[c]);
-
-        if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(chan->CheckIntr),
-                                      CRNT_ILK_TYPE CHECK_INTR_ACTIVE,
-                                      CRNT_ILK_TYPE CHECK_INTR_DETECTED) == CHECK_INTR_DETECTED)
-        {
-            //ASSERT(!deviceExtension->simplexOnly);
-            chan->DpcState = DPC_STATE_ISR;
-            if(!AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
-                InterlockedExchange(&(chan->CheckIntr), CHECK_INTR_IDLE);
-            }
-        }
-    }
-    KdPrint2((PRINT_PREFIX "AtapiCallBack: return\n"));
-    return;
-
-} // end AtapiCallBack__()
-
-VOID
-NTAPI
-AtapiCallBack_X(
-    IN PVOID HwDeviceExtension
-    )
-{
-    AtapiCallBack__(HwDeviceExtension, (UCHAR)((PHW_DEVICE_EXTENSION)HwDeviceExtension)->ActiveDpcChan);
-} // end AtapiCallBack_X()
-
-#endif //UNIATA_CORE
-
-/*++
-
-Routine Description:
-
-    This is the interrupt service routine for ATAPI IDE miniport driver.
-
-Arguments:
-
-    HwDeviceExtension - HBA miniport driver's adapter data storage
-
-Return Value:
-
-    TRUE if expecting an interrupt.
-
---*/
-BOOLEAN
-NTAPI
-AtapiInterrupt(
-    IN PVOID HwDeviceExtension
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    ULONG c, _c;
-    BOOLEAN status = FALSE;
-    ULONG c_state;
-    ULONG i_res = 0;
-    ULONG pass;
-    //BOOLEAN checked[AHCI_MAX_PORT];
-    ULONG hIS;
-    ULONG checked;
-
-    KdPrint2((PRINT_PREFIX "Intr: DeviceID+VendorID/Rev %#x/%#x (ex %d)\n",
-        deviceExtension->DevID, deviceExtension->RevID, deviceExtension->ExpectingInterrupt ));
-
-    if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        // AHCI may generate state change notification, never skip this check
-        hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): AHCI: hIS=%x cntrlr %#x chan %#x\n",hIS, deviceExtension->DevIndex, deviceExtension->Channel));
-        if(!hIS) {
-            return FALSE;
-        }
-        // assume all non-interrupted ports to be already checked
-        checked = ~hIS;
-        // assume all not implemented ports to be already checked
-        checked |= ~deviceExtension->AHCI_PI;
-    } else {
-        checked = 0; // assume all ports are not checked
-    }
-
-    if(!deviceExtension->ExpectingInterrupt) {
-        // if we do not expect interrupt, exit now,
-        // but keep in mind that it can be unexpected one
-        // Note: this is just a hint, not exact counter
-        KdPrint2((PRINT_PREFIX "unexpected, 1st chance\n"));
-        //deviceExtension->ExpectingInterrupt++;
-        //return FALSE;
-    }
-    // clear this flag now, it can be set again in sub-calls
-    deviceExtension->ExpectingInterrupt=0;
-
-
-//    for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
-//        checked[_c] = (UCHAR)((hIS >> _c) & 0x01);
-//    }
-
-//    fc = 
-    for(pass=0; pass<2; pass++) {
-        //KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): pass %d\n", pass));
-        if(status && pass) {
-            // we catched some expected interrupts now.
-            // do not touch unexpected until next ISR call
-            break;
-        }
-        for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
-
-            c = (_c+deviceExtension->FirstChannelToCheck) % deviceExtension->NumberChannels;
-
-            if((checked>>c) & 0x01)
-                continue;
-
-            // check non-empty and expecting interrupt channels first
-            if(!pass && !deviceExtension->chan[c].ExpectingInterrupt)
-                continue;
-
-            checked |= (ULONG)1 << c;
-
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): cntrlr %#x chan %#x\n",deviceExtension->DevIndex, c));
-
-            if(CrNtInterlockedExchangeAdd(&(deviceExtension->chan[c].DisableIntr), 0)) {
-                // we get here on idle channels or when ISR is posted to DPC
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): disabled INTR on ch %d\n", c));
-                continue;
-            }
-            // lock channel. Wait, while 2nd ISR checks interrupt on this channel
-            do {
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): try lock\n"));
-                // c_state = deviceExtension->chan[c].CheckIntr;
-                // if (deviceExtension->chan[c].CheckIntr == CHECK_INTR_DETECTED) {
-                //     deviceExtension->chan[c].CheckIntr = CHECK_INTR_ACTIVE;
-                // }
-                c_state =
-                    (ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
-                                              CRNT_ILK_TYPE CHECK_INTR_ACTIVE,
-                                              CRNT_ILK_TYPE CHECK_INTR_DETECTED);
-                if(c_state == CHECK_INTR_IDLE) {
-                    // c_state = deviceExtension->chan[c].CheckIntr;
-                    // if (deviceExtension->chan[c].CheckIntr == CHECK_INTR_IDLE) {
-                    //     deviceExtension->chan[c].CheckIntr = CHECK_INTR_ACTIVE
-                    // }
-                    c_state =
-                        (ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
-                                                  CRNT_ILK_TYPE CHECK_INTR_ACTIVE,
-                                                  CRNT_ILK_TYPE CHECK_INTR_IDLE);
-                }
-            } while(c_state == CHECK_INTR_CHECK);
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): locked\n"));
-            // check if already serviced
-            if(c_state == CHECK_INTR_ACTIVE) {
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): CHECK_INTR_ACTIVE\n"));
-                continue;
-            }
-
-            if((c_state == CHECK_INTR_DETECTED) ||
-               (i_res = AtapiCheckInterrupt__(deviceExtension, (UCHAR)c))) {
-
-                if(i_res == INTERRUPT_REASON_UNEXPECTED) {
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): Catch unexpected\n"));
-                    InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
-                    //return TRUE;
-                    status = TRUE;
-                    continue;
-                }
-                // disable interrupts on other channel of legacy mode
-                // ISA-bridged onboard controller
-                if(deviceExtension->simplexOnly /*||
-                   ((WinVer_Id() > WinVer_NT) && BMList[deviceExtension->DevIndex].MasterDev)*/) {
-                    AtapiDisableInterrupts(deviceExtension, !c);
-                }
-
-                deviceExtension->chan[c].DpcState = DPC_STATE_ISR;
-                if(AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
-                    deviceExtension->LastInterruptedChannel = (UCHAR)c;
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): return status TRUE\n"));
-                    status = TRUE;
-                } else {
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): set CHECK_INTR_IDLE\n"));
-                    InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
-                }
-
-                // re-enable interrupts on other channel
-                if(deviceExtension->simplexOnly /*||
-                   ((WinVer_Id() > WinVer_NT) && BMList[deviceExtension->DevIndex].MasterDev)*/) {
-                    AtapiEnableInterrupts(deviceExtension, !c);
-                }
-
-            } else {
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): set CHECK_INTR_IDLE (2)\n"));
-                InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
-            }
-
-        }
-    }
-    KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): exit with status %#x\n", status));
-    if(status) {
-        deviceExtension->FirstChannelToCheck++;
-        if(deviceExtension->FirstChannelToCheck >= deviceExtension->NumberChannels)
-            deviceExtension->FirstChannelToCheck = 0;
-    }
-    return status;
-} // end AtapiInterrupt()
-
-//ULONG i2c = 0;
-#ifndef UNIATA_CORE
-
-BOOLEAN
-NTAPI
-AtapiInterrupt2(
-    IN PKINTERRUPT Interrupt,
-    IN PVOID Isr2HwDeviceExtension
-    )
-{
-    // This ISR is intended to catch interrupts when we are already in other ISR instance
-    // for the same device. This may happen when we have multiple channels,
-    // especially on SMP machines
-
-    PISR2_DEVICE_EXTENSION Isr2DeviceExtension = (PISR2_DEVICE_EXTENSION)Isr2HwDeviceExtension;
-    PHW_DEVICE_EXTENSION deviceExtension = Isr2DeviceExtension->HwDeviceExtension;
-    ULONG c;
-    BOOLEAN status = FALSE;
-    ULONG c_count = 0;
-    ULONG i_res;
-    ULONG hIS;
-    ULONG checked;
-
-    // we should never get here for ISA/MCA
-    if(!BMList[deviceExtension->DevIndex].Isr2Enable) {
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt2: NOT ACTIVE cntrlr %#x chan %#x\n",deviceExtension->DevIndex, deviceExtension->Channel));
-        return FALSE;
-    }
-
-    if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        // AHCI may generate state change notification, never skip this check
-        hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt2: AHCI: hIS=%x cntrlr %#x chan %#x\n",hIS, deviceExtension->DevIndex, deviceExtension->Channel));
-        if(!hIS) {
-            return FALSE;
-        }
-        // assume all non-interrupted ports to be already checked
-        checked = ~hIS; 
-        // assume all not implemented ports to be already checked
-        checked |= ~deviceExtension->AHCI_PI;
-
-    } else {
-        checked = 0; // assume all ports are not checked
-    }
-    if(!deviceExtension->ExpectingInterrupt) {
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt2: !deviceExtension->ExpectingInterrupt\n"));
-        deviceExtension->ExpectingInterrupt++;
-        return FALSE;
-    }
-    //deviceExtension->ExpectingInterrupt = 0;
-
-    for(c=0; c<deviceExtension->NumberChannels; c++) {
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt2: cntrlr %#x chan %#x\n",deviceExtension->DevIndex, c));
-
-        if((checked>>c) & 0x01)
-            continue;
-
-        checked |= (ULONG)1 << c;
-
-        if(CrNtInterlockedExchangeAdd(&(deviceExtension->chan[c].DisableIntr), 0)) {
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt2: disabled INTR\n"));
-            continue;
-        }
-
-        if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
-                                      CRNT_ILK_TYPE CHECK_INTR_CHECK,
-                                      CRNT_ILK_TYPE CHECK_INTR_IDLE) != CHECK_INTR_IDLE)
-        {
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt2: !CHECK_INTR_IDLE\n"));
-            // hunt on unexpected intr (Some devices generate double interrupts,
-            // some controllers (at least CMD649) interrupt twice with small delay.
-            // If interrupts are disabled, they queue interrupt and re-issue it later,
-            // when we do not expect it.
-            continue;
-        }
-
-        c_count++;
-        if((i_res = AtapiCheckInterrupt__(deviceExtension, (UCHAR)c))) {
-
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt2: intr\n"));
-            if(i_res == INTERRUPT_REASON_UNEXPECTED) {
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt2: Catch unexpected\n"));
-                InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
-                return TRUE;
-            }
-
-            status = TRUE;
-            InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_DETECTED);
-        } else {
-            InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
-        }
-    }
-    KdPrint2((PRINT_PREFIX "AtapiInterrupt2: status %d, c_count %d\n", status, c_count));
-    if(status && (c_count != deviceExtension->NumberChannels)) {
-        // there is an active ISR/DPC for one channel, but
-        // we have an interrupt from another one
-        // Lets inform current ISR/DPC about new interrupt
-        InterlockedExchange(&(deviceExtension->ReCheckIntr), CHECK_INTR_DETECTED);
-    } else {
-        status = FALSE;
-    }
-    KdPrint2((PRINT_PREFIX "AtapiInterrupt2: return %d\n", status));
-    return status;
-    
-} // end AtapiInterrupt2()
-
-RETTYPE_XXableInterrupts
-NTAPI
-AtapiInterruptDpc(
-    IN PVOID HwDeviceExtension
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    ULONG c;
-
-    for(c=0; c<deviceExtension->NumberChannels; c++) {
-        KdPrint2((PRINT_PREFIX "AtapiInterruptDpc: %#x\n",c));
-
-        if(!(deviceExtension->chan[c].ChannelCtrlFlags & CTRFLAGS_DPC_REQ)) {
-
-            if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
-                                          CRNT_ILK_TYPE CHECK_INTR_ACTIVE,
-                                          CRNT_ILK_TYPE CHECK_INTR_DETECTED) != CHECK_INTR_DETECTED)
-            {
-                continue;
-            }
-                        
-        } else {
-            deviceExtension->chan[c].ChannelCtrlFlags &= ~CTRFLAGS_DPC_REQ;
-        }
-/*
-        if(OldReqState != REQ_STATE_DPC_INTR_REQ) {
-            AtapiDisableInterrupts(deviceExtension, lChannel);
-        }
-*/
-        deviceExtension->chan[c].DpcState = DPC_STATE_DPC;
-        if(!AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
-            InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
-        }
-    }
-    return RETVAL_XXableInterrupts;
-} // end AtapiInterruptDpc()
-
-
-RETTYPE_XXableInterrupts
-NTAPI
-AtapiEnableInterrupts__(
-    IN PVOID HwDeviceExtension
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts__():\n"));
-    ULONG c;
-    PHW_CHANNEL chan = NULL;
-
-    for(c=0; c<deviceExtension->NumberChannels; c++) {
-        KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts__(2): %#x\n",c));
-        chan = &(deviceExtension->chan[c]);
-
-        if(chan->ChannelCtrlFlags & CTRFLAGS_ENABLE_INTR_REQ) {
-            // enable intrs on requested channel
-            chan->ChannelCtrlFlags &= ~CTRFLAGS_ENABLE_INTR_REQ;
-            AtapiEnableInterrupts(HwDeviceExtension, c);
-            InterlockedExchange(&(chan->CheckIntr),
-                                          CHECK_INTR_IDLE);
-
-            // check if current or other channel(s) interrupted
-            //AtapiInterrupt(HwDeviceExtension);
-
-            if(deviceExtension->simplexOnly) {
-                break;
-            }
-        } else {
-            // check if other channel(s) interrupted
-            // must do nothing in simplex mode
-            if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(chan->CheckIntr),
-                                          CRNT_ILK_TYPE CHECK_INTR_ACTIVE,
-                                          CRNT_ILK_TYPE CHECK_INTR_DETECTED) != CHECK_INTR_DETECTED) {
-                continue;
-            }
-            //ASSERT(!deviceExtension->simplexOnly);
-            chan->DpcState = DPC_STATE_ISR;
-            if(!AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
-                InterlockedExchange(&(chan->CheckIntr), CHECK_INTR_IDLE);
-            }
-        }
-    }
-    // In simplex mode next command must be sent to device here
-    if(deviceExtension->simplexOnly && chan) {
-        PSCSI_REQUEST_BLOCK srb;
-        chan = UniataGetNextChannel(chan);
-        if(chan) {
-            srb = UniataGetCurRequest(chan);
-        } else {
-            srb = NULL;
-        }
-        if(srb) {
-            AtapiStartIo__(HwDeviceExtension, srb, FALSE);
-        }
-    }
-
-    return RETVAL_XXableInterrupts;
-
-} // end AtapiEnableInterrupts__()
-
-#endif //UNIATA_CORE
-
-
-VOID
-NTAPI
-AtapiEnableInterrupts(
-    IN PVOID HwDeviceExtension,
-    IN ULONG c
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PHW_CHANNEL chan;
-    //UCHAR statusByte;
-    
-    if(c >= deviceExtension->NumberChannels) {
-        KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: WRONG CHANNEL\n",c));
-        return;
-    }
-    if((deviceExtension->HwFlags & UNIATA_AHCI) &&
-       !UniataAhciChanImplemented(deviceExtension, c)) {
-        KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: not imp. CHANNEL\n",c));
-        return;
-    }
-
-    chan = &(deviceExtension->chan[c]);
-    KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: %d\n",c, chan->DisableIntr));
-    if(!InterlockedDecrement(&chan->DisableIntr)) {
-        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-            UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IE,
-                (ATA_AHCI_P_IX_CPD | ATA_AHCI_P_IX_TFE | ATA_AHCI_P_IX_HBF |
-                 ATA_AHCI_P_IX_HBD | ATA_AHCI_P_IX_INF | ATA_AHCI_P_IX_IF | ATA_AHCI_P_IX_OF |
-                 ((/*ch->pm_level == */0) ? ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC : 0) |
-                 ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC | /* DEBUG */ 
-                 ATA_AHCI_P_IX_DI |
-                 ATA_AHCI_P_IX_DP | ATA_AHCI_P_IX_UF | ATA_AHCI_P_IX_SDB |
-                 ATA_AHCI_P_IX_DS | ATA_AHCI_P_IX_PS | ATA_AHCI_P_IX_DHR)
-                );
-        } else {
-            //SelectDrive(chan, 0);
-            //GetBaseStatus(chan, statusByte);
-            AtapiWritePort1(chan, IDX_IO2_o_Control,
-                                   0 | IDE_DC_A_4BIT );
-            //if(chan->NumberLuns) {
-            //    SelectDrive(chan, 1);
-            //    GetBaseStatus(chan, statusByte);
-            //    AtapiWritePort1(chan, IDX_IO2_o_Control,
-            //                           IDE_DC_A_4BIT );
-            //    SelectDrive(chan, chan->cur_cdev);
-            //}
-        }
-        chan->ChannelCtrlFlags &= ~CTRFLAGS_INTR_DISABLED;
-    } else {
-        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-            // keep interrupts disabled
-            UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IE, 0);
-        } else {
-            AtapiWritePort1(chan, IDX_IO2_o_Control,
-                               IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
-        }
-    }
-    return;
-} // end AtapiEnableInterrupts()
-
-VOID
-NTAPI
-AtapiDisableInterrupts(
-    IN PVOID HwDeviceExtension,
-    IN ULONG c
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PHW_CHANNEL chan;
-    if(c >= deviceExtension->NumberChannels) {
-        KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: WRONG CHANNEL\n",c));
-        return;
-    }
-    chan = &(deviceExtension->chan[c]);
-    KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: %d\n",c, chan->DisableIntr));
-    // mark channel as busy
-    if(InterlockedIncrement(&chan->DisableIntr)) {
-        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-            UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IE, 0);
-        } else {
-            //SelectDrive(chan, 0);
-            AtapiWritePort1(chan, IDX_IO2_o_Control,
-                                   IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
-            //if(chan->NumberLuns) {
-            //    SelectDrive(chan, 1);
-            //    AtapiWritePort1(chan, IDX_IO2_o_Control,
-            //                           IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
-            //    SelectDrive(chan, chan->cur_cdev);
-            //}
-        }
-        chan->ChannelCtrlFlags |= CTRFLAGS_INTR_DISABLED;
-    }
-
-    return;
-} // end AtapiDisableInterrupts()
-
-VOID
-UniataExpectChannelInterrupt(
-    IN struct _HW_CHANNEL* chan,
-    IN BOOLEAN Expecting
-    )
-{
-    chan->ExpectingInterrupt = Expecting;
-    if(Expecting) {
-        chan->DeviceExtension->ExpectingInterrupt++;
-    } else
-    if(chan->DeviceExtension->ExpectingInterrupt) {
-        chan->DeviceExtension->ExpectingInterrupt--;
-    }
-    return;
-} // end UniataExpectChannelInterrupt()
-
-/*
-    Check hardware for interrupt state
- */
-BOOLEAN
-NTAPI
-AtapiCheckInterrupt__(
-    IN PVOID HwDeviceExtension,
-    IN UCHAR c // logical channel
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PHW_CHANNEL chan = &(deviceExtension->chan[c]);
-    PHW_LU_EXTENSION LunExt;
-
-    ULONG VendorID  = deviceExtension->DevID & 0xffff;
-    ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
-
-    ULONG status;
-    ULONG pr_status = 0;
-    UCHAR dma_status = 0;
-    UCHAR reg8 = 0;
-    ULONG reg32 = 0;
-    UCHAR statusByte = 0;
-    ULONG slotNumber = deviceExtension->slotNumber;
-    ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
-    ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
-    UCHAR Channel;
-    UCHAR lChannel;
-    BOOLEAN DmaTransfer = FALSE;
-    BOOLEAN OurInterrupt = FALSE;
-    BOOLEAN StatusValid = FALSE;
-//    ULONG k;
-    UCHAR interruptReason;
-    BOOLEAN EarlyIntr = FALSE;
-    BOOLEAN SingleBlockIntr = FALSE;
-
-    KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__:\n"));
-
-    lChannel = c;
-    Channel = (UCHAR)(deviceExtension->Channel + lChannel);
-    LunExt = chan->lun[chan->cur_cdev];
-
-    //KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__ chan %#x:\n", chan));
-    //KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__ (%d/%d):\n", Channel, chan->cur_cdev));
-
-    if((ChipFlags & UNIATA_AHCI) &&
-        UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
-
-        if(!UniataAhciChanImplemented(deviceExtension, lChannel)) {
-            return OurInterrupt;
-        }
-
-        OurInterrupt = UniataAhciStatus(HwDeviceExtension, lChannel, DEVNUM_NOT_SPECIFIED);
-        if((OurInterrupt == INTERRUPT_REASON_UNEXPECTED) &&
-           (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE)) {
-            UniataAhciWaitCommandReady(chan, 2 /* ms */ );
-            statusByte = (UCHAR)UniataAhciWaitReady(chan, 0 /* immediate */);
-            if(!(statusByte & (IDE_STATUS_BUSY)) ) {
-                KdPrint2((PRINT_PREFIX "ATAPI special case READY\n"));
-                //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
-                OurInterrupt = INTERRUPT_REASON_OUR;
-            } else
-            if((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRDY)) == (IDE_STATUS_BUSY | IDE_STATUS_DRDY) ) {
-                KdPrint2((PRINT_PREFIX "ATAPI special case pre ERR-READY\n"));
-                OurInterrupt = INTERRUPT_REASON_OUR;
-            } else
-            if(statusByte & IDE_STATUS_ERROR) {
-                KdPrint2((PRINT_PREFIX "ATAPI special case ERR-READY\n"));
-                OurInterrupt = INTERRUPT_REASON_OUR;
-            } else {
-                KdPrint2((PRINT_PREFIX "ATAPI special case ? %x\n", statusByte));
-                OurInterrupt = INTERRUPT_REASON_OUR;
-            }
-        }
-        return OurInterrupt;
-    }
-
-    if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_ACTIVE) {
-        DmaTransfer = TRUE;
-        KdPrint2((PRINT_PREFIX "  cntrlr %#x:%#x, lch %#x DmaTransfer = TRUE\n", deviceExtension->DevIndex,
-            deviceExtension->Channel + c, c));
-    } else {
-        KdPrint2((PRINT_PREFIX "  cntrlr %#x:%#x, lch %#x DmaTransfer = FALSE\n", deviceExtension->DevIndex,
-            deviceExtension->Channel + c, c));
-        dma_status = GetDmaStatus(deviceExtension, lChannel);
-        KdPrint2((PRINT_PREFIX "  DMA status %#x\n", dma_status));
-    }
-
-    // do controller-specific interrupt servicing staff
-    if(deviceExtension->UnknownDev) {
-        KdPrint2((PRINT_PREFIX "  UnknownDev\n"));
-        goto check_unknown;
-    }
-
-    // Attention !
-    // We can catch (BM_STATUS_ACTIVE + BM_STATUS_INTR) when operation is actually completed
-    // Such behavior was observed with Intel ICH-xxx chips
-    // This condition shall also be treated as 'our interrupt' because of BM_STATUS_INTR flag
-
-    switch(VendorID) {
-
-    case ATA_PROMISE_ID: {
-        switch(ChipType) {
-        case PROLD:
-        case PRNEW:
-            status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x1c);
-            if (!DmaTransfer)
-                break;
-            if (!(status & 
-                  ((Channel) ? 0x00004000 : 0x00000400))) {
-                KdPrint2((PRINT_PREFIX "  Promise old/new unexpected\n"));
-                return INTERRUPT_REASON_IGNORE;
-            }
-            break;
-        case PRTX:
-            AtapiWritePort1(chan, IDX_BM_DeviceSpecific0, 0x0b);
-            status = AtapiReadPort1(chan, IDX_BM_DeviceSpecific1);
-            if (!DmaTransfer)
-                break;
-            if(!(status & 0x20)) {
-                KdPrint2((PRINT_PREFIX "  Promise tx unexpected\n"));
-                return INTERRUPT_REASON_IGNORE;
-            }
-            break;
-        case PRMIO: {
-            ULONG stat_reg = (ChipFlags & PRG2) ? 0x60 : 0x6c;
-            status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x40);
-            AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x40, status);
-
-            if(status & (1 << (Channel+1))) {
-                // our
-            } else {
-                KdPrint2((PRINT_PREFIX "  Promise mio unexpected\n"));
-                return INTERRUPT_REASON_IGNORE;
-            }
-
-            if(!(ChipFlags & UNIATA_SATA))
-                break;
-
-            pr_status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),stat_reg);
-            AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),stat_reg, (pr_status & (0x11 << Channel)));
-            if(pr_status & (0x11 << Channel)) {
-                // TODO: reset channel
-                KdPrint2((PRINT_PREFIX "  Promise mio unexpected + reset req\n"));
-                UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH, 0);
-            }
-            if(!(status & (0x01 << Channel))) {
-                // Connect event
-                KdPrint2((PRINT_PREFIX "  Promise mio unexpected attach\n"));
-                UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH, 0);
-            }
-            if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
-                OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
-            } else {
-                return INTERRUPT_REASON_IGNORE;
-            }
-
-            AtapiWritePort4(chan, IDX_BM_DeviceSpecific0, 0x00000001);
-            break; }
-        }
-        break; }
-    case ATA_NVIDIA_ID: {
-        if(!(ChipFlags & UNIATA_SATA))
-            break;
-
-        KdPrint2((PRINT_PREFIX "NVIDIA\n"));
-
-        ULONG offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010;
-        ULONG shift = Channel * ((ChipFlags & NVQ) ? 4 : 16);
-
-        /* get and clear interrupt status */
-        if(ChipFlags & NVQ) {
-            pr_status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs);
-            AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, (0x0fUL << shift) | 0x00f000f0);
-        } else {
-            pr_status = AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs);
-            AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, (0x0f << shift));
-        }
-        KdPrint2((PRINT_PREFIX "  pr_status %x, shift %x\n", pr_status, shift));
-
-        /* check for and handle connect events */
-        if(((pr_status & (0x0cUL << shift)) == (0x04UL << shift)) ) {
-            UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH, 0);
-        }
-        /* check for and handle disconnect events */
-        if((pr_status & (0x08UL << shift)) &&
-            !((pr_status & (0x04UL << shift) &&
-            UniataSataReadPort4(chan, IDX_SATA_SStatus, 0))) ) {
-            UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH, 0);
-        }
-        /* do we have any device action ? */
-        if(!(pr_status & (0x01UL << shift))) {
-            KdPrint2((PRINT_PREFIX "  nVidia unexpected\n"));
-            if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
-                OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
-            } else {
-                return INTERRUPT_REASON_IGNORE;
-            }
-        }
-
-        break; }
-    case ATA_ATI_ID:
-        KdPrint2((PRINT_PREFIX "ATI\n"));
-        if(ChipType == SIIMIO) {
-            // fall to SiI
-        } else {
-            break;
-        }
-    case ATA_SILICON_IMAGE_ID:
-
-        if(ChipType == SIIMIO) {
-
-            reg32 = AtapiReadPort4(chan, IDX_BM_DeviceSpecific0);
-            KdPrint2((PRINT_PREFIX "  Sii DS0 %x\n", reg32));
-            if(reg32 == 0xffffffff) {
-                KdPrint2((PRINT_PREFIX "  Sii mio unexpected\n"));
-                return INTERRUPT_REASON_IGNORE;
-            }
-            if(!(reg32 & (BM_DS0_SII_DMA_SATA_IRQ | BM_DS0_SII_DMA_COMPLETE | BM_DS0_SII_IRQ | BM_DS0_SII_DMA_ENABLE | BM_DS0_SII_DMA_ERROR))) {
-                KdPrint2((PRINT_PREFIX "  Sii mio unexpected (2)\n"));
-                return INTERRUPT_REASON_IGNORE;
-            }
-
-            if(ChipFlags & UNIATA_SATA) {
-                if(reg32 & (BM_DS0_SII_DMA_SATA_IRQ | BM_DS0_SII_IRQ)) {
-
-                    /* SIEN doesn't mask SATA IRQs on some 3112s.  Those
-                    * controllers continue to assert IRQ as long as
-                    * SError bits are pending.  Clear SError immediately.
-                    */
-                    if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
-                        OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
-                    }
-                }
-            }
-
-            if (!DmaTransfer)
-                break;
-            if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
-                KdPrint2((PRINT_PREFIX "  Sii mio unexpected (3)\n"));
-                return OurInterrupt;
-            }
-            AtapiWritePort1(chan, IDX_BM_Status, dma_status & ~BM_STATUS_ERR);
-            goto skip_dma_stat_check;
-
-        } else {
-            if(!(deviceExtension->HwFlags & SIIINTR))
-                break;
-            GetPciConfig1(0x71, reg8);
-            KdPrint2((PRINT_PREFIX "  0x71 = %#x\n", reg8));
-            if (!(reg8 &
-                  (Channel ? 0x08 : 0x04))) {
-                return INTERRUPT_REASON_IGNORE;
-            }
-            if (!DmaTransfer) {
-                KdPrint2((PRINT_PREFIX "  cmd our\n"));
-                OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
-            }
-            SetPciConfig1(0x71, (Channel ? 0x08 : 0x04));
-        }
-        break;
-
-    case ATA_ACARD_ID:
-        if (!DmaTransfer)
-            break;
-        //dma_status = GetDmaStatus(deviceExtension, lChannel);
-        if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
-            KdPrint2((PRINT_PREFIX "  Acard unexpected\n"));
-            return INTERRUPT_REASON_IGNORE;
-        }
-        AtapiWritePort1(chan, IDX_BM_Status, dma_status | BM_STATUS_INTR);
-        AtapiStallExecution(1);
-        AtapiWritePort1(chan, IDX_BM_Command,
-            AtapiReadPort1(chan, IDX_BM_Command) & ~BM_COMMAND_START_STOP);
-        goto skip_dma_stat_check;
-    case ATA_INTEL_ID:
-        if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
-            if(ChipFlags & UNIATA_AHCI) {
-                // Do nothing here
-            } else
-            if(ChipFlags & UNIATA_SATA) {
-                if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
-                    OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
-                }
-                if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
-                    if(UniataSataClearErr(chan->DeviceExtension, chan->lChannel, UNIATA_SATA_IGNORE_CONNECT, 1)) {
-                        OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
-                    }
-                }
-            }
-        }
-        break;
-    default:
-        if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
-            if(ChipFlags & UNIATA_AHCI) {
-                // Do nothing here
-            } else
-            if(ChipFlags & UNIATA_SATA) {
-                if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
-                    OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
-                }
-            }
-        }
-    }
-check_unknown:
-    KdPrint2((PRINT_PREFIX "  perform generic check\n"));
-    if (DmaTransfer) {
-        if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
-            KdPrint2((PRINT_PREFIX "  DmaTransfer + !BM_STATUS_INTR (%x)\n", dma_status));
-            if(dma_status & BM_STATUS_ERR) {
-                KdPrint2((PRINT_PREFIX "  DmaTransfer + BM_STATUS_ERR -> our\n"));
-                OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
-            } else {
-                KdPrint2((PRINT_PREFIX "  getting status...\n"));
-                GetStatus(chan, statusByte);
-                StatusValid = 1;
-                KdPrint2((PRINT_PREFIX "  status %#x\n", statusByte));
-                if(statusByte & IDE_STATUS_ERROR) {
-                    KdPrint2((PRINT_PREFIX "  IDE_STATUS_ERROR -> our\n", statusByte));
-                    OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
-                } else
-                if ((statusByte & IDE_STATUS_DSC) &&
-                    (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
-                    (dma_status == BM_STATUS_ACTIVE)) {
-                    KdPrint2((PRINT_PREFIX "  special case DMA + ATAPI + IDE_STATUS_DSC -> our\n", statusByte));
-                    // some devices interrupts on each block transfer even in DMA mode
-                    if(LunExt->TransferMode >= ATA_SDMA && LunExt->TransferMode <= ATA_WDMA2) {
-                        KdPrint2((PRINT_PREFIX "  wait for completion\n"));
-                        ///* clear interrupt and get status */
-                        //GetBaseStatus(chan, statusByte);
-                        //return INTERRUPT_REASON_IGNORE;
-                        SingleBlockIntr = TRUE;
-                    }
-                } else {
-                    return INTERRUPT_REASON_IGNORE;
-                }
-            }
-        }
-    } else {
-        if(dma_status & BM_STATUS_INTR) {
-            // bullshit, we have DMA interrupt, but had never initiate DMA operation
-            KdPrint2((PRINT_PREFIX "  clear unexpected DMA intr\n"));
-            AtapiDmaDone(deviceExtension, DEVNUM_NOT_SPECIFIED ,lChannel, NULL);
-            // catch it !
-            OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
-        }
-    }
-skip_dma_stat_check:
-    if(!(ChipFlags & UNIATA_SATA) && chan->ExpectingInterrupt) {
-        AtapiStallExecution(1);
-    }
-
-    /* if drive is busy it didn't interrupt */
-    /* the exception is DCS + BSY state of ATAPI devices */
-    if(!StatusValid) {
-        KdPrint2((PRINT_PREFIX "  getting status...\n"));
-        GetStatus(chan, statusByte);
-    }
-    if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
-        KdPrint3((PRINT_PREFIX "  ATAPI status %#x\n", statusByte));
-    } else {
-        KdPrint2((PRINT_PREFIX "  IDE status %#x\n", statusByte));
-    }
-    if (statusByte == IDE_STATUS_WRONG) {
-        // interrupt from empty controller ?
-    } else 
-    if (statusByte & IDE_STATUS_BUSY) {
-        if(!chan->ExpectingInterrupt) {
-            KdPrint3((PRINT_PREFIX "  unexpected intr + BUSY\n"));
-            return OurInterrupt;
-        }
-
-        if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
-            KdPrint2((PRINT_PREFIX "  ATAPI additional check\n"));
-        } else {
-            KdPrint2((PRINT_PREFIX "  expecting intr + BUSY (3), non ATAPI\n"));
-            return INTERRUPT_REASON_IGNORE;
-        }
-        if((statusByte & ~(IDE_STATUS_DRQ | IDE_STATUS_INDEX)) !=
-           (IDE_STATUS_BUSY | IDE_STATUS_DRDY | IDE_STATUS_DSC)) {
-            KdPrint3((PRINT_PREFIX "  unexpected status, seems it is not our\n"));
-            return INTERRUPT_REASON_IGNORE;
-        }
-        if(!(LunExt->DeviceFlags & DFLAGS_INT_DRQ) && (statusByte & IDE_STATUS_DRQ)) {
-            KdPrint3((PRINT_PREFIX "  unexpected DRQ, seems it is not our\n"));
-            return INTERRUPT_REASON_IGNORE;
-        }
-
-        EarlyIntr = TRUE;
-
-        if(dma_status & BM_STATUS_INTR) {
-            KdPrint3((PRINT_PREFIX "  our interrupt with BSY set, try wait in ISR or post to DPC\n"));
-            /* clear interrupt and get status */
-            GetBaseStatus(chan, statusByte);
-            if(!(dma_status & BM_STATUS_ACTIVE)) {
-                AtapiDmaDone(deviceExtension, DEVNUM_NOT_SPECIFIED ,lChannel, NULL);
-            }
-            KdPrint3((PRINT_PREFIX "  base status %#x (+BM_STATUS_INTR)\n", statusByte));
-            return INTERRUPT_REASON_OUR;
-        }
-
-        if(g_WaitBusyInISR) {
-            GetStatus(chan, statusByte);
-            KdPrint2((PRINT_PREFIX "  status re-check %#x\n", statusByte));
-            reg8 = AtapiReadPort1(chan, IDX_IO1_i_Error);
-            KdPrint2((PRINT_PREFIX "  Error reg (%#x)\n", reg8));
-            if (!(statusByte & IDE_STATUS_BUSY)) {
-                KdPrint2((PRINT_PREFIX "  expecting intr + cleared BUSY\n"));
-            }
-            if (statusByte & IDE_STATUS_BUSY) {
-                KdPrint2((PRINT_PREFIX "  still BUSY, seems it is not our\n"));
-                return INTERRUPT_REASON_IGNORE;
-            }
-        }
-
-    }
-
-    /* clear interrupt and get status */
-    GetBaseStatus(chan, statusByte);
-    KdPrint2((PRINT_PREFIX "  base status %#x\n", statusByte));
-    if (statusByte == IDE_STATUS_WRONG) {
-        // interrupt from empty controller ?
-    } else 
-    if(!(statusByte & (IDE_STATUS_DRQ | IDE_STATUS_DRDY))) {
-        KdPrint2((PRINT_PREFIX "  no DRQ/DRDY set\n"));
-        return OurInterrupt;
-    }
-
-#ifndef UNIATA_PIO_ONLY
-    if(DmaTransfer) {
-        if(!SingleBlockIntr && (!EarlyIntr || g_WaitBusyInISR)) {
-            dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
-        } else {
-            PSCSI_REQUEST_BLOCK srb = UniataGetCurRequest(chan);
-            PATA_REQ AtaReq = srb ? (PATA_REQ)(srb->SrbExtension) : NULL;
-
-            //ASSERT(AtaReq);
-
-            if(SingleBlockIntr) {
-                KdPrint2((PRINT_PREFIX "  set REQ_STATE_ATAPI_EXPECTING_DATA_INTR2.\n"));
-            } else {
-                KdPrint2((PRINT_PREFIX "  set REQ_STATE_EARLY_INTR.\n"));
-            }
-            if(AtaReq) {
-                AtaReq->ReqState = SingleBlockIntr ? REQ_STATE_ATAPI_EXPECTING_DATA_INTR2 : REQ_STATE_EARLY_INTR;
-            }
-        }
-    }
-#endif //
-
-    if (!(chan->ExpectingInterrupt)) {
-
-        KdPrint2((PRINT_PREFIX "  Unexpected interrupt.\n"));
-
-        if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
-            KdPrint2((PRINT_PREFIX "  ATAPI additional check\n"));
-        } else {
-            KdPrint2((PRINT_PREFIX "  OurInterrupt = %d\n", OurInterrupt));
-            return OurInterrupt;
-        }
-        interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
-        KdPrint3((PRINT_PREFIX "AtapiCheckInterrupt__: ATAPI int reason %x\n", interruptReason));
-        return OurInterrupt;
-    }
-    //ASSERT(!chan->queue_depth || chan->cur_req);
-
-    KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__: exit with TRUE\n"));
-    return INTERRUPT_REASON_OUR;
-
-} // end AtapiCheckInterrupt__()
-
-
-BOOLEAN
-NTAPI
-AtapiInterrupt__(
-    IN PVOID HwDeviceExtension,
-    IN UCHAR c
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PHW_CHANNEL chan = &(deviceExtension->chan[c]);
-    // Get current Srb
-    PSCSI_REQUEST_BLOCK srb = UniataGetCurRequest(chan);
-    PATA_REQ AtaReq = srb ? (PATA_REQ)(srb->SrbExtension) : NULL;
-
-    ULONG wordCount = 0, wordsThisInterrupt = DEV_BSIZE/2;
-    ULONG status = SRB_STATUS_SUCCESS;
-    UCHAR dma_status = 0;
-    ULONG i;
-    ULONG k;
-    UCHAR statusByte = 0,interruptReason;
-
-    BOOLEAN atapiDev = FALSE;
-
-#ifdef _DEBUG
-    UCHAR Channel;
-#endif //_DEBUG
-    UCHAR lChannel;
-    UCHAR DeviceNumber;
-    BOOLEAN DmaTransfer = FALSE;
-    UCHAR error = 0;
-    ULONG TimerValue = 1000;
-    ULONG TotalTimerValue = 0;
-#ifdef UNIATA_USE_XXableInterrupts
-    BOOLEAN InDpc = (KeGetCurrentIrql() == DISPATCH_LEVEL);
-#else
-    BOOLEAN InDpc = (chan->DpcState != DPC_STATE_ISR);
-#endif // UNIATA_USE_XXableInterrupts
-    BOOLEAN UseDpc = deviceExtension->UseDpc;
-//    BOOLEAN RestoreUseDpc = FALSE;
-    BOOLEAN DataOverrun = FALSE;
-    BOOLEAN NoStartIo = TRUE;
-    BOOLEAN NoRetry = FALSE;
-
-    KdPrint2((PRINT_PREFIX "AtapiInterrupt:\n"));
-    if(InDpc) {
-        KdPrint2((PRINT_PREFIX "  InDpc = TRUE\n"));
-        //ASSERT((chan->ChannelCtrlFlags & CTRFLAGS_INTR_DISABLED));
-    }
-
-    UCHAR PathId;
-    UCHAR TargetId;
-    UCHAR Lun;
-    UCHAR OldReqState = REQ_STATE_NONE;
-    //ULONG ldev;
-    PHW_LU_EXTENSION LunExt;
-
-    lChannel = c;
-
-#ifdef _DEBUG
-    Channel = (UCHAR)(deviceExtension->Channel + lChannel);
-
-    KdPrint2((PRINT_PREFIX "  cntrlr %#x:%d, irql %#x, c %d\n", deviceExtension->DevIndex, Channel, KeGetCurrentIrql(), c));
-#endif //_DEBUG
-
-    if((chan->ChannelCtrlFlags & CTRFLAGS_DMA_ACTIVE) ||
-       (AtaReq && (AtaReq->Flags & REQ_FLAG_DMA_OPERATION)) ||
-       (deviceExtension->HwFlags & UNIATA_AHCI)) {
-        DmaTransfer = TRUE;
-        KdPrint2((PRINT_PREFIX "  DmaTransfer = TRUE\n"));
-    }
-
-    if (srb) {
-        PathId   = srb->PathId;  
-        TargetId = srb->TargetId;
-        Lun      = srb->Lun;     
-    } else {
-        PathId = (UCHAR)c;
-        TargetId =
-        Lun      = 0;
-        goto enqueue_next_req;
-    }
-
-    //ldev = GET_LDEV2(PathId, TargetId, Lun);
-    DeviceNumber = (UCHAR)(TargetId);
-    LunExt = chan->lun[DeviceNumber];
-    atapiDev = (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
-    KdPrint2((PRINT_PREFIX "  dev_type %s\n", atapiDev ? "ATAPI" : "IDE"));
-
-    // check if we are in ISR DPC
-    if(InDpc) {
-        KdPrint2((PRINT_PREFIX "  InDpc -> CTRFLAGS_INTR_DISABLED\n"));
-        goto ServiceInterrupt;
-    }
-
-    if (DmaTransfer) {
-        dma_status = GetDmaStatus(deviceExtension, lChannel);
-    }
-
-    if (!(chan->ExpectingInterrupt)) {
-
-        KdPrint2((PRINT_PREFIX "  Unexpected interrupt for this channel.\n"));
-        return FALSE;
-    }
-
-    // change request state
-    if(AtaReq) {
-        OldReqState = AtaReq->ReqState;
-        AtaReq->ReqState = REQ_STATE_PROCESSING_INTR;
-        KdPrint2((PRINT_PREFIX "  OldReqState = %x\n", OldReqState));
-    }
-
-    // We don't want using DPC for fast operations, like
-    // DMA completion, sending CDB, short ATAPI transfers, etc.
-    // !!!! BUT !!!!
-    // We MUST use DPC, because of interprocessor synchronization
-    // on multiprocessor platforms
-
-    if(DmaTransfer)
-        goto ServiceInterrupt;
-
-    switch(OldReqState) {
-    case REQ_STATE_ATAPI_EXPECTING_CMD_INTR:
-        KdPrint3((PRINT_PREFIX "  EXPECTING_CMD_INTR\n"));
-    case REQ_STATE_ATAPI_EXPECTING_DATA_INTR:
-    case REQ_STATE_ATAPI_EXPECTING_DATA_INTR2:
-    case REQ_STATE_DPC_WAIT_BUSY0:
-    case REQ_STATE_DPC_WAIT_BUSY1:
-        KdPrint2((PRINT_PREFIX "  continue service interrupt\n"));
-        goto ServiceInterrupt;
-    case REQ_STATE_ATAPI_DO_NOTHING_INTR:
-        KdPrint2((PRINT_PREFIX "  do nothing on interrupt\n"));
-        return TRUE;
-    }
-
-    if((!DmaTransfer && !atapiDev) || deviceExtension->DriverMustPoll) {
-        KdPrint2((PRINT_PREFIX "  service PIO HDD\n"));
-        UseDpc = FALSE;
-    }
-
-#ifndef UNIATA_CORE
-
-    if(!UseDpc)
-        goto ServiceInterrupt;
-
-#ifdef UNIATA_USE_XXableInterrupts
-    if(InDpc) {
-        KdPrint2((PRINT_PREFIX "  Unexpected InDpc\n"));
-        ASSERT(FALSE);
-        // shall never get here
-        TimerValue = 1;
-        goto CallTimerDpc;
-    }
-
-    KdPrint2((PRINT_PREFIX "  this is direct DPC call on DRQL\n"));
-    if(AtaReq) {
-        AtaReq->ReqState = REQ_STATE_DPC_INTR_REQ;
-        KdPrint2((PRINT_PREFIX "  ReqState -> REQ_STATE_DPC_INTR_REQ\n"));
-    } else {
-        KdPrint2((PRINT_PREFIX "  DPC without AtaReq!!!\n"));
-    }
-#else
-    KdPrint2((PRINT_PREFIX "call service interrupt\n"));
-    goto ServiceInterrupt;
-#endif // UNIATA_USE_XXableInterrupts
-
-PostToDpc:
-
-    // Attention !!!
-    // AtapiInterruptDpc() is called on DISPATCH_LEVEL
-    // We always get here when are called from timer callback, which is invoked on DRQL.
-    // It is intended to lower IRQL and let other interrupts to be serviced while we are waiting for BUSY release
-
-    KdPrint2((PRINT_PREFIX "AtapiInterrupt: start DPC init...\n"));
-    // disable interrupts for this channel,
-    // but avoid recursion and double-disable
-    if(OldReqState != REQ_STATE_DPC_WAIT_BUSY1) {
-        UniataExpectChannelInterrupt(chan, FALSE);
-        AtapiDisableInterrupts(deviceExtension, lChannel);
-    }
-    // go to ISR DPC
-    chan->ChannelCtrlFlags |= CTRFLAGS_DPC_REQ;
-
-#ifdef UNIATA_USE_XXableInterrupts
-    // Will lower IRQL to DISPATCH_LEVEL
-    ScsiPortNotification(CallEnableInterrupts, HwDeviceExtension,
-                         /*c ?*/ AtapiInterruptDpc/*_1 : AtapiInterruptDpc_0*/);
-    KdPrint2((PRINT_PREFIX "AtapiInterrupt: DPC inited\n"));
-#else
-    // Will raise IRQL to DIRQL
-    AtapiQueueTimerDpc(HwDeviceExtension, c,
-                         AtapiInterruptDpc,
-                         TimerValue);
-    KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
-#endif // UNIATA_USE_XXableInterrupts
-    return TRUE;
-
-#ifndef UNIATA_CORE
-CallTimerDpc:
-    AtaReq->ReqState = REQ_STATE_PROCESSING_INTR;
-CallTimerDpc2:
-    if(!InDpc && OldReqState != REQ_STATE_DPC_WAIT_BUSY1) {
-        // we must block interrupts from this channel
-        // If device generate new interrupt before we get to DPC,
-        // ISR will assume, that it is NOT our interrupt
-        AtapiDisableInterrupts(deviceExtension, lChannel);
-        // We should not clean ExpectingInterrupt flag on channel, since it is used in DPC
-    }
-    // Will raise IRQL to DIRQL
-    AtapiQueueTimerDpc(HwDeviceExtension, c,
-                         AtapiCallBack_X,
-                         TimerValue);
-    return TRUE;
-#endif //UNIATA_CORE
-
-ServiceInterrupt:
-
-    if(AtaReq && InDpc) {
-        switch(AtaReq->ReqState) {
-        case REQ_STATE_DPC_WAIT_DRQ0:
-            goto PIO_wait_DRQ0;
-        case REQ_STATE_DPC_WAIT_BUSY:
-            goto PIO_wait_busy;
-        case REQ_STATE_DPC_WAIT_DRQ:
-            goto PIO_wait_DRQ;
-        case REQ_STATE_DPC_WAIT_DRQ_ERR:
-            goto continue_err;
-        case REQ_STATE_DPC_WAIT_BUSY0:
-        case REQ_STATE_DPC_WAIT_BUSY1:
-            // continue normal execution
-            break;
-        }
-    }
-#else
-ServiceInterrupt:
-#endif //UNIATA_CORE
-/*
-    // make additional delay for old devices (if we are not in DPC)
-    if((!LunExt->IdentifyData.MajorRevision || (deviceExtension->lun[DeviceNumber].TransferMode < ATA_PIO4))
-             &&
-       !InDpc &&
-       !atapiDev &&
-       !(deviceExtension->HwFlags & UNIATA_SATA)
-       ) {
-        KdPrint2((PRINT_PREFIX "  additional delay 10us for old devices\n"));
-        AtapiStallExecution(10);
-    }
-*/
-
-    /* clear interrupt and get status */
-    if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, srb);
-        statusByte = (UCHAR)(AtaReq->ahci.in_status & IDE_STATUS_MASK);
-
-        if(chan->AhciLastIS & ~(ATA_AHCI_P_IX_DHR | ATA_AHCI_P_IX_PS | ATA_AHCI_P_IX_DS | ATA_AHCI_P_IX_SDB)) {
-            KdPrint3((PRINT_PREFIX "Err intr (%#x), SE (%#x)\n",
-                chan->AhciLastIS & ~(ATA_AHCI_P_IX_DHR | ATA_AHCI_P_IX_PS | ATA_AHCI_P_IX_DS | ATA_AHCI_P_IX_SDB),
-                chan->AhciLastSError));
-            if(chan->AhciLastIS & ~ATA_AHCI_P_IX_OF) {
-                //KdPrint3((PRINT_PREFIX "Err mask (%#x)\n", chan->AhciLastIS & ~ATA_AHCI_P_IX_OF));
-                // We have some other error except Overflow
-                // Just signal ERROR, operation will be aborted in ERROR branch.
-                statusByte |= IDE_STATUS_ERROR;
-                AtaReq->ahci.in_serror = chan->AhciLastSError;
-                if(chan->AhciLastSError & (ATA_SE_HANDSHAKE_ERR | ATA_SE_LINKSEQ_ERR | ATA_SE_TRANSPORT_ERR | ATA_SE_UNKNOWN_FIS)) {
-                    KdPrint2((PRINT_PREFIX "Unrecoverable\n"));
-                    NoRetry = TRUE;
-                }
-            } else {
-                // We have only Overflow. Abort operation and continue
-#ifdef _DEBUG
-                UniataDumpAhciPortRegs(chan);
-#endif
-                if(!UniataAhciAbortOperation(chan)) {
-                    KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
-                }
-#ifdef _DEBUG
-                UniataDumpAhciPortRegs(chan);
-#endif
-                UniataAhciWaitCommandReady(chan, 10);
-            }
-        }
-
-    } else {
-        GetBaseStatus(chan, statusByte);
-    }
-    if(atapiDev) {
-        KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Entered with status (%#x)\n", statusByte));
-    } else {
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt: Entered with status (%#x)\n", statusByte));
-    }
-
-    if(!UseDpc) {
-        KdPrint2((PRINT_PREFIX "  operate like in DPC\n"));
-        InDpc = TRUE;
-    }
-                                                                       
-    if (!atapiDev) {
-        // IDE
-        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-            KdPrint3((PRINT_PREFIX "  AHCI branch (IDE)\n"));
-        } else
-        if (statusByte & IDE_STATUS_BUSY) {
-            if (deviceExtension->DriverMustPoll) {
-                // Crashdump is polling and we got caught with busy asserted.
-                // Just go away, and we will be polled again shortly.
-                KdPrint2((PRINT_PREFIX "  Hit BUSY while polling during crashdump.\n"));
-                goto ReturnEnableIntr;
-            }
-try_dpc_wait:
-            // Ensure BUSY is non-asserted.
-            // make a very small idle before falling to DPC
-            k = (InDpc && UseDpc) ? 1000 : 2;
-
-            for (i = 0; i < k; i++) {
-
-                GetBaseStatus(chan, statusByte);
-                if (!(statusByte & IDE_STATUS_BUSY)) {
-                    break;
-                }
-                AtapiStallExecution(10);
-            }
-
-            if (!InDpc && UseDpc && i == 2) {
-
-                KdPrint2((PRINT_PREFIX "  BUSY on entry. Status %#x, Base IO %#x\n", statusByte));
-
-                TimerValue = 50;
-                AtaReq->ReqState = REQ_STATE_DPC_WAIT_BUSY0;
-
-#ifndef UNIATA_CORE
-                goto PostToDpc;
-#else //UNIATA_CORE
-                AtapiStallExecution(TimerValue);
-                goto ServiceInterrupt;
-#endif //UNIATA_CORE
-            } else 
-            if (InDpc && i == k) {
-                // reset the controller.
-                KdPrint2((PRINT_PREFIX 
-                            "  Resetting due to BUSY on entry - %#x.\n",
-                            statusByte));
-                goto IntrPrepareResetController;
-            }
-        }
-    } else {
-        // ATAPI
-        if(!LunExt->IdentifyData.MajorRevision &&
-            InDpc &&
-            /*!atapiDev &&*/
-            !(deviceExtension->HwFlags & UNIATA_SATA)
-            ) {
-            //KdPrint2((PRINT_PREFIX "  additional delay 10us for old devices (2)\n"));
-            //AtapiStallExecution(10);
-        }
-        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-            KdPrint3((PRINT_PREFIX "  AHCI branch (ATAPI)\n"));
-        } else {
-            interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
-            KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
-        }
-
-        if (statusByte & IDE_STATUS_BUSY) {
-        //if(chan->ChannelCtrlFlags & CTRFLAGS_DSC_BSY) {}
-/*
-#ifndef UNIATA_CORE
-            // This is just workaround
-            // We should DISABLE interrupts before entering WAIT state
-            UniataExpectChannelInterrupt(chan, TRUE);
-#endif //UNIATA_CORE
-*/
-            KdPrint3((PRINT_PREFIX "  BUSY on ATAPI device, waiting %d us\n", LunExt->AtapiReadyWaitDelay));
-#ifndef UNIATA_CORE
-            if(LunExt->AtapiReadyWaitDelay && (LunExt->AtapiReadyWaitDelay > g_opt_MaxIsrWait) && !InDpc && UseDpc) {
-                TimerValue = LunExt->AtapiReadyWaitDelay;
-                KdPrint2((PRINT_PREFIX "  too long wait: ISR -> DPC (0)\n"));
-                AtaReq->ReqState = REQ_STATE_DPC_WAIT_BUSY0;
-                goto CallTimerDpc2;
-            }
-#endif //UNIATA_CORE
-            TimerValue = 10;
-            for(k=20; k; k--) {
-                GetBaseStatus(chan, statusByte);
-                KdPrint3((PRINT_PREFIX "  status re-check %#x\n", statusByte));
-                KdPrint3((PRINT_PREFIX "  Error reg (%#x)\n",
-                            AtapiReadPort1(chan, IDX_ATAPI_IO1_i_Error)));
-                if (!(statusByte & IDE_STATUS_BUSY)) {
-                    KdPrint2((PRINT_PREFIX "  expecting intr + cleared BUSY\n"));
-                    break;
-                }
-                TotalTimerValue += TimerValue;
-                if(k <= 1) {
-                    KdPrint3((PRINT_PREFIX "  too long wait -> DPC\n"));
-                    if(!InDpc) {
-                        KdPrint2((PRINT_PREFIX "  too long wait: ISR -> DPC\n"));
-                        TimerValue = 100;
-                        AtaReq->ReqState = REQ_STATE_DPC_WAIT_BUSY0;
-                    } else {
-                        KdPrint2((PRINT_PREFIX "  too long wait: DPC -> DPC\n"));
-                        TimerValue = 1000;
-                        AtaReq->ReqState = REQ_STATE_DPC_WAIT_BUSY1;
-                    }
-#ifndef UNIATA_CORE
-                    if(UseDpc) {
-                        if(!LunExt->AtapiReadyWaitDelay) {
-                            LunExt->AtapiReadyWaitDelay = TotalTimerValue*2/3;
-                        }
-                        goto CallTimerDpc2;
-                    }
-#endif //UNIATA_CORE
-                }
-
-                AtapiStallExecution(TimerValue);
-                TimerValue += 10;
-            }
-            if(!LunExt->AtapiReadyWaitDelay) {
-                LunExt->AtapiReadyWaitDelay = TotalTimerValue*2/3;
-                KdPrint2((PRINT_PREFIX "  store AtapiReadyWaitDelay: %d\n", LunExt->AtapiReadyWaitDelay));
-            }
-            if (statusByte & IDE_STATUS_BUSY) {
-                KdPrint3((PRINT_PREFIX "  expecting intr + BUSY (2), try DPC wait\n"));
-                goto try_dpc_wait;
-            }
-        }
-    }
-
-    if(AtaReq && DmaTransfer && !(deviceExtension->HwFlags & UNIATA_AHCI)) {
-        switch(OldReqState) {
-        case REQ_STATE_EARLY_INTR:
-        case REQ_STATE_DPC_WAIT_BUSY0:
-
-            if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_ACTIVE) {
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt: DMA still active\n"));
-                dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
-            }
-            break;
-        }
-    }
-
-//retry_check:
-    // Check for error conditions.
-    if ((statusByte & IDE_STATUS_ERROR) ||
-        (dma_status & BM_STATUS_ERR)) {
-
-        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-            error = AtaReq->ahci.in_error;
-            // wait ready
-#ifdef _DEBUG
-            UniataDumpAhciPortRegs(chan);
-#endif
-            if(!UniataAhciAbortOperation(chan)) {
-                KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
-            }
-            // clear interrupts again
-            UniataAhciWaitCommandReady(chan, 10);
-#ifdef _DEBUG
-            UniataDumpAhciPortRegs(chan);
-#endif
-            UniataAhciStatus(HwDeviceExtension, lChannel, DEVNUM_NOT_SPECIFIED);
-            if(NoRetry) {
-                AtaReq->retry += MAX_RETRIES;
-                if(!error && (statusByte & IDE_STATUS_ERROR)) {
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: force error status\n"));
-                    error |= IDE_STATUS_ERROR;
-                }
-            }
-#ifdef _DEBUG
-            UniataDumpAhciPortRegs(chan);
-#endif
-        } else {
-            error = AtapiReadPort1(chan, IDX_IO1_i_Error);
-        }
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt: Error %#x\n", error));
-/*
-        if(error & IDE_STATUS_CORRECTED_ERROR) {
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: (corrected)\n"));
-            statusByte &= ~IDE_STATUS_ERROR;
-            goto retry_check;
-        }
-*/
-        if(AtaReq) {
-            KdPrint2((PRINT_PREFIX "  Bad Lba %#I64x\n", AtaReq->lba));
-        } else {
-            KdPrint2((PRINT_PREFIX "  Bad Lba unknown\n"));
-        }
-
-        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-            KdPrint2((PRINT_PREFIX "  no wait ready after error\n"));
-        } else
-        if(!atapiDev) {
-            KdPrint2((PRINT_PREFIX "  wait 100 ready after IDE error\n"));
-            AtapiStallExecution(100);
-        } else {
-            KdPrint2((PRINT_PREFIX "  wait 10 ready after ATAPI error\n"));
-            AtapiStallExecution(10);
-        }
-continue_err:
-
-        KdPrint3((PRINT_PREFIX "  Intr on DRQ %x\n",
-            LunExt->DeviceFlags & DFLAGS_INT_DRQ));
-
-        for (k = atapiDev ? 0 : 200; k; k--) {
-            GetBaseStatus(chan, statusByte);
-            if (!(statusByte & IDE_STATUS_DRQ)) {
-                AtapiStallExecution(50);
-            } else {
-                break;
-            }
-        }
-
-        if (!atapiDev) {
-            /* if this is a UDMA CRC error, reinject request */
-
-            AtaReq->retry++;
-            if(AtaReq->retry < MAX_RETRIES) {
-#ifdef IO_STATISTICS
-                chan->lun[DeviceNumber]->ModeErrorCount[AtaReq->retry]++;
-#endif //IO_STATISTICS
-                if(DmaTransfer /*&&
-                   (error & IDE_ERROR_ICRC)*/) {
-                    KdPrint2((PRINT_PREFIX "Errors in DMA mode\n"));
-                    if(AtaReq->retry < MAX_RETRIES) {
-//fallback_pio:
-                        if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
-                            //AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
-                            // Downrate will happen in AtapiDmaReinit(), try UDMA-2 for HDD only
-                            AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
-                        }
-                        AtaReq->ReqState = REQ_STATE_QUEUED;
-                        goto reenqueue_req;
-                    }
-                } else {
-                    if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) {
-                        AtaReq->retry++;
-                    }
-                    KdPrint2((PRINT_PREFIX "Errors in PIO mode\n"));
-                }
-            }
-        } else {
-            interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
-            KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Error, int reason %x\n", interruptReason));
-
-            if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
-                if(deviceExtension->HwFlags & UNIATA_AHCI) {
-                    // Do nothing here
-                } else
-                if(deviceExtension->HwFlags & UNIATA_SATA) {
-                    UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, 0);
-                }
-            }
-
-            if(DmaTransfer && (chan->lun[DeviceNumber]->TransferMode > ATA_UDMA2) &&
-               ((error >> 4) == SCSI_SENSE_HARDWARE_ERROR)) {
-                if(AtaReq->retry < MAX_RETRIES) {
-//fallback_pio:
-                    // Downrate will happen in AtapiDmaReinit(), use PIO immediately for ATAPI
-                    AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
-                    AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
-//                        LunExt->DeviceFlags |= DFLAGS_FORCE_DOWNRATE;
-                    AtaReq->ReqState = REQ_STATE_QUEUED;
-                    goto reenqueue_req;
-                }
-            } else {
-                if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) {
-                    AtaReq->retry++;
-                }
-                KdPrint3((PRINT_PREFIX "Errors in PIO mode\n"));
-            }
-        }
-
-        KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error\n"));
-        if (srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
-            // Fail this request.
-            status = SRB_STATUS_ERROR;
-            goto CompleteRequest;
-        } else {
-            KdPrint2((PRINT_PREFIX "  continue with SCSIOP_REQUEST_SENSE\n"));
-        }
-    } else
-    if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE_LBA48) {
-        KdPrint2((PRINT_PREFIX "DMA doesn't work right with LBA48\n"));
-        deviceExtension->HbaCtrlFlags |= HBAFLAGS_DMA_DISABLED_LBA48;
-    } else
-    if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE) {
-#ifdef IO_STATISTICS
-        KdPrint2((PRINT_PREFIX "Some higher mode doesn't work right :((\n"));
-        KdPrint2((PRINT_PREFIX "Recovery stats[%d]: %d vs %d\n",
-              AtaReq->retry,
-              LunExt->RecoverCount[AtaReq->retry],
-              LunExt->BlockIoCount
-              ));
-        LunExt->RecoverCount[AtaReq->retry]++;
-        if(LunExt->RecoverCount[AtaReq->retry] >= LunExt->BlockIoCount/3 ||
-           (deviceExtension->HwFlags & UNIATA_NO80CHK)
-           ) {
-#else
-        if(deviceExtension->HwFlags & UNIATA_NO80CHK) {
-#endif //IO_STATISTICS
-            KdPrint2((PRINT_PREFIX "Limit transfer rate to %x\n", LunExt->TransferMode));
-            LunExt->LimitedTransferMode =
-                LunExt->TransferMode;
-        }
-    }
-#ifdef IO_STATISTICS
-    if(AtaReq->bcount) {
-        // we need stats for Read/Write operations
-        LunExt->BlockIoCount++;
-    }
-    LunExt->IoCount++;
-#endif //IO_STATISTICS
-
-continue_PIO:
-
-    // check reason for this interrupt.
-    if (atapiDev) {
-
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt: ATAPI branch\n"));
-        // ATAPI branch
-
-        interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
-        KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
-        if(DmaTransfer) {
-            wordsThisInterrupt = DEV_BSIZE/2*512;
-        } else {
-            wordsThisInterrupt = DEV_BSIZE/2;
-        }
-
-    } else {
-
-        // ATA branch
-
-        if(DmaTransfer) {
-            // simulate DRQ for DMA transfers
-            statusByte |= IDE_STATUS_DRQ;
-        }
-        if (statusByte & IDE_STATUS_DRQ) {
-
-            if(DmaTransfer) {
-                wordsThisInterrupt = DEV_BSIZE/2*512;
-            } else
-            if (LunExt->MaximumBlockXfer) {
-                wordsThisInterrupt = DEV_BSIZE/2 * LunExt->MaximumBlockXfer;
-            }
-
-            if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
-
-                interruptReason = ATAPI_IR_IO_toHost;
-
-            } else if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
-                interruptReason = ATAPI_IR_IO_toDev;
-
-            } else {
-                status = SRB_STATUS_ERROR;
-                goto CompleteRequest;
-            }
-
-        } else if (statusByte & IDE_STATUS_BUSY) {
-
-            //AtapiEnableInterrupts(deviceExtension, lChannel);
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: return FALSE on ATA IDE_STATUS_BUSY\n"));
-            return FALSE;
-
-        } else {
-
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: !DRQ, !BUSY, WordsLeft %#x\n", AtaReq->WordsLeft));
-            if (AtaReq->WordsLeft) {
-
-                // Funky behaviour seen with PCI IDE (not all, just one).
-PIO_wait_DRQ0:
-                // The ISR hits with DRQ low, but comes up later.
-                for (k = 0; k < 5000; k++) {
-                    GetBaseStatus(chan, statusByte);
-                    if (statusByte & IDE_STATUS_DRQ) {
-                        break;
-                    }
-                    if(!InDpc) {
-                        // goto DPC
-                        AtaReq->ReqState = REQ_STATE_DPC_WAIT_DRQ0;
-                        TimerValue = 100;
-                        KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (drq0)\n"));
-#ifndef UNIATA_CORE
-                        goto PostToDpc;
-#else //UNIATA_CORE
-                        AtapiStallExecution(TimerValue);
-                        goto ServiceInterrupt;
-#endif //UNIATA_CORE
-                    }
-                    AtapiStallExecution(100);
-                }
-                if (k == 5000) {
-                    // reset the controller.
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: Resetting due to DRQ not up. Status %#x\n",
-                                statusByte));
-IntrPrepareResetController:
-                    AtapiResetController__(HwDeviceExtension, lChannel, RESET_COMPLETE_CURRENT);
-                    goto ReturnEnableIntr;
-
-                } else {
-                    interruptReason = (srb->SrbFlags & SRB_FLAGS_DATA_IN) ? ATAPI_IR_IO_toHost : ATAPI_IR_IO_toDev;
-                }
-
-            } else {
-                // Command complete - verify, write, or the SMART enable/disable.
-                // Also get_media_status
-                interruptReason = ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd;
-            }
-        }
-    }
-
-    KdPrint2((PRINT_PREFIX "AtapiInterrupt: i-reason=%d, status=%#x\n", interruptReason, statusByte));
-    if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        KdPrint2((PRINT_PREFIX "  AHCI path, WordsTransfered %x, WordsLeft %x\n", AtaReq->WordsTransfered, AtaReq->WordsLeft));
-/*        if(chan->AhciLastIS & ATA_AHCI_P_IX_OF) {
-            //status = SRB_STATUS_DATA_OVERRUN;
-            DataOverrun = TRUE;
-        } else {
-            status = SRB_STATUS_SUCCESS;
-        }*/
-        if(AtaReq->WordsTransfered >= AtaReq->WordsLeft) {
-            AtaReq->WordsLeft = 0;
-        } else {
-            AtaReq->WordsLeft -= AtaReq->WordsTransfered;
-        }
-        //if(AtaReq->WordsLeft && (status == SRB_STATUS_SUCCESS)) {
-        //    status = SRB_STATUS_DATA_OVERRUN;
-        //}
-        status = SRB_STATUS_SUCCESS;
-        chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
-        goto CompleteRequest;
-    } else
-    if ((interruptReason == ATAPI_IR_COD_Cmd) && (statusByte & IDE_STATUS_DRQ)) {
-        if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) {
-            AtapiDmaDBPreSync(HwDeviceExtension, chan, srb);
-        }
-        // Write the packet.
-        KdPrint3((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n"));
-        // Send CDB to device.
-        WriteBuffer(chan, (PUSHORT)srb->Cdb, 
-                          LunExt->IdentifyData.AtapiCmdSize ? 8 : 6,
-                          /*0*/ PIO0_TIMING);
-        AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR;
-
-        if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) {
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: AtapiDmaStart().\n"));
-            AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, srb);
-        }
-
-        goto ReturnEnableIntr;
-
-    } else if ((interruptReason == ATAPI_IR_IO_toDev) && (statusByte & IDE_STATUS_DRQ)) {
-
-        // Write the data.
-        if (atapiDev) {
-
-            // Pick up bytes to transfer and convert to words.
-            wordCount =
-                AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountLow);
-
-            wordCount |=
-                (USHORT)AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountHigh) << 8;
-
-            // Covert bytes to words.
-            wordCount >>= 1;
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: get W wordCount %#x\n", wordCount));
-
-            if (wordCount != AtaReq->WordsLeft) {
-                KdPrint2((PRINT_PREFIX 
-                           "AtapiInterrupt: %d words requested; %d words xferred\n",
-                           AtaReq->WordsLeft,
-                           wordCount));
-            }
-
-            // Verify this makes sense.
-            if (wordCount > AtaReq->WordsLeft) {
-                wordCount = AtaReq->WordsLeft;
-                KdPrint2((PRINT_PREFIX 
-                           "AtapiInterrupt: Write underrun\n"));
-                DataOverrun = TRUE;
-            }
-
-        } else {
-
-            // IDE path. Check if words left is at least DEV_BSIZE/2 = 256.
-            if (AtaReq->WordsLeft < wordsThisInterrupt) {
-               // Transfer only words requested.
-               wordCount = AtaReq->WordsLeft;
-            } else {
-               // Transfer next block.
-               wordCount = wordsThisInterrupt;
-            }
-        }
-
-        if (DmaTransfer &&
-            (chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION)) {
-            //ASSERT(AtaReq->WordsLeft == wordCount);
-            if(AtaReq->ReqState == REQ_STATE_ATAPI_EXPECTING_DATA_INTR2) {
-                KdPrint2((PRINT_PREFIX 
-                          "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount));
-                if(AtaReq->WordsLeft > wordCount) {
-                    AtaReq->WordsLeft -= wordCount;
-                    AtaReq->WordsTransfered += wordCount;
-                    AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR;
-                    goto ReturnEnableIntr;
-                }
-                dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
-            }
-            AtaReq->WordsTransfered = AtaReq->WordsLeft;
-            AtaReq->WordsLeft = 0;
-            status = SRB_STATUS_SUCCESS;
-            chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
-            goto CompleteRequest;
-        }
-
-        // Ensure that this is a write command.
-        if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
-
-           KdPrint2((PRINT_PREFIX 
-                      "AtapiInterrupt: Write interrupt\n"));
-
-           statusByte = WaitOnBusy(chan);
-
-            if (/*atapiDev || */ !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/
-                || (wordCount & 1)) {
-
-               WriteBuffer(chan,
-                           AtaReq->DataBuffer,
-                           wordCount,
-                           UniataGetPioTiming(LunExt));
-           } else {
-
-               WriteBuffer2(chan,
-                           (PULONG)(AtaReq->DataBuffer),
-                           wordCount / 2,
-                           UniataGetPioTiming(LunExt));
-           }
-        } else {
-
-            KdPrint3((PRINT_PREFIX 
-                        "AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n",
-                        interruptReason,
-                        srb));
-
-            // Fail this request.
-            status = SRB_STATUS_ERROR;
-            if(!wordCount && atapiDev && (srb->Cdb[0] != SCSIOP_REQUEST_SENSE)) {
-                // some devices feel bad after incorrect commands and may need reset
-                KdPrint2((PRINT_PREFIX 
-                          "AtapiInterrupt: Try ATAPI reset\n"));
-
-                AtapiDisableInterrupts(deviceExtension, lChannel);
-                AtapiSoftReset(chan, DeviceNumber);
-                AtapiEnableInterrupts(deviceExtension, lChannel);
-                status = SRB_STATUS_BUS_RESET;
-                AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-
-//                goto IntrPrepareResetController;
-            }
-            goto CompleteRequest;
-        }
-        // Advance data buffer pointer and bytes left.
-        AtaReq->DataBuffer += wordCount;
-        AtaReq->WordsLeft -= wordCount;
-        AtaReq->WordsTransfered += wordCount;
-
-        if (atapiDev) {
-            AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR;
-        }
-
-        goto ReturnEnableIntr;
-
-    } else if (interruptReason == ATAPI_IR_IO_toHost && (statusByte & IDE_STATUS_DRQ)) {
-
-continue_read_drq:
-
-        if (atapiDev) {
-
-            // Pick up bytes to transfer and convert to words.
-            wordCount =
-                (ULONG)AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountLow) |
-                ((ULONG)AtapiReadPort1(chan, IDX_ATAPI_IO1_i_ByteCountHigh) << 8);
-
-            // Convert bytes to words.
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: get R byteCount %#x\n", wordCount));
-            wordCount >>= 1;            
-            /*
-                When ATAPI 64k PIO read is requested we may have 0xfffe byte 
-                count reported for 0x10000 bytes in single interrupt.
-                It is not allowed to read entire 64k block with DwordIo intead of 
-                wait for last word.
-            */
-            if (wordCount != AtaReq->WordsLeft) {
-                KdPrint2((PRINT_PREFIX 
-                           "AtapiInterrupt: %d words requested; %d words xferred\n",
-                           AtaReq->WordsLeft,
-                           wordCount));
-            }
-
-            // Verify this makes sense.
-            if (wordCount > AtaReq->WordsLeft) {
-                wordCount = AtaReq->WordsLeft;
-                DataOverrun = TRUE;
-            }
-
-        } else {
-
-            // Check if words left is at least 256.
-            if (AtaReq->WordsLeft < wordsThisInterrupt) {
-               // Transfer only words requested.
-               wordCount = AtaReq->WordsLeft;
-            } else {
-               // Transfer next block.
-               wordCount = wordsThisInterrupt;
-            }
-        }
-
-        if(DmaTransfer &&
-           (chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION)) {
-            if(AtaReq->ReqState == REQ_STATE_ATAPI_EXPECTING_DATA_INTR2) {
-                KdPrint2((PRINT_PREFIX 
-                          "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount));
-                if(AtaReq->WordsLeft > wordCount) {
-                    AtaReq->WordsLeft -= wordCount;
-                    AtaReq->WordsTransfered += wordCount;
-                    AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR;
-                    goto ReturnEnableIntr;
-                }
-                dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
-            }
-            //ASSERT(AtaReq->WordsLeft == wordCount);
-            AtaReq->WordsTransfered = AtaReq->WordsLeft;
-            AtaReq->WordsLeft = 0;
-            status = SRB_STATUS_SUCCESS;
-            chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
-            goto CompleteRequest;
-        }
-        // Ensure that this is a read command.
-        if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
-
-/*           KdPrint2((
-                      "AtapiInterrupt: Read interrupt\n"));*/
-
-            statusByte = WaitOnBusy(chan);
-
-            if(wordCount&1 && atapiDev && (g_opt_VirtualMachine == VM_BOCHS)) {
-                KdPrint2((PRINT_PREFIX 
-                          "IdeIntr: unaligned ATAPI %#x Words\n", wordCount));
-            } else
-            if(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) {
-                KdPrint2((PRINT_PREFIX 
-                          "IdeIntr: pre-Read %#x Dwords\n", wordCount/2));
-
-                ReadBuffer2(chan,
-                           (PULONG)(AtaReq->DataBuffer),
-                           wordCount / 2,
-                           UniataGetPioTiming(LunExt));
-                // Advance data buffer pointer and bytes left.
-                AtaReq->DataBuffer += wordCount & ~1;
-                AtaReq->WordsLeft -= wordCount & ~1;
-                AtaReq->WordsTransfered += wordCount & ~1;
-                wordCount &= 1;
-            }
-            if (wordCount) {
-                KdPrint2((PRINT_PREFIX 
-                           "IdeIntr: Read %#x words\n", wordCount));
-
-                ReadBuffer(chan,
-                          AtaReq->DataBuffer,
-                          wordCount,
-                          UniataGetPioTiming(LunExt));
-            }
-
-            KdPrint2(("IdeIntr: PIO Read AtaReq->DataBuffer %#x, srb->DataBuffer %#x\n", AtaReq->DataBuffer, (srb ? srb->DataBuffer : (void*)-1) ));
-            //KdDump(AtaReq->DataBuffer, wordCount*2);
-            if(srb && atapiDev && srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
-                KdDump(AtaReq->DataBuffer, wordCount*2);
-            }
-
-            GetBaseStatus(chan, statusByte);
-            KdPrint2((PRINT_PREFIX "  status re-check %#x\n", statusByte));
-
-            if(DataOverrun) {
-                KdPrint2((PRINT_PREFIX "  DataOverrun\n"));
-                AtapiSuckPort2(chan);
-                GetBaseStatus(chan, statusByte);
-            }
-
-            if(statusByte & IDE_STATUS_BUSY) {
-                for (i = 0; i < 2; i++) {
-                    AtapiStallExecution(10);
-                    GetBaseStatus(chan, statusByte);
-                    if (!(statusByte & IDE_STATUS_BUSY)) {
-                        break;
-                    }
-                }
-            }
-
-        } else {
-
-            KdPrint3((PRINT_PREFIX 
-                        "AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n",
-                        interruptReason,
-                        srb));
-
-            // Fail this request.
-            status = SRB_STATUS_ERROR;
-            goto CompleteRequest;
-        }
-//continue_atapi_pio_read:
-        // Advance data buffer pointer and bytes left.
-        AtaReq->DataBuffer += wordCount;
-        AtaReq->WordsLeft -= wordCount;
-        AtaReq->WordsTransfered += wordCount;
-
-        // Check for read command complete.
-        if (AtaReq->WordsLeft == 0) {
-
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: all transferred, AtaReq->WordsLeft == 0\n"));
-            if (atapiDev) {
-
-                if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM) {
-
-                    // Work around to make many atapi devices return correct sector size
-                    // of 2048. Also certain devices will have sector count == 0x00, check
-                    // for that also.
-                    if (srb->Cdb[0] == SCSIOP_READ_CAPACITY) {
-
-                        AtaReq->DataBuffer -= AtaReq->WordsTransfered;
-                        if (AtaReq->DataBuffer[0] == 0x00) {
-                            *((ULONG *) &(AtaReq->DataBuffer[0])) = 0xFFFFFF7F;
-                        }
-
-                        *((ULONG *) &(AtaReq->DataBuffer[2])) = 0x00080000;
-                        AtaReq->DataBuffer += AtaReq->WordsTransfered;
-                    }
-#ifndef UNIATA_INIT_CHANGERS
-                    else
-                    if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
-
-                        KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status));
-                        // Bingo!!
-                        AtapiHwInitializeChanger (HwDeviceExtension,
-                                                  srb,
-                                                  (PMECHANICAL_STATUS_INFORMATION_HEADER) srb->DataBuffer);
-                        LunExt->DeviceFlags |= DFLAGS_CHANGER_INITED;
-                        KdPrint2((PRINT_PREFIX "  set DFLAGS_CHANGER_INITED\n"));
-                    }
-#endif // UNIATA_INIT_CHANGERS
-                }
-                GetStatus(chan, statusByte);
-                if(!(statusByte & IDE_STATUS_BUSY)) {
-                    // Assume command is completed if BUSY is cleared
-                    // and all data read
-                    // Optionally, we may receive COMPLETE interrupt later and
-                    // treat it as unexpected
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: early complete ? status %x\n", statusByte));
-
-                    status = SRB_STATUS_SUCCESS;
-                    goto CompleteRequest;
-                }
-
-            } else {
-
-            /*
-                // Completion for IDE drives.
-                if (AtaReq->WordsLeft) {
-                    status = SRB_STATUS_DATA_OVERRUN;
-                } else {
-                    status = SRB_STATUS_SUCCESS;
-                }
-
-                goto CompleteRequest;
-            */
-                status = SRB_STATUS_SUCCESS;
-                goto CompleteRequest;
-
-            }
-        } else {
-            if (atapiDev) {
-                AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR;
-                GetStatus(chan, statusByte);
-                if(!(statusByte & IDE_STATUS_BUSY)) {
-                    // Assume command is completed if BUSY is cleared
-                    // even if NOT all data read
-                    // Optionally, we may receive COMPLETE interrupt later and
-                    // treat it as unexpected
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: early complete + underrun ? status %x\n", statusByte));
-
-                    status = SRB_STATUS_SUCCESS;
-                    goto CompleteRequest;
-                }
-            } else {
-                if(!atapiDev && !DataOverrun && (srb->SrbFlags & SRB_FLAGS_DATA_IN) &&
-                    ((statusByte & ~IDE_STATUS_INDEX) == (IDE_STATUS_IDLE | IDE_STATUS_DRQ))) {
-                    KdPrint2((PRINT_PREFIX "  HDD read data ready \n"));
-                    goto continue_read_drq;
-                }
-            }
-        }
-
-        goto ReturnEnableIntr;
-
-    } else if (interruptReason == (ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd) && !(statusByte & IDE_STATUS_DRQ)) {
-
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt: interruptReason = CompleteRequest\n"));
-        // Command complete. We exactly know this because of IReason.
-
-        if(DmaTransfer) {
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, was DmaTransfer\n"));
-            AtaReq->WordsTransfered += AtaReq->WordsLeft;
-            AtaReq->WordsLeft = 0;
-        } else {
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, was PIO\n"));
-
-            wordCount = AtaReq->WordsLeft;
-            // Advance data buffer pointer and bytes left.
-            AtaReq->DataBuffer += wordCount;
-            AtaReq->WordsLeft -= wordCount;
-            AtaReq->WordsTransfered += wordCount;
-
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: wordCount %#x, WordsTransfered %#x\n", wordCount, AtaReq->WordsTransfered));
-
-        }
-        //if (AtaReq->WordsLeft) {
-        //    status = SRB_STATUS_DATA_OVERRUN;
-        //} else {
-            status = SRB_STATUS_SUCCESS;
-        //}
-
-#ifdef UNIATA_DUMP_ATAPI
-        if(srb &&
-           srb->SrbFlags & SRB_FLAGS_DATA_IN) {
-            UCHAR                   ScsiCommand;
-            PCDB                    Cdb;
-            PCHAR                   CdbData;
-            PCHAR                   ModeSelectData;
-            ULONG                   CdbDataLen;
-            PSCSI_REQUEST_BLOCK     Srb = srb;
-
-            Cdb = (PCDB)(Srb->Cdb);
-            ScsiCommand = Cdb->CDB6.OperationCode;
-            CdbData = (PCHAR)(Srb->DataBuffer);
-            CdbDataLen = Srb->DataTransferLength;
-
-            if(CdbDataLen > 0x1000) {
-                CdbDataLen = 0x1000;
-            }
-
-            KdPrint(("--\n"));
-            KdPrint2(("DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
-            KdPrint2(("P:T:D=%d:%d:%d\n",
-                                      Srb->PathId,
-                                      Srb->TargetId,
-                                      Srb->Lun));
-            KdPrint(("Complete SCSI Command %2.2x\n", ScsiCommand));
-            KdDump(Cdb, 16);
-
-            if(ScsiCommand == SCSIOP_MODE_SENSE) {
-                KdPrint(("ModeSense 6\n"));
-                PMODE_PARAMETER_HEADER ParamHdr = (PMODE_PARAMETER_HEADER)CdbData;
-                ModeSelectData = CdbData+4;
-                KdDump(CdbData, CdbDataLen);
-            } else
-            if(ScsiCommand == SCSIOP_MODE_SENSE10) {
-                KdPrint(("ModeSense 10\n"));
-                PMODE_PARAMETER_HEADER ParamHdr = (PMODE_PARAMETER_HEADER)CdbData;
-                ModeSelectData = CdbData+8;
-                KdDump(CdbData, CdbDataLen);
-            } else {
-                if(srb->SrbFlags & SRB_FLAGS_DATA_IN) {
-                    KdPrint(("Read buffer from device:\n"));
-                    KdDump(CdbData, CdbDataLen);
-                }
-            }
-            KdPrint(("--\n"));
-        }
-#endif //UNIATA_DUMP_ATAPI
-
-CompleteRequest:
-
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, srbstatus %x\n", status));
-        // Check and see if we are processing our secret (mechanism status/request sense) srb
-
-        if(AtaReq->WordsLeft && (status == SRB_STATUS_SUCCESS)) {
-            KdPrint2((PRINT_PREFIX "WordsLeft %#x -> SRB_STATUS_DATA_OVERRUN\n", AtaReq->WordsLeft));
-            status = SRB_STATUS_DATA_OVERRUN;
-        }
-
-        if (AtaReq->OriginalSrb) {
-
-            ULONG srbStatus;
-
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: OriginalSrb != NULL\n"));
-            if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
-#ifdef UNIATA_INIT_CHANGERS
-                // We can get here only when UNIATA_INIT_CHANGERS is defined
-                KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status));
-                if (status == SRB_STATUS_SUCCESS) {
-                    // Bingo!!
-                    AtapiHwInitializeChanger (HwDeviceExtension,
-                                              srb,
-                                              (PMECHANICAL_STATUS_INFORMATION_HEADER) srb->DataBuffer);
-
-                    // Get ready to issue the original srb
-                    srb = AtaReq->Srb = AtaReq->OriginalSrb;
-                    AtaReq->OriginalSrb = NULL;
-
-                } else {
-                    // failed!  Get the sense key and maybe try again
-                    srb = AtaReq->Srb = BuildRequestSenseSrb (
-                                                          HwDeviceExtension,
-                                                          AtaReq->OriginalSrb);
-                }
-/*
-                // do not enable interrupts in DPC, do not waste time, do it now!
-                if(UseDpc && chan->DisableIntr) {
-                    AtapiEnableInterrupts(HwDeviceExtension, c);
-                    UseDpc = FALSE;
-                    RestoreUseDpc = TRUE;
-                }
-*/
-                srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL);
-
-                KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (1)\n", chan->ExpectingInterrupt));
-
-                if (srbStatus == SRB_STATUS_PENDING) {
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (1)\n"));
-                    goto ReturnEnableIntr;
-                }
-/*
-                if(RestoreUseDpc) {
-                    // restore state on error
-                    UseDpc = TRUE;
-                    AtapiDisableInterrupts(HwDeviceExtension, c);
-                }
-*/
-#else 
-                KdPrint((PRINT_PREFIX "AtapiInterrupt: ERROR: internal SCSIOP_MECHANISM_STATUS !!!!\n"));
-                ASSERT(FALSE);
-#endif // UNIATA_INIT_CHANGERS
-            } else { // srb->Cdb[0] == SCSIOP_REQUEST_SENSE)
-
-                PSENSE_DATA senseData = (PSENSE_DATA) srb->DataBuffer;
-#ifdef __REACTOS__
-                (void)senseData;
-#endif
-                KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI command status %#x\n", status));
-                if (status == SRB_STATUS_DATA_OVERRUN) {
-                    // Check to see if we at least get mininum number of bytes
-                    if ((srb->DataTransferLength - AtaReq->WordsLeft) >
-                        (FIELD_OFFSET (SENSE_DATA, AdditionalSenseLength) + sizeof(senseData->AdditionalSenseLength))) {
-                        status = SRB_STATUS_SUCCESS;
-                    }
-                }
-
-                if (status == SRB_STATUS_SUCCESS) {
-#ifndef UNIATA_CORE
-#ifdef UNIATA_INIT_CHANGERS
-                    if ((senseData->SenseKey != SCSI_SENSE_ILLEGAL_REQUEST) &&
-                        FALSE &&
-                        chan->MechStatusRetryCount) {
-
-                        KdPrint3((PRINT_PREFIX "AtapiInterrupt: MechStatusRetryCount %#x\n", chan->MechStatusRetryCount));
-                        // The sense key doesn't say the last request is illegal, so try again
-                        chan->MechStatusRetryCount--;
-                        srb = AtaReq->Srb = BuildMechanismStatusSrb (
-                                                              HwDeviceExtension,
-                                                              AtaReq->OriginalSrb);
-                    } else
-#endif // UNIATA_INIT_CHANGERS
-                    {
-                        // Get ready to issue the original srb
-                        srb = AtaReq->Srb = AtaReq->OriginalSrb;
-                        AtaReq->OriginalSrb = NULL;
-                    }
-#endif //UNIATA_CORE
-/*
-                    // do not enable interrupts in DPC, do not waste time, do it now!
-                    if(UseDpc && chan->DisableIntr) {
-                        AtapiEnableInterrupts(HwDeviceExtension, c);
-                        UseDpc = FALSE;
-                        RestoreUseDpc = TRUE;
-                    }
-*/
-                    srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL);
-
-                    KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (2)\n", chan->ExpectingInterrupt));
-
-                    if (srbStatus == SRB_STATUS_PENDING) {
-                        KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (2)\n"));
-                        goto ReturnEnableIntr;
-                    }
-/*
-                    if(RestoreUseDpc) {
-                        // restore state on error
-                        UseDpc = TRUE;
-                        AtapiDisableInterrupts(HwDeviceExtension, c);
-                    }
-*/
-                }
-            }
-
-            // If we get here, it means AtapiSendCommand() has failed
-            // Can't recover.  Pretend the original srb has failed and complete it.
-
-            KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. complete OriginalSrb\n"));
-
-            if (AtaReq->OriginalSrb) {
-                srb = AtaReq->Srb = AtaReq->OriginalSrb;
-                AtaReq->OriginalSrb = NULL;
-            }
-
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (3)\n", chan->ExpectingInterrupt));
-
-            // fake an error and read no data
-            status = SRB_STATUS_ERROR;
-            srb->ScsiStatus = 0;
-            AtaReq->DataBuffer = (PUSHORT)(srb->DataBuffer);
-            AtaReq->WordsLeft = srb->DataTransferLength;
-            chan->RDP = FALSE;
-
-        } else if (status == SRB_STATUS_ERROR) {
-
-            // Map error to specific SRB status and handle request sense.
-            KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. Begin mapping...\n"));
-            status = MapError(deviceExtension,
-                              srb);
-
-            chan->RDP = FALSE;
-
-        } else if(!DmaTransfer) {
-
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion\n"));
-            // Command complete.
-PIO_wait_busy:
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion, wait BUSY\n"));
-            // Wait for busy to drop.
-            for (i = 0; i < 5*30; i++) {
-                GetBaseStatus(chan, statusByte);
-                if (!(statusByte & IDE_STATUS_BUSY)) {
-                    break;
-                }
-                if(!InDpc) {
-                    // goto DPC
-                    AtaReq->ReqState = REQ_STATE_DPC_WAIT_BUSY;
-                    TimerValue = 200;
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (busy)\n"));
-#ifndef UNIATA_CORE
-                    goto PostToDpc;
-#else //UNIATA_CORE
-                    AtapiStallExecution(TimerValue);
-                    goto ServiceInterrupt;
-#endif //UNIATA_CORE
-                }
-                AtapiStallExecution(100);
-            }
-
-            if (i == 5*30) {
-
-                // reset the controller.
-                KdPrint2((PRINT_PREFIX 
-                            "AtapiInterrupt: Resetting due to BSY still up - %#x.\n",
-                            statusByte));
-                goto IntrPrepareResetController;
-            }
-            // Check to see if DRQ is still up.
-            if(statusByte & IDE_STATUS_DRQ) {
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt: DRQ...\n"));
-                if(srb) {
-                    if(srb->SrbFlags & SRB_FLAGS_DATA_IN) {
-                        KdPrint2((PRINT_PREFIX "srb %x data in\n", srb));
-                    } else {
-                        KdPrint2((PRINT_PREFIX "srb %x data out\n", srb));
-                    }
-                } else {
-                    KdPrint2((PRINT_PREFIX "srb NULL\n"));
-                }
-                if(AtaReq) {
-                    KdPrint2((PRINT_PREFIX "AtaReq %x AtaReq->WordsLeft=%x\n", AtaReq, AtaReq->WordsLeft));
-                } else {
-                    KdPrint2((PRINT_PREFIX "AtaReq NULL\n"));
-                }
-                if(AtaReq && AtaReq->WordsLeft /*&&
-                   !(LunExt->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_TAPE_DEVICE | DFLAGS_LBA_ENABLED))*/) {
-                    KdPrint2((PRINT_PREFIX "DRQ+AtaReq->WordsLeft -> next portion\n"));
-                    goto continue_PIO;
-                }
-            }
-            //if (atapiDev && (statusByte & IDE_STATUS_DRQ)) {}
-            //if ((statusByte & IDE_STATUS_DRQ)) {}
-            if((statusByte & IDE_STATUS_DRQ) &&
-               (LunExt->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_TAPE_DEVICE | DFLAGS_LBA_ENABLED)) ) {
-
-PIO_wait_DRQ:
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO_wait_DRQ\n"));
-                for (i = 0; i < 200; i++) {
-                    GetBaseStatus(chan, statusByte);
-                    if (!(statusByte & IDE_STATUS_DRQ)) {
-                        break;
-                    }
-                    if(!InDpc) {
-                        // goto DPC
-                        KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (drq)\n"));
-                        AtaReq->ReqState = REQ_STATE_DPC_WAIT_DRQ;
-                        TimerValue = 100;
-#ifndef UNIATA_CORE
-                        goto PostToDpc;
-#else //UNIATA_CORE
-                        AtapiStallExecution(TimerValue);
-                        goto ServiceInterrupt;
-#endif //UNIATA_CORE
-                    }
-                    AtapiStallExecution(100);
-                }
-
-                if (i == 200) {
-                    // reset the controller.
-                    KdPrint2((PRINT_PREFIX   "AtapiInterrupt: Resetting due to DRQ still up - %#x\n",
-                                statusByte));
-                    goto IntrPrepareResetController;
-                }
-            }
-            if(atapiDev) {
-                KdPrint2(("IdeIntr: ATAPI Read AtaReq->DataBuffer %#x, srb->DataBuffer %#x, len %#x\n",
-                     AtaReq->DataBuffer, (srb ? srb->DataBuffer : (void*)(-1)), srb->DataTransferLength ));
-                //KdDump(srb->DataBuffer, srb->DataTransferLength);
-            }
-            if(!AtapiDmaPioSync(HwDeviceExtension, srb, (PUCHAR)(srb->DataBuffer), srb->DataTransferLength)) {
-                KdPrint2(("IdeIntr: Can't sync DMA and PIO buffers\n"));
-            }
-        }
-
-        // Clear interrupt expecting flag.
-        UniataExpectChannelInterrupt(chan, FALSE);
-        // clear this flag now, it can be set again in sub-calls
-        InterlockedExchange(&(chan->CheckIntr),
-                                      CHECK_INTR_IDLE);
-
-        // Sanity check that there is a current request.
-        if(srb != NULL) {
-            // Set status in SRB.
-            srb->SrbStatus = (UCHAR)status;
-
-            // Check for underflow.
-            if(AtaReq->WordsLeft) {
-
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt: Check for underflow, AtaReq->WordsLeft %x\n", AtaReq->WordsLeft));
-                // Subtract out residual words and update if filemark hit,
-                // setmark hit , end of data, end of media...
-                if (!(LunExt->DeviceFlags & DFLAGS_TAPE_DEVICE)) {
-                    if (status == SRB_STATUS_DATA_OVERRUN) {
-                        srb->DataTransferLength -= AtaReq->WordsLeft*2;
-                    } else {
-                        srb->DataTransferLength = 0;
-                    }
-                } else {
-                    srb->DataTransferLength -= AtaReq->WordsLeft*2;
-                }
-            }
-            if(status == SRB_STATUS_SUCCESS) {
-                //if(!(deviceExtension->HwFlags & UNIATA_AHCI) && !atapiDev) {
-                //    // This should be set in UniataAhciEndTransaction() for AHCI
-                //    AtaReq->WordsTransfered += AtaReq->bcount * DEV_BSIZE/2;
-                //}
-                if(!atapiDev &&
-                   AtaReq->WordsTransfered*2 < AtaReq->TransferLength) {
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: more I/O required (%x of %x bytes) -> reenqueue\n",
-                         AtaReq->WordsTransfered*2, AtaReq->TransferLength));
-                    AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
-                    AtaReq->ReqState = REQ_STATE_PREPARE_TO_NEXT;
-                    goto reenqueue_req;
-                } else {
-                    KdPrint2((PRINT_PREFIX "   Transfered %x, full size %x\n",
-                        AtaReq->WordsTransfered*2, AtaReq->TransferLength));
-                }
-            }
-
-            if (srb->Function != SRB_FUNCTION_IO_CONTROL) {
-
-CompleteRDP:
-                // Indicate command complete.
-                if (!(chan->RDP)) {
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestComplete\n"));
-IntrCompleteReq:
-
-                    if (status == SRB_STATUS_SUCCESS &&
-                        srb->SenseInfoBuffer &&
-                        srb->SenseInfoBufferLength >= sizeof(SENSE_DATA)) {
-
-                        PSENSE_DATA  senseBuffer = (PSENSE_DATA)srb->SenseInfoBuffer;
-
-                        KdPrint2((PRINT_PREFIX "AtapiInterrupt: set AutoSense\n"));
-                        senseBuffer->ErrorCode = 0;
-                        senseBuffer->Valid     = 1;
-                        senseBuffer->AdditionalSenseLength = 0xb;
-                        senseBuffer->SenseKey =  0;
-                        senseBuffer->AdditionalSenseCode = 0;
-                        senseBuffer->AdditionalSenseCodeQualifier = 0;
-
-                        srb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
-                    }
-                    AtapiDmaDBSync(chan, srb);
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: remove srb %#x, status %x\n", srb, status));
-                    UniataRemoveRequest(chan, srb);
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestComplete, srb %#x\n", srb));
-                    ScsiPortNotification(RequestComplete,
-                                         deviceExtension,
-                                         srb);
-                }
-            } else {
-
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt: IOCTL completion\n"));
-
-                if (status != SRB_STATUS_SUCCESS) {
-                    error = AtapiReadPort1(chan, IDX_IO1_i_Error);
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: error %#x\n", error));
-                }
-
-                if(!AtapiStringCmp( (PCHAR)(((PSRB_IO_CONTROL)(srb->DataBuffer))->Signature),"SCSIDISK",sizeof("SCSIDISK")-1)) {
-
-                    PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
-                    // Build the SMART status block depending upon the completion status.
-                    cmdOutParameters->cBufferSize = wordCount;
-                    cmdOutParameters->DriverStatus.bDriverError = (error) ? SMART_IDE_ERROR : 0;
-                    cmdOutParameters->DriverStatus.bIDEError = error;
-
-                    // If the sub-command is return smart status, jam the value from cylinder low and high, into the
-                    // data buffer.
-                    if (chan->SmartCommand == RETURN_SMART_STATUS) {
-                        PIDEREGS_EX regs = (PIDEREGS_EX)&(cmdOutParameters->bBuffer);
-
-                        regs->bOpFlags = 0;
-                        UniataSnapAtaRegs(chan, 0, regs);
-
-                        regs->bCommandReg = SMART_CMD;
-                        regs->bFeaturesReg = RETURN_SMART_STATUS;
-
-                        cmdOutParameters->cBufferSize = 8;
-                    }
-                    chan->SmartCommand = 0; // cleanup after execution
-                }
-                // Indicate command complete.
-                goto IntrCompleteReq;
-            }
-
-        } else {
-
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: No SRB!\n"));
-        }
-
-        if (chan->RDP) {
-            // Check DSC
-            for (i = 0; i < 5; i++) {
-                GetBaseStatus(chan, statusByte);
-                if(!(statusByte & IDE_STATUS_BUSY)) {
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: RDP + cleared BUSY\n"));
-                    chan->RDP = FALSE;
-                    goto CompleteRDP;
-                } else
-                if (statusByte & IDE_STATUS_DSC) {
-                    KdPrint2((PRINT_PREFIX "AtapiInterrupt: Clear RDP\n"));
-                    chan->RDP = FALSE;
-                    goto CompleteRDP;
-                } 
-                AtapiStallExecution(50);
-            }
-        }
-        // RDP can be cleared since previous check
-        if (chan->RDP) {
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestTimerCall 2000\n"));
-
-            TimerValue = 2000;
-#ifndef UNIATA_CORE
-            goto CallTimerDpc;
-#else //UNIATA_CORE
-            AtapiStallExecution(TimerValue);
-            goto ServiceInterrupt;
-#endif //UNIATA_CORE
-        }
-
-//            ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-enqueue_next_req:
-        // Get next request
-        srb = UniataGetCurRequest(chan);
-
-reenqueue_req:
-
-#ifndef UNIATA_CORE
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt: NextRequest, srb=%#x\n",srb));
-        if(!srb) {
-            ScsiPortNotification(NextRequest,
-                                 deviceExtension,
-                                 NULL);
-        } else {
-            ScsiPortNotification(NextLuRequest,
-                                 deviceExtension, 
-                                 PathId,
-                                 TargetId,
-                                 Lun);
-            // in simplex mode next command must NOT be sent here
-            if(!deviceExtension->simplexOnly) {
-                AtapiStartIo__(HwDeviceExtension, srb, FALSE);
-            }
-        }
-        // Try to get SRB fron any non-empty queue (later)
-        if(deviceExtension->simplexOnly) {
-            NoStartIo = FALSE;
-        }
-#endif //UNIATA_CORE
-
-        goto ReturnEnableIntr;
-
-    } else {
-
-        // Unexpected int. Catch it
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt: Unexpected ATAPI interrupt. InterruptReason %#x. Status %#x.\n",
-                    interruptReason,
-                    statusByte));
-
-        if(g_opt_VirtualMachine == VM_QEMU) {
-            if(interruptReason == ATAPI_IR_IO_toDev && !(statusByte & IDE_STATUS_DRQ) && !DmaTransfer) {
-                statusByte = WaitForDrq(chan);
-                if(statusByte & IDE_STATUS_DRQ) {
-                    goto continue_PIO;
-                }
-            }
-        }
-
-        if(OldReqState == REQ_STATE_DPC_WAIT_BUSY0 &&
-           AtaReq->WordsLeft == 0) {
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: pending WAIT_BUSY0. Complete.\n"));
-            status = SRB_STATUS_SUCCESS;
-            chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
-            goto CompleteRequest;
-        }
-    }
-
-ReturnEnableIntr:
-
-    KdPrint2((PRINT_PREFIX "AtapiInterrupt: ReturnEnableIntr\n",srb));
-    //UniataExpectChannelInterrupt(chan, TRUE); // device may interrupt
-    deviceExtension->ExpectingInterrupt = TRUE;
-    if(UseDpc) {
-        if(CrNtInterlockedExchangeAdd(&(chan->DisableIntr), 0)) {
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: call AtapiEnableInterrupts__()\n"));
-#ifdef UNIATA_USE_XXableInterrupts
-            //ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
-            chan->ChannelCtrlFlags |= CTRFLAGS_ENABLE_INTR_REQ;
-            // must be called on DISPATCH_LEVEL
-            ScsiPortNotification(CallDisableInterrupts, HwDeviceExtension,
-                                 AtapiEnableInterrupts__);
-#else
-            AtapiEnableInterrupts(HwDeviceExtension, c);
-            InterlockedExchange(&(chan->CheckIntr),
-                                          CHECK_INTR_IDLE);
-            // Will raise IRQL to DIRQL
-#ifndef UNIATA_CORE
-            AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
-                                 AtapiEnableInterrupts__,
-                                 1);
-#endif // UNIATA_CORE
-            KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
-#endif // UNIATA_USE_XXableInterrupts
-        }
-    }
-
-    InterlockedExchange(&(chan->CheckIntr), CHECK_INTR_IDLE);
-    // in simplex mode next command must be sent here if
-    // DPC is not used
-    KdPrint2((PRINT_PREFIX "AtapiInterrupt: exiting, UseDpc=%d, NoStartIo=%d\n", UseDpc, NoStartIo));
-
-#ifndef UNIATA_CORE
-    if(!UseDpc && /*deviceExtension->simplexOnly &&*/ !NoStartIo) {
-        chan = UniataGetNextChannel(chan);
-        if(chan) {
-            srb = UniataGetCurRequest(chan);
-        } else {
-            srb = NULL;
-        }
-        KdPrint2((PRINT_PREFIX "AtapiInterrupt: run srb %x\n", srb));
-        if(srb) {
-            AtapiStartIo__(HwDeviceExtension, srb, FALSE);
-        }
-    }
-#endif //UNIATA_CORE
-    return TRUE;
-
-} // end AtapiInterrupt__()
-
-#ifndef UNIATA_CORE
-
-/*++
-
-Routine Description:
-
-    This routine handles SMART enable, disable, read attributes and threshold commands.
-
-Arguments:
-
-    HwDeviceExtension - HBA miniport driver's adapter data storage
-    Srb - IO request packet
-
-Return Value:
-
-    SRB status
-
---*/
-ULONG
-NTAPI
-IdeSendSmartCommand(
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb,
-    IN ULONG targetId // assume it is always valid
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    ULONG                c               ; // = GET_CHANNEL(Srb); may be invalid
-    PHW_CHANNEL          chan            ; // = &(deviceExtension->chan[c]);
-    PATA_REQ             AtaReq          = (PATA_REQ)(Srb->SrbExtension);
-    PSENDCMDOUTPARAMS    cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
-    SENDCMDINPARAMS      cmdInParameters = *(PSENDCMDINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
-    PIDEREGS             regs            = &cmdInParameters.irDriveRegs;
-//    ULONG                i;
-    UCHAR                statusByte;
-    ULONG DeviceNumber;
-
-    if (regs->bCommandReg != SMART_CMD) {
-        KdPrint2((PRINT_PREFIX 
-                    "IdeSendSmartCommand: bCommandReg != SMART_CMD\n"));
-        return SRB_STATUS_INVALID_REQUEST;
-    }
-
-    c = targetId / deviceExtension->NumberLuns;
-    DeviceNumber = targetId % deviceExtension->NumberLuns;
-    KdPrint2((PRINT_PREFIX "  c %d, dev %d\n", c, DeviceNumber));
-
-    chan = &(deviceExtension->chan[c]);
-
-    chan->SmartCommand = regs->bFeaturesReg;
-
-    // Determine which of the commands to carry out.
-    switch(regs->bFeaturesReg) {
-    case READ_ATTRIBUTES:
-    case READ_THRESHOLDS:
-    case READ_LOG_SECTOR:
-    case WRITE_LOG_SECTOR:
-
-        if(Srb->DataTransferLength < sizeof(SRB_IO_CONTROL)+sizeof(SENDCMDOUTPARAMS) + READ_ATTRIBUTE_BUFFER_SIZE - 1) {
-            KdPrint2((PRINT_PREFIX 
-                        "IdeSendSmartCommand: wrong buffer size\n"));
-            return SRB_STATUS_DATA_OVERRUN;
-        }
-
-        statusByte = WaitOnBusy(chan);
-
-        if (statusByte & IDE_STATUS_BUSY) {
-            KdPrint2((PRINT_PREFIX 
-                        "IdeSendSmartCommand: Returning BUSY status\n"));
-            return SRB_STATUS_BUSY;
-        }
-
-        // Zero the ouput buffer as the input buffer info. has been saved off locally (the buffers are the same).
-        RtlZeroMemory(cmdOutParameters, sizeof(SENDCMDOUTPARAMS) + READ_ATTRIBUTE_BUFFER_SIZE - 1);
-
-        // Set data buffer pointer and words left.
-        AtaReq->DataBuffer = (PUSHORT)cmdOutParameters->bBuffer;
-        AtaReq->WordsLeft = READ_ATTRIBUTE_BUFFER_SIZE / 2;
-
-        statusByte = AtaCommand(deviceExtension, DeviceNumber, c,
-                   regs->bCommandReg,
-                   (USHORT)(regs->bCylLowReg) | (((USHORT)(regs->bCylHighReg)) << 8),
-                   0,
-                   regs->bSectorNumberReg,
-                   regs->bSectorCountReg,
-                   regs->bFeaturesReg,
-                   ATA_IMMEDIATE);
-
-        if(!(statusByte & IDE_STATUS_ERROR)) {
-            // Wait for interrupt.
-            return SRB_STATUS_PENDING;
-        }
-        return SRB_STATUS_ERROR;
-
-    case ENABLE_SMART:
-    case DISABLE_SMART:
-    case RETURN_SMART_STATUS:
-    case ENABLE_DISABLE_AUTOSAVE:
-    case EXECUTE_OFFLINE_DIAGS:
-    case SAVE_ATTRIBUTE_VALUES:
-    case AUTO_OFFLINE:
-
-        statusByte = WaitOnBusy(chan);
-
-        if (statusByte & IDE_STATUS_BUSY) {
-            KdPrint2((PRINT_PREFIX 
-                        "IdeSendSmartCommand: Returning BUSY status\n"));
-            return SRB_STATUS_BUSY;
-        }
-
-        // Zero the ouput buffer as the input buffer info. has been saved off locally (the buffers are the same).
-        RtlZeroMemory(cmdOutParameters, sizeof(SENDCMDOUTPARAMS) - 1);
-
-        // Set data buffer pointer and indicate no data transfer.
-        AtaReq->DataBuffer = (PUSHORT)cmdOutParameters->bBuffer;
-        AtaReq->WordsLeft = 0;
-
-        statusByte = AtaCommand(deviceExtension, DeviceNumber, c,
-                   regs->bCommandReg,
-                   (USHORT)(regs->bCylLowReg) | (((USHORT)(regs->bCylHighReg)) << 8),
-                   0,
-                   regs->bSectorNumberReg,
-                   regs->bSectorCountReg,
-                   regs->bFeaturesReg,
-                   ATA_IMMEDIATE);
-
-        if(!(statusByte & IDE_STATUS_ERROR)) {
-            // Wait for interrupt.
-            UniataExpectChannelInterrupt(chan, TRUE); // device may interrupt
-            return SRB_STATUS_PENDING;
-        }
-        return SRB_STATUS_ERROR;
-    } // end switch(regs->bFeaturesReg)
-
-    return SRB_STATUS_INVALID_REQUEST;
-
-} // end IdeSendSmartCommand()
-
-#endif //UNIATA_CORE
-
-ULONGLONG
-NTAPI
-UniAtaCalculateLBARegs(
-    PHW_LU_EXTENSION     LunExt,
-    ULONGLONG            startingSector,
-    PULONG               max_bcount
-    )
-{
-    UCHAR                drvSelect,sectorNumber;
-    USHORT               cylinder;
-    ULONG                tmp;
-
-    if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
-        (*max_bcount) = 0;
-        if(LunExt->LimitedTransferMode >= ATA_DMA) {
-            if(LunExt->DeviceExtension) {
-                (*max_bcount) = LunExt->DeviceExtension->MaximumDmaTransferLength / DEV_BSIZE;
-            }
-        }
-        return startingSector;
-    }
-    tmp = LunExt->IdentifyData.SectorsPerTrack *
-                       LunExt->IdentifyData.NumberOfHeads;
-    if(!tmp) {
-        KdPrint2((PRINT_PREFIX "UniAtaCalculateLBARegs: 0-sized\n"));
-        cylinder     = 0;
-        drvSelect    = 0;
-        sectorNumber = 1;
-        (*max_bcount) = LunExt->IdentifyData.SectorsPerTrack;
-    } else {
-        cylinder =    (USHORT)(startingSector / tmp);
-        drvSelect =   (UCHAR)((startingSector % tmp) / LunExt->IdentifyData.SectorsPerTrack); 
-        sectorNumber = (UCHAR)(startingSector % LunExt->IdentifyData.SectorsPerTrack) + 1;
-        (*max_bcount) = LunExt->IdentifyData.SectorsPerTrack - sectorNumber + 1;
-        KdPrint2((PRINT_PREFIX "UniAtaCalculateLBARegs: C:H:S=%#x:%#x:%#x, max_bc %#x\n",
-            cylinder, drvSelect, sectorNumber, (*max_bcount)));
-    }
-
-    return (ULONG)(sectorNumber&0xff) | (((ULONG)cylinder&0xffff)<<8) | (((ULONG)drvSelect&0xf)<<24);
-} // end UniAtaCalculateLBARegs()
-
-ULONGLONG
-NTAPI
-UniAtaCalculateLBARegsBack(
-    PHW_LU_EXTENSION     LunExt,
-    ULONGLONG            lba
-    )
-{
-    ULONG                drvSelect,sectorNumber;
-    ULONG                cylinder;
-    ULONG                tmp;
-
-    if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
-        return lba;
-    }
-    tmp = LunExt->IdentifyData.SectorsPerTrack *
-                       LunExt->IdentifyData.NumberOfHeads;
-
-    cylinder     = (USHORT)((lba >> 8) & 0xffff);
-    drvSelect    = (UCHAR)((lba >> 24) & 0xf);
-    sectorNumber = (UCHAR)(lba & 0xff);
-
-    lba = sectorNumber-1 +
-          (drvSelect*LunExt->IdentifyData.SectorsPerTrack) +
-          (cylinder*tmp);
-
-    return lba;
-} // end UniAtaCalculateLBARegsBack()
-
-
-/*++
-
-Routine Description:
-
-    This routine handles IDE read and writes.
-
-Arguments:
-
-    HwDeviceExtension - HBA miniport driver's adapter data storage
-    Srb - IO request packet
-
-Return Value:
-
-    SRB status
-
---*/
-ULONG
-NTAPI
-IdeReadWrite(
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb,
-    IN ULONG CmdAction
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    UCHAR                lChannel = GET_CHANNEL(Srb);
-    PHW_CHANNEL          chan = &(deviceExtension->chan[lChannel]);
-    PHW_LU_EXTENSION     LunExt;
-    PATA_REQ             AtaReq = (PATA_REQ)(Srb->SrbExtension);
-    //ULONG                ldev = GET_LDEV(Srb);
-    UCHAR                DeviceNumber = GET_CDEV(Srb);;
-    ULONGLONG            startingSector=0;
-    ULONG                max_bcount = 0;
-    ULONG                wordCount = 0;
-    UCHAR                statusByte,statusByte2;
-    UCHAR                cmd;
-    ULONGLONG            lba;
-    BOOLEAN              use_dma = FALSE;
-    ULONG                fis_size;
-
-    AtaReq->Flags |= REQ_FLAG_REORDERABLE_CMD;
-    LunExt = chan->lun[DeviceNumber];
-
-    if((CmdAction & CMD_ACTION_PREPARE) &&
-       (AtaReq->ReqState != REQ_STATE_READY_TO_TRANSFER)) {
-
-        if(LunExt->opt_ReadOnly && 
-           (Srb->SrbFlags & SRB_FLAGS_DATA_OUT)) {
-            if(LunExt->opt_ReadOnly == 1) {
-                KdPrint2((PRINT_PREFIX "Abort WRITE (Soft R/O)\n"));
-                return SRB_STATUS_ERROR;
-            } else {
-                KdPrint2((PRINT_PREFIX "Ignore WRITE (Soft R/O)\n"));
-                return SRB_STATUS_SUCCESS;
-            }
-        }
-
-        // Set data buffer pointer and words left.
-        AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
-
-        if(AtaReq->WordsTransfered) {
-            AtaReq->DataBuffer = ((PUSHORT)(Srb->DataBuffer)) + AtaReq->WordsTransfered;
-            startingSector = (UniAtaCalculateLBARegsBack(LunExt, AtaReq->lba)) /* latest lba */ + AtaReq->bcount /* previous bcount */;
-            AtaReq->bcount = (AtaReq->TransferLength - AtaReq->WordsTransfered*2 + DEV_BSIZE-1) / DEV_BSIZE;
-            KdPrint2((PRINT_PREFIX "IdeReadWrite (Chained REQ): Starting sector %I64x, OrigWordsRequested %#x, WordsTransfered %#x, DevSize %#x\n",
-                       startingSector,
-                       AtaReq->TransferLength/2,
-                       AtaReq->WordsTransfered,
-                       AtaReq->bcount));
-        } else {
-            AtaReq->DataBuffer = (PUSHORT)(Srb->DataBuffer);
-            AtaReq->TransferLength = Srb->DataTransferLength;
-            // Set up 1st block.
-            switch(Srb->Cdb[0]) {
-            case SCSIOP_READ:
-            case SCSIOP_WRITE:
-                MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA);
-                MOV_SWP_DW2DD(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
-                break;
-            case SCSIOP_READ12:
-            case SCSIOP_WRITE12:
-                MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB12READWRITE.LBA);
-                MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB12READWRITE.NumOfBlocks);
-                break;
-            case SCSIOP_READ16:
-            case SCSIOP_WRITE16:
-                MOV_QD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB16READWRITE.LBA);
-                MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB16READWRITE.NumOfBlocks);
-                break;
-            }
-            KdPrint2((PRINT_PREFIX "IdeReadWrite (Orig REQ): Starting sector %I64x, OrigWordsRequested %#x, DevSize %#x\n",
-                       startingSector,
-                       AtaReq->TransferLength/2,
-                       AtaReq->bcount));
-        }
-        lba = UniAtaCalculateLBARegs(LunExt, startingSector, &max_bcount);
-
-        if(max_bcount) {
-            AtaReq->bcount = min(AtaReq->bcount, max_bcount);
-        }
-        AtaReq->WordsLeft = min(AtaReq->TransferLength - AtaReq->WordsTransfered*2,
-                                AtaReq->bcount * DEV_BSIZE) / 2;
-
-        KdPrint2((PRINT_PREFIX "IdeReadWrite (REQ): Starting sector is %I64x, Number of WORDS %#x, DevSize %#x\n",
-                   startingSector,
-                   AtaReq->WordsLeft,
-                   AtaReq->bcount));
-
-        AtaReq->lba = lba;
-        if(LunExt->errRetry &&
-           lba == LunExt->errLastLba &&
-           /* AtaReq->bcount && */ // errRetry can be set only for non-zero bcount
-           AtaReq->bcount == LunExt->errBCount) {
-            KdPrint3((PRINT_PREFIX "IdeReadWrite: Retry after BUS_RESET %d @%#I64x (%#x)\n",
-                LunExt->errRetry, LunExt->errLastLba, LunExt->errBCount));
-            if(AtaReq->retry < MAX_RETRIES) {
-                AtaReq->retry = LunExt->errRetry;
-                AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
-            }
-            LunExt->errRetry = 0;
-        }
-
-        // assume best case here
-        // we cannot reinit Dma until previous request is completed
-        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-            UniataAhciSetupCmdPtr(AtaReq);
-            if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
-                          (PUCHAR)(AtaReq->DataBuffer),
-                          AtaReq->bcount * DEV_BSIZE)) {
-                KdPrint3((PRINT_PREFIX "IdeReadWrite: AHCI !DMA\n"));
-                return SRB_STATUS_ERROR;
-            }
-        } else
-        if ((LunExt->LimitedTransferMode >= ATA_DMA)) {
-            use_dma = TRUE;
-            // this will set REQ_FLAG_DMA_OPERATION in AtaReq->Flags on success
-            if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
-                          (PUCHAR)(AtaReq->DataBuffer),
-                          AtaReq->bcount * DEV_BSIZE)) {
-                use_dma = FALSE;
-            }
-        }
-
-        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-            KdPrint2((PRINT_PREFIX "IdeReadWrite: setup AHCI FIS\n"));
-            RtlZeroMemory(&(AtaReq->ahci.ahci_cmd_ptr->cfis), sizeof(AtaReq->ahci_cmd0.cfis));
-
-            fis_size = UniataAhciSetupFIS_H2D(deviceExtension, DeviceNumber, lChannel,
-                   &(AtaReq->ahci.ahci_cmd_ptr->cfis[0]),
-                    (AtaReq->Flags & REQ_FLAG_READ) ? IDE_COMMAND_READ_DMA : IDE_COMMAND_WRITE_DMA,
-                    lba,
-                     (USHORT)(AtaReq->bcount),
-                    0
-                    /*,(AtaReq->Flags & REQ_FLAG_READ) ? 0 : ATA_AHCI_CMD_WRITE*/
-                    );
-
-            if(!fis_size) {
-                KdPrint3((PRINT_PREFIX "IdeReadWrite: AHCI !FIS\n"));
-                return SRB_STATUS_ERROR;
-            }
-
-            AtaReq->ahci.io_cmd_flags = UniAtaAhciAdjustIoFlags(0, (AtaReq->Flags & REQ_FLAG_READ) ? 0 : ATA_AHCI_CMD_WRITE, fis_size, DeviceNumber);
-            KdPrint2((PRINT_PREFIX "IdeReadWrite ahci io flags %x: \n", AtaReq->ahci.io_cmd_flags));
-        }
-
-        AtaReq->ReqState = REQ_STATE_READY_TO_TRANSFER;
-
-    } else { // exec_only
-        KdPrint2((PRINT_PREFIX "IdeReadWrite (ExecOnly): \n"));
-        lba = AtaReq->lba;
-
-        if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
-            use_dma = TRUE;
-        }
-    }
-    if(!(CmdAction & CMD_ACTION_EXEC)) {
-
-        return SRB_STATUS_PENDING;
-    }
-
-    // if this is queued request, reinit DMA and check
-    // if DMA mode is still available
-    AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
-    if (/*EnableDma &&*/
-        (LunExt->TransferMode >= ATA_DMA)) {
-        use_dma = TRUE;
-    } else {
-        AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
-        use_dma = FALSE;
-    }
-
-    // Check if write request.
-    if (Srb->SrbFlags & SRB_FLAGS_DATA_IN) {
-
-        // Prepare read command.
-        if(use_dma) {
-            cmd = IDE_COMMAND_READ_DMA;
-        } else
-        if(LunExt->MaximumBlockXfer) {
-            cmd = IDE_COMMAND_READ_MULTIPLE;
-        } else {
-            cmd = IDE_COMMAND_READ;
-        }
-    } else {
-
-        // Prepare write command.
-        if (use_dma) {
-            wordCount = AtaReq->bcount*DEV_BSIZE/2;
-            cmd = IDE_COMMAND_WRITE_DMA;
-        } else
-        if (LunExt->MaximumBlockXfer) {
-            wordCount = DEV_BSIZE/2 * LunExt->MaximumBlockXfer;
-
-            if (AtaReq->WordsLeft < wordCount) {
-               // Transfer only words requested.
-               wordCount = AtaReq->WordsLeft;
-            }
-            cmd = IDE_COMMAND_WRITE_MULTIPLE;
-
-        } else {
-            wordCount = DEV_BSIZE/2;
-            cmd = IDE_COMMAND_WRITE;
-        }
-    }
-
-    // Send IO command.
-    KdPrint2((PRINT_PREFIX "IdeReadWrite: Lba %#I64x, Count %#x(%#x)\n", lba, ((Srb->DataTransferLength + 0x1FF) / 0x200),
-                                                           ((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE)));
-    if(use_dma) {
-        chan->ChannelCtrlFlags |= CTRFLAGS_DMA_OPERATION;
-    } else {
-        chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
-    }
-
-    if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        // AHCI doesn't distinguish DMA and PIO
-        //AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
-        UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
-        UniataExpectChannelInterrupt(chan, TRUE); // device may interrupt
-        InterlockedExchange(&(chan->CheckIntr),
-                                      CHECK_INTR_IDLE);
-        return SRB_STATUS_PENDING;
-    }
-
-    if ((Srb->SrbFlags & SRB_FLAGS_DATA_IN) ||
-        use_dma) {
-        if(use_dma) {
-            AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb);
-            if(g_opt_BochsDmaReadWorkaround &&
-               (Srb->SrbFlags & SRB_FLAGS_DATA_IN)) {
-                KdPrint2((PRINT_PREFIX "CTRFLAGS_DMA_BEFORE_R on BOCHS\n"));
-                AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
-            }
-        }
-        statusByte2 = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
-                     cmd, lba,
-                     (USHORT)(AtaReq->bcount),
-//                     (UCHAR)((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE),
-                     0, ATA_IMMEDIATE);
-/*        if(statusByte2 != IDE_STATUS_WRONG) {
-            GetStatus(chan, statusByte2);
-        }*/
-        if(statusByte2 & IDE_STATUS_ERROR) {
-            // Unfortunately, we cannot handle errors in such a way in real life (except known bad blocks).
-            // Because some devices doesn't reset ERR from previous command immediately after getting new one.
-            // On the other hand we cannot wait here because of possible timeout condition
-            statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
-            KdPrint2((PRINT_PREFIX "IdeReadWrite: status %#x, error %#x\n", statusByte2, statusByte));
-            return SRB_STATUS_ERROR;
-        }
-        if(use_dma) {
-           if(!g_opt_BochsDmaReadWorkaround ||
-              !(Srb->SrbFlags & SRB_FLAGS_DATA_IN)) {
-                //GetStatus(chan, statusByte2);
-                AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
-            }
-        }
-        return SRB_STATUS_PENDING;
-    }
-
-    statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
-                 cmd, lba,
-                 (USHORT)(AtaReq->bcount),
-//                 (UCHAR)((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE),
-                 0, ATA_WAIT_INTR);
-
-    if (!(statusByte & IDE_STATUS_DRQ) ||
-        statusByte == IDE_STATUS_WRONG) {
-
-        if(statusByte == IDE_STATUS_WRONG) {
-            KdPrint2((PRINT_PREFIX 
-                       "IdeReadWrite: error sending command (%#x)\n",
-                       statusByte));
-        } else {
-            KdPrint2((PRINT_PREFIX 
-                       "IdeReadWrite: DRQ never asserted (%#x)\n",
-                       statusByte));
-        }
-
-        AtaReq->WordsLeft = 0;
-
-        // Clear interrupt expecting flag.
-        UniataExpectChannelInterrupt(chan, FALSE);
-        InterlockedExchange(&(chan->CheckIntr),
-                                      CHECK_INTR_IDLE);
-
-        // Clear current SRB.
-        UniataRemoveRequest(chan, Srb);
-
-        return (statusByte == IDE_STATUS_WRONG) ? SRB_STATUS_ERROR : SRB_STATUS_TIMEOUT;
-    }
-
-    UniataExpectChannelInterrupt(chan, TRUE);
-    InterlockedExchange(&(chan->CheckIntr),
-                                  CHECK_INTR_IDLE);
-
-    // Write next DEV_BSIZE/2*N words.
-    if (!(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) || (wordCount & 1)) {
-        KdPrint2((PRINT_PREFIX 
-                   "IdeReadWrite: Write %#x words\n", wordCount));
-
-        WriteBuffer(chan,
-                  AtaReq->DataBuffer,
-                  wordCount,
-                  UniataGetPioTiming(LunExt));
-
-    } else {
-
-        KdPrint2((PRINT_PREFIX 
-                   "IdeReadWrite: Write %#x Dwords\n", wordCount/2));
-
-        WriteBuffer2(chan,
-                   (PULONG)(AtaReq->DataBuffer),
-                   wordCount / 2,
-                   UniataGetPioTiming(LunExt));
-    }
-
-    // Adjust buffer address and words left count.
-    AtaReq->WordsLeft -= wordCount;
-    AtaReq->DataBuffer += wordCount;
-    AtaReq->WordsTransfered += wordCount;
-
-    // Wait for interrupt.
-    return SRB_STATUS_PENDING;
-
-} // end IdeReadWrite()
-
-#ifndef UNIATA_CORE
-
-/*++
-
-Routine Description:
-    This routine handles IDE Verify.
-
-Arguments:
-    HwDeviceExtension - HBA miniport driver's adapter data storage
-    Srb - IO request packet
-    `
-Return Value:
-    SRB status
-
---*/
-ULONG
-NTAPI
-IdeVerify(
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    UCHAR                lChannel = GET_CHANNEL(Srb);
-    PHW_CHANNEL          chan = &(deviceExtension->chan[lChannel]);
-    PATA_REQ             AtaReq = (PATA_REQ)(Srb->SrbExtension);
-    PHW_LU_EXTENSION     LunExt;
-    //ULONG                ldev = GET_LDEV(Srb);
-    ULONG                DeviceNumber = GET_CDEV(Srb);
-    UCHAR                statusByte;
-    ULONGLONG            startingSector=0;
-    ULONG                max_bcount;
-    ULONGLONG            sectors;
-    ULONGLONG            endSector;
-    ULONG                sectorCount=0;
-    ULONGLONG            lba;
-
-    LunExt = chan->lun[DeviceNumber];
-    // Drive has these number sectors.
-    if(!(sectors = (ULONG)(LunExt->NumOfSectors))) {
-        sectors = LunExt->IdentifyData.SectorsPerTrack *
-                  LunExt->IdentifyData.NumberOfHeads *
-                  LunExt->IdentifyData.NumberOfCylinders;
-    }
-
-    KdPrint2((PRINT_PREFIX 
-                "IdeVerify: Total sectors %#x\n",
-                sectors));
-
-    // Get starting sector number from CDB.
-    switch(Srb->Cdb[0]) {
-    case SCSIOP_VERIFY:
-        MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA);
-        MOV_SWP_DW2DD(sectorCount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
-        break;
-    case SCSIOP_VERIFY12:
-        MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB12READWRITE.LBA);
-        MOV_DD_SWP(sectorCount, ((PCDB)Srb->Cdb)->CDB12READWRITE.NumOfBlocks);
-        break;
-    case SCSIOP_VERIFY16:
-        MOV_QD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB16READWRITE.LBA);
-        MOV_DD_SWP(sectorCount, ((PCDB)Srb->Cdb)->CDB16READWRITE.NumOfBlocks);
-        break;
-    }
-
-    KdPrint2((PRINT_PREFIX 
-                "IdeVerify: Starting sector %#I64x. Number of blocks %#x\n",
-                startingSector,
-                sectorCount));
-
-    endSector = startingSector + sectorCount;
-
-    KdPrint2((PRINT_PREFIX 
-                "IdeVerify: Ending sector %#I64x\n",
-                endSector));
-
-    if (endSector > sectors) {
-
-        // Too big, round down.
-        KdPrint2((PRINT_PREFIX 
-                    "IdeVerify: Truncating request to %#x blocks\n",
-                    sectors - startingSector - 1));
-
-        sectorCount = (ULONG)(sectors - startingSector - 1);
-
-    } else {
-
-        // Set up sector count register. Round up to next block.
-        if (sectorCount > 0xFF) {
-            sectorCount = (USHORT)0xFF;
-        }
-    }
-
-    // Set data buffer pointer and words left.
-    AtaReq->DataBuffer = (PUSHORT)Srb->DataBuffer;
-    AtaReq->WordsLeft = Srb->DataTransferLength / 2;
-
-    // Indicate expecting an interrupt.
-    InterlockedExchange(&(chan->CheckIntr),
-                                  CHECK_INTR_IDLE);
-
-    lba = UniAtaCalculateLBARegs(LunExt, startingSector, &max_bcount);
-
-    statusByte = AtaCommand48(deviceExtension, LunExt->Lun, GET_CHANNEL(Srb),
-                 IDE_COMMAND_VERIFY, lba,
-                 (USHORT)sectorCount,
-                 0, ATA_IMMEDIATE);
-
-    if(!(statusByte & IDE_STATUS_ERROR)) {
-        // Wait for interrupt.
-        return SRB_STATUS_PENDING;
-    }
-    return SRB_STATUS_ERROR;
-
-} // end IdeVerify()
-
-#endif //UNIATA_CORE
-
-/*++
-
-Routine Description:
-    Send ATAPI packet command to device.
-
-Arguments:
-    HwDeviceExtension - HBA miniport driver's adapter data storage
-    Srb - IO request packet
-
-Return Value:
-
---*/
-ULONG
-NTAPI
-AtapiSendCommand(
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb,
-    IN ULONG CmdAction
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    UCHAR                lChannel = GET_CHANNEL(Srb);
-    PHW_CHANNEL          chan = &(deviceExtension->chan[lChannel]);
-    PATA_REQ             AtaReq = (PATA_REQ)(Srb->SrbExtension);
-    PHW_LU_EXTENSION     LunExt;
-    //ULONG                ldev = GET_LDEV(Srb);
-    ULONG                DeviceNumber = GET_CDEV(Srb);
-    ULONG flags;
-    UCHAR statusByte,statusByte0,byteCountLow,byteCountHigh;
-    UCHAR interruptReason;
-    BOOLEAN use_dma = FALSE;
-    BOOLEAN dma_reinited = FALSE;
-    BOOLEAN retried = FALSE;
-    ULONG                fis_size, i;
-    UCHAR FeatureReg=0;
-
-    LunExt = chan->lun[DeviceNumber];
-
-    KdPrint3((PRINT_PREFIX "AtapiSendCommand: req state %#x, Action %x\n", AtaReq->ReqState, CmdAction));
-    if(AtaReq->ReqState < REQ_STATE_PREPARE_TO_TRANSFER)
-        AtaReq->ReqState = REQ_STATE_PREPARE_TO_TRANSFER;
-
-
-#ifdef UNIATA_DUMP_ATAPI
-    if(CmdAction & CMD_ACTION_PREPARE) {
-        UCHAR                   ScsiCommand;
-        PCDB                    Cdb;
-        PCHAR                   CdbData;
-        PCHAR                   ModeSelectData;
-        ULONG                   CdbDataLen;
-
-        Cdb = (PCDB)(Srb->Cdb);
-        ScsiCommand = Cdb->CDB6.OperationCode;
-        CdbData = (PCHAR)(Srb->DataBuffer);
-        CdbDataLen = Srb->DataTransferLength;
-
-        if(CdbDataLen > 0x1000) {
-            CdbDataLen = 0x1000;
-        }
-
-        KdPrint(("--\n"));
-        KdPrint2(("DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
-        KdPrint2(("P:T:D=%d:%d:%d\n",
-                                  Srb->PathId,
-                                  Srb->TargetId,
-                                  Srb->Lun));
-        KdPrint(("SCSI Command %2.2x\n", ScsiCommand));
-        KdDump(Cdb, 16);
-
-        if(ScsiCommand == SCSIOP_WRITE_CD) {
-            KdPrint(("Write10, LBA %2.2x%2.2x%2.2x%2.2x\n",
-                     Cdb->WRITE_CD.LBA[0],
-                     Cdb->WRITE_CD.LBA[1],
-                     Cdb->WRITE_CD.LBA[2],
-                     Cdb->WRITE_CD.LBA[3]
-                     ));
-        } else
-        if(ScsiCommand == SCSIOP_WRITE12) {
-            KdPrint(("Write12, LBA %2.2x%2.2x%2.2x%2.2x\n",
-                     Cdb->CDB12READWRITE.LBA[0],
-                     Cdb->CDB12READWRITE.LBA[1],
-                     Cdb->CDB12READWRITE.LBA[2],
-                     Cdb->CDB12READWRITE.LBA[3]
-                     ));
-        } else
-        if(ScsiCommand == SCSIOP_WRITE16) {
-            KdPrint(("Write16, LBA %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
-                     Cdb->CDB16READWRITE.LBA[0],
-                     Cdb->CDB16READWRITE.LBA[1],
-                     Cdb->CDB16READWRITE.LBA[2],
-                     Cdb->CDB16READWRITE.LBA[3],
-                     Cdb->CDB16READWRITE.LBA[4],
-                     Cdb->CDB16READWRITE.LBA[5],
-                     Cdb->CDB16READWRITE.LBA[6],
-                     Cdb->CDB16READWRITE.LBA[7]
-                     ));
-        } else
-        if(ScsiCommand == SCSIOP_MODE_SELECT) {
-            KdPrint(("ModeSelect 6\n"));
-            PMODE_PARAMETER_HEADER ParamHdr = (PMODE_PARAMETER_HEADER)CdbData;
-            ModeSelectData = CdbData+4;
-            KdDump(CdbData, CdbDataLen);
-        } else
-        if(ScsiCommand == SCSIOP_MODE_SELECT10) {
-            KdPrint(("ModeSelect 10\n"));
-            PMODE_PARAMETER_HEADER ParamHdr = (PMODE_PARAMETER_HEADER)CdbData;
-            ModeSelectData = CdbData+8;
-            KdDump(CdbData, CdbDataLen);
-        } else {
-            if(Srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
-                KdPrint(("Send buffer to device:\n"));
-                KdDump(CdbData, CdbDataLen);
-            }
-        }
-        KdPrint(("--\n"));
-    }
-#endif //UNIATA_DUMP_ATAPI
-
-
-    if(CmdAction == CMD_ACTION_PREPARE) {
-        KdPrint2((PRINT_PREFIX "AtapiSendCommand: CMD_ACTION_PREPARE, Cdb %x\n", &(Srb->Cdb)));
-
-        switch (Srb->Cdb[0]) {
-        case SCSIOP_RECEIVE:
-        case SCSIOP_SEND:
-        case SCSIOP_READ:
-        case SCSIOP_WRITE:
-        case SCSIOP_READ12:
-        case SCSIOP_WRITE12:
-        case SCSIOP_READ16:
-        case SCSIOP_WRITE16:
-            // all right
-            break;
-        case SCSIOP_READ_CD:
-        case SCSIOP_READ_CD_MSF:
-            if(deviceExtension->opt_AtapiDmaRawRead) {
-                // all right
-                break;
-            }
-            /* FALL THROUGH */
-        default:
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_BUSY\n"));
-            return SRB_STATUS_BUSY;
-        }
-        //
-#ifdef UNIATA_INIT_CHANGERS
-        if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED) &&
-            !AtaReq->OriginalSrb) {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_BUSY (2)\n"));
-            return SRB_STATUS_BUSY;
-        }
-#endif // UNIATA_INIT_CHANGERS
-    }
-
-#ifndef UNIATA_CORE
-    // standard atapi.sys claims:
-
-    // We need to know how many platters our atapi cd-rom device might have.
-    // Before anyone tries to send a srb to our target for the first time,
-    // we must "secretly" send down a separate mechanism status srb in order to
-    // initialize our device extension changer data.  That's how we know how
-    // many platters our target has.
-
-    // BUT!
-    // some devices freeze (sometimes) forever on this command
-    // Let CD-ROM driver send this command itself, if it find it necessary
-    // We shall just parse output (if any)
-
-#ifdef UNIATA_INIT_CHANGERS
-    if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED) &&
-        !AtaReq->OriginalSrb) {
-
-        ULONG srbStatus;
-
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: BuildMechanismStatusSrb()\n"));
-        // Set this flag now. If the device hangs on the mech. status
-        // command, we will not have the chance to set it.
-        LunExt->DeviceFlags |= DFLAGS_CHANGER_INITED;
-
-        chan->MechStatusRetryCount = 3;
-        AtaReq->OriginalSrb = Srb;
-        AtaReq->Srb = BuildMechanismStatusSrb (
-                                        HwDeviceExtension,
-                                        Srb);
-
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: AtapiSendCommand recursive\n"));
-        srbStatus = AtapiSendCommand(HwDeviceExtension, AtaReq->Srb, CMD_ACTION_ALL);
-        if (srbStatus == SRB_STATUS_PENDING) {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_PENDING (2)\n"));
-            return srbStatus;
-        } else {
-
-            // failed!  Get the sense key and maybe try again
-            AtaReq->Srb = BuildRequestSenseSrb (  HwDeviceExtension,
-                                                  AtaReq->OriginalSrb);
-
-            srbStatus = AtapiSendCommand(HwDeviceExtension, AtaReq->Srb, CMD_ACTION_ALL);
-
-            KdPrint3((PRINT_PREFIX "AtapiSendCommand: chan->ExpectingInterrupt %d (1)\n", chan->ExpectingInterrupt));
-
-            if (srbStatus == SRB_STATUS_PENDING) {
-                KdPrint2((PRINT_PREFIX "AtapiSendCommand: send orig SRB_STATUS_PENDING (2.1)\n"));
-                return srbStatus;
-            }
-
-            // failed again ? should not get here
-            AtaReq->Srb = AtaReq->OriginalSrb;
-            AtaReq->OriginalSrb = NULL;
-            // fall out
-        }
-    }
-#endif // UNIATA_INIT_CHANGERS
-#endif //UNIATA_CORE
-
-    if((CmdAction & CMD_ACTION_PREPARE) &&
-       (AtaReq->ReqState != REQ_STATE_READY_TO_TRANSFER)) {
-
-        KdPrint2((PRINT_PREFIX "AtapiSendCommand: prepare..., ATAPI CMD %x (Cdb %x)\n", Srb->Cdb[0], &(Srb->Cdb)));
-
-        if(!LunExt->IdentifyData.AtapiCmdSize &&
-            (Srb->CdbLength > 12)) {
-            KdPrint2((PRINT_PREFIX "Cdb16 not supported\n"));
-            return SRB_STATUS_INVALID_REQUEST;
-        }
-
-        // Set data buffer pointer and words left.
-        AtaReq->DataBuffer = (PUSHORT)Srb->DataBuffer;
-        AtaReq->WordsLeft = Srb->DataTransferLength / 2;
-        AtaReq->TransferLength = Srb->DataTransferLength;
-        AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
-        // reset this to force PRD init. May be already setup by recursive SRB
-        AtaReq->dma_entries = 0;
-
-        // check if reorderable
-        switch(Srb->Cdb[0]) {
-        case SCSIOP_READ16:
-        case SCSIOP_WRITE16:
-
-            MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB16READWRITE.NumOfBlocks);
-            MOV_QD_SWP(AtaReq->lba, ((PCDB)Srb->Cdb)->CDB16READWRITE.LBA);
-            goto GetLba2;
-
-        case SCSIOP_READ12:
-        case SCSIOP_WRITE12:
-
-            MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB12READWRITE.NumOfBlocks);
-            goto GetLba;
-
-        case SCSIOP_READ:
-        case SCSIOP_WRITE:
-
-            MOV_SWP_DW2DD(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
-GetLba:
-            MOV_DD_SWP(AtaReq->lba, ((PCDB)Srb->Cdb)->CDB10.LBA);
-GetLba2:
-            AtaReq->Flags |= REQ_FLAG_REORDERABLE_CMD;
-            AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
-            AtaReq->Flags |= (Srb->Cdb[0] == SCSIOP_WRITE ||
-                              Srb->Cdb[0] == SCSIOP_WRITE12 ||
-                              Srb->Cdb[0] == SCSIOP_WRITE16) ?
-                              REQ_FLAG_WRITE : REQ_FLAG_READ;
-            break;
-        default:
-            AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
-            if(!AtaReq->TransferLength) {
-                KdPrint(("  assume 0-transfer\n"));
-            } else
-            if(Srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
-                KdPrint(("  assume OUT\n"));
-                AtaReq->Flags |= REQ_FLAG_WRITE;
-            } else
-            if(Srb->SrbFlags & SRB_FLAGS_DATA_IN) {
-                KdPrint(("  assume IN\n"));
-                AtaReq->Flags |= REQ_FLAG_READ;
-            }
-            break;
-        }
-
-        // check if DMA read/write
-        if(g_opt_AtapiNoDma) {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: CTRFLAGS_DMA_BEFORE_R => no dma\n"));
-            use_dma = FALSE;
-        } else
-        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: force use dma (ahci)\n"));
-            use_dma = TRUE;
-            goto setup_dma;
-        } else
-/*        if((deviceExtension->HwFlags & UNIATA_SATA) && (LunExt->OrigTransferMode >= ATA_DMA)) {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: force use dma (sata)\n"));
-            use_dma = TRUE;
-            goto setup_dma;
-        } else*/
-        if(Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: SCSIOP_REQUEST_SENSE, no DMA setup\n"));
-        } else
-        if(AtaReq->TransferLength && !(AtaReq->TransferLength & 0x0f)) {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: try DMA setup\n"));
-            // try use DMA if TransferLength is 16-byte aligned
-            switch(Srb->Cdb[0]) {
-            case SCSIOP_WRITE:
-            case SCSIOP_WRITE12:
-            case SCSIOP_WRITE16:
-            case SCSIOP_SEND:
-                if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_RO)
-                    break;
-                /* FALLTHROUGH */
-            case SCSIOP_RECEIVE:
-            case SCSIOP_READ:
-            case SCSIOP_READ12:
-            case SCSIOP_READ16:
-
-                if(deviceExtension->opt_AtapiDmaReadWrite) {
-call_dma_setup:
-                    if(deviceExtension->HwFlags & UNIATA_AHCI) {
-                        KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma (ahci)\n"));
-                        use_dma = TRUE;
-                    } else
-                    if(AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
-                                  (PUCHAR)(AtaReq->DataBuffer),
-                                  Srb->DataTransferLength
-                                  /*((Srb->DataTransferLength + DEV_BSIZE-1) & ~(DEV_BSIZE-1))*/
-                                  )) {
-                        KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma\n"));
-                        use_dma = TRUE;
-                    }
-                }
-                break;
-            case SCSIOP_READ_CD:
-            case SCSIOP_READ_CD_MSF:
-                if(deviceExtension->opt_AtapiDmaRawRead)
-                    goto call_dma_setup;
-                break;
-            default:
-
-                if(deviceExtension->opt_AtapiDmaControlCmd) {
-                    if(Srb->SrbFlags & SRB_FLAGS_DATA_IN) {
-                        // read operation
-                        use_dma = TRUE;
-                    } else {
-                        // write operation
-                        if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_RO) {
-                            KdPrint2((PRINT_PREFIX "dma RO\n"));
-                            use_dma = FALSE;
-                        } else {
-                            use_dma = TRUE;
-                        }
-                    }
-                }
-                break;
-            }
-            // try setup DMA
-setup_dma:
-            if(use_dma) {
-                if(deviceExtension->HwFlags & UNIATA_AHCI) {
-                    KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma (ahci)\n"));
-                    //use_dma = TRUE;
-                } else
-                if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
-                              (PUCHAR)(AtaReq->DataBuffer),
-                              Srb->DataTransferLength)) {
-                    KdPrint2((PRINT_PREFIX "AtapiSendCommand: no dma\n"));
-                    use_dma = FALSE;
-                } else {
-                    KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma\n"));
-                }
-            }
-        } else {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: zero/unaligned transfer %x, no DMA setup\n", AtaReq->TransferLength));
-        }
-
-
-        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-
-            UniataAhciSetupCmdPtr(AtaReq);
-
-            if(!Srb->DataTransferLength) {
-                KdPrint2((PRINT_PREFIX "zero-transfer\n"));
-                use_dma = FALSE;
-            } else
-            if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
-                          (PUCHAR)(AtaReq->DataBuffer),
-                          Srb->DataTransferLength)) {
-                KdPrint2((PRINT_PREFIX "AtapiSendCommand: no AHCI dma!\n"));
-                return SRB_STATUS_ERROR;
-            }
-            if(!use_dma) {
-                AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
-            } else {
-                FeatureReg |= ATA_F_DMA;
-                if(LunExt->IdentifyData.AtapiDMA.DMADirRequired) {
-                    if(Srb->SrbFlags & SRB_FLAGS_DATA_IN) {
-                        KdPrint2((PRINT_PREFIX "Set DMADir.\n"));
-                        FeatureReg |= ATA_F_DMAREAD;
-                    }
-                }
-            }
-
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: setup AHCI FIS\n"));
-            // this is done in UniataAhciSetupFIS_H2D()
-            //RtlZeroMemory(&(AtaReq->ahci.ahci_cmd_ptr->cfis), sizeof(AtaReq->ahci_cmd0.cfis)); 
-            RtlCopyMemory(&(AtaReq->ahci.ahci_cmd_ptr->acmd), Srb->Cdb, Srb->CdbLength);
-
-            fis_size = UniataAhciSetupFIS_H2D(deviceExtension, DeviceNumber, lChannel,
-                   &(AtaReq->ahci.ahci_cmd_ptr->cfis[0]),
-                    IDE_COMMAND_ATAPI_PACKET /* command */,
-                    0 /* lba */,
-                    (Srb->DataTransferLength >= 0x10000) ? (USHORT)(0xffff) : (USHORT)(Srb->DataTransferLength),
-                    FeatureReg/* feature */
-                    );
-
-            if(!fis_size) {
-                KdPrint3((PRINT_PREFIX "AtapiSendCommand: AHCI !FIS\n"));
-                return SRB_STATUS_ERROR;
-            }
-
-            AtaReq->ahci.io_cmd_flags = UniAtaAhciAdjustIoFlags(0,
-                ((Srb->DataTransferLength && (Srb->SrbFlags & SRB_FLAGS_DATA_OUT)) ? ATA_AHCI_CMD_WRITE : 0) |
-                (ATA_AHCI_CMD_ATAPI | ATA_AHCI_CMD_PREFETCH),
-                fis_size, DeviceNumber);
-
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand ahci io flags %x: \n", AtaReq->ahci.io_cmd_flags));
-        }
-    
-    } else {
-        if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
-            // if this is queued request, reinit DMA and check
-            // if DMA mode is still available
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiDmaReinit()  (1)\n"));
-            AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
-            if (/*EnableDma &&*/
-                (LunExt->TransferMode >= ATA_DMA)) {
-                KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma (2)\n"));
-                use_dma = TRUE;
-            } else {
-                AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
-                KdPrint2((PRINT_PREFIX "AtapiSendCommand: no dma (2)\n"));
-                use_dma = FALSE;
-            }
-            dma_reinited = TRUE;
-        }
-    }
-
-    if(!(CmdAction & CMD_ACTION_EXEC)) {
-        KdPrint2((PRINT_PREFIX "AtapiSendCommand: !CMD_ACTION_EXEC => SRB_STATUS_PENDING\n"));
-        return SRB_STATUS_PENDING;
-    }
-    KdPrint3((PRINT_PREFIX "AtapiSendCommand: use_dma=%d, Cmd %x\n", use_dma, Srb->Cdb[0]));
-    if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
-        KdPrint2((PRINT_PREFIX "  REQ_FLAG_DMA_OPERATION\n"));
-    }
-
-    if((Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) && !(deviceExtension->HwFlags & UNIATA_SATA)) {
-        KdPrint2((PRINT_PREFIX "AtapiSendCommand: SCSIOP_REQUEST_SENSE -> no dma setup (2)\n"));
-        use_dma = FALSE;
-        AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
-        AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
-    } if(AtaReq->TransferLength) {
-        if(!dma_reinited) {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiDmaReinit()\n"));
-            AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
-            if (/*EnableDma &&*/
-                (LunExt->TransferMode >= ATA_DMA)) {
-                use_dma = TRUE;
-            } else {
-                AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
-                use_dma = FALSE;
-            }
-        }
-    } else {
-        KdPrint2((PRINT_PREFIX "AtapiSendCommand: zero transfer\n"));
-        use_dma = FALSE;
-        AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
-        if(!deviceExtension->opt_AtapiDmaZeroTransfer && !(deviceExtension->HwFlags & UNIATA_SATA)) {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiDmaReinit() to PIO\n"));
-            AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
-        }
-    }
-    KdPrint2((PRINT_PREFIX "AtapiSendCommand: use_dma=%d\n", use_dma));
-    if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
-        KdPrint2((PRINT_PREFIX "  REQ_FLAG_DMA_OPERATION\n"));
-    }
-    
-    KdPrint2((PRINT_PREFIX "AtapiSendCommand: CMD_ACTION_EXEC\n"));
-
-    KdPrint3((PRINT_PREFIX "AtapiSendCommand: Cdb %x Command %#x to TargetId %d lun %d\n",
-               &(Srb->Cdb), Srb->Cdb[0], Srb->TargetId, Srb->Lun));
-    
-    // Make sure command is to ATAPI device.
-    flags = LunExt->DeviceFlags;
-    if(flags & (DFLAGS_SANYO_ATAPI_CHANGER | DFLAGS_ATAPI_CHANGER)) {
-        if((Srb->Lun) > (LunExt->DiscsPresent - 1)) {
-
-            // Indicate no device found at this address.
-            AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-            return SRB_STATUS_SELECTION_TIMEOUT;
-        }
-    } else if(Srb->Lun > 0) {
-        AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-        return SRB_STATUS_SELECTION_TIMEOUT;
-    }
-
-    if(!(flags & DFLAGS_ATAPI_DEVICE)) {
-        AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-        return SRB_STATUS_SELECTION_TIMEOUT;
-    }
-retry:
-    // Select device 0 or 1. Or more for PM
-    SelectDrive(chan, DeviceNumber);
-
-    // Verify that controller is ready for next command.
-    GetStatus(chan, statusByte);
-    KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status %#x\n", statusByte));
-
-    if(statusByte == IDE_STATUS_WRONG) {
-        KdPrint2((PRINT_PREFIX "AtapiSendCommand: bad status 0xff on entry\n"));
-        goto make_reset;
-    }
-    if(statusByte & IDE_STATUS_BUSY) {
-        if(statusByte & IDE_STATUS_DSC) {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: DSC on entry (%#x), try exec\n", statusByte));
-        } else {
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: Device busy (%#x) -> reset\n", statusByte));
-            // We have to make reset here, since we are expecting device to be available
-            //return SRB_STATUS_BUSY; // this cause queue freeze
-            goto make_reset;
-        }
-    }
-    if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        ULONG CI;
-        // Check if command list is free
-        CI = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CI);
-        if(CI) {
-            // controller is busy, however we expect it to be free
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: Controller busy (CI=%#x) -> reset\n", CI));
-            goto make_reset;
-        }
-    }
-    if(statusByte & IDE_STATUS_ERROR) {
-        if (Srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
-
-            KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on entry: (%#x)\n", statusByte));
-            // Read the error reg. to clear it and fail this request.
-            AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-            return MapError(deviceExtension, Srb);
-        } else {
-            KdPrint2((PRINT_PREFIX "  continue with SCSIOP_REQUEST_SENSE\n", statusByte));
-        }
-    }
-    // If a tape drive doesn't have DSC set and the last command is restrictive, don't send
-    // the next command. See discussion of Restrictive Delayed Process commands in QIC-157.
-    if((!(statusByte & IDE_STATUS_DSC)) &&
-          (flags & (DFLAGS_TAPE_DEVICE | DFLAGS_ATAPI_DEVICE)) && chan->RDP) {
-
-        AtapiStallExecution(200);
-        KdPrint2((PRINT_PREFIX "AtapiSendCommand: DSC not set. %#x => SRB_STATUS_PENDING\n",statusByte));
-        AtaReq->ReqState = REQ_STATE_QUEUED;
-        return SRB_STATUS_PENDING;
-    }
-
-    if(IS_RDP(Srb->Cdb[0])) {
-        chan->RDP = TRUE;
-        KdPrint2((PRINT_PREFIX "AtapiSendCommand: %#x mapped as DSC restrictive\n", Srb->Cdb[0]));
-    } else {
-        chan->RDP = FALSE;
-    }
-    if(statusByte & IDE_STATUS_DRQ) {
-
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status (%#x). Attempting to recover.\n",
-                    statusByte));
-        // Try to drain the data that one preliminary device thinks that it has
-        // to transfer. Hopefully this random assertion of DRQ will not be present
-        // in production devices.
-        statusByte = AtapiSuckPort2(chan);
-/*
-        for (i = 0; i < 0x10000; i++) {
-            GetStatus(chan, statusByte);
-            if(statusByte & IDE_STATUS_DRQ) {
-                AtapiReadPort2(chan, IDX_IO1_i_Data);
-            } else {
-                break;
-            }
-        }
-*/
-        if (statusByte & IDE_STATUS_DRQ) {
-            KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ still asserted. Status (%#x)\n", statusByte));
-make_reset:
-            AtapiDisableInterrupts(deviceExtension, lChannel);
-
-            AtapiSoftReset(chan, DeviceNumber);
-
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: Issued soft reset to Atapi device. \n"));
-            // Re-initialize Atapi device.
-            CheckDevice(HwDeviceExtension, GET_CHANNEL(Srb), DeviceNumber, TRUE);
-/*
-            IssueIdentify(HwDeviceExtension, DeviceNumber, GET_CHANNEL(Srb),
-                          IDE_COMMAND_ATAPI_IDENTIFY, FALSE);
-*/
-            // Inform the port driver that the bus has been reset.
-            ScsiPortNotification(ResetDetected, HwDeviceExtension, 0);
-            // Clean up device extension fields that AtapiStartIo won't.
-            UniataExpectChannelInterrupt(chan, FALSE);
-            chan->RDP = FALSE;
-            InterlockedExchange(&(deviceExtension->chan[GET_CHANNEL(Srb)].CheckIntr),
-                                          CHECK_INTR_IDLE);
-
-            AtapiEnableInterrupts(deviceExtension, lChannel);
-/*
-            AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-            return SRB_STATUS_BUS_RESET;
-*/
-            if(!retried) {
-                KdPrint3((PRINT_PREFIX "AtapiSendCommand: retry after reset.\n"));
-                retried = TRUE;
-                goto retry;
-            }
-            KdPrint3((PRINT_PREFIX "AtapiSendCommand: selection timeout.\n"));
-            AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-            return SRB_STATUS_SELECTION_TIMEOUT;
-        }
-    }
-
-    if(flags & (DFLAGS_SANYO_ATAPI_CHANGER | DFLAGS_ATAPI_CHANGER)) {
-        // As the cdrom driver sets the LUN field in the cdb, it must be removed.
-        Srb->Cdb[1] &= ~0xE0;
-        if((Srb->Cdb[0] == SCSIOP_TEST_UNIT_READY) && (flags & DFLAGS_SANYO_ATAPI_CHANGER)) {
-            // Torisan changer. TUR's are overloaded to be platter switches.
-            Srb->Cdb[7] = Srb->Lun;
-        }
-    }
-
-    // SETUP DMA !!!!!
-
-    if(use_dma) {
-        chan->ChannelCtrlFlags |= CTRFLAGS_DMA_OPERATION;
-    } else {
-        chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
-    }
-
-    if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        KdPrint2((PRINT_PREFIX "AtapiSendCommand: AHCI, begin transaction\n"));
-        //AtaReq->Flags = ~REQ_FLAG_DMA_OPERATION; // keep proped DMA flag for proper RETRY handling
-        UniataExpectChannelInterrupt(chan, TRUE);
-        UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
-        return SRB_STATUS_PENDING;
-    }
-
-    statusByte = WaitOnBusy(chan);
-    KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entry Status (%#x)\n",
-               statusByte));
-
-    if(use_dma) {
-        FeatureReg |= ATA_F_DMA;
-        if(LunExt->IdentifyData.AtapiDMA.DMADirRequired) {
-            if(Srb->SrbFlags & SRB_FLAGS_DATA_IN) {
-                FeatureReg |= ATA_F_DMAREAD;
-            }
-        }
-    }
-
-    // Write transfer byte count to registers.
-    if (Srb->DataTransferLength >= 0x10000) {
-        byteCountLow = byteCountHigh = 0xFF;
-    } else {
-        byteCountLow = (UCHAR)(Srb->DataTransferLength & 0xFF);
-        byteCountHigh = (UCHAR)(Srb->DataTransferLength >> 8);
-    }
-
-    KdPrint3((PRINT_PREFIX "AtapiSendCommand: F:%#x, CntHL:%#x:%#x.\n", FeatureReg, byteCountHigh, byteCountLow));
-
-    if (flags & DFLAGS_INT_DRQ) {
-        // This device interrupts when ready to receive the packet.
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: Wait for int. to send packet. Status (%#x)\n",
-                   statusByte));
-
-        UniataExpectChannelInterrupt(chan, TRUE);
-        AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_CMD_INTR;
-        InterlockedExchange(&(chan->CheckIntr),
-                                      CHECK_INTR_IDLE);
-        // inform driver that packet command must be sent in ISR
-        flags |= DFLAGS_INT_DRQ;
-    } else {
-        // This device quickly sets DRQ when ready to receive the packet.
-        KdPrint2((PRINT_PREFIX "AtapiSendCommand: Poll for int. to send packet. Status (%#x)\n",
-                   statusByte));
-
-        UniataExpectChannelInterrupt(chan, TRUE);
-        AtaReq->ReqState = REQ_STATE_ATAPI_DO_NOTHING_INTR;
-        InterlockedExchange(&(chan->CheckIntr),
-                                      CHECK_INTR_IDLE);
-
-        if(g_opt_AtapiSendDisableIntr) {
-            AtapiDisableInterrupts(deviceExtension, lChannel);
-        }
-        // remember status. Later we may check if error appeared after cmd packet 
-        statusByte0 = statusByte;
-    }
-
-    // must be already selected, experimental for ROS BUG-9119
-    //AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1) );
-    AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Feature /*IDX_IO1_o_Feature*/, FeatureReg);
-    //AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Unused0, 0);  // experimental for ROS BUG-9119
-    //AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Unused1, 0);  // experimental for ROS BUG-9119
-    AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountLow, byteCountLow);
-    AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh, byteCountHigh);
-    // Write ATAPI packet command.
-    AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Command /*IDX_IO1_o_Command*/, IDE_COMMAND_ATAPI_PACKET);
-
-    if (flags & DFLAGS_INT_DRQ) {
-        // Wait for interrupt and send PACKET there
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (DRQ)\n"));
-        return SRB_STATUS_PENDING;
-    }
-
-    WaitOnBusy(chan);
-/*
-    // Wait for DRQ.
-    statusByte = WaitForDrq(chan);
-
-    // Need to read status register and clear interrupt (if any)
-    GetBaseStatus(chan, statusByte);
-
-    if (!(statusByte & IDE_STATUS_DRQ)) {
-        if(g_opt_AtapiSendDisableIntr) {
-            AtapiEnableInterrupts(deviceExtension, lChannel);
-        }
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ never asserted (%#x)\n", statusByte));
-        AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-        return SRB_STATUS_ERROR;
-    }
-*/
-    GetStatus(chan, statusByte);
-    KdPrint3((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte));
-
-    //statusByte = WaitOnBaseBusy(chan);
-
-    // Indicate expecting an interrupt and wait for it.
-    UniataExpectChannelInterrupt(chan, TRUE);
-
-    for(i=0; i<5000; i++) {
-        if(g_opt_AtapiSendDisableIntr) {
-            GetStatus(chan, statusByte);
-        } else {
-            GetBaseStatus(chan, statusByte);
-        }
-        interruptReason = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason);
-        //KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x (%d)\n", interruptReason, i));
-        if(((interruptReason & ATAPI_IR_COD) == ATAPI_IR_COD_Cmd) &&
-           (((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)) == IDE_STATUS_DRQ))) {
-            break;
-        }
-        AtapiStallExecution(g_opt_WaitDrqDelay*2);
-#ifdef _DEBUG
-//        KdPrint3((PRINT_PREFIX "AtapiSendCommand: wait CoD, status (%#x)\n", interruptReason));
-#endif // _DEBUG
-    }
-    if(((interruptReason & ATAPI_IR_COD) != ATAPI_IR_COD_Cmd) ||
-       (((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)) != IDE_STATUS_DRQ)) ) {
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: no CoD raised, abort cmd\n"));
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x (%d)\n", interruptReason, i));
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte));
-        if(g_opt_AtapiSendDisableIntr) {
-            AtapiEnableInterrupts(deviceExtension, lChannel);
-        }
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ+CoD never asserted\n"));
-        statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: Err on cmd: (%#x)\n", statusByte));
-        if(statusByte >> 4) {
-            GetBaseStatus(chan, statusByte);
-            AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-            return MapError(deviceExtension, Srb);
-        }
-        goto make_reset;
-//        AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-//        return SRB_STATUS_ERROR;
-    } else {
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: ready for packet, status %#x, i=%d\n", interruptReason, i));
-    }
-    // clear interrupt
-    GetBaseStatus(chan, statusByte);
-
-    if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) {
-        AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb);
-    }
-    if(g_opt_AtapiSendDisableIntr) {
-        AtapiEnableInterrupts(deviceExtension, lChannel);
-    }
-
-    // Send CDB to device.
-    WriteBuffer(chan,
-                (PUSHORT)Srb->Cdb,
-                LunExt->IdentifyData.AtapiCmdSize ? 8 : 6,
-                /*0*/ PIO0_TIMING);
-
-    GetStatus(chan, statusByte);
-    KdPrint3((PRINT_PREFIX "AtapiSendCommand: cmd status (%#x)\n", statusByte));
-
-    // When we operate in DMA mode, we should not start transfer when there is an error on entry
-    // Interrupt may never come in such case.
-    if(statusByte & IDE_STATUS_ERROR) {
-
-        GetBaseStatus(chan, statusByte);
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on cmd: (%#x)\n", statusByte));
-
-        interruptReason = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x\n", interruptReason));
-
-        // TODO:  we should check interruptReason and decide what to do now
-
-        // Read the error reg. to clear it and fail this request.
-        AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-        return MapError(deviceExtension, Srb);
-    }
-    if(statusByte & IDE_STATUS_DRQ) {
-        // Some devices require this. If error condition is not checked in such a way,
-        // device may not operate correctly and would be treated as failed
-        // (and finally invisible for OS)
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ on cmd: (%#x)\n", statusByte));
-        // Read the error reg. to clear it and fail this request.
-        statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: Err on cmd: (%#x)\n", statusByte));
-        if(statusByte >> 4) {
-            GetBaseStatus(chan, statusByte);
-            AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-            return MapError(deviceExtension, Srb);
-        }
-    }
-
-    if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) {
-        AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
-    }
-
-    InterlockedExchange(&(chan->CheckIntr),
-                                  CHECK_INTR_IDLE);
-    AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR;
-
-    KdPrint3((PRINT_PREFIX "AtapiSendCommand: ExpectingInterrupt (%#x)\n", chan->ExpectingInterrupt));
-
-    KdPrint2((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (3)\n"));
-    return SRB_STATUS_PENDING;
-
-} // end AtapiSendCommand()
-
-
-#ifndef UNIATA_CORE
-
-/*++
-
-Routine Description:
-    Program ATA registers for IDE disk transfer.
-
-Arguments:
-    HwDeviceExtension - ATAPI driver storage.
-    Srb - System request block.
-
-Return Value:
-    SRB status (pending if all goes well).
-
---*/
-
-#ifdef _DEBUG
-ULONG check_point = 0;
-#define SetCheckPoint(cp)  { check_point = (cp) ; }
-#else
-#define SetCheckPoint(cp)
-#endif
-
-ULONG
-NTAPI
-IdeSendCommand(
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb,
-    IN ULONG CmdAction
-    )
-{
-    SetCheckPoint(1);
-    KdPrint2((PRINT_PREFIX "** Ide: Command: entryway\n"));
-    SetCheckPoint(2);
-
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    SetCheckPoint(3);
-    UCHAR                lChannel;
-    PHW_CHANNEL          chan;
-    PCDB cdb;
-    PHW_LU_EXTENSION     LunExt;
-
-    SetCheckPoint(4);
-
-    UCHAR statusByte,errorByte;
-    ULONG status = SRB_STATUS_INVALID_REQUEST;
-    ULONG i;
-    ULONGLONG lba;
-    PMODE_PARAMETER_HEADER   modeData;
-    //ULONG ldev;
-    ULONG DeviceNumber;
-    PATA_REQ AtaReq;
-    UCHAR command;
-
-    SetCheckPoint(5);
-    //ULONG __ebp__ = 0;
-
-    SetCheckPoint(0x20);
-    KdPrint2((PRINT_PREFIX "** Ide: Command:\n\n"));
-/*    __asm {
-        mov eax,ebp
-        mov __ebp__, eax
-    }*/
-    /*KdPrint2((PRINT_PREFIX "** Ide: Command EBP %#x, pCdb %#x, cmd %#x\n",
-        __ebp__, &(Srb->Cdb[0]), Srb->Cdb[0]));
-    KdPrint2((PRINT_PREFIX "** Ide: Command %s\n",
-        (CmdAction == CMD_ACTION_PREPARE) ? "Prep " : ""));
-    KdPrint2((PRINT_PREFIX "** Ide: Command Srb %#x\n",
-        Srb));
-    KdPrint2((PRINT_PREFIX "** Ide: Command SrbExt %#x\n",
-        Srb->SrbExtension));
-    KdPrint2((PRINT_PREFIX "** Ide: Command to device %d\n",
-        Srb->TargetId));*/
-
-    SetCheckPoint(0x30);
-    AtaReq = (PATA_REQ)(Srb->SrbExtension);
-
-    KdPrint2((PRINT_PREFIX "** Ide: Command &AtaReq %#x\n",
-        &AtaReq));
-    KdPrint2((PRINT_PREFIX "** Ide: Command AtaReq %#x\n",
-        AtaReq));
-    KdPrint2((PRINT_PREFIX "** --- **\n"));
-
-    lChannel = GET_CHANNEL(Srb);
-    chan = &(deviceExtension->chan[lChannel]);
-    //ldev = GET_LDEV(Srb);
-    DeviceNumber = GET_CDEV(Srb);
-    LunExt = chan->lun[DeviceNumber];
-
-    SetCheckPoint(0x40);
-    if(AtaReq->ReqState < REQ_STATE_PREPARE_TO_TRANSFER)
-        AtaReq->ReqState = REQ_STATE_PREPARE_TO_TRANSFER;
-
-    cdb = (PCDB)(Srb->Cdb);
-
-    if(CmdAction == CMD_ACTION_PREPARE) {
-        switch (Srb->Cdb[0]) {
-        case SCSIOP_SERVICE_ACTION16:
-            if( cdb->SERVICE_ACTION16.ServiceAction==SCSIOP_SA_READ_CAPACITY16 ) {
-                // ok
-            } else {
-                goto default_no_prep;
-            }
-#ifdef NAVO_TEST
-        case SCSIOP_INQUIRY: // now it requires device access
-#endif //NAVO_TEST
-        case SCSIOP_READ_CAPACITY:
-        case SCSIOP_READ:
-        case SCSIOP_WRITE:
-        case SCSIOP_READ12:
-        case SCSIOP_WRITE12:
-        case SCSIOP_READ16:
-        case SCSIOP_WRITE16:
-        case SCSIOP_REQUEST_SENSE:
-            // all right
-            KdPrint2((PRINT_PREFIX "** Ide: Command continue prep\n"));
-            SetCheckPoint(50);
-            break;
-        default:
-default_no_prep:
-            SetCheckPoint(0);
-            KdPrint2((PRINT_PREFIX "** Ide: Command break prep\n"));
-            return SRB_STATUS_BUSY;
-        }
-    }
-
-    SetCheckPoint(0x100 | Srb->Cdb[0]);
-    switch (Srb->Cdb[0]) {
-    case SCSIOP_INQUIRY:
-
-        KdPrint2((PRINT_PREFIX 
-                   "IdeSendCommand: SCSIOP_INQUIRY PATH:LUN:TID = %#x:%#x:%#x\n",
-                   Srb->PathId, Srb->Lun, Srb->TargetId));
-        // Filter out wrong TIDs.
-        if ((Srb->Lun != 0) ||
-            (Srb->PathId >= deviceExtension->NumberChannels) ||
-            (Srb->TargetId >= deviceExtension->NumberLuns)) {
-
-            KdPrint2((PRINT_PREFIX 
-                       "IdeSendCommand: SCSIOP_INQUIRY rejected\n"));
-            // Indicate no device found at this address.
-            status = SRB_STATUS_SELECTION_TIMEOUT;
-            break;
-
-        } else {
-
-            KdPrint2((PRINT_PREFIX 
-                       "IdeSendCommand: SCSIOP_INQUIRY ok\n"));
-            PINQUIRYDATA    inquiryData  = (PINQUIRYDATA)(Srb->DataBuffer);
-            PIDENTIFY_DATA2 identifyData = &(LunExt->IdentifyData);
-
-            if (!(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
-                
-                if(!CheckDevice(HwDeviceExtension, lChannel, DeviceNumber, FALSE)) {
-                    KdPrint2((PRINT_PREFIX 
-                               "IdeSendCommand: SCSIOP_INQUIRY rejected (2)\n"));
-                    // Indicate no device found at this address.
-#ifndef NAVO_TEST
-                    status = SRB_STATUS_SELECTION_TIMEOUT;
-                    break;
-                }
-            } else {
-                if(!UniataAnybodyHome(HwDeviceExtension, lChannel, DeviceNumber)) {
-                    KdPrint2((PRINT_PREFIX 
-                               "IdeSendCommand: SCSIOP_INQUIRY device have gone\n"));
-                    // Indicate no device found at this address.
-                    UniataForgetDevice(chan->lun[DeviceNumber]);
-#endif //NAVO_TEST
-                    status = SRB_STATUS_SELECTION_TIMEOUT;
-                    break;
-                }
-            }
-
-            // Zero INQUIRY data structure.
-            RtlZeroMemory((PCHAR)(Srb->DataBuffer), Srb->DataTransferLength);
-
-            // Standard IDE interface only supports disks.
-            inquiryData->DeviceType = DIRECT_ACCESS_DEVICE;
-
-            // Set the removable bit, if applicable.
-            if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) {
-                KdPrint2((PRINT_PREFIX 
-                           "RemovableMedia\n"));
-                inquiryData->RemovableMedia = 1;
-            }
-            // Set the Relative Addressing (LBA) bit, if applicable.
-            if (LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
-                inquiryData->RelativeAddressing = 1;
-                KdPrint2((PRINT_PREFIX 
-                           "RelativeAddressing\n"));
-            }
-            // Set the CommandQueue bit
-            inquiryData->CommandQueue = 1;
-
-            // Fill in vendor identification fields.
-            for (i = 0; i < 24; i += 2) {
-                MOV_DW_SWP(inquiryData->DeviceIdentificationString[i], ((PUCHAR)identifyData->ModelNumber)[i]);
-            }
-/*
-            // Initialize unused portion of product id.
-            for (i = 0; i < 4; i++) {
-                inquiryData->ProductId[12+i] = ' ';
-            }
-*/
-            // Move firmware revision from IDENTIFY data to
-            // product revision in INQUIRY data.
-            for (i = 0; i < 4; i += 2) {
-                MOV_DW_SWP(inquiryData->ProductRevisionLevel[i], ((PUCHAR)identifyData->FirmwareRevision)[i]);
-            }
-
-            status = SRB_STATUS_SUCCESS;
-        }
-
-        break;
-
-    case SCSIOP_REPORT_LUNS: {
-
-        ULONG alen;
-        PREPORT_LUNS_INFO_HDR LunInfo;
-        
-        KdPrint2((PRINT_PREFIX 
-                   "IdeSendCommand: SCSIOP_REPORT_LUNS PATH:LUN:TID = %#x:%#x:%#x\n",
-                   Srb->PathId, Srb->Lun, Srb->TargetId));
-
-        MOV_DD_SWP(alen, cdb->REPORT_LUNS.AllocationLength);
-
-        if(alen < 16) {
-            goto invalid_cdb;
-        }
-        alen = 8;
-
-        LunInfo = (PREPORT_LUNS_INFO_HDR)(Srb->DataBuffer);
-        RtlZeroMemory(LunInfo, 16);
-
-        MOV_DD_SWP( LunInfo->ListLength, alen );
-        Srb->DataTransferLength = 16;
-        status = SRB_STATUS_SUCCESS;
-
-        break; }
-
-    case SCSIOP_MODE_SENSE:
-
-        KdPrint2((PRINT_PREFIX 
-                   "IdeSendCommand: SCSIOP_MODE_SENSE PATH:LUN:TID = %#x:%#x:%#x\n",
-                   Srb->PathId, Srb->Lun, Srb->TargetId));
-        
-        if(cdb->MODE_SENSE.PageCode == MODE_PAGE_POWER_CONDITION) {
-            PMODE_POWER_CONDITION_PAGE modeData;
-
-            KdPrint2((PRINT_PREFIX "MODE_PAGE_POWER_CONDITION\n"));
-            modeData = (PMODE_POWER_CONDITION_PAGE)(Srb->DataBuffer);
-            if(cdb->MODE_SENSE.AllocationLength < sizeof(MODE_POWER_CONDITION_PAGE)) {
-                status = SRB_STATUS_DATA_OVERRUN;
-            } else {
-                RtlZeroMemory(modeData, sizeof(MODE_POWER_CONDITION_PAGE));
-                modeData->PageCode = MODE_PAGE_POWER_CONDITION;
-#ifdef __REACTOS__
-                modeData->PageLength = sizeof(MODE_POWER_CONDITION_PAGE)-sizeof(MODE_PARAMETER_HEADER);
-#else
-                modeData->PageLength = sizeof(MODE_PAGE_POWER_CONDITION)-sizeof(MODE_PARAMETER_HEADER);
-#endif
-                modeData->Byte3.Fields.Idle = LunExt->PowerState <= StartStop_Power_Idle;
-                modeData->Byte3.Fields.Standby = LunExt->PowerState == StartStop_Power_Standby;
-                Srb->DataTransferLength = sizeof(MODE_POWER_CONDITION_PAGE);
-                status = SRB_STATUS_SUCCESS;
-            }
-        } else
-        if(cdb->MODE_SENSE.PageCode == MODE_PAGE_CACHING) {
-            PMODE_CACHING_PAGE modeData;
-
-            KdPrint2((PRINT_PREFIX "MODE_PAGE_CACHING\n"));
-            modeData = (PMODE_CACHING_PAGE)(Srb->DataBuffer);
-            if(cdb->MODE_SENSE.AllocationLength < sizeof(MODE_CACHING_PAGE)) {
-                status = SRB_STATUS_DATA_OVERRUN;
-            } else {
-                RtlZeroMemory(modeData, sizeof(MODE_CACHING_PAGE));
-                modeData->PageCode = MODE_PAGE_CACHING;
-                modeData->PageLength = sizeof(MODE_CACHING_PAGE)-sizeof(MODE_PARAMETER_HEADER);
-                modeData->ReadDisableCache = (LunExt->DeviceFlags & DFLAGS_RCACHE_ENABLED) ? 0 : 1;
-                modeData->WriteCacheEnable = (LunExt->DeviceFlags & DFLAGS_WCACHE_ENABLED) ? 1 : 0;
-                Srb->DataTransferLength = sizeof(MODE_CACHING_PAGE);
-                status = SRB_STATUS_SUCCESS;
-            }
-        } else
-        if (LunExt->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED) {
-
-            // This is used to determine if the media is write-protected.
-            // Since IDE does not support mode sense then we will modify just the portion we need
-            // so the higher level driver can determine if media is protected.
-
-            //SelectDrive(chan, DeviceNumber);
-            //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_GET_MEDIA_STATUS);
-            //statusByte = WaitOnBusy(chan);
-            statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_GET_MEDIA_STATUS, 0, 0, 0, 0, 0, ATA_WAIT_READY);
-
-            if (!(statusByte & IDE_STATUS_ERROR)) {
-
-                // no error occured return success, media is not protected
-                UniataExpectChannelInterrupt(chan, FALSE);
-                InterlockedExchange(&(chan->CheckIntr),
-                                              CHECK_INTR_IDLE);
-                status = SRB_STATUS_SUCCESS;
-
-            } else {
-
-                // error occured, handle it locally, clear interrupt
-                errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
-
-                GetBaseStatus(chan, statusByte);
-                UniataExpectChannelInterrupt(chan, FALSE);
-                InterlockedExchange(&(chan->CheckIntr),
-                                              CHECK_INTR_IDLE);
-                status = SRB_STATUS_SUCCESS;
-
-                if (errorByte & IDE_ERROR_DATA_ERROR) {
-
-                    //media is write-protected, set bit in mode sense buffer
-                    modeData = (PMODE_PARAMETER_HEADER)Srb->DataBuffer;
-
-                    Srb->DataTransferLength = sizeof(MODE_PARAMETER_HEADER);
-                    modeData->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
-                }
-            }
-            status = SRB_STATUS_SUCCESS;
-        } else {
-            status = SRB_STATUS_INVALID_REQUEST;
-        }
-        break;
-
-    case SCSIOP_TEST_UNIT_READY:
-
-        KdPrint2((PRINT_PREFIX 
-                   "IdeSendCommand: SCSIOP_TEST_UNIT_READY PATH:LUN:TID = %#x:%#x:%#x\n",
-                   Srb->PathId, Srb->Lun, Srb->TargetId));
-        if (chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED) {
-
-            // Select device 0 or 1.
-            //SelectDrive(chan, DeviceNumber);
-            //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_GET_MEDIA_STATUS);
-            // Wait for busy. If media has not changed, return success
-            //statusByte = WaitOnBusy(chan);
-            statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_GET_MEDIA_STATUS, 0, 0, 0, 0, 0, ATA_WAIT_READY);
-
-            if (!(statusByte & IDE_STATUS_ERROR)){
-                UniataExpectChannelInterrupt(chan, FALSE);
-                InterlockedExchange(&(chan->CheckIntr),
-                                              CHECK_INTR_IDLE);
-                status = SRB_STATUS_SUCCESS;
-            } else {
-                errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
-                if (errorByte == IDE_ERROR_DATA_ERROR){
-
-                    // Special case: If current media is write-protected,
-                    // the 0xDA command will always fail since the write-protect bit
-                    // is sticky,so we can ignore this error
-                    GetBaseStatus(chan, statusByte);
-                    UniataExpectChannelInterrupt(chan, FALSE);
-                    InterlockedExchange(&(chan->CheckIntr),
-                                                  CHECK_INTR_IDLE);
-                    status = SRB_STATUS_SUCCESS;
-
-                } else {
-
-                    // Request sense buffer to be build
-                    UniataExpectChannelInterrupt(chan, TRUE);
-                    InterlockedExchange(&(chan->CheckIntr),
-                                                  CHECK_INTR_IDLE);
-                    status = SRB_STATUS_PENDING;
-               }
-            }
-        } else {
-            status = SRB_STATUS_SUCCESS;
-        }
-
-        break;
-
-    case SCSIOP_READ_CAPACITY:
-
-        KdPrint2((PRINT_PREFIX 
-                   "** IdeSendCommand: SCSIOP_READ_CAPACITY PATH:LUN:TID = %#x:%#x:%#x\n",
-                   Srb->PathId, Srb->Lun, Srb->TargetId));
-        // Claim 512 byte blocks (big-endian).
-        //((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock = 0x20000;
-        i = DEV_BSIZE;
-        RtlZeroMemory(Srb->DataBuffer, sizeof(READ_CAPACITY_DATA));
-        MOV_DD_SWP( ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock, i );
-
-        // Calculate last sector.
-        if(!(i = (ULONG)LunExt->NumOfSectors)) {
-            i = LunExt->IdentifyData.SectorsPerTrack *
-                LunExt->IdentifyData.NumberOfHeads *
-                LunExt->IdentifyData.NumberOfCylinders;
-        }
-        i--;
-
-        //((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress =
-        //    (((PUCHAR)&i)[0] << 24) |  (((PUCHAR)&i)[1] << 16) |
-        //    (((PUCHAR)&i)[2] << 8) | ((PUCHAR)&i)[3];
-
-        MOV_DD_SWP( ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress, i );
-
-        KdPrint2((PRINT_PREFIX 
-                   "** IDE disk %#x - #sectors %#x, #heads %#x, #cylinders %#x\n",
-                   Srb->TargetId,
-                   LunExt->IdentifyData.SectorsPerTrack,
-                   LunExt->IdentifyData.NumberOfHeads,
-                   LunExt->IdentifyData.NumberOfCylinders));
-
-
-        status = SRB_STATUS_SUCCESS;
-        break;
-
-    case SCSIOP_SERVICE_ACTION16:
-
-        if( cdb->SERVICE_ACTION16.ServiceAction==SCSIOP_SA_READ_CAPACITY16 ) {
-            KdPrint2((PRINT_PREFIX 
-                       "** IdeSendCommand: SCSIOP_READ_CAPACITY PATH:LUN:TID = %#x:%#x:%#x\n",
-                       Srb->PathId, Srb->Lun, Srb->TargetId));
-            // Claim 512 byte blocks (big-endian).
-            //((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock = 0x20000;
-            i = DEV_BSIZE;
-            RtlZeroMemory(Srb->DataBuffer, sizeof(READ_CAPACITY16_DATA));
-            MOV_DD_SWP( ((PREAD_CAPACITY16_DATA)Srb->DataBuffer)->BytesPerBlock, i );
-
-            // Calculate last sector.
-            if(!(lba = LunExt->NumOfSectors)) {
-                lba = LunExt->IdentifyData.SectorsPerTrack *
-                    LunExt->IdentifyData.NumberOfHeads *
-                    LunExt->IdentifyData.NumberOfCylinders;
-            }
-            lba--;
-            MOV_QD_SWP( ((PREAD_CAPACITY16_DATA)Srb->DataBuffer)->LogicalBlockAddress, lba );
-
-            KdPrint2((PRINT_PREFIX 
-                       "** IDE disk %#x - #sectors %#x, #heads %#x, #cylinders %#x (16)\n",
-                       Srb->TargetId,
-                       LunExt->IdentifyData.SectorsPerTrack,
-                       LunExt->IdentifyData.NumberOfHeads,
-                       LunExt->IdentifyData.NumberOfCylinders));
-
-            status = SRB_STATUS_SUCCESS;
-        } else {
-            goto default_abort;
-        }
-        break;
-
-    case SCSIOP_VERIFY:
-    case SCSIOP_VERIFY12:
-    case SCSIOP_VERIFY16:
-
-        KdPrint2((PRINT_PREFIX 
-                   "IdeSendCommand: SCSIOP_VERIFY PATH:LUN:TID = %#x:%#x:%#x\n",
-                   Srb->PathId, Srb->Lun, Srb->TargetId));
-        status = IdeVerify(HwDeviceExtension,Srb);
-
-        break;
-
-    case SCSIOP_READ:
-    case SCSIOP_WRITE:
-    case SCSIOP_READ12:
-    case SCSIOP_WRITE12:
-    case SCSIOP_READ16:
-    case SCSIOP_WRITE16:
-
-        KdPrint2((PRINT_PREFIX 
-                   "IdeSendCommand: SCSIOP_%s PATH:LUN:TID = %#x:%#x:%#x\n",
-                   (Srb->Cdb[0] == SCSIOP_WRITE) ? "WRITE" : "READ",
-                   Srb->PathId, Srb->Lun, Srb->TargetId));
-        AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
-        AtaReq->Flags |= (Srb->Cdb[0] == SCSIOP_WRITE ||
-                          Srb->Cdb[0] == SCSIOP_WRITE12 ||
-                          Srb->Cdb[0] == SCSIOP_WRITE16) ? REQ_FLAG_WRITE : REQ_FLAG_READ;
-        status = IdeReadWrite(HwDeviceExtension,
-                              Srb, CmdAction);
-        break;
-
-    case SCSIOP_START_STOP_UNIT:
-
-        KdPrint2((PRINT_PREFIX 
-                   "IdeSendCommand: SCSIOP_START_STOP_UNIT immed %d PATH:LUN:TID = %#x:%#x:%#x\n",
-                   cdb->START_STOP.Immediate, Srb->PathId, Srb->Lun, Srb->TargetId));
-        //Determine what type of operation we should perform
-
-        command = 0;
-
-        if(cdb->START_STOP.FL ||
-           cdb->START_STOP.FormatLayerNumber ||
-           cdb->START_STOP.Reserved2 ||
-           cdb->START_STOP.Reserved2_2 ||
-           cdb->START_STOP.Reserved3 ||
-           FALSE) {
-            goto invalid_cdb;
-        }
-
-        if (cdb->START_STOP.PowerConditions) {
-            KdPrint2((PRINT_PREFIX "START_STOP Power %d\n", cdb->START_STOP.PowerConditions));
-            switch(cdb->START_STOP.PowerConditions) {
-            case StartStop_Power_Idle:
-                command = IDE_COMMAND_IDLE_IMMED;
-                break;
-            case StartStop_Power_Standby:
-                command = IDE_COMMAND_STANDBY_IMMED;
-                break;
-            case StartStop_Power_Sleep:
-                // TODO: we should save power state in order to know
-                // that RESET sould be issued to revert device into
-                // operable state
-
-                command = IDE_COMMAND_SLEEP;
-                break;
-            default:
-                goto invalid_cdb;
-            }
-            LunExt->PowerState = cdb->START_STOP.PowerConditions;
-        } else
-        if (cdb->START_STOP.LoadEject == 1) {
-            KdPrint2((PRINT_PREFIX "START_STOP eject\n"));
-            // Eject media,
-            // first select device 0 or 1.
-            //SelectDrive(chan, DeviceNumber);
-            //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_MEDIA_EJECT);
-            command = IDE_COMMAND_MEDIA_EJECT;
-        } else
-        if (cdb->START_STOP.Start == 0) {
-            KdPrint2((PRINT_PREFIX "START_STOP standby\n"));
-            command = IDE_COMMAND_STANDBY_IMMED;
-        } else {
-            // TODO: we may need to perform hard reset (after sleep) or
-            // issue IDE_COMMAND_IDLE_IMMED in order to activate device
-            KdPrint2((PRINT_PREFIX "START_STOP activate\n"));
-
-            if(LunExt->PowerState == StartStop_Power_Sleep) {
-                UniataUserDeviceReset(deviceExtension, LunExt, lChannel);
-                status = SRB_STATUS_SUCCESS;
-                break;
-            } else
-            if(LunExt->PowerState > StartStop_Power_Idle) {
-                KdPrint2((PRINT_PREFIX "  issue IDLE\n"));
-                command = IDE_COMMAND_IDLE_IMMED;
-            } else {
-                KdPrint2((PRINT_PREFIX "  do nothing\n"));
-                status = SRB_STATUS_SUCCESS;
-                break;
-            }
-        }
-        if(command) {
-            statusByte = WaitOnBaseBusy(chan);
-            statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, command, 0, 0, 0, 0, 0, 
-                cdb->START_STOP.Immediate ? ATA_IMMEDIATE : ATA_WAIT_READY);
-            status = (statusByte & IDE_STATUS_ERROR) ? SRB_STATUS_ERROR : SRB_STATUS_SUCCESS;
-            //UniataExpectChannelInterrupt(chan, TRUE); // device may interrupt
-
-        } else {
-invalid_cdb:
-            KdPrint2((PRINT_PREFIX "START_STOP invalid\n"));
-            if (Srb->SenseInfoBuffer) {
-
-                PSENSE_DATA  senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
-
-                senseBuffer->ErrorCode = 0x70;
-                senseBuffer->Valid     = 1;
-                senseBuffer->AdditionalSenseLength = 0xb;
-                senseBuffer->SenseKey = SCSI_SENSE_ILLEGAL_REQUEST;
-                senseBuffer->AdditionalSenseCode = SCSI_ADSENSE_INVALID_CDB;
-                senseBuffer->AdditionalSenseCodeQualifier = 0;
-
-                Srb->SrbStatus = SRB_STATUS_AUTOSENSE_VALID;
-                Srb->ScsiStatus = SCSISTAT_CHECK_CONDITION;
-            }
-            status = SRB_STATUS_ERROR;
-        }
-        break;
-
-    case SCSIOP_MEDIUM_REMOVAL:
-
-        cdb = (PCDB)Srb->Cdb;
-
-        if(LunExt->IdentifyData.Removable) {
-            statusByte = WaitOnBaseBusy(chan);
-
-            //SelectDrive(chan, DeviceNumber);
-            if (cdb->MEDIA_REMOVAL.Prevent != FALSE) {
-                //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_DOOR_LOCK);
-                statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_DOOR_LOCK, 0, 0, 0, 0, 0, ATA_IMMEDIATE);
-            } else {
-                //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_DOOR_UNLOCK);
-                statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_DOOR_UNLOCK, 0, 0, 0, 0, 0, ATA_IMMEDIATE);
-            }
-            status = SRB_STATUS_SUCCESS;
-        } else {
-            status = SRB_STATUS_INVALID_REQUEST;
-        }
-        break;
-
-#if 0
-    // Note: I don't implement this, because NTFS driver too often issues this command
-    // It causes awful performance degrade. However, if somebody wants, I will implement
-    // SCSIOP_FLUSH_BUFFER/SCSIOP_SYNCHRONIZE_CACHE optionally.
-    case SCSIOP_FLUSH_BUFFER:
-    case SCSIOP_SYNCHRONIZE_CACHE:
-
-        SelectDrive(chan, DeviceNumber);
-        AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_FLUSH_CACHE);
-        status = SRB_STATUS_SUCCESS;
-//        status = SRB_STATUS_PENDING;
-        statusByte = WaitOnBusy(chan);
-        break;
-#endif
-
-    case SCSIOP_REQUEST_SENSE:
-        // this function makes sense buffers to report the results
-        // of the original GET_MEDIA_STATUS command
-
-        KdPrint2((PRINT_PREFIX 
-                   "IdeSendCommand: SCSIOP_REQUEST_SENSE PATH:LUN:TID = %#x:%#x:%#x\n",
-                   Srb->PathId, Srb->Lun, Srb->TargetId));
-        if (LunExt->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED) {
-            status = IdeBuildSenseBuffer(HwDeviceExtension,Srb);
-            break;
-        }
-        status = SRB_STATUS_INVALID_REQUEST;
-        break;
-
-    // ATA_PASSTHORUGH
-    case SCSIOP_ATA_PASSTHROUGH:
-    {
-        PIDEREGS_EX regs;
-        BOOLEAN use_dma = FALSE;
-        ULONG to_lim;
-        
-        regs = (PIDEREGS_EX) &(Srb->Cdb[2]);
-
-        if(chan->DeviceExtension->HwFlags & UNIATA_SATA) {
-            //lChannel = Srb->TargetId >> 1;
-        } else {
-            DeviceNumber = max(DeviceNumber, 1);
-            regs->bDriveHeadReg &= 0x0f;
-            regs->bDriveHeadReg |= (UCHAR) (((DeviceNumber & 0x1) << 4) | 0xA0);
-        }
-
-        if((regs->bOpFlags & 1) == 0) {      // execute ATA command
-
-            KdPrint2((PRINT_PREFIX 
-                       "IdeSendCommand: SCSIOP_ATA_PASSTHROUGH (exec) PATH:LUN:TID = %#x:%#x:%#x\n",
-                       Srb->PathId, Srb->Lun, Srb->TargetId));
-
-            if((regs->bOpFlags & UNIATA_SPTI_EX_SPEC_TO) == UNIATA_SPTI_EX_SPEC_TO) {
-                to_lim = Srb->TimeOutValue;
-            } else {
-                if(Srb->TimeOutValue <= 2) {
-                    to_lim = Srb->TimeOutValue*900;
-                } else {
-                    to_lim = (Srb->TimeOutValue*999) - 500;
-                }
-            }
-
-            AtapiDisableInterrupts(deviceExtension, lChannel);
-
-            if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
-                // AHCI
-                statusByte = UniataAhciSendPIOCommandDirect(
-                        deviceExtension,
-                        lChannel,
-                        DeviceNumber,
-                        Srb,
-                        regs,
-                        ATA_WAIT_INTR,
-                        to_lim
-                        );
-                if(statusByte == IDE_STATUS_WRONG) {
-                    goto passthrough_err;
-                }
-                if(statusByte & (IDE_STATUS_BUSY | IDE_STATUS_ERROR)) {
-                    UniataAhciAbortOperation(chan);
-                    goto passthrough_err;
-                }
-                goto passthrough_done;
-            }
-
-            // SATA/PATA
-            if((AtaCommandFlags[regs->bCommandReg] & ATA_CMD_FLAG_DMA) || (regs->bOpFlags & UNIATA_SPTI_EX_USE_DMA)) {
-                if((chan->lun[DeviceNumber]->LimitedTransferMode >= ATA_DMA)) {
-                    use_dma = TRUE;
-                    // this will set REQ_FLAG_DMA_OPERATION in AtaReq->Flags on success
-                    if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
-                                  (PUCHAR)(Srb->DataBuffer),
-                                  ((Srb->DataTransferLength + DEV_BSIZE-1) & ~(DEV_BSIZE-1)))) {
-                        use_dma = FALSE;
-                    }
-                }
-            }
-
-            AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, regs->bDriveHeadReg);
-            AtapiStallExecution(10);
-            if(use_dma) {
-                AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb);
-            }
-
-            if((regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) == 0) {      // execute ATA command
-                AtapiWritePort1(chan, IDX_IO1_o_Feature,      regs->bFeaturesReg);
-                AtapiWritePort1(chan, IDX_IO1_o_BlockCount,   regs->bSectorCountReg);
-                AtapiWritePort1(chan, IDX_IO1_o_BlockNumber,  regs->bSectorNumberReg);
-                AtapiWritePort1(chan, IDX_IO1_o_CylinderLow,  regs->bCylLowReg);
-                AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, regs->bCylHighReg);
-            } else {
-                AtapiWritePort1(chan, IDX_IO1_o_Feature,      regs->bFeaturesRegH);
-                AtapiWritePort1(chan, IDX_IO1_o_Feature,      regs->bFeaturesReg);
-                AtapiWritePort1(chan, IDX_IO1_o_BlockCount,   regs->bSectorCountRegH);
-                AtapiWritePort1(chan, IDX_IO1_o_BlockCount,   regs->bSectorCountReg);
-                AtapiWritePort1(chan, IDX_IO1_o_BlockNumber,  regs->bSectorNumberRegH);
-                AtapiWritePort1(chan, IDX_IO1_o_BlockNumber,  regs->bSectorNumberReg);
-                AtapiWritePort1(chan, IDX_IO1_o_CylinderLow,  regs->bCylLowRegH);
-                AtapiWritePort1(chan, IDX_IO1_o_CylinderLow,  regs->bCylLowReg);
-                AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, regs->bCylHighRegH);
-                AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, regs->bCylHighReg);
-            }
-            AtapiWritePort1(chan, IDX_IO1_o_Command,      regs->bCommandReg);
-            
-            if(use_dma) {
-                GetBaseStatus(chan, statusByte);
-                if(statusByte & IDE_STATUS_ERROR) {
-                    goto passthrough_err;
-                }
-                AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
-            }
-
-            ScsiPortStallExecution(1);                  // wait for busy to be set
-
-            for(i=0; i<to_lim;i+=2) {      // 2 msec from WaitOnBaseBusy()
-                statusByte = WaitOnBaseBusy(chan);      // wait for busy to be clear, up to 2 msec
-                GetBaseStatus(chan, statusByte);
-                if(statusByte & IDE_STATUS_ERROR) {
-                    break;
-                }
-                if(!(statusByte & IDE_STATUS_BUSY)) {
-                    break;
-                }
-            }
-            if(i >= to_lim) {
-                //if(regs->bOpFlags & UNIATA_SPTI_EX_FREEZE_TO) {
-                //}
-                AtapiResetController__(HwDeviceExtension, lChannel, RESET_COMPLETE_NONE);
-                goto passthrough_err;
-            }
-
-            if(use_dma) {
-                AtapiCheckInterrupt__(deviceExtension, (UCHAR)lChannel);
-            }
-            AtapiDmaDone(deviceExtension, DeviceNumber, lChannel, NULL);
-            GetBaseStatus(chan, statusByte);
-
-            if(statusByte & (IDE_STATUS_BUSY | IDE_STATUS_ERROR)) {
-                AtapiSuckPort2(chan);
-passthrough_err:
-                if (Srb->SenseInfoBuffer) {
-
-                    PSENSE_DATA  senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
-
-                    senseBuffer->ErrorCode = 0x70;
-                    senseBuffer->Valid     = 1;
-                    senseBuffer->AdditionalSenseLength = 0xb;
-                    senseBuffer->SenseKey =  SCSI_SENSE_ABORTED_COMMAND;
-                    senseBuffer->AdditionalSenseCode = 0;
-                    senseBuffer->AdditionalSenseCodeQualifier = 0;
-
-                    Srb->SrbStatus = SRB_STATUS_AUTOSENSE_VALID;
-                    Srb->ScsiStatus = SCSISTAT_CHECK_CONDITION;
-                }
-                status = SRB_STATUS_ERROR;
-            } else {
-
-                if(!use_dma) {
-                    if (statusByte & IDE_STATUS_DRQ) {
-                        if (Srb->SrbFlags & SRB_FLAGS_DATA_IN) {
-                            ReadBuffer(chan,
-                                       (PUSHORT) Srb->DataBuffer,
-                                       Srb->DataTransferLength / 2,
-                                       0);
-                        } else if (Srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
-                            WriteBuffer(chan,
-                                        (PUSHORT) Srb->DataBuffer,
-                                        Srb->DataTransferLength / 2,
-                                        0);
-                        }
-                    }
-                }
-                status = SRB_STATUS_SUCCESS;
-            }
-passthrough_done:;
-            AtapiEnableInterrupts(deviceExtension, lChannel);
-
-        } else { // read task register
-
-            BOOLEAN use48;
-            regs = (PIDEREGS_EX) Srb->DataBuffer;
-
-            KdPrint2((PRINT_PREFIX 
-                       "IdeSendCommand: SCSIOP_ATA_PASSTHROUGH (snap) PATH:LUN:TID = %#x:%#x:%#x\n",
-                       Srb->PathId, Srb->Lun, Srb->TargetId));
-
-            if((Srb->DataTransferLength >= sizeof(IDEREGS_EX)) &&
-               (regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND)) {
-                use48 = TRUE;
-            } else
-            if(Srb->DataTransferLength >= sizeof(IDEREGS)) {
-                use48 = FALSE;
-            } else {
-                KdPrint2((PRINT_PREFIX " buffer too small \n"));
-                status = SRB_STATUS_DATA_OVERRUN;
-                break;
-            }
-            RtlZeroMemory(regs, use48 ? sizeof(IDEREGS_EX) : sizeof(IDEREGS));
-            regs->bOpFlags = use48 ? ATA_FLAGS_48BIT_COMMAND : 0;
-            UniataSnapAtaRegs(chan, 0, regs);
-
-            status = SRB_STATUS_SUCCESS;
-        }
-        break;
-    }
-
-    default:
-default_abort:
-        KdPrint2((PRINT_PREFIX 
-                   "IdeSendCommand: Unsupported command %#x\n",
-                   Srb->Cdb[0]));
-
-        status = SRB_STATUS_INVALID_REQUEST;
-
-    } // end switch
-
-    if(status == SRB_STATUS_PENDING) {
-        KdPrint2((PRINT_PREFIX "IdeSendCommand: SRB_STATUS_PENDING\n"));
-        if(CmdAction & CMD_ACTION_EXEC) {
-            KdPrint2((PRINT_PREFIX "IdeSendCommand: REQ_STATE_EXPECTING_INTR\n"));
-            AtaReq->ReqState = REQ_STATE_EXPECTING_INTR;
-        }
-    } else {
-        KdPrint2((PRINT_PREFIX "IdeSendCommand: REQ_STATE_TRANSFER_COMPLETE\n"));
-        AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
-    }
-
-    return status;
-
-} // end IdeSendCommand()
-
-
-/*++
-
-Routine Description:
-    Enables disables media status notification
-
-Arguments:
-    HwDeviceExtension - ATAPI driver storage.
-
---*/
-VOID
-NTAPI
-IdeMediaStatus(
-    BOOLEAN EnableMSN,
-    IN PVOID HwDeviceExtension,
-    IN ULONG lChannel,
-    IN ULONG DeviceNumber
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PHW_CHANNEL          chan;
-    UCHAR statusByte,errorByte;
-
-    chan = &(deviceExtension->chan[lChannel]);
-    SelectDrive(chan, DeviceNumber);
-
-    if (EnableMSN != FALSE){
-
-        // If supported enable Media Status Notification support
-        if ((chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_REMOVABLE_DRIVE)) {
-
-            // enable
-            statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel,
-                                IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                0, ATA_C_F_ENAB_MEDIASTAT, ATA_WAIT_BASE_READY);
-
-            if (statusByte & IDE_STATUS_ERROR) {
-                // Read the error register.
-                errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
-
-                KdPrint2((PRINT_PREFIX 
-                            "IdeMediaStatus: Error enabling media status. Status %#x, error byte %#x\n",
-                             statusByte,
-                             errorByte));
-            } else {
-                chan->lun[DeviceNumber]->DeviceFlags |= DFLAGS_MEDIA_STATUS_ENABLED;
-                KdPrint2((PRINT_PREFIX "IdeMediaStatus: Media Status Notification Supported\n"));
-                chan->ReturningMediaStatus = 0;
-
-            }
-
-        }
-    } else { // end if EnableMSN != FALSE
-
-        // disable if previously enabled
-        if ((chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED)) {
-
-            statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel,
-                                IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                0, ATA_C_F_DIS_MEDIASTAT, ATA_WAIT_BASE_READY);
-            chan->lun[DeviceNumber]->DeviceFlags &= ~DFLAGS_MEDIA_STATUS_ENABLED;
-        }
-
-
-    }
-
-
-} // end IdeMediaStatus()
-
-
-/*++
-
-Routine Description:
-
-    Builts an artificial sense buffer to report the results of a GET_MEDIA_STATUS
-    command. This function is invoked to satisfy the SCSIOP_REQUEST_SENSE.
-Arguments:
-
-    HwDeviceExtension - ATAPI driver storage.
-    Srb - System request block.
-
-Return Value:
-
-    SRB status (ALWAYS SUCCESS).
-
---*/
-ULONG
-NTAPI
-IdeBuildSenseBuffer(
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-//    ULONG status;
-    PSENSE_DATA  senseBuffer = (PSENSE_DATA)Srb->DataBuffer;
-    UCHAR ReturningMediaStatus = deviceExtension->chan[GET_CHANNEL(Srb)].ReturningMediaStatus;
-
-    if (senseBuffer){
-
-        if(ReturningMediaStatus & IDE_ERROR_MEDIA_CHANGE) {
-
-            senseBuffer->ErrorCode = 0x70;
-            senseBuffer->Valid     = 1;
-            senseBuffer->AdditionalSenseLength = 0xb;
-            senseBuffer->SenseKey =  SCSI_SENSE_UNIT_ATTENTION;
-            senseBuffer->AdditionalSenseCode = SCSI_ADSENSE_MEDIUM_CHANGED;
-            senseBuffer->AdditionalSenseCodeQualifier = 0;
-        } else if(ReturningMediaStatus & IDE_ERROR_MEDIA_CHANGE_REQ) {
-
-            senseBuffer->ErrorCode = 0x70;
-            senseBuffer->Valid     = 1;
-            senseBuffer->AdditionalSenseLength = 0xb;
-            senseBuffer->SenseKey =  SCSI_SENSE_UNIT_ATTENTION;
-            senseBuffer->AdditionalSenseCode = SCSI_ADSENSE_MEDIUM_CHANGED;
-            senseBuffer->AdditionalSenseCodeQualifier = 0;
-        } else if(ReturningMediaStatus & IDE_ERROR_END_OF_MEDIA) {
-
-            senseBuffer->ErrorCode = 0x70;
-            senseBuffer->Valid     = 1;
-            senseBuffer->AdditionalSenseLength = 0xb;
-            senseBuffer->SenseKey =  SCSI_SENSE_NOT_READY;
-            senseBuffer->AdditionalSenseCode = SCSI_ADSENSE_NO_MEDIA_IN_DEVICE;
-            senseBuffer->AdditionalSenseCodeQualifier = 0;
-        } else if(ReturningMediaStatus & IDE_ERROR_DATA_ERROR) {
-
-            senseBuffer->ErrorCode = 0x70;
-            senseBuffer->Valid     = 1;
-            senseBuffer->AdditionalSenseLength = 0xb;
-            senseBuffer->SenseKey =  SCSI_SENSE_DATA_PROTECT;
-            senseBuffer->AdditionalSenseCode = 0;
-            senseBuffer->AdditionalSenseCodeQualifier = 0;
-        }
-        return SRB_STATUS_SUCCESS;
-    }
-    return SRB_STATUS_ERROR;
-
-}// End of IdeBuildSenseBuffer
-
-VOID
-NTAPI
-UniataUserDeviceReset(
-    PHW_DEVICE_EXTENSION deviceExtension,
-    PHW_LU_EXTENSION LunExt,
-    ULONG lChannel
-    )
-{
-    ULONG i;
-    AtapiDisableInterrupts(deviceExtension, lChannel);
-    if ((LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
-        (LunExt->PowerState != StartStop_Power_Sleep)) {
-        KdPrint2((PRINT_PREFIX "UniataUserDeviceReset: Reset ATAPI\n"));
-        AtapiSoftReset(&(deviceExtension->chan[lChannel]), LunExt->Lun);
-    } else {
-        KdPrint2((PRINT_PREFIX "UniataUserDeviceReset: Reset IDE -> reset entire channel\n"));
-        AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_NONE);
-        for(i=0; i<deviceExtension->NumberLuns; i++) {
-            deviceExtension->chan[lChannel].lun[i]->DeviceFlags |= DFLAGS_REINIT_DMA;
-        }
-    }
-    LunExt->DeviceFlags |= DFLAGS_REINIT_DMA;  // force PIO/DMA reinit
-    AtapiEnableInterrupts(deviceExtension, lChannel);
-    return;
-} // end UniataUserDeviceReset()
-
-BOOLEAN
-NTAPI
-UniataNeedQueueing(
-    PHW_DEVICE_EXTENSION deviceExtension,
-    PHW_CHANNEL          chan,
-    BOOLEAN              TopLevel
-    )
-{
-    BOOLEAN PostReq = FALSE;
-    if(TopLevel) {
-        KdPrint3((PRINT_PREFIX "UniataNeedQueueing: TopLevel, qd=%x\n", chan->queue_depth));
-        if(chan->queue_depth > 0) {
-#if 0
-            if(atapiDev &&
-               ((Srb->Cdb[0] == SCSIOP_TEST_UNIT_READY)/* ||
-                (Srb->Cdb[0] == SCSIOP_REQUEST_SENSE)*/) ) {
-                KdPrint2((PRINT_PREFIX "spec: SCSIOP_TEST_UNIT_READY\n"));
-                //PostReq = FALSE;
-                status = SRB_STATUS_BUSY;
-                goto skip_exec;
-            } else {
-                PostReq = TRUE;
-            }
-#else
-            PostReq = TRUE;
-#endif
-        } else
-        if(deviceExtension->simplexOnly && deviceExtension->queue_depth > 0) {
-            PostReq = TRUE;
-        }
-    } else {
-        KdPrint3((PRINT_PREFIX "UniataNeedQueueing: qd=%x\n", chan->queue_depth));
-    }
-    return PostReq;
-} // end UniataNeedQueueing()
-
-/*++
-
-Routine Description:
-
-    This routine is called from the SCSI port driver synchronized
-    with the kernel to start an IO request.
-    ->HwStartIo
-
-Arguments:
-
-    HwDeviceExtension - HBA miniport driver's adapter data storage
-    Srb - IO request packet
-
-Return Value:
-
-    TRUE
-
---*/
-BOOLEAN
-NTAPI
-AtapiStartIo(
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb
-    )
-{
-    return AtapiStartIo__(HwDeviceExtension, Srb, TRUE);
-} // end AtapiStartIo()
-
-BOOLEAN
-NTAPI
-AtapiStartIo__(
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb,
-    IN BOOLEAN TopLevel
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    UCHAR                lChannel;
-    PHW_CHANNEL          chan;
-    PHW_LU_EXTENSION     LunExt;
-    ULONG status;
-    //ULONG ldev;
-    ULONG DeviceNumber;
-    UCHAR PathId;
-    UCHAR TargetId;
-    UCHAR Lun;
-    PATA_REQ AtaReq;
-    PSCSI_REQUEST_BLOCK tmpSrb;
-    BOOLEAN PostReq = FALSE;
-    BOOLEAN atapiDev;
-    BOOLEAN commPort = FALSE;
-
-    // deviceExtension->Isr2DevObj must always be NULL for non-PCI
-    if(deviceExtension->Isr2DevObj && !BMList[deviceExtension->DevIndex].Isr2Enable) {
-        KdPrint2((PRINT_PREFIX "Isr2Enable -> 1\n"));
-        BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
-    }
-//    deviceExtension->QueueNewIrql = max(deviceExtension->QueueNewIrql, KeGetCurrentIrql());
-
-/*                KeBugCheckEx(0xc000000e,
-                             (Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
-                             Srb->Function, 
-                             TopLevel, 0x80000001);
-*/
-    if(TopLevel && Srb && Srb->SrbExtension) {
-        KdPrint2((PRINT_PREFIX "TopLevel\n"));
-        //RtlZeroMemory(Srb->SrbExtension, sizeof(ATA_REQ));
-        UniAtaClearAtaReq(Srb->SrbExtension);
-    }
-
-    do { // fetch all queued commands for the channel (if valid)
-
-        lChannel = GET_CHANNEL(Srb);
-        //ldev = GET_LDEV(Srb);
-        chan = NULL;
-        LunExt = NULL;
-        DeviceNumber = GET_CDEV(Srb);
-        commPort = FALSE;
-
-        //ASSERT(deviceExtension);
-        //ASSERT(chan);
-
-        KdPrint2((PRINT_PREFIX 
-                   "** AtapiStartIo: Function %#x, PATH:LUN:TID = %#x:%#x:%#x\n",
-                   Srb->Function, Srb->PathId, Srb->Lun, Srb->TargetId));
-        KdPrint2((PRINT_PREFIX "   DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
-
-        if(lChannel == deviceExtension->NumberChannels &&
-           !Srb->Lun && !Srb->TargetId &&
-           ((Srb->Function == SRB_FUNCTION_IO_CONTROL) ||
-            (Srb->Function == SRB_FUNCTION_EXECUTE_SCSI && Srb->Cdb[0] == SCSIOP_INQUIRY))
-           ) {
-            // This is our virtual device
-            KdPrint2((PRINT_PREFIX 
-                       "AtapiStartIo: Communication port\n"));
-            if(Srb->Function == SRB_FUNCTION_EXECUTE_SCSI) {
-
-                if(Srb->DataTransferLength < sizeof(PINQUIRYDATA)) {
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: Buffer too small: %#x < %#x\n", Srb->DataTransferLength,
-                        sizeof(PINQUIRYDATA) ));
-wrong_buffer_size:
-                    status = SRB_STATUS_DATA_OVERRUN;
-                    goto complete_req;
-                }
-
-                PINQUIRYDATA    inquiryData  = (PINQUIRYDATA)(Srb->DataBuffer);
-
-                KdPrint2((PRINT_PREFIX 
-                           "  INQUIRY\n"));
-                // Zero INQUIRY data structure.
-                RtlZeroMemory((PCHAR)(Srb->DataBuffer), Srb->DataTransferLength);
-
-                inquiryData->DeviceType = COMMUNICATION_DEVICE;
-
-                // Fill in vendor identification fields.
-                RtlCopyMemory(&inquiryData->VendorId, &uniata_comm_name, 28);
-
-                status = SRB_STATUS_SUCCESS;
-                goto complete_req;
-            }
-            commPort = TRUE;
-            /* Pass IOCTL request down */
-        } else
-        if(lChannel >= deviceExtension->NumberChannels ||
-            Srb->TargetId /*DeviceNumber*/ >= deviceExtension->NumberLuns ||
-            Srb->Lun) {
-
-            if(lChannel >= deviceExtension->NumberChannels) {
-                chan = NULL;
-            }
-
-reject_srb:
-            //if(!CheckDevice(HwDeviceExtension, lChannel, DeviceNumber, FALSE)) {
-            KdPrint3((PRINT_PREFIX 
-                           "AtapiStartIo: SRB rejected\n"));
-            // Indicate no device found at this address.
-            KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n"));
-            status = SRB_STATUS_SELECTION_TIMEOUT;
-            goto complete_req;
-            //}
-        } else
-        if((deviceExtension->HwFlags & UNIATA_AHCI) &&
-           !UniataAhciChanImplemented(deviceExtension, lChannel)) {
-            chan = NULL;
-        }
-
-        if(!commPort) {
-            chan = &(deviceExtension->chan[lChannel]);
-            LunExt = chan->lun[DeviceNumber];
-            if(!LunExt) {
-                goto reject_srb;
-            }
-            atapiDev = (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
-        } else {
-            atapiDev = FALSE;
-        }
-
-#ifdef _DEBUG
-        if(!commPort && !LunExt) {
-#if 0
-            PrintNtConsole("de = %#x, chan = %#x , dev %#x, nchan %#x\n",
-                deviceExtension,
-                chan, DeviceNumber,
-                deviceExtension->NumberChannels);
-            PrintNtConsole("lchan = %#x, cdev %#x, lun0 %#x\n",
-                lChannel, GET_CDEV(Srb), deviceExtension->chan[0].lun[0]);
-            PrintNtConsole("Function %#x, PATH:LUN:TID = %#x:%#x:%#x\n",
-                       Srb->Function, Srb->PathId, Srb->Lun, Srb->TargetId);
-#endif //0
-/*
-            int i;
-            for(i=0; i<1000; i++) {
-                AtapiStallExecution(3*1000);
-            }
-*/
-            goto reject_srb;
-        }
-#endif //_DEBUG
-
-        // Determine which function.
-        switch (Srb->Function) {
-
-        case SRB_FUNCTION_EXECUTE_SCSI:
-
-            if(!LunExt || !(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
-                if(Srb->Cdb[0] == SCSIOP_ATA_PASSTHROUGH) {
-                    // let passthrough go
-                } else
-                if(Srb->Cdb[0] == SCSIOP_INQUIRY) {
-                    // let INQUIRY go
-                } else {
-
-                //if(!CheckDevice(HwDeviceExtension, lChannel, DeviceNumber, FALSE)) {
-                    KdPrint2((PRINT_PREFIX 
-                               "AtapiStartIo: EXECUTE_SCSI rejected (2)\n"));
-                    // Indicate no device found at this address.
-                    KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n"));
-                    status = SRB_STATUS_SELECTION_TIMEOUT;
-                    break;
-                //}
-                }
-            } else {
-                KdPrint2((PRINT_PREFIX 
-                           "  SRB %#x, CDB %#x, AtaReq %#x, SCmd %#x\n", Srb, &(Srb->Cdb), Srb->SrbExtension, Srb->Cdb[0]));
-            }
-/*
-            __try {
-                if(Srb->DataTransferLength) {
-                    UCHAR a;
-                    a = ((PUCHAR)(Srb->DataBuffer))[0];
-                    g_foo += a;
-                }
-            } __except(EXCEPTION_EXECUTE_HANDLER) {
-                KdPrint3((PRINT_PREFIX 
-                           "AtapiStartIo: Bad data buffer -> EXECUTE_SCSI rejected\n"));
-                // Indicate no device found at this address.
-                KdPrint3((PRINT_PREFIX "SRB_STATUS_ERROR\n"));
-                status = SRB_STATUS_ERROR;
-                KdPrint2((PRINT_PREFIX "  *** Exception...\n"));
-                ASSERT(FALSE);
-                break;
-            }
-*/
-            PostReq = UniataNeedQueueing(deviceExtension, chan, TopLevel);
-
-            if(PostReq) {
-
-                KdPrint3((PRINT_PREFIX "Non-empty queue\n"));
-                if (atapiDev &&
-                    (Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)) {
-                    KdPrint3((PRINT_PREFIX "Try ATAPI prepare\n"));
-
-                    status = AtapiSendCommand(HwDeviceExtension, Srb, CMD_ACTION_PREPARE);
-                } else {
-                    KdPrint2((PRINT_PREFIX "Try IDE prepare\n"));
-                    status = IdeSendCommand(HwDeviceExtension, Srb, CMD_ACTION_PREPARE);
-                }
-                /*KeBugCheckEx(0xc000000e,
-                             (Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
-                             Srb->Function, 
-                             status, 0x80000001);*/
-                if(status == SRB_STATUS_BUSY)
-                    status = SRB_STATUS_PENDING;
-                // Insert requests AFTER they have been initialized on
-                // CMD_ACTION_PREPARE stage
-                // we should not check TopLevel here (it is always TRUE)
-                //ASSERT(chan->lun[GET_CDEV(Srb)]);
-                UniataQueueRequest(chan, Srb);
-
-                KdPrint2((PRINT_PREFIX "AtapiStartIo: Already have %d request(s)!\n", chan->queue_depth));
-
-            } else {
-
-                // Send command to device.
-                KdPrint2((PRINT_PREFIX "Send to device %x\n", Srb->Cdb[0]));
-                if(TopLevel) {
-                    KdPrint2((PRINT_PREFIX "TopLevel (2), srb %#x\n", Srb));
-                    AtaReq = (PATA_REQ)(Srb->SrbExtension);
-                    KdPrint2((PRINT_PREFIX "TopLevel (3), AtaReq %#x\n", AtaReq));
-                    //ASSERT(!AtaReq->Flags);
-                    //ASSERT(chan->lun[GET_CDEV(Srb)]);
-                    UniataQueueRequest(chan, Srb);
-//                    AtaReq = (PATA_REQ)(Srb->SrbExtension);
-                    //ASSERT(!AtaReq->Flags);
-                    AtaReq->ReqState = REQ_STATE_QUEUED;
-                    //ASSERT(!AtaReq->Flags);
-                }
-
-#ifndef NAVO_TEST
-                if(!LunExt || !(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
-                    if(!LunExt) {
-                        goto reject_srb;
-                    }
-                    if(Srb->Cdb[0] == SCSIOP_INQUIRY) {
-                        if(UniataAnybodyHome(deviceExtension, chan->lChannel, DeviceNumber)) {
-                            if(!CheckDevice(HwDeviceExtension, chan->lChannel, DeviceNumber, TRUE)) {
-                                goto reject_srb;
-                            }
-                        }
-                        if(!(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
-                            goto reject_srb;
-                        }
-                    } else
-                    if(Srb->Cdb[0] == SCSIOP_ATA_PASSTHROUGH) {
-                        // allow
-                    } else {
-                        goto reject_srb;
-                    }
-                }
-#endif //NAVO_TEST
-
-                if(atapiDev &&
-                   (Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)/* &&
-                   (Srb->Cdb[0] != SCSIOP_REPORT_LUNS)*/) {
-                    KdPrint3((PRINT_PREFIX "Try ATAPI send %x\n", Srb->Cdb[0]));
-                    status = AtapiSendCommand(HwDeviceExtension, Srb, CMD_ACTION_ALL);
-                } else {
-                    KdPrint2((PRINT_PREFIX "Try IDE send\n"));
-/*                    {
-                        ULONG __ebp__ = 0;
-                        ULONG __esp__ = 0;
-
-                        KdPrint2((PRINT_PREFIX "** before IdeSendCommand:\n"));
-                        __asm {
-                            mov eax,ebp
-                            mov __ebp__, eax
-                            mov eax,esp
-                            mov __esp__, eax
-                        }
-                        KdPrint2((PRINT_PREFIX "** before Ide: EBP:%#x ESP:%#x\n", __ebp__, __esp__));
-                    }*/
-                    status = IdeSendCommand(HwDeviceExtension, Srb, CMD_ACTION_ALL);
-                }
-/*                KeBugCheckEx(0xc000000e,
-                             (Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
-                             Srb->Function, 
-                             status, 0x80000002);*/
-
-            }
-//skip_exec:
-            TopLevel = FALSE;
-
-            break;
-
-        case SRB_FUNCTION_ABORT_COMMAND:
-
-            tmpSrb = ScsiPortGetSrb(HwDeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun,
-                               Srb->QueueTag);
-            // Verify that SRB to abort is still outstanding.
-            if((tmpSrb != Srb->NextSrb) ||
-               !chan->queue_depth) {
-
-                KdPrint2((PRINT_PREFIX "AtapiStartIo: SRB to abort already completed\n"));
-
-                // Complete abort SRB.
-                status = SRB_STATUS_ABORT_FAILED;
-                break;
-            }
-
-            AtaReq = (PATA_REQ)(tmpSrb->SrbExtension);
-            if(AtaReq->ReqState > REQ_STATE_READY_TO_TRANSFER) {
-                if (!AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_CURRENT)) {
-                      KdPrint2((PRINT_PREFIX "AtapiStartIo: Abort command failed\n"));
-                    // Log reset failure.
-                    KdPrint3((PRINT_PREFIX 
-                                "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d)\n",
-                                      HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8
-                                ));
-                    ScsiPortLogError(HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8);
-                    status = SRB_STATUS_ERROR;
-
-                } else {
-                    status = SRB_STATUS_SUCCESS;
-                }
-            } else {
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt: remove aborted srb %#x\n", tmpSrb));
-                if (tmpSrb->SenseInfoBuffer &&
-                    tmpSrb->SenseInfoBufferLength >= sizeof(SENSE_DATA)) {
-
-                    PSENSE_DATA  senseBuffer = (PSENSE_DATA)tmpSrb->SenseInfoBuffer;
-
-                    senseBuffer->ErrorCode = 0;
-                    senseBuffer->Valid     = 1;
-                    senseBuffer->AdditionalSenseLength = 0xb;
-                    senseBuffer->SenseKey =  SCSI_SENSE_ABORTED_COMMAND;
-                    senseBuffer->AdditionalSenseCode = 0;
-                    senseBuffer->AdditionalSenseCodeQualifier = 0;
-
-                    tmpSrb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
-                }
-                AtapiDmaDBSync(chan, tmpSrb);
-                UniataRemoveRequest(chan, tmpSrb);
-                // Indicate command complete.
-                ScsiPortNotification(RequestComplete,
-                                     deviceExtension,
-                                     tmpSrb);
-                status = SRB_STATUS_SUCCESS;
-            }
-            break;
-
-            // Abort function indicates that a request timed out.
-            // Call reset routine. Card will only be reset if
-            // status indicates something is wrong.
-            // Fall through to reset code.
-
-        case SRB_FUNCTION_RESET_DEVICE:
-        case SRB_FUNCTION_RESET_LOGICAL_UNIT:
-
-            // Reset single device.
-            // For now we support only Lun=0
-
-            // Note: reset is immediate command, it cannot be queued since it is usually used to
-            // revert not-responding device to operational state
-            KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset device request received\n"));
-            UniataUserDeviceReset(deviceExtension, LunExt, lChannel);
-            status = SRB_STATUS_SUCCESS;
-            break;
-
-        case SRB_FUNCTION_RESET_BUS:
-do_bus_reset:
-            // Reset Atapi and SCSI bus.
-
-            // Note: reset is immediate command, it cannot be queued since it is usually used to
-            // revert not- responding device to operational state
-            KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset bus request received\n"));
-            if (!AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_ALL)) {
-                  KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset bus failed\n"));
-                // Log reset failure.
-                KdPrint3((PRINT_PREFIX 
-                            "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d) - (2)\n",
-                                  HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8
-                            ));
-                ScsiPortLogError(HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8);
-                status = SRB_STATUS_ERROR;
-
-            } else {
-                status = SRB_STATUS_SUCCESS;
-            }
-
-            break;
-
-        case SRB_FUNCTION_SHUTDOWN:
-
-            KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown\n"));
-            if(!LunExt || !(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
-                KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown - no such device\n"));
-            } else
-            if(atapiDev) {
-                // FLUSH ATAPI device - do nothing
-                KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown - ATAPI device\n"));
-            } else {
-                // FLUSH IDE/ATA device
-                KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown - IDE device\n"));
-                AtapiDisableInterrupts(deviceExtension, lChannel);
-                status = AtaCommand(deviceExtension, DeviceNumber, GET_CHANNEL(Srb),
-                           IDE_COMMAND_FLUSH_CACHE, 0, 0, 0, 0, 0, ATA_WAIT_IDLE);
-                // If supported & allowed, reset write cacheing
-                if(LunExt->DeviceFlags & DFLAGS_WCACHE_ENABLED) {
-
-                    // Disable write cache
-                    status = AtaCommand(deviceExtension, DeviceNumber, lChannel,
-                                        IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                        0, ATA_C_F_DIS_WCACHE, ATA_WAIT_BASE_READY);
-                    // Check for errors.
-                    if (status & IDE_STATUS_ERROR) {
-                        KdPrint2((PRINT_PREFIX 
-                                    "AtapiHwInitialize: Disable write cacheing on Device %d failed\n",
-                                    DeviceNumber));
-                    }
-                    LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
-
-                    // Re-enable write cache
-                    status = AtaCommand(deviceExtension, DeviceNumber, lChannel,
-                                        IDE_COMMAND_SET_FEATURES, 0, 0, 0,
-                                        0, ATA_C_F_ENAB_WCACHE, ATA_WAIT_BASE_READY);
-                    // Check for errors.
-                    if (status & IDE_STATUS_ERROR) {
-                        KdPrint2((PRINT_PREFIX 
-                                    "AtapiHwInitialize: Enable write cacheing on Device %d failed\n",
-                                    DeviceNumber));
-                        LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
-                    } else {
-                        LunExt->DeviceFlags |= DFLAGS_WCACHE_ENABLED;
-                    }
-                }
-
-                AtapiEnableInterrupts(deviceExtension, lChannel);
-            }
-            status = SRB_STATUS_SUCCESS;
-
-            break;
-
-        case SRB_FUNCTION_FLUSH:
-
-            KdPrint2((PRINT_PREFIX "AtapiStartIo: Flush (do nothing)\n"));
-            status = SRB_STATUS_SUCCESS;
-            break;
-
-        case SRB_FUNCTION_IO_CONTROL: {
-
-            ULONG len;
-
-            KdPrint2((PRINT_PREFIX "AtapiStartIo: SRB_FUNCTION_IO_CONTROL\n"));
-
-            len = Srb->DataTransferLength;
-
-            if(!AtapiStringCmp( (PCHAR)(((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature),"SCSIDISK",sizeof("SCSIDISK")-1)) {
-
-                ULONG targetId = (ULONG)(-1);
-
-                if(len < sizeof(SRB_IO_CONTROL)) {
-                    goto wrong_buffer_size;
-                }
-
-                // extract bogus bus address
-                switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) {
-                case IOCTL_SCSI_MINIPORT_SMART_VERSION: {
-                    PGETVERSIONINPARAMS versionParameters = (PGETVERSIONINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
-
-                    if(len < sizeof(SRB_IO_CONTROL)+sizeof(GETVERSIONINPARAMS)) {
-                        goto wrong_buffer_size;
-                    }
-
-                    targetId = versionParameters->bIDEDeviceMap;
-                    KdPrint2((PRINT_PREFIX "targetId (smart ver) %d\n", targetId));
-                    break; }
-                case IOCTL_SCSI_MINIPORT_IDENTIFY:
-                case IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS:
-                case IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS:
-                case IOCTL_SCSI_MINIPORT_ENABLE_SMART:
-                case IOCTL_SCSI_MINIPORT_DISABLE_SMART:
-                case IOCTL_SCSI_MINIPORT_RETURN_STATUS:
-                case IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE:
-                case IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES:
-                case IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS:
-                case IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTO_OFFLINE:
-                case IOCTL_SCSI_MINIPORT_READ_SMART_LOG:
-                case IOCTL_SCSI_MINIPORT_WRITE_SMART_LOG:
-                    {
-                    PSENDCMDINPARAMS   cmdInParameters = (PSENDCMDINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
-
-                    if(len < sizeof(SRB_IO_CONTROL)+sizeof(SENDCMDINPARAMS) - 1) {
-                        goto wrong_buffer_size;
-                    }
-
-                    targetId = cmdInParameters->bDriveNumber;
-                    KdPrint2((PRINT_PREFIX "targetId (smart/ident) %d\n", targetId));
-                    break; }
-                default:
-invalid_request:
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: invalid IoControl %#x for SCSIDISK signature\n",
-                                ((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode ));
-                    status = SRB_STATUS_INVALID_REQUEST;
-                    goto complete_req;
-                } // end switch()
-
-                // adjust (if necessary) bus address
-                if(targetId != (ULONG)(-1)) {
-
-                    // This is done because of how the IOCTL_SCSI_MINIPORT
-                    // determines 'targetid's'. Disk.sys places the real target id value
-                    // in the DeviceMap field. Once we do some parameter checking, the value passed
-                    // back to the application will be determined.
-
-                    if (deviceExtension->NumberChannels == 1) {
-                        // do this for legacy controllers and legacy callers
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: legacy call\n"));
-                        DeviceNumber = (targetId & 0x01);
-                        lChannel = 0;
-                    } else
-                    if(commPort) {
-                        // do this for smartmontools, sending IOCTLs to PhysicalDrive%d
-                        // due to DISK.SYS design bug, we have invalid SCSI address in SRB
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: legacy call (2)\n"));
-                        if(deviceExtension->HwFlags & UNIATA_AHCI) {
-                            lChannel = (UCHAR)targetId / 2;
-                            DeviceNumber = 0;
-                        } else {
-                            lChannel = (UCHAR)(targetId / 2);
-                            DeviceNumber = targetId & 0x01;
-                        }
-                    } else {
-                        // otherwise assume lChannel and DeviceNumber from Srb are ok
-                    }
-                    if(lChannel >= deviceExtension->NumberChannels ||
-                        DeviceNumber >= deviceExtension->NumberLuns) {
-                        KdPrint2((PRINT_PREFIX 
-                                   "AtapiStartIo: SCSIDISK IOCTL for non-exestent drive %d -> EXECUTE_SCSI rejected (2)\n",
-                                       targetId));
-                        // Indicate no device found at this address.
-                        goto reject_srb;
-                    }
-                    targetId = lChannel*deviceExtension->NumberLuns+DeviceNumber;
-                    chan = &(deviceExtension->chan[lChannel]);
-                    LunExt = chan->lun[DeviceNumber];
-                    if(!LunExt) {
-                        goto reject_srb;
-                    }
-                    atapiDev = (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
-
-                    if (!(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
-                        goto reject_srb;
-                    }
-                }
-
-                switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) {
-                case IOCTL_SCSI_MINIPORT_SMART_VERSION: {
-
-                    PGETVERSIONINPARAMS versionParameters = (PGETVERSIONINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
-                    UCHAR deviceNumberMap;
-
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: IOCTL_SCSI_MINIPORT_SMART_VERSION\n"));
-
-                    // Version and revision per SMART 1.03
-
-                    versionParameters->bVersion = 1;
-                    versionParameters->bRevision = 1;
-                    versionParameters->bReserved = 0;
-
-                    // Indicate that support for IDE IDENTIFY, ATAPI IDENTIFY and SMART commands.
-                    versionParameters->fCapabilities = (CAP_ATA_ID_CMD | CAP_ATAPI_ID_CMD | CAP_SMART_CMD);
-
-                    if (atapiDev) {
-                        goto invalid_request;
-                    }
-
-                    // NOTE: This will only set the bit
-                    // corresponding to this drive's target id.
-                    // The bit mask is as follows:
-                    //
-                    //     -Sec Pri
-                    //     S M S M
-                    //     3 2 1 0
-
-                    if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
-                        deviceNumberMap = 1 << lChannel;
-                        DeviceNumber = 0;
-                    } else
-                    if (deviceExtension->NumberChannels == 1) {
-                        if (chan->PrimaryAddress) {
-                            deviceNumberMap = 1 << DeviceNumber;
-                        } else {
-                            deviceNumberMap = 4 << DeviceNumber;
-                        }
-                    } else {
-                        deviceNumberMap = 1 << (DeviceNumber+lChannel*2);
-                    }
-
-                    versionParameters->bIDEDeviceMap = deviceNumberMap;
-
-                    status = SRB_STATUS_SUCCESS;
-                    break;
-                }
-
-                case IOCTL_SCSI_MINIPORT_IDENTIFY: {
-
-                    PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
-                    SENDCMDINPARAMS   cmdInParameters = *(PSENDCMDINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
-
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: IOCTL_SCSI_MINIPORT_IDENTIFY\n"));
-                    // Extract the target.
-                    KdPrint2((PRINT_PREFIX "targetId %d\n", targetId));
-
-                    switch(cmdInParameters.irDriveRegs.bCommandReg) {
-                    case ID_CMD:
-                        if(atapiDev) {
-                            KdPrint2((PRINT_PREFIX "Error: ID_CMD for ATAPI\n"));
-                            goto invalid_request;
-                        }
-                        /* FALL THROUGH */
-                    case ATAPI_ID_CMD:
-
-                        if(!atapiDev &&
-                           (cmdInParameters.irDriveRegs.bCommandReg == ATAPI_ID_CMD)) {
-                            KdPrint2((PRINT_PREFIX "Error: ATAPI_ID_CMD for non-ATAPI\n"));
-                            goto invalid_request;
-                        }
-
-                        len = min(len, sizeof(SENDCMDOUTPARAMS) - 1 + IDENTIFY_BUFFER_SIZE);
-                        // Zero the output buffer
-                        RtlZeroMemory(cmdOutParameters, len);
-/*                        for (i = 0; i < (sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1); i++) {
-                            ((PUCHAR)cmdOutParameters)[i] = 0;
-                        }*/
-
-                        // Build status block.
-                        cmdOutParameters->cBufferSize = min(IDENTIFY_BUFFER_SIZE, len - sizeof(SENDCMDOUTPARAMS) + 1);
-                        cmdOutParameters->DriverStatus.bDriverError = 0;
-                        cmdOutParameters->DriverStatus.bIDEError = 0;
-
-                        // Extract the identify data from the device extension.
-                        ScsiPortMoveMemory (cmdOutParameters->bBuffer, &(LunExt->IdentifyData),
-                            cmdOutParameters->cBufferSize);
-
-                        if((cmdOutParameters->cBufferSize == IDENTIFY_BUFFER_SIZE) &&
-                           (LunExt->IdentifyData.ChecksumValid == ATA_ChecksumValid)) {
-                            // adjust checksum if it is possible
-                            CHAR csum = 0;
-                            ULONG i;
-
-                            for(i=0; i < IDENTIFY_BUFFER_SIZE-1; i++) {
-                                csum += (CHAR)(cmdOutParameters->bBuffer[i]);
-                            }
-                            cmdOutParameters->bBuffer[i] = -csum;
-                            KdPrint2((PRINT_PREFIX "AtapiStartIo: adjust checksum %d\n"));
-                        }
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: IOCTL_SCSI_MINIPORT_IDENTIFY Ok\n"));
-
-                        status = SRB_STATUS_SUCCESS;
-
-                        break;
-                    default:
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: not supported ID code %x\n",
-                            cmdInParameters.irDriveRegs.bCommandReg));
-                        status = SRB_STATUS_INVALID_REQUEST;
-                        break;
-                    }
-                    break;
-                }
-/*
-                case  IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS:
-                case  IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS:
-                case  IOCTL_SCSI_MINIPORT_ENABLE_SMART:
-                case  IOCTL_SCSI_MINIPORT_DISABLE_SMART:
-                case  IOCTL_SCSI_MINIPORT_RETURN_STATUS:
-                case  IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE:
-                case  IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES:
-                case  IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS:
-*/
-                default:
-                    // *all* IOCTLs here are SMART
-                    if(commPort) {
-                        KdPrint2((PRINT_PREFIX 
-                                   "AtapiStartIo: SCSIDISK Smart IOCTL for commPort -> EXECUTE_SCSI rejected (3)\n"));
-                    }
-                    if (atapiDev) {
-                        goto invalid_request;
-                    }
-
-                    PostReq = UniataNeedQueueing(deviceExtension, chan, TopLevel);
-
-                    if(PostReq || TopLevel) {
-                        UniataQueueRequest(chan, Srb);
-                        AtaReq = (PATA_REQ)(Srb->SrbExtension);
-                        AtaReq->ReqState = REQ_STATE_QUEUED;
-                    }
-
-                    if(PostReq) {
-
-                        KdPrint2((PRINT_PREFIX "Non-empty queue (SMART)\n"));
-                        status = SRB_STATUS_PENDING;
-
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: Already have %d request(s)!\n", chan->queue_depth));
-                    } else {
-
-                        status = IdeSendSmartCommand(HwDeviceExtension, Srb, targetId);
-                    }
-                    break;
-
-                // we should not get here, checked above
-/*                default :
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: invalid IoControl %#x for SCSIDISK signature\n",
-                                ((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode ));
-                    status = SRB_STATUS_INVALID_REQUEST;
-                    break;
-*/
-                }
-            } else
-            if(!AtapiStringCmp( (PCHAR)(((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature),"-UNIATA-", sizeof("-UNIATA-")-1)) {
-
-                PUNIATA_CTL AtaCtl = (PUNIATA_CTL)(Srb->DataBuffer);
-                //ULONG ldev = GET_LDEV2(AtaCtl->addr.PathId, AtaCtl->addr.TargetId, 0);
-                ULONG DeviceNumber = AtaCtl->addr.TargetId;
-                BOOLEAN bad_ldev;
-                ULONG i, pos;
-
-                pos = FIELD_OFFSET(UNIATA_CTL, RawData);
-                //chan = &(deviceExtension->chan[lChannel]);
-                if(len < pos) {
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
-                        FIELD_OFFSET(UNIATA_CTL, RawData) ));
-                    goto wrong_buffer_size;
-                }
-
-                if(AtaCtl->addr.Lun ||
-                   AtaCtl->addr.TargetId >= deviceExtension->NumberLuns || 
-                   AtaCtl->addr.PathId >= deviceExtension->NumberChannels) {
-
-                    chan = NULL;
-                    bad_ldev = TRUE;
-                    LunExt = NULL;
-
-                } else {
-                    bad_ldev = FALSE;
-                    lChannel = AtaCtl->addr.PathId;
-                    chan = &(deviceExtension->chan[lChannel]);
-                    LunExt = chan->lun[DeviceNumber];
-                }
-
-                KdPrint2((PRINT_PREFIX "AtapiStartIo: -UNIATA- %#x, dev %#x\n", AtaCtl->hdr.ControlCode, DeviceNumber));
-
-                /* check for valid LUN */
-                switch (AtaCtl->hdr.ControlCode) {
-                case  IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES:
-                case  IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE:
-                    // this would be BUS reset
-                    if(bad_ldev &&
-                       (AtaCtl->addr.PathId >= deviceExtension->NumberChannels ||
-                        AtaCtl->addr.TargetId != 0xff ||
-                        AtaCtl->addr.Lun != 0
-                        )) {
-                        if(AtaCtl->hdr.ControlCode == IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES &&
-                           DeviceNumber < deviceExtension->NumberLuns) { // AtaCtl->addr.TargetId != 0xff
-                            lChannel = AtaCtl->addr.PathId;
-                            chan = &(deviceExtension->chan[lChannel]);
-                            LunExt = chan->lun[DeviceNumber];
-                            // OK
-                        } else {
-                            goto handle_bad_ldev;
-                        }
-                    } else {
-                        lChannel = AtaCtl->addr.PathId;
-                        chan = &(deviceExtension->chan[lChannel]);
-                    }
-                    break;
-                case  IOCTL_SCSI_MINIPORT_UNIATA_DELETE_DEVICE:
-                case  IOCTL_SCSI_MINIPORT_UNIATA_SET_MAX_MODE:
-                case  IOCTL_SCSI_MINIPORT_UNIATA_GET_MODE:
-                case  IOCTL_SCSI_MINIPORT_UNIATA_RESETBB:
-//                case  IOCTL_SCSI_MINIPORT_UNIATA_REG_IO:
-                    if(bad_ldev) {
-handle_bad_ldev:
-                        KdPrint2((PRINT_PREFIX 
-                                   "AtapiStartIo: bad_ldev -> IOCTL SRB rejected\n"));
-                        // Indicate no device found at this address.
-                        goto reject_srb;
-                    }
-                }
-
-                /* check if queueing is necessary */
-                switch (AtaCtl->hdr.ControlCode) {
-                case  IOCTL_SCSI_MINIPORT_UNIATA_RESETBB:
-                    if(!LunExt->nBadBlocks) {
-                        break;
-                    }
-                    goto uata_ctl_queue;
-                case  IOCTL_SCSI_MINIPORT_UNIATA_SET_MAX_MODE:
-                    if(len < pos+sizeof(AtaCtl->SetMode)) {
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
-                            pos+sizeof(AtaCtl->SetMode) ));
-                        goto wrong_buffer_size;
-                    }
-                    if(!AtaCtl->SetMode.ApplyImmediately) {
-                        break;
-                    }
-                    goto uata_ctl_queue;
-                case  IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES:
-                //case  IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE: reset must be processed immediately
-uata_ctl_queue:
-                    KdPrint2((PRINT_PREFIX "put to queue (UNIATA)\n"));
-                    PostReq = UniataNeedQueueing(deviceExtension, chan, TopLevel);
-
-                    if(PostReq || TopLevel) {
-                        UniataQueueRequest(chan, Srb);
-                        AtaReq = (PATA_REQ)(Srb->SrbExtension);
-                        AtaReq->ReqState = REQ_STATE_QUEUED;
-                    }
-                    if(PostReq) {
-                        KdPrint2((PRINT_PREFIX "Non-empty queue (UNIATA)\n"));
-                        status = SRB_STATUS_PENDING;
-
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: Already have %d request(s)!\n", chan->queue_depth));
-                        goto complete_req;
-                    } 
-                } // end switch (AtaCtl->hdr.ControlCode)
-
-                /* process request */
-                switch (AtaCtl->hdr.ControlCode) {
-                case  IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES:
-
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: rescan bus\n"));
-
-                    if(len < pos+sizeof(AtaCtl->FindDelDev)) {
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
-                            pos+sizeof(AtaCtl->FindDelDev) ));
-                        goto wrong_buffer_size;
-                    }
-                    if(AtaCtl->FindDelDev.Flags & UNIATA_ADD_FLAGS_UNHIDE) {
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: unhide from further detection\n"));
-                        if(AtaCtl->addr.TargetId != 0xff) {
-                            LunExt->DeviceFlags &= ~DFLAGS_HIDDEN;
-                        } else {
-                        }
-                    }
-
-                    for(i=0; i<AtaCtl->FindDelDev.WaitForPhysicalLink && i<30; i++) {
-                        AtapiStallExecution(1000 * 1000);
-                    }
-
-                    FindDevices(HwDeviceExtension,
-                                ((AtaCtl->addr.TargetId == 0xff) && (AtaCtl->FindDelDev.Flags & UNIATA_ADD_FLAGS_UNHIDE))
-                                     ? UNIATA_FIND_DEV_UNHIDE : 0,
-                                AtaCtl->addr.PathId);
-                    status = SRB_STATUS_SUCCESS;
-
-                    break;
-
-                case  IOCTL_SCSI_MINIPORT_UNIATA_DELETE_DEVICE: {
-
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: remove %#x:%#x\n", AtaCtl->addr.PathId, AtaCtl->addr.TargetId));
-
-                    if(len < pos+sizeof(AtaCtl->FindDelDev)) {
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
-                            pos+sizeof(AtaCtl->FindDelDev) ));
-                        goto wrong_buffer_size;
-                    }
-                    LunExt->DeviceFlags = 0;
-                    if(AtaCtl->FindDelDev.Flags & UNIATA_REMOVE_FLAGS_HIDE) {
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: hide from further detection\n"));
-                        //LunExt->DeviceFlags |= DFLAGS_HIDDEN;
-                        UniataForgetDevice(LunExt);
-                    }
-
-                    for(i=0; i<AtaCtl->FindDelDev.WaitForPhysicalLink && i<30; i++) {
-                        AtapiStallExecution(1000 * 1000);
-                    }
-
-                    status = SRB_STATUS_SUCCESS;
-                    break;
-                }
-                case  IOCTL_SCSI_MINIPORT_UNIATA_SET_MAX_MODE: {
-
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: Set transfer mode\n"));
-
-                    if(len < pos+sizeof(AtaCtl->SetMode)) {
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
-                            pos+sizeof(AtaCtl->SetMode) ));
-                        goto wrong_buffer_size;
-                    }
-                    if(AtaCtl->SetMode.OrigMode != IOMODE_NOT_SPECIFIED) {
-                        LunExt->OrigTransferMode = (UCHAR)(AtaCtl->SetMode.OrigMode);
-                    }
-                    if(AtaCtl->SetMode.MaxMode != IOMODE_NOT_SPECIFIED) {
-                        LunExt->LimitedTransferMode = (UCHAR)(AtaCtl->SetMode.MaxMode);
-                        if(LunExt->LimitedTransferMode > 
-                           LunExt->OrigTransferMode) {
-                            // check for incorrect value
-                            LunExt->LimitedTransferMode =
-                                LunExt->OrigTransferMode;
-                        }
-                    }
-                    LunExt->TransferMode = min(LunExt->LimitedTransferMode, LunExt->OrigTransferMode);
-
-                    LunExt->DeviceFlags |= DFLAGS_REINIT_DMA;  // force PIO/DMA reinit
-                    if(AtaCtl->SetMode.ApplyImmediately) {
-                        AtapiDmaInit__(deviceExtension, LunExt);
-                    }
-/*                    LunExt->TransferMode =
-                    LunExt->LimitedTransferMode = (UCHAR)(setTransferMode->Mode);*/
-                    status = SRB_STATUS_SUCCESS;
-                    break;
-                }
-                case  IOCTL_SCSI_MINIPORT_UNIATA_GET_MODE: {
-
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: Get transfer mode\n"));
-
-                    if(len < pos+sizeof(AtaCtl->GetMode)) {
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
-                            pos+sizeof(AtaCtl->GetMode) ));
-                        goto wrong_buffer_size;
-                    }
-                    AtaCtl->GetMode.OrigMode    = LunExt->OrigTransferMode;
-                    AtaCtl->GetMode.MaxMode     = LunExt->LimitedTransferMode;
-                    AtaCtl->GetMode.CurrentMode = LunExt->TransferMode;
-                    AtaCtl->GetMode.PhyMode     = LunExt->PhyTransferMode;
-
-                    status = SRB_STATUS_SUCCESS;
-                    break;
-                }
-                case  IOCTL_SCSI_MINIPORT_UNIATA_GET_VERSION: {
-
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: Get version\n"));
-
-                    if(len < pos+sizeof(AtaCtl->Version)) {
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
-                            pos+sizeof(AtaCtl->Version) ));
-                        goto wrong_buffer_size;
-                    }
-                    AtaCtl->Version.Length      = sizeof(GETDRVVERSION);
-                    AtaCtl->Version.VersionMj   = UNIATA_VER_MJ;
-                    AtaCtl->Version.VersionMn   = UNIATA_VER_MN;
-                    AtaCtl->Version.SubVerMj    = UNIATA_VER_SUB_MJ;
-                    AtaCtl->Version.SubVerMn    = UNIATA_VER_SUB_MN;
-
-                    status = SRB_STATUS_SUCCESS;
-                    break;
-                }
-                case  IOCTL_SCSI_MINIPORT_UNIATA_ADAPTER_INFO: {
-
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: Get adapter info\n"));
-
-                    if(len < pos+sizeof(AtaCtl->AdapterInfo)) {
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
-                            pos+sizeof(AtaCtl->AdapterInfo) ));
-                        goto wrong_buffer_size;
-                    }
-                    AtaCtl->AdapterInfo.HeaderLength = sizeof(ADAPTERINFO);
-
-                    AtaCtl->AdapterInfo.DevID      = deviceExtension->DevID;
-                    AtaCtl->AdapterInfo.RevID      = deviceExtension->RevID;
-                    AtaCtl->AdapterInfo.slotNumber = deviceExtension->slotNumber;
-                    AtaCtl->AdapterInfo.SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
-                    AtaCtl->AdapterInfo.DevIndex   = deviceExtension->DevIndex;
-                    AtaCtl->AdapterInfo.Channel    = deviceExtension->Channel;
-                    AtaCtl->AdapterInfo.HbaCtrlFlags = deviceExtension->HbaCtrlFlags;
-                    AtaCtl->AdapterInfo.simplexOnly= deviceExtension->simplexOnly;
-                    AtaCtl->AdapterInfo.MemIo      = FALSE;/*deviceExtension->MemIo;*/
-                    AtaCtl->AdapterInfo.UnknownDev = deviceExtension->UnknownDev;
-                    AtaCtl->AdapterInfo.MasterDev  = deviceExtension->MasterDev;
-                    AtaCtl->AdapterInfo.MaxTransferMode = deviceExtension->MaxTransferMode;
-                    AtaCtl->AdapterInfo.HwFlags    = deviceExtension->HwFlags;
-                    AtaCtl->AdapterInfo.OrigAdapterInterfaceType = deviceExtension->OrigAdapterInterfaceType;
-                    AtaCtl->AdapterInfo.BusInterruptLevel = deviceExtension->BusInterruptLevel;
-                    AtaCtl->AdapterInfo.InterruptMode = deviceExtension->InterruptMode;
-                    AtaCtl->AdapterInfo.BusInterruptVector = deviceExtension->BusInterruptVector;
-                    AtaCtl->AdapterInfo.NumberChannels = deviceExtension->NumberChannels;
-                    AtaCtl->AdapterInfo.NumberLuns = (UCHAR)deviceExtension->NumberLuns;
-                    AtaCtl->AdapterInfo.AdapterInterfaceType = deviceExtension->AdapterInterfaceType;
-                    if(deviceExtension->FullDevName) {
-                        strncpy(AtaCtl->AdapterInfo.DeviceName, deviceExtension->FullDevName, 64);
-                    }
-                    AtaCtl->AdapterInfo.ChanInfoValid = FALSE;
-                    AtaCtl->AdapterInfo.LunInfoValid = FALSE;
-                    AtaCtl->AdapterInfo.ChanHeaderLengthValid = TRUE;
-
-                    pos += AtaCtl->AdapterInfo.HeaderLength;
-
-                    // zero tail
-                    RtlZeroMemory(((PCHAR)AtaCtl)+pos,
-                        len-pos);
-
-                    if(len >= pos+AtaCtl->AdapterInfo.NumberChannels*sizeof(CHANINFO)) {
-                        PCHANINFO ChanInfo = (PCHANINFO)( ((PCHAR)AtaCtl)+pos );
-                        PHW_CHANNEL cur_chan;
-                        KdPrint2((PRINT_PREFIX "AtapiStartIo: Fill channel info\n"));
-                        for(i=0;i<AtaCtl->AdapterInfo.NumberChannels;i++) {
-                            KdPrint2((PRINT_PREFIX "chan[%d] %x\n", i, cur_chan));
-                            cur_chan = &(deviceExtension->chan[i]);
-                            ChanInfo->MaxTransferMode = cur_chan->MaxTransferMode;
-                            ChanInfo->ChannelCtrlFlags = cur_chan->ChannelCtrlFlags;
-                            RtlCopyMemory(&(ChanInfo->QueueStat), &(cur_chan->QueueStat), sizeof(ChanInfo->QueueStat));
-                            ChanInfo->ReorderCount        = cur_chan->ReorderCount;
-                            ChanInfo->IntersectCount      = cur_chan->IntersectCount;
-                            ChanInfo->TryReorderCount     = cur_chan->TryReorderCount;
-                            ChanInfo->TryReorderHeadCount = cur_chan->TryReorderHeadCount;
-                            ChanInfo->TryReorderTailCount = cur_chan->TryReorderTailCount;
-                            //ChanInfo->opt_MaxTransferMode = cur_chan->opt_MaxTransferMode;
-                            ChanInfo++;
-                        }
-                        AtaCtl->AdapterInfo.ChanInfoValid = TRUE;
-                        AtaCtl->AdapterInfo.ChanHeaderLength = sizeof(*ChanInfo);
-                    }
-
-                    status = SRB_STATUS_SUCCESS;
-                    break;
-                }
-                case  IOCTL_SCSI_MINIPORT_UNIATA_RESETBB: {
-                    
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: Forget BB list\n"));
-
-                    ForgetBadBlocks(LunExt);
-
-                    status = SRB_STATUS_SUCCESS;
-                    break;
-                }
-                case  IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE: {
-
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset device\n"));
-
-                    if(bad_ldev) {
-                        goto do_bus_reset;
-                    } else {
-                        UniataUserDeviceReset(deviceExtension, LunExt, AtaCtl->addr.PathId);
-                    }
-
-                    status = SRB_STATUS_SUCCESS;
-                    break;
-                }
-                default :
-                    KdPrint2((PRINT_PREFIX "AtapiStartIo: invalid IoControl %#x for -UNIATA- signature\n",
-                                AtaCtl->hdr.ControlCode ));
-                    status = SRB_STATUS_INVALID_REQUEST;
-                    break;
-                }
-
-            } else {
-                KdPrint2((PRINT_PREFIX "AtapiStartIo: IoControl signature incorrect. Send %s, expected %s or %s\n",
-                            ((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,
-                            "SCSIDISK", "-UNIATA-"));
-
-                status = SRB_STATUS_INVALID_REQUEST;
-                break;
-            }
-
-            break;
-        } // end SRB_FUNCTION_IO_CONTROL
-        default:
-
-            KdPrint2((PRINT_PREFIX "AtapiStartIo: Unknown IOCTL\n"));
-            // Indicate unsupported command.
-            status = SRB_STATUS_INVALID_REQUEST;
-
-//            break;
-
-        } // end switch
-
-complete_req:
-
-        PathId   = Srb->PathId;
-        TargetId = Srb->TargetId;
-        Lun      = Srb->Lun;
-
-        if (status != SRB_STATUS_PENDING) {
-
-            KdPrint2((PRINT_PREFIX 
-                       "AtapiStartIo: Srb %#x complete with status %#x\n",
-                       Srb,
-                       status));
-
-            // Set status in SRB.
-            Srb->SrbStatus = (UCHAR)status;
-
-            if(chan && Srb) {
-                KdPrint2((PRINT_PREFIX "AtapiStartIo: AtapiDmaDBSync(%x, %x)\n", chan, Srb));
-                AtapiDmaDBSync(chan, Srb);
-            }
-            KdPrint2((PRINT_PREFIX "AtapiStartIo: UniataRemoveRequest(%x, %x)\n", chan, Srb));
-            UniataRemoveRequest(chan, Srb);
-            // Indicate command complete.
-            KdPrint2((PRINT_PREFIX "AtapiStartIo: ScsiPortNotification\n"));
-            ScsiPortNotification(RequestComplete,
-                                 deviceExtension,
-                                 Srb);
-
-            KdPrint2((PRINT_PREFIX "AtapiStartIo: UniataGetCurRequest\n"));
-            // Remove current Srb & get next one
-            if((Srb = UniataGetCurRequest(chan))) {
-                AtaReq = (PATA_REQ)(Srb->SrbExtension);
-                if(AtaReq->ReqState > REQ_STATE_QUEUED) {
-                    // current request is under precessing, thus
-                    // we should do nothing here
-                    Srb = NULL;
-                }
-            }
-            KdPrint2((PRINT_PREFIX "AtapiStartIo: chan %x, Src %x\n", chan, Srb));
-            if(!chan) {
-                //ASSERT(TopLevel);
-            }
-        }
-        KdPrint2((PRINT_PREFIX "AtapiStartIo: next Srb %x\n", Srb));
-
-    } while (Srb && (status != SRB_STATUS_PENDING));
-
-    KdPrint2((PRINT_PREFIX "AtapiStartIo: query PORT for next request\n"));
-    // Indicate ready for next request.
-    ScsiPortNotification(NextRequest,
-                         deviceExtension,
-                         NULL);
-
-    ScsiPortNotification(NextLuRequest,
-                         deviceExtension, 
-                         PathId,
-                         TargetId,
-                         Lun);
-
-    return TRUE;
-
-} // end AtapiStartIo__()
-
-#if 0
-void
-NTAPI
-UniataInitAtaCommands()
-{
-    int i;
-    UCHAR command;
-    UCHAR flags;
-
-    KdPrint2((PRINT_PREFIX "UniataInitAtaCommands:\n"));
-
-    for(i=0; i<256; i++) {
-
-        flags = 0;
-        command = i;
-
-        //KdPrint2((PRINT_PREFIX "cmd %2.2x: ", command));
-
-        switch(command) {
-        case IDE_COMMAND_READ_DMA48:
-        case IDE_COMMAND_READ_DMA_Q48:
-        case IDE_COMMAND_READ_STREAM_DMA48:
-        case IDE_COMMAND_READ_STREAM48:
-        case IDE_COMMAND_WRITE_DMA48:
-        case IDE_COMMAND_WRITE_DMA_Q48:
-        case IDE_COMMAND_READ_DMA_Q:
-        case IDE_COMMAND_READ_DMA:
-        case IDE_COMMAND_WRITE_DMA:
-        case IDE_COMMAND_WRITE_DMA_Q:
-        case IDE_COMMAND_WRITE_STREAM_DMA48:
-        case IDE_COMMAND_WRITE_STREAM48:
-        case IDE_COMMAND_WRITE_FUA_DMA48:
-        case IDE_COMMAND_WRITE_FUA_DMA_Q48:
-        case IDE_COMMAND_READ_LOG_DMA48:
-        case IDE_COMMAND_WRITE_LOG_DMA48:
-        case IDE_COMMAND_TRUSTED_RCV_DMA:
-        case IDE_COMMAND_TRUSTED_SEND_DMA:
-        case IDE_COMMAND_DATA_SET_MGMT:
-            //KdPrint2((PRINT_PREFIX "DMA "));
-            flags |= ATA_CMD_FLAG_DMA;
-        }
-
-        switch(command) {
-        case IDE_COMMAND_WRITE_FUA_DMA48:
-        case IDE_COMMAND_WRITE_FUA_DMA_Q48:
-        case IDE_COMMAND_WRITE_MUL_FUA48:
-
-            flags |= ATA_CMD_FLAG_FUA;
-            /* FALL THROUGH */
-
-        case IDE_COMMAND_READ48:
-        case IDE_COMMAND_READ_DMA48:
-        case IDE_COMMAND_READ_DMA_Q48:
-        case IDE_COMMAND_READ_MUL48:
-        case IDE_COMMAND_READ_STREAM_DMA48:
-        case IDE_COMMAND_READ_STREAM48:
-        case IDE_COMMAND_WRITE48:
-        case IDE_COMMAND_WRITE_DMA48:
-        case IDE_COMMAND_WRITE_DMA_Q48:
-        case IDE_COMMAND_WRITE_MUL48:
-        case IDE_COMMAND_WRITE_STREAM_DMA48:
-        case IDE_COMMAND_WRITE_STREAM48:
-        case IDE_COMMAND_FLUSH_CACHE48:
-        case IDE_COMMAND_VERIFY48:
-
-            //KdPrint2((PRINT_PREFIX "48 "));
-            flags |= ATA_CMD_FLAG_48;
-            /* FALL THROUGH */
-
-        case IDE_COMMAND_READ:
-        case IDE_COMMAND_READ_MULTIPLE:
-        case IDE_COMMAND_READ_DMA:
-        case IDE_COMMAND_READ_DMA_Q:
-        case IDE_COMMAND_WRITE:
-        case IDE_COMMAND_WRITE_MULTIPLE:
-        case IDE_COMMAND_WRITE_DMA:
-        case IDE_COMMAND_WRITE_DMA_Q:
-        case IDE_COMMAND_FLUSH_CACHE:
-        case IDE_COMMAND_VERIFY:
-
-            //KdPrint2((PRINT_PREFIX "LBA "));
-            flags |= ATA_CMD_FLAG_LBAIOsupp;
-        }
-
-        switch(command) {
-        case IDE_COMMAND_READ_NATIVE_SIZE48:
-        case IDE_COMMAND_SET_NATIVE_SIZE48:
-            // we cannot set LBA flag for these commands to avoid BadBlock handling
-            //flags |= ATA_CMD_FLAG_LBAIOsupp;
-            flags |= ATA_CMD_FLAG_48;
-
-        case IDE_COMMAND_READ_NATIVE_SIZE:
-        case IDE_COMMAND_SET_NATIVE_SIZE:
-
-            flags |= ATA_CMD_FLAG_LBAIOsupp | ATA_CMD_FLAG_FUA;
-        }
-
-        flags |= ATA_CMD_FLAG_48supp;
-
-        switch (command) {
-        case IDE_COMMAND_READ:
-            command = IDE_COMMAND_READ48; break;
-        case IDE_COMMAND_READ_MULTIPLE:
-            command = IDE_COMMAND_READ_MUL48; break;
-        case IDE_COMMAND_READ_DMA:
-            command = IDE_COMMAND_READ_DMA48; break;
-        case IDE_COMMAND_READ_DMA_Q:
-            command = IDE_COMMAND_READ_DMA_Q48; break;
-        case IDE_COMMAND_WRITE:
-            command = IDE_COMMAND_WRITE48; break;
-        case IDE_COMMAND_WRITE_MULTIPLE:
-            command = IDE_COMMAND_WRITE_MUL48; break;
-        case IDE_COMMAND_WRITE_DMA:
-            command = IDE_COMMAND_WRITE_DMA48; break;
-        case IDE_COMMAND_WRITE_DMA_Q:
-            command = IDE_COMMAND_WRITE_DMA_Q48; break;
-        case IDE_COMMAND_FLUSH_CACHE:
-            command = IDE_COMMAND_FLUSH_CACHE48; break;
-    //    case IDE_COMMAND_READ_NATIVE_SIZE:
-    //            command = IDE_COMMAND_READ_NATIVE_SIZE48; break;
-        case IDE_COMMAND_SET_NATIVE_SIZE:
-            command = IDE_COMMAND_SET_NATIVE_SIZE48; break;
-        case IDE_COMMAND_VERIFY:
-            command = IDE_COMMAND_VERIFY48; break;
-        default:
-            //KdPrint2((PRINT_PREFIX "!28->48 "));
-            flags &= ~ATA_CMD_FLAG_48supp;
-        }
-
-        switch (command) {
-        case IDE_COMMAND_READ:
-        case IDE_COMMAND_READ_MULTIPLE:
-        case IDE_COMMAND_READ_DMA48:
-        case IDE_COMMAND_READ_DMA_Q48:
-        case IDE_COMMAND_READ_STREAM_DMA48:
-        case IDE_COMMAND_READ_STREAM48:
-        case IDE_COMMAND_READ_DMA_Q:
-        case IDE_COMMAND_READ_DMA:
-        case IDE_COMMAND_READ_LOG_DMA48:
-        case IDE_COMMAND_TRUSTED_RCV_DMA:
-        case IDE_COMMAND_IDENTIFY:
-        case IDE_COMMAND_ATAPI_IDENTIFY:
-            //KdPrint2((PRINT_PREFIX "RD "));
-            flags |= ATA_CMD_FLAG_In;
-            break;
-        case IDE_COMMAND_WRITE:
-        case IDE_COMMAND_WRITE_MULTIPLE:
-        case IDE_COMMAND_WRITE_DMA48:
-        case IDE_COMMAND_WRITE_DMA_Q48:
-        case IDE_COMMAND_WRITE_DMA:
-        case IDE_COMMAND_WRITE_DMA_Q:
-        case IDE_COMMAND_WRITE_STREAM_DMA48:
-        case IDE_COMMAND_WRITE_STREAM48:
-        case IDE_COMMAND_WRITE_FUA_DMA48:
-        case IDE_COMMAND_WRITE_FUA_DMA_Q48:
-            //KdPrint2((PRINT_PREFIX "WR "));
-            flags |= ATA_CMD_FLAG_Out;
-            break;
-        }
-
-        //KdPrint2((PRINT_PREFIX "\t -> %2.2x (%2.2x)\n", command, flags));
-        AtaCommands48[i]   = command;
-        AtaCommandFlags[i] = flags;
-    }
-} // end UniataInitAtaCommands()
-#endif
-
-/*++
-
-Routine Description:
-
-    Installable driver initialization entry point for system.
-
-Arguments:
-
-    Driver Object
-
-Return Value:
-
-    Status from ScsiPortInitialize()
-
---*/
-extern "C"
-ULONG
-NTAPI
-DriverEntry(
-    IN PVOID DriverObject,
-    IN PVOID Argument2
-    )
-{
-    HW_INITIALIZATION_DATA_COMMON hwInitializationData;
-    ULONG                  adapterCount;
-    ULONG                  i, c, alt, pref_alt;
-    ULONG                  statusToReturn, newStatus;
-    PUNICODE_STRING        RegistryPath = (PUNICODE_STRING)Argument2;
-    BOOLEAN                ReEnter = FALSE;
-//    WCHAR                  a;
-#ifndef USE_REACTOS_DDK
-    NTSTATUS               status;
-#endif
-
-    PCONFIGURATION_INFORMATION GlobalConfig = IoGetConfigurationInformation();
-    BOOLEAN PrimaryClaimed   = FALSE;
-    BOOLEAN SecondaryClaimed = FALSE;
-    BOOLEAN IgnoreIsaCompatiblePci = FALSE;
-    BOOLEAN IgnoreNativePci = FALSE;
-
-    LARGE_INTEGER t0, t1;
-
-    KdPrint2((PRINT_PREFIX "%s", (PCCHAR)ver_string));
-    //a = (WCHAR)strlen(ver_string);
-
-    statusToReturn = 0xffffffff;
-
-    // Zero out structure.
-    RtlZeroMemory(((PCHAR)&hwInitializationData), sizeof(hwInitializationData));
-
-    // Set size of hwInitializationData.
-    hwInitializationData.comm.HwInitializationDataSize =
-      sizeof(hwInitializationData.comm) +
-//      sizeof(hwInitializationData.nt4) +
-      ((WinVer_Id() <= WinVer_NT) ? 0 : sizeof(hwInitializationData.w2k));
-    KdPrint(("HwInitializationDataSize = %x\n", hwInitializationData.comm.HwInitializationDataSize));
-
-    // Set entry points.
-    hwInitializationData.comm.HwInitialize = (PHW_INITIALIZE)AtapiHwInitialize;
-    hwInitializationData.comm.HwResetBus = (PHW_RESET_BUS)AtapiResetController;
-    hwInitializationData.comm.HwStartIo = (PHW_STARTIO)AtapiStartIo;
-    hwInitializationData.comm.HwInterrupt = (PHW_INTERRUPT)AtapiInterrupt;
-
-    // Specify size of extensions.
-    hwInitializationData.comm.DeviceExtensionSize     = sizeof(HW_DEVICE_EXTENSION);
-    hwInitializationData.comm.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION);
-    hwInitializationData.comm.SrbExtensionSize        = sizeof(ATA_REQ);
-
-    // Indicate PIO device.
-    hwInitializationData.comm.MapBuffers = TRUE;
-
-    // Request and parse arument string.
-    KdPrint2((PRINT_PREFIX "\n\nUniATA: parse ArgumentString\n"));
-    // Zero out structure.
-    hwInitializationData.comm.NumberOfAccessRanges = 2;
-    hwInitializationData.comm.HwFindAdapter = AtapiReadArgumentString;
-    ScsiPortInitialize(DriverObject,
-                                    Argument2,
-                                    &hwInitializationData.comm,
-                                    &adapterCount);
-
-    if(!g_Dump) {
-        Connect_DbgPrint();
-        g_opt_Verbose = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PrintLogo", 0);
-        if(g_opt_Verbose) {
-            _PrintNtConsole("Universal ATA driver v 0." UNIATA_VER_STR "\n");
-        }
-        IgnoreIsaCompatiblePci = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreIsaCompatiblePci", IgnoreIsaCompatiblePci) ? TRUE : FALSE;
-        IgnoreNativePci = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreNativePci", IgnoreNativePci) ? TRUE : FALSE;
-    } else {
-        KdPrint(("crashdump mode\n"));
-    }
-
-    if(!SavedDriverObject) {
-        SavedDriverObject = (PDRIVER_OBJECT)DriverObject;
-#ifdef USE_REACTOS_DDK
-        KdPrint(("UniATA Init: OS should be ReactOS\n"));
-        MajorVersion=0x04;
-        MinorVersion=0x01;
-        BuildNumber=1;
-        CPU_num = KeNumberProcessors;
-#else
-        // we are here for the 1st time
-        // init CrossNT and get OS version
-        if(!NT_SUCCESS(status = CrNtInit(SavedDriverObject, RegistryPath))) {
-            KdPrint(("UniATA Init: CrNtInit failed with status %#x\n", status));
-            //HalDisplayString((PUCHAR)"DbgPrnHkInitialize: CrNtInit failed\n");
-            return status;
-        }
-        CPU_num = *KeNumberProcessors;
-#endif // USE_REACTOS_DDK
-        KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, CPU_num));
-
-        KeQuerySystemTime(&t0);
-        do {
-            KeQuerySystemTime(&t1);
-        } while(t0.QuadPart == t1.QuadPart);
-        t0=t1;
-        g_Perf=0;
-        do {
-            KeQuerySystemTime(&t1);
-            g_Perf++;
-        } while(t0.QuadPart == t1.QuadPart);
-        g_PerfDt = (ULONG)((t1.QuadPart - t0.QuadPart)/10);
-        KdPrint(("Performance calibration: dt=%d, counter=%I64d\n", g_PerfDt, g_Perf ));
-    } else {
-        KdPrint(("UniATA Init: ReEnter\n"));
-        ReEnter = TRUE;
-    }
-
-    // (re)read bad block list
-    InitBadBlocks(NULL);
-
-    if(!ReEnter) {
-        // init ATA command translation table
-        //UniataInitAtaCommands();
-
-        // get registry path to settings
-        RtlCopyMemory(&SavedRegPath, RegistryPath, sizeof(UNICODE_STRING));
-        SavedRegPath.Buffer = (PWCHAR)&SavedRegPathBuffer;
-        SavedRegPath.Length = min(RegistryPath->Length, 255*sizeof(WCHAR));
-        SavedRegPath.MaximumLength = 255*sizeof(WCHAR);
-        RtlCopyMemory(SavedRegPath.Buffer, RegistryPath->Buffer, SavedRegPath.Length);
-        SavedRegPath.Buffer[SavedRegPath.Length/sizeof(WCHAR)] = 0;
-    }
-
-    if(WinVer_Id() >= WinVer_2k) {
-        if(AtapiRegCheckParameterValue(NULL, L"Paramaters\\PnpInterface", L"1", 0)) {
-            KdPrint(("UniATA: Behave as WDM, mlia (1)\n"));
-            WinVer_WDM_Model = TRUE;
-        }
-        if(AtapiRegCheckParameterValue(NULL, L"Paramaters\\PnpInterface", L"5", 0)) {
-            KdPrint(("UniATA: Behave as WDM, mlia (5)\n"));
-            WinVer_WDM_Model = TRUE;
-        }
-    }
-
-    SkipRaids = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"SkipRaids", 1);
-    ForceSimplex = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"ForceSimplex", 0);
-#ifdef _DEBUG
-    g_LogToDisplay = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"LogToDisplay", 0);
-#endif //_DEBUG
-
-    // Set PnP-specific API
-    if(WinVer_Id() > WinVer_NT) {
-        KdPrint(("set NeedPhysicalAddresses = TRUE\n"));
-        hwInitializationData.comm.NeedPhysicalAddresses = TRUE;
-        KdPrint(("set AtapiAdapterControl() ptr\n"));
-        hwInitializationData.w2k.HwAdapterControl = (PHW_ADAPTER_CONTROL)AtapiAdapterControl;
-    }
-
-    KdPrint2((PRINT_PREFIX "\n\nUniATA init... (%d)\n", ReEnter));
-    if(!ReEnter) {
-
-        g_opt_VirtualMachine = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"VirtualMachineType", g_opt_VirtualMachine);
-        if(g_opt_VirtualMachine > VM_MAX_KNOWN) {
-            g_opt_VirtualMachine = 0;
-        }
-        if(AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"VirtualBox", (g_opt_VirtualMachine == VM_VBOX))) {
-            g_opt_VirtualMachine = VM_VBOX;
-        }
-        // Pre-scan PCI bus, also check if we are under VM
-        // But do not perform scan if PCI bus is claimed as unused
-        if(!IgnoreIsaCompatiblePci || !IgnoreNativePci) {
-            KdPrint2((PRINT_PREFIX "\nATAPI IDE enum supported PCI BusMaster Devices\n"));
-            UniataEnumBusMasterController(DriverObject, Argument2);
-        }
-
-        switch(g_opt_VirtualMachine) {
-        case VM_VBOX:
-            KdPrint2((PRINT_PREFIX "adjust options for VirtualBox\n"));
-            // adjust options for VirtualBox
-            g_opt_WaitBusyCount = 20000;
-            g_opt_WaitBusyDelay = 150;
-            g_opt_WaitDrqDelay  = 100;
-            g_opt_WaitBusyLongCount = 20000;
-            g_opt_MaxIsrWait = 200;
-            g_opt_AtapiSendDisableIntr = FALSE;
-            g_opt_AtapiDmaRawRead = FALSE;
-            break;
-        case VM_BOCHS:
-            KdPrint2((PRINT_PREFIX "adjust options for Bochs\n"));
-            g_opt_AtapiNoDma = TRUE;
-        }
-
-        if(!hasPCI) {
-            KdPrint2((PRINT_PREFIX "old slow machine, adjust timings\n"));
-            // old slow machine, adjust timings (us)
-            g_opt_WaitBusyResetCount = 20000;
-            g_opt_WaitBusyCount = 20000;
-            g_opt_WaitBusyDelay = 150;
-            g_opt_WaitDrqDelay  = 100;
-            g_opt_WaitBusyLongCount = 20000;
-            g_opt_MaxIsrWait = 200;
-            g_opt_DriveSelectNanoDelay = 400;
-        }
-        if(g_opt_VirtualMachine > VM_NONE) {
-            g_opt_DriveSelectNanoDelay = 0;
-        }
-        if(CPU_num > 1) {
-            g_opt_AtapiSendDisableIntr = TRUE;
-        }
-
-        g_opt_WaitBusyCount = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitBusyCount", g_opt_WaitBusyCount); // 200 vs 20000
-        g_opt_WaitBusyDelay = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitBusyDelay", g_opt_WaitBusyDelay); // 10 vs 150
-        g_opt_WaitDrqDelay  = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitDrqDelay",  g_opt_WaitDrqDelay);  // 10 vs 100
-        g_opt_WaitBusyLongCount = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitBusyLongCount", g_opt_WaitBusyLongCount); // 2000 vs 20000
-        g_opt_WaitBusyLongDelay = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"WaitBusyLongDelay", g_opt_WaitBusyLongDelay); // 250 vs 250
-        g_opt_AtapiSendDisableIntr = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiSendDisableIntr",  g_opt_AtapiSendDisableIntr) ? TRUE : FALSE;  // 1 vs 0
-        g_opt_AtapiDmaRawRead      = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaRawRead",       g_opt_AtapiDmaRawRead) ? TRUE : FALSE;       // 1 vs 0
-        g_opt_AtapiNoDma    = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiNoDma", g_opt_AtapiNoDma) ? TRUE : FALSE;       // 1 vs 0
-        g_opt_MaxIsrWait    = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"MaxIsrWait", g_opt_MaxIsrWait);       // 40 vs xxx
-        g_opt_DriveSelectNanoDelay = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"DriveSelectNanoDelay", g_opt_DriveSelectNanoDelay);
-    } // end !re-enter
-
-    // Look for legacy ISA-bridged PCI IDE controller (onboard)
-    KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: Look for legacy ISA-bridged PCI IDE controller (onboard)\n"));
-    KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: BMListLen %d\n", BMListLen));
-    for (i=0; i <BMListLen; i++) {
-
-        if(!BMList[i].MasterDev) {
-            KdPrint2((PRINT_PREFIX "!BMList[i].MasterDev\n"));
-            break;
-        }
-        if(IgnoreIsaCompatiblePci) {
-            break;
-        }
-        if(ReEnter) {
-            KdPrint2((PRINT_PREFIX "ReEnter, skip it\n"));
-            if(BMList[i].ChanInitOk & 0x03) {
-                KdPrint2((PRINT_PREFIX "Already initialized, skip it\n"));
-                statusToReturn =
-                newStatus = STATUS_SUCCESS;
-            }
-            continue;
-        }
-        //BMList[i].AltInitMasterDev = (UCHAR)0xff;
-
-        if(GlobalConfig->AtDiskPrimaryAddressClaimed)
-            PrimaryClaimed = TRUE;
-        if(GlobalConfig->AtDiskSecondaryAddressClaimed)
-            SecondaryClaimed = TRUE;
-        pref_alt = 0;
-
-        if(!WinVer_WDM_Model && !PrimaryClaimed && !SecondaryClaimed && !g_Dump &&
-            !(BMList[i].ChanInitOk & 0x80)) {
-            
-            // We just want to claim our PCI device in compatible mode, since we shall not
-            // tell system that we use it inside HwInitialize
-            // Even more, we shall cheat system, that work with ISA
-            // Note: this call may (but not 'must' or 'can') cause IO resource
-            // reallocation and switch to native mode if HAL supports this
-            newStatus = (ULONG)UniataClaimLegacyPCIIDE(i);
-            // Special check for NT3.51/NT4 (not ReactOS !!!)
-            if(((NTSTATUS)newStatus == STATUS_CONFLICTING_ADDRESSES) &&
-               //(BMList[i].ChanInitOk & 0x40) &&
-               /*CPU_num > 1 &&*/
-               (WinVer_Id() <= WinVer_NT)) {
-                // Some NT3/4 SMP (but not only) HALs cannot reallocate IO resources of
-                // BusMaster PCI controller
-                // Since nobody claimed Primary/Secondary yet, try init and claim them
-                // However it is not 100% safe way, especially under ReactOS, which doesn't resolve
-                // conflicts yet.
-                // We relay on ScsiPort internal checks
-                KdPrint2((PRINT_PREFIX "Can't acquire PCI part of BusMaster on SMP NT3/4 system, try init anyway.\n"));
-                newStatus = STATUS_SUCCESS;
-                // Prefer alternative init method (try to change Isa -> PCI in ConfigInfo first)
-                pref_alt = 1;
-            }
-            if(newStatus != STATUS_SUCCESS) {
-                KdPrint2((PRINT_PREFIX "Can't acquire PCI part of BusMaster, try as pure ISA later.\n"));
-                break;
-            }
-        }
-
-        if(g_opt_Verbose) {
-            _PrintNtConsole("Init standard Dual-channel PCI ATA controller:");
-        }
-
-        for(alt = 0; alt < (ULONG)(WinVer_WDM_Model ? 1 : 2) ; alt++) {
-
-            for(c=0; c<2; c++) {
-                // check is channel is manually excluded
-                if(AtapiRegCheckDevValue(NULL, c, DEVNUM_NOT_SPECIFIED, L"IgnoreIsaCompatiblePci", 0)) {
-                    break;
-                }
-                if(c==0) {
-                    if(PrimaryClaimed) {
-                        KdPrint2((PRINT_PREFIX "Primary already claimed\n"));
-                        continue;
-                    }
-                } else
-                if(c==1) {
-                    if(SecondaryClaimed) {
-                        KdPrint2((PRINT_PREFIX "Secondary already claimed\n"));
-                        continue;
-                    }
-                }
-
-                if((WinVer_Id() < WinVer_2k)) {
-                    // do not even try if already claimed
-                    if(c==0) {
-                        GlobalConfig->AtDiskPrimaryAddressClaimed = FALSE;
-                    } else
-                    if(c==1) {
-                        GlobalConfig->AtDiskSecondaryAddressClaimed = FALSE;
-                    }
-                }
-                if(!WinVer_WDM_Model) {
-                    hwInitializationData.comm.HwFindAdapter = UniataFindBusMasterController;
-                } else {
-                    // in WDM model things are different....
-                    hwInitializationData.comm.HwFindAdapter = (c == 0) ?
-                        UniataFindCompatBusMasterController1 : UniataFindCompatBusMasterController2;
-                }
-                hwInitializationData.comm.NumberOfAccessRanges = 6;
-                hwInitializationData.comm.AdapterInterfaceType = Isa;
-
-                if(!WinVer_WDM_Model) {
-                    BMList[i].channel = (UCHAR)c;
-                }
-
-                KdPrint2((PRINT_PREFIX "Try init channel %d, method %d\n", c, alt));
-                newStatus = ScsiPortInitialize(DriverObject,
-                                               Argument2,
-                                               &hwInitializationData.comm,
-                                               (PVOID)(i | ((alt ^ pref_alt) ? 0x80000000 : 0)));
-                KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x\n", newStatus));
-                if (newStatus < statusToReturn) {
-                    statusToReturn = newStatus;
-                }
-                if (newStatus == STATUS_SUCCESS) {
-                    if(WinVer_Id() < WinVer_2k) {
-                        // This should be done in HwInitialize under w2k+ to ensure that 
-                        // channel is actually initialized
-                        BMList[i].ChanInitOk |= 0x01 << c;
-                    } else {
-                        if(BMList[i].ChanInitOk & (0x01 << c)) {
-                            KdPrint2((PRINT_PREFIX "HwInit passed\n"));
-                        }
-                    }
-/*
-                    if(BMList[i].MasterDev && (WinVer_Id() > WinVer_NT)) {
-                        c = 1; // this will break our for()
-                        BMList[i].ChanInitOk |= 0x01 << c;
-                    }
-*/
-                }
-            }
-/*            if(WinVer_Id() >= WinVer_2k) {
-                // the following didn't work under higher OSes,
-                // until we move setting of FLAGS to HwInit
-                KdPrint2((PRINT_PREFIX "make still one attempt\n"));
-                continue;
-            }*/
-            if(BMList[i].ChanInitOk & 0x03) {
-                // Under NT we receive status immediately, so
-                // we can omit alternative init method if STATUS_SUCCESS returned.
-                // Under w2k+ we relay on flags, set in HwInitialize.
-                KdPrint2((PRINT_PREFIX "Ok, no more retries required\n"));
-                break;
-            } else
-            if(WinVer_Id() >= WinVer_2k) {
-                // try AltInit if HwInit was not called immediately under w2k+
-                KdPrint2((PRINT_PREFIX "make still one attempt w2k+\n"));
-            } else {
-                // if (WinVer_Id() == WinVer_NT) and some error occured
-                // try alternative init method
-                KdPrint2((PRINT_PREFIX "make still one attempt w2k+\n"));
-            }
-        } // for(alt...)
-        if(g_opt_Verbose) {
-            if(BMList[i].ChanInitOk & 0x03) {
-                _PrintNtConsole("  OK\n");
-            } else {
-                _PrintNtConsole("  failed\n");
-            }
-        }
-
-    }
-
-/*    KeBugCheckEx(0xc000000e,
-                 (i << 16) | BMList[0].ChanInitOk,
-                 c, 
-                 newStatus, statusToReturn);*/
-
-    // Look for PCI IDE controller
-    KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: Look for PCI IDE controller\n"));
-    KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: i %d, BMListLen %d\n", i, BMListLen));
-    for (; i <BMListLen; i++) {
-
-        if(IgnoreNativePci) {
-            break;
-        }
-/*        if(BMList[i].MasterDev)
-            continue;*/
-        if(g_opt_Verbose) {
-            _PrintNtConsole("Init PCI ATA controller Vendor/Dev %4.4s//%4.4s at PCI Address %d:%d:%d",
-                BMList[i].VendorId, BMList[i].DeviceId,
-                BMList[i].busNumber,
-                BMList[i].slotNumber % PCI_MAX_FUNCTION,
-                (BMList[i].slotNumber / PCI_MAX_FUNCTION) % PCI_MAX_DEVICES);
-        }
-
-        hwInitializationData.comm.HwFindAdapter = UniataFindBusMasterController;
-        hwInitializationData.comm.NumberOfAccessRanges = 6;
-        hwInitializationData.comm.AdapterInterfaceType = PCIBus;
-
-        hwInitializationData.comm.VendorId             = (PVOID)BMList[i].VendorId;
-        hwInitializationData.comm.VendorIdLength       = (USHORT) BMList[i].VendorIdLength;
-        hwInitializationData.comm.DeviceId             = (PVOID)BMList[i].DeviceId;
-        hwInitializationData.comm.DeviceIdLength       = (USHORT) BMList[i].DeviceIdLength;
-
-        BMList[i].channel = 0/*(UCHAR)c*/;
-
-        KdPrint2((PRINT_PREFIX "Try init %4.4s %4.4s \n",
-                               hwInitializationData.comm.VendorId,
-                               hwInitializationData.comm.DeviceId));
-        newStatus = ScsiPortInitialize(DriverObject,
-                                       Argument2,
-                                       &hwInitializationData.comm,
-                                       (PVOID)i);
-        KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x\n", newStatus));
-        if(newStatus == (ULONG)STATUS_DEVICE_DOES_NOT_EXIST && BMList[i].NeedAltInit) {
-            // Note: this is actually a BUG in scsiport.sys
-            // It stops scanning PCI bus when reaches empty PCI Function inside Slot
-            // However, this PCI Slot may have higher non-empty Functions
-            // UniATA will perform all staff instead of ScsiPort under NT,
-            // but for ReactOS it is better to patch ScsiPort.
-            KdPrint2((PRINT_PREFIX "STATUS_DEVICE_DOES_NOT_EXIST, try workaround\n"));
-            hwInitializationData.comm.AdapterInterfaceType = Isa;
-            newStatus = ScsiPortInitialize(DriverObject,
-                                           Argument2,
-                                           &hwInitializationData.comm,
-                                           (PVOID)(i | 0x80000000));
-            KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x (2)\n", newStatus));
-        }
-        if (newStatus < statusToReturn)
-            statusToReturn = newStatus;
-
-        if(g_opt_Verbose) {
-            if(newStatus == STATUS_SUCCESS) {
-                _PrintNtConsole("  OK\n");
-            } else {
-                _PrintNtConsole("  failed\n");
-            }
-        }
-
-    }
-
-/*    KeBugCheckEx(0xc000000e,
-                 i,
-                 c, 
-                 newStatus, statusToReturn);*/
-
-    // --------------
-
-    hwInitializationData.comm.VendorId             = 0;
-    hwInitializationData.comm.VendorIdLength       = 0;
-    hwInitializationData.comm.DeviceId             = 0;
-    hwInitializationData.comm.DeviceIdLength       = 0;
-
-    if(!BMListLen) {
-        hwInitializationData.comm.SrbExtensionSize        = //FIELD_OFFSET(ATA_REQ, ata);
-                                                            sizeof(ATA_REQ);
-        KdPrint2((PRINT_PREFIX "using AtaReq sz %x\n", hwInitializationData.comm.SrbExtensionSize));
-    }
-
-    // The adapter count is used by the find adapter routine to track how
-    // which adapter addresses have been tested.
-
-    // Indicate 2 access ranges and reset FindAdapter.
-    hwInitializationData.comm.NumberOfAccessRanges = 2;
-    hwInitializationData.comm.HwFindAdapter = AtapiFindIsaController;
-
-    if(!AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreIsa", 0)) {
-        // Indicate ISA bustype.
-        hwInitializationData.comm.AdapterInterfaceType = Isa;
-        adapterCount = 0;
-
-        // Call initialization for ISA bustype.
-        KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: Look for ISA Controllers\n"));
-        newStatus =  ScsiPortInitialize(DriverObject,
-                                        Argument2,
-                                        &hwInitializationData.comm,
-                                        &adapterCount);
-        KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x\n", newStatus));
-        if (newStatus < statusToReturn)
-            statusToReturn = newStatus;
-    }
-    if(!AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreMca", 0)) {
-        // Set up for MCA
-        KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: Look for MCA Controllers\n"));
-        hwInitializationData.comm.AdapterInterfaceType = MicroChannel;
-        adapterCount = 0;
-
-        newStatus =  ScsiPortInitialize(DriverObject,
-                                        Argument2,
-                                        &hwInitializationData.comm,
-                                        &adapterCount);
-        KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x\n", newStatus));
-        if (newStatus < statusToReturn)
-            statusToReturn = newStatus;
-    }
-    InDriverEntry = FALSE;
-
-    KdPrint2((PRINT_PREFIX "\n\nLeave UNIATA MiniPort DriverEntry with status %#x\n", statusToReturn));
-
-    return statusToReturn;
-
-} // end DriverEntry()
-
-
-PSCSI_REQUEST_BLOCK
-NTAPI
-BuildMechanismStatusSrb(
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PSCSI_REQUEST_BLOCK srb;
-    PCDB cdb;
-    PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
-
-    srb = &(deviceExtension->chan[GET_CHANNEL(Srb)].InternalSrb);
-
-    RtlZeroMemory((PCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
-
-    srb->PathId     = (UCHAR)(Srb->PathId);
-    srb->TargetId   = (UCHAR)(Srb->TargetId);
-    srb->Function   = SRB_FUNCTION_EXECUTE_SCSI;
-    srb->Length     = sizeof(SCSI_REQUEST_BLOCK);
-
-    // Set flags to disable synchronous negociation.
-    srb->SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
-
-    // Set timeout to 4 seconds.
-    srb->TimeOutValue = 4;
-
-    srb->CdbLength          = 6;
-    srb->DataBuffer         = &(deviceExtension->chan[GET_CHANNEL(Srb)].MechStatusData);
-    srb->DataTransferLength = sizeof(MECHANICAL_STATUS_INFORMATION_HEADER);
-    srb->SrbExtension       = AtaReq;
-
-    // Set CDB operation code.
-    cdb = (PCDB)srb->Cdb;
-    cdb->MECH_STATUS.OperationCode       = SCSIOP_MECHANISM_STATUS;
-    cdb->MECH_STATUS.AllocationLength[1] = sizeof(MECHANICAL_STATUS_INFORMATION_HEADER);
-
-    KdPrint2((PRINT_PREFIX " MechanismStatusSrb %#x\n", srb));
-
-    return srb;
-} // end BuildMechanismStatusSrb()
-
-#endif //UNIATA_CORE
-
-PSCSI_REQUEST_BLOCK
-NTAPI
-BuildRequestSenseSrb (
-    IN PVOID HwDeviceExtension,
-    IN PSCSI_REQUEST_BLOCK Srb
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PSCSI_REQUEST_BLOCK srb;
-    PCDB cdb;
-    PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
-
-    srb = &(deviceExtension->chan[GET_CHANNEL(Srb)].InternalSrb);
-
-    RtlZeroMemory((PCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
-
-    srb->PathId     = (UCHAR)(Srb->PathId);
-    srb->TargetId   = (UCHAR)(Srb->TargetId);
-    srb->Function   = SRB_FUNCTION_EXECUTE_SCSI;
-    srb->Length     = sizeof(SCSI_REQUEST_BLOCK);
-
-    // Set flags to disable synchronous negociation.
-    srb->SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
-
-    // Set timeout to 2 seconds.
-    srb->TimeOutValue = 4;
-
-    srb->CdbLength          = 6;
-    srb->DataBuffer         = &(deviceExtension->chan[GET_CHANNEL(Srb)].MechStatusSense);
-    srb->DataTransferLength = sizeof(SENSE_DATA);
-    srb->SrbExtension       = AtaReq;
-
-    // Set CDB operation code.
-    cdb = (PCDB)srb->Cdb;
-    cdb->CDB6INQUIRY.OperationCode    = SCSIOP_REQUEST_SENSE;
-    cdb->CDB6INQUIRY.AllocationLength = sizeof(SENSE_DATA);
-
-    KdPrint2((PRINT_PREFIX " RequestSenseSrb %#x\n", srb));
-
-    return srb;
-} // end BuildRequestSenseSrb()
-
-#ifndef UNIATA_CORE
-
-ULONG
-NTAPI
-AtapiRegCheckDevLunValue(
-    IN PVOID HwDeviceExtension,
-    IN PCWCH NamePrefix,
-    IN ULONG chan,
-    IN ULONG dev,
-    IN PCWSTR Name,
-    IN ULONG Default
-    )
-{
-    WCHAR namex[160];
-    ULONG val = Default;
-
-    val = AtapiRegCheckParameterValue(
-        HwDeviceExtension, NamePrefix, Name, val);
-
-    if(chan != CHAN_NOT_SPECIFIED) {
-        swprintf(namex, L"%s\\Chan_%1.1d", NamePrefix, chan);
-        val = AtapiRegCheckParameterValue(
-            HwDeviceExtension, namex, Name, val);
-        if(dev != DEVNUM_NOT_SPECIFIED) {
-            swprintf(namex, L"%s\\Chan_%1.1d\\%s", NamePrefix, chan, (dev & 0x01) ? L"Lun_1" : L"Lun_0");
-            val = AtapiRegCheckParameterValue(
-                HwDeviceExtension, namex, Name, val);
-        }
-    }
-    return val;
-} // end AtapiRegCheckDevLunValue()
-
-ULONG
-NTAPI
-EncodeVendorStr(
-   OUT PWCHAR Buffer,
-    IN PUCHAR Str,
-    IN ULONG  Length
-    )
-{
-    ULONG i,j;
-    WCHAR a;
-
-    for(i=0, j=0; i<Length; i++, j++) {
-        // fix byte-order
-        a = Str[i ^ 0x01];
-        if(!a) {
-            Buffer[j] = 0;
-            return j;
-        } else
-        if(a == ' ') {
-            Buffer[j] = '_';
-        } else
-        if((a == '_') ||
-           (a == '#') ||
-           (a == '\\') ||
-           (a == '\"') ||
-           (a == '\'') ||
-           (a <  ' ') ||
-           (a >= 127)) {
-            Buffer[j] = '#';
-            j++;
-            swprintf(Buffer+j, L"%2.2x", a);
-            j++;
-        } else {
-            Buffer[j] = a;
-        }
-    }
-    Buffer[j] = 0;
-    return j;
-} // end EncodeVendorStr()
-
-ULONG
-NTAPI
-AtapiRegCheckDevValue(
-    IN PVOID HwDeviceExtension,
-    IN ULONG chan,
-    IN ULONG dev,
-    IN PCWSTR Name,
-    IN ULONG Default
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-//    WCHAR name0[11];
-//    WCHAR name1[11+4+5];
-//    WCHAR name2[11+4+4+10];
-//    WCHAR name3[11+4+4+5+20];
-//    WCHAR name3[11+4+4+5+20+1];
-    WCHAR namex[160];
-
-    WCHAR namev[16];
-    WCHAR named[16];
-    WCHAR names[20];
-
-    IN ULONG VendorID;
-    IN ULONG DeviceID;
-    IN ULONG SlotNumber;
-
-    ULONG val = Default;
-
-    KdPrint(( " Parameter %ws\n", Name));
-
-    if(deviceExtension) {
-        VendorID   =  deviceExtension->DevID        & 0xffff;
-        DeviceID   = (deviceExtension->DevID >> 16) & 0xffff;
-        SlotNumber = deviceExtension->slotNumber;
-    } else {
-        VendorID   = 0xffff;
-        DeviceID   = 0xffff;
-        SlotNumber = 0xffffffff;
-    }
-
-    val = AtapiRegCheckDevLunValue(
-        HwDeviceExtension, L"Parameters", chan, dev, Name, val);
-
-    if(deviceExtension) {
-        if(deviceExtension->AdapterInterfaceType == PCIBus) {
-            // PCI
-            swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex);
-            swprintf(namex, L"Parameters%s", namev);
-            val = AtapiRegCheckDevLunValue(
-                HwDeviceExtension, namex, chan, dev, Name, val);
-
-
-            swprintf(namev, L"\\Ven_%4.4x", VendorID);
-            swprintf(named, L"\\Dev_%4.4x", DeviceID);
-            swprintf(names, L"\\Slot_%8.8x", SlotNumber);
-
-            swprintf(namex, L"Parameters%s", namev);
-            val = AtapiRegCheckDevLunValue(
-                HwDeviceExtension, namex, chan, dev, Name, val);
-
-            swprintf(namex, L"Parameters%s%s", namev, named);
-            val = AtapiRegCheckDevLunValue(
-                HwDeviceExtension, namex, chan, dev, Name, val);
-
-            swprintf(namex, L"Parameters%s%s%s", namev, named, names);
-            val = AtapiRegCheckDevLunValue(
-                HwDeviceExtension, namex, chan, dev, Name, val);
-        } else
-        if(deviceExtension->AdapterInterfaceType == Isa) {
-            // Isa
-            swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex+BMListLen);
-            swprintf(namex, L"Parameters%s", namev);
-            val = AtapiRegCheckDevLunValue(
-                HwDeviceExtension, namex, chan, dev, Name, val);
-
-            swprintf(namev, L"\\ISA_%d", deviceExtension->DevIndex);
-            swprintf(namex, L"Parameters%s", namev);
-            val = AtapiRegCheckDevLunValue(
-                HwDeviceExtension, namex, chan, dev, Name, val);
-
-        } else
-        if(deviceExtension->AdapterInterfaceType == MicroChannel) {
-            // MicroChannel
-            swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex+BMListLen+IsaCount);
-            swprintf(namex, L"Parameters%s", namev);
-            val = AtapiRegCheckDevLunValue(
-                HwDeviceExtension, namex, chan, dev, Name, val);
-
-            swprintf(namev, L"\\MCA_%d", deviceExtension->DevIndex);
-            swprintf(namex, L"Parameters%s", namev);
-            val = AtapiRegCheckDevLunValue(
-                HwDeviceExtension, namex, chan, dev, Name, val);
-
-        }
-    }
-
-    KdPrint(( " Parameter %ws = %#x\n", Name, val));
-    return val;
-
-} // end AtapiRegCheckDevValue()
-
-/*
-    The user must specify that Xxx is to run on the platform
-    by setting the registry value HKEY_LOCAL_MACHINE\System\CurrentControlSet\
-    Services\UniATA\Xxx:REG_DWORD:Zzz.
-
-    The user can override the global setting to enable or disable Xxx on a
-    specific cdrom device by setting the key HKEY_LOCAL_MACHINE\System\
-    CurrentControlSet\Services\UniATA\Parameters\Device<N>\Xxx:REG_DWORD to one or zero.
-
-    If this registry value does not exist or contains the value zero then
-    the timer to check for media change does not run.
-
-    Arguments:
-
-    RegistryPath - pointer to the unicode string inside
-                   ...\CurrentControlSet\Services\UniATA
-    DeviceNumber - The number of the HBA device object
-
-    Returns:    Registry Key value
- */
-ULONG
-NTAPI
-AtapiRegCheckParameterValue(
-    IN PVOID HwDeviceExtension,
-    IN PCWSTR PathSuffix,
-    IN PCWSTR Name,
-    IN ULONG Default
-    )
-{
-#define ITEMS_TO_QUERY 2 // always 1 greater than what is searched 
-
-//    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    NTSTATUS          status;
-    LONG              zero = Default;
-
-    RTL_QUERY_REGISTRY_TABLE parameters[ITEMS_TO_QUERY];
-
-//    LONG              tmp = 0;
-    LONG              doRun = Default;
-
-    PUNICODE_STRING   RegistryPath = &SavedRegPath;
-
-    UNICODE_STRING    paramPath;
-
-    if(g_Dump) {
-        goto failed;
-    }
-
-    // <SavedRegPath>\<PathSuffix> -> <Name>
-//    KdPrint(( "AtapiCheckRegValue: %ws -> %ws\n", PathSuffix, Name));
-//    KdPrint(( "AtapiCheckRegValue: RegistryPath %ws\n", RegistryPath->Buffer));
-
-    paramPath.Length = 0;
-    paramPath.MaximumLength = RegistryPath->Length +
-        (wcslen(PathSuffix)+2)*sizeof(WCHAR);
-    paramPath.Buffer = (PWCHAR)ExAllocatePool(NonPagedPool, paramPath.MaximumLength);
-    if(!paramPath.Buffer) {
-        KdPrint(("AtapiCheckRegValue: couldn't allocate paramPath\n"));
-        return Default;
-    }
-
-    RtlZeroMemory(paramPath.Buffer, paramPath.MaximumLength);
-    RtlAppendUnicodeToString(&paramPath, RegistryPath->Buffer);
-    RtlAppendUnicodeToString(&paramPath, L"\\");
-    RtlAppendUnicodeToString(&paramPath, REGRTL_STR_PTYPE PathSuffix);
-
-    // Check for the Xxx value.
-    RtlZeroMemory(parameters, (sizeof(RTL_QUERY_REGISTRY_TABLE)*ITEMS_TO_QUERY));
-
-    parameters[0].Flags         = RTL_QUERY_REGISTRY_DIRECT;
-    parameters[0].Name          = REGRTL_STR_PTYPE Name;
-    parameters[0].EntryContext  = &doRun;
-    parameters[0].DefaultType   = REG_DWORD;
-    parameters[0].DefaultData   = &zero;
-    parameters[0].DefaultLength = sizeof(ULONG);
-
-    status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
-                                    paramPath.Buffer, parameters, NULL, NULL);
-    if(NT_SUCCESS(status)) {
-        KdPrint(( "AtapiCheckRegValue: %ws -> %ws is %#x\n", PathSuffix, Name, doRun));
-    }
-
-    ExFreePool(paramPath.Buffer);
-
-    if(!NT_SUCCESS(status)) {
-failed:
-        doRun = Default;
-    }
-
-    return doRun;
-
-#undef ITEMS_TO_QUERY
-
-} // end AtapiRegCheckParameterValue()
-
-
-SCSI_ADAPTER_CONTROL_STATUS
-NTAPI
-AtapiAdapterControl(
-    IN PVOID HwDeviceExtension,
-    IN SCSI_ADAPTER_CONTROL_TYPE ControlType,
-    IN PVOID Parameters
-    )
-{
-    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PSCSI_SUPPORTED_CONTROL_TYPE_LIST pControlTypeList;
-    ULONG                numberChannels  = deviceExtension->NumberChannels;
-    ULONG c;
-    NTSTATUS status;
-
-    KdPrint(( "AtapiAdapterControl: %#x\n", ControlType));
-
-    switch(ControlType) {
-        case ScsiQuerySupportedControlTypes: {
-            BOOLEAN supportedTypes[ScsiAdapterControlMax] = {
-                TRUE,       // ScsiQuerySupportedControlTypes
-                TRUE,       // ScsiStopAdapter
-                TRUE,       // ScsiRestartAdapter
-                FALSE,      // ScsiSetBootConfig
-                FALSE       // ScsiSetRunningConfig
-            };
-
-            ULONG lim = ScsiAdapterControlMax;
-            ULONG i;
-
-            pControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST) Parameters;
-
-            if(pControlTypeList->MaxControlType < lim) {
-                lim = pControlTypeList->MaxControlType;
-            }
-
-            for(i = 0; i < lim; i++) {
-                pControlTypeList->SupportedTypeList[i] = supportedTypes[i];
-            }
-
-            break;
-
-        }
-        case ScsiStopAdapter: {
-
-            KdPrint(( "AtapiAdapterControl: ScsiStopAdapter\n"));
-            // Shut down all interrupts on the adapter.  They'll get re-enabled
-            // by the initialization routines.
-            for (c = 0; c < numberChannels; c++) {
-                AtapiResetController(deviceExtension, c);
-                AtapiDisableInterrupts(deviceExtension, c);
-            }
-            if(deviceExtension->AdapterInterfaceType == PCIBus) {
-                // we must never get here for non-PCI
-                /*status =*/ UniataDisconnectIntr2(HwDeviceExtension);
-                BMList[deviceExtension->DevIndex].Isr2Enable = FALSE;
-            }
-            break;
-        }
-        case ScsiRestartAdapter: {
-
-            KdPrint(( "AtapiAdapterControl: ScsiRestartAdapter\n"));
-            // Enable all the interrupts on the adapter while port driver call
-            // for power up an HBA that was shut down for power management
-
-            AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, CHAN_NOT_SPECIFIED);
-            status = UniataConnectIntr2(HwDeviceExtension);
-            if(NT_SUCCESS(status)) {
-                for (c = 0; c < numberChannels; c++) {
-                    AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, c);
-                    FindDevices(HwDeviceExtension, 0, c);
-                    AtapiEnableInterrupts(deviceExtension, c);
-                    AtapiHwInitialize__(deviceExtension, c);
-                }
-                if(deviceExtension->Isr2DevObj) {
-                    // we must never get here for non-PCI
-                    BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
-                }
-            }
-
-            break;
-        }
-
-        default: {
-            KdPrint(( "AtapiAdapterControl: default => return ScsiAdapterControlUnsuccessful\n"));
-            return ScsiAdapterControlUnsuccessful;
-        }
-    }
-
-    return ScsiAdapterControlSuccess;
-} // end AtapiAdapterControl()
-
-#endif //UNIATA_CORE
-
-extern "C"
-NTHALAPI
-VOID
-NTAPI
-HalDisplayString (
-    PUCHAR String
-    );
-
-#define DEBUG_MSG_BUFFER_SIZE   512
-
-extern "C"
-VOID
-_cdecl
-_PrintNtConsole(
-    PCCH DebugMessage,
-    ...
-    )
-{
-    //int len;
-    UCHAR dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE];
-//    UNICODE_STRING msgBuff;
-    va_list ap;
-    va_start(ap, DebugMessage);
-
-    /*len =*/ _vsnprintf((PCHAR)&dbg_print_tmp_buff[0], DEBUG_MSG_BUFFER_SIZE-1, DebugMessage, ap);
-
-    dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE-1] = 0;
-
-    //DbgPrint(((PCHAR)&(dbg_print_tmp_buff[0]))); // already done in KdPrint macro
-    HalDisplayString(dbg_print_tmp_buff);
-
-#ifdef _DEBUG
-    if(g_LogToDisplay > 1) {
-        AtapiStallExecution(g_LogToDisplay*1000);
-    }
-#endif // _DEBUG
-
-    va_end(ap);
-
-} // end PrintNtConsole()
-