diff -uN M:\work\UniATA\etc\v45g\driver\atapi.h M:\work\UniATA\BusMaster\driver\atapi.h
--- M:\work\UniATA\etc\v45g\driver\atapi.h	Tue Aug 12 01:13:18 2014
+++ M:\work\UniATA\BusMaster\driver\atapi.h	Sun Feb 22 09:48:11 2015
@@ -437,6 +437,7 @@
 #define IDE_DRIVE_2                  0x10
 #define IDE_DRIVE_SELECT_1           (IDE_DRIVE_SELECT | IDE_DRIVE_1)
 #define IDE_DRIVE_SELECT_2           (IDE_DRIVE_SELECT | IDE_DRIVE_2)
+#define IDE_DRIVE_MASK               (IDE_DRIVE_SELECT_1 | IDE_DRIVE_SELECT_2)
 
 #define IDE_USE_LBA                  0x40
 
diff -uN M:\work\UniATA\etc\v45g\driver\bm_devs.h M:\work\UniATA\BusMaster\driver\bm_devs.h
--- M:\work\UniATA\etc\v45g\driver\bm_devs.h	Tue Aug 12 00:59:48 2014
+++ M:\work\UniATA\BusMaster\driver\bm_devs.h	Tue Feb 24 02:09:48 2015
@@ -696,6 +696,11 @@
 #define VIAPRQ		0x8000
 #define VIASATA         0x10000
 
+#define CYRIX_OLD       0
+#define CYRIX_3x        1
+#define CYRIX_NEW       2
+#define CYRIX_35        3
+
 #define ITE_33          0
 #define ITE_133         1
 #define ITE_133_NEW     2
@@ -734,6 +739,7 @@
     PCI_DEV_HW_SPEC_BM( 7411, 1022, 0x00, ATA_UDMA5, "AMD 766"          , 0 | AMDBUG                      ),
     PCI_DEV_HW_SPEC_BM( 7441, 1022, 0x00, ATA_UDMA5, "AMD 768"          , 0                               ),
     PCI_DEV_HW_SPEC_BM( 7469, 1022, 0x00, ATA_UDMA6, "AMD 8111"         , 0                               ),
+    PCI_DEV_HW_SPEC_BM( 208F, 1022, 0x00, ATA_UDMA4, "AMD CS5535"       , CYRIX_35                        ),
     PCI_DEV_HW_SPEC_BM( 209a, 1022, 0x00, ATA_UDMA5, "AMD CS5536"       , 0                               ),
 
     PCI_DEV_HW_SPEC_BM( 4349, 1002, 0x00, ATA_UDMA5, "ATI IXP200"       , 0                                       ),
@@ -1041,6 +1047,7 @@
     PCI_DEV_HW_SPEC_BM( 0d8f, 10de, 0x00, ATA_SA300, "nVidia nForce MCP89 AB", UNIATA_SATA | UNIATA_AHCI  ),
 
     PCI_DEV_HW_SPEC_BM( 0502, 100b, 0x00, ATA_UDMA2, "National Geode SC1100", 0                                   ),
+    PCI_DEV_HW_SPEC_BM( 002d, 100b, 0x00, ATA_UDMA4, "National Geode CS5535", CYRIX_35                            ),
 
     PCI_DEV_HW_SPEC_BM( 4d33, 105a, 0x00, ATA_UDMA2, "Promise PDC20246" , PROLD | 0x00                            ),
     PCI_DEV_HW_SPEC_BM( 4d38, 105a, 0x00, ATA_UDMA4, "Promise PDC20262" , PRNEW | 0x00                            ),
@@ -1204,7 +1211,9 @@
 */
     PCI_DEV_HW_SPEC_BM( 0001, 16ca, 0x00, ATA_WDMA2, "Cenatek Rocket Drive",0                                     ),
 
-    PCI_DEV_HW_SPEC_BM( 0102, 1078, 0x00, ATA_UDMA2, "Cyrix 5530"       , 0                                       ),
+    PCI_DEV_HW_SPEC_BM( 0000, 1078, 0x00, ATA_WDMA2, "Cyrix 5510"       , CYRIX_OLD                               ),
+    PCI_DEV_HW_SPEC_BM( 0002, 1078, 0x00, ATA_WDMA2, "Cyrix 5520"       , CYRIX_OLD                               ),
+    PCI_DEV_HW_SPEC_BM( 0102, 1078, 0x00, ATA_UDMA2, "Cyrix 5530"       , CYRIX_3x                                ),
 
     PCI_DEV_HW_SPEC_BM( 1000, 1042, 0x00, ATA_PIO4,  "RZ 100x"          , 0                                       ),
     PCI_DEV_HW_SPEC_BM( 1001, 1042, 0x00, ATA_PIO4,  "RZ 100x"          , 0                                       ),
diff -uN M:\work\UniATA\etc\v45g\driver\id_ata.cpp M:\work\UniATA\BusMaster\driver\id_ata.cpp
--- M:\work\UniATA\etc\v45g\driver\id_ata.cpp	Thu Feb 19 11:28:54 2015
+++ M:\work\UniATA\BusMaster\driver\id_ata.cpp	Tue Feb 24 03:00:23 2015
@@ -498,6 +498,7 @@
         if (statusByte & IDE_STATUS_DRQ) {
             // Suck out any remaining bytes and throw away.
             AtapiReadPort2(chan, IDX_IO1_i_Data);
+            UniataNanoSleep(PIO0_TIMING);
         } else {
             break;
         }
@@ -512,13 +513,14 @@
 DDKFASTAPI
 AtapiSuckPortBuffer2(
     IN PHW_CHANNEL chan,
-    IN PVOID Buffer,
+    IN PUSHORT Buffer,
     IN ULONG Count
     )
 {
     UCHAR statusByte;
     ULONG i;
     USHORT data;
+    BOOLEAN retry = FALSE;
 
     // Assume, proper drive is already seleted
     WaitOnBusyLong(chan);
@@ -528,15 +530,25 @@
         if (statusByte & IDE_STATUS_DRQ) {
             // Suck out any remaining bytes and throw away.
             data = AtapiReadPort2(chan, IDX_IO1_i_Data);
-            (*((USHORT*)Buffer)) = data;
-            Count--; \
-            Buffer = ((USHORT*)Buffer)+1; \
-        } else {
+            (*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()
@@ -1644,7 +1656,7 @@
             // 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.
+            // specifying 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
@@ -2219,6 +2231,19 @@
                 PATA_REQ AtaReq = (PATA_REQ)(CurSrb->SrbExtension);
 
                 KdPrint2((PRINT_PREFIX "AtapiResetController: pending SRB %#x, chan %#x\n", CurSrb, chan));
+                if(CurSrb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
+                    PHW_LU_EXTENSION     LunExt;
+                    KdPrint2((PRINT_PREFIX "  was MechStatus\n"));
+
+                    i = GET_CDEV(CurSrb);
+                    KdPrint2((PRINT_PREFIX "  Lun %x\n", i));
+                    LunExt = chan->lun[i];
+
+                    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));
@@ -5485,7 +5510,7 @@
                         interruptReason,
                         srb));
 
-            if(!wordCount && atapiDev && !g_opt_AtapiSendDisableIntr &&
+            if(!wordCount && atapiDev && 
                 !(statusByte & (IDE_STATUS_ERROR | IDE_STATUS_BUSY)) &&
                  (statusByte & IDE_STATUS_DRQ)) {
                 // this can be late Packet interrupt after packet sending
diff -uN M:\work\UniATA\etc\v45g\driver\id_dma.cpp M:\work\UniATA\BusMaster\driver\id_dma.cpp
--- M:\work\UniATA\etc\v45g\driver\id_dma.cpp	Thu Feb 19 09:34:12 2015
+++ M:\work\UniATA\BusMaster\driver\id_dma.cpp	Tue Feb 24 02:24:19 2015
@@ -1236,29 +1236,85 @@
         /*********/
         /* Cyrix */
         /*********/
-        ULONG cyr_piotiming[] =
-            { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 };
-        ULONG cyr_wdmatiming[] = { 0x00077771, 0x00012121, 0x00002020 };
-        ULONG cyr_udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 };
-        ULONG mode_reg = 0x24+(dev << 3);
-
+dma_cs55xx:
         if(apiomode >= 4)
             apiomode = 4;
-        for(i=udmamode; i>=0; i--) {
-            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
-                AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[udmamode]);
+
+        if(ChipType == CYRIX_3x) {
+            ULONG cyr_piotiming[] =
+                { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 };
+            ULONG cyr_wdmatiming[] = { 0x00077771, 0x00012121, 0x00002020 };
+            ULONG cyr_udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 };
+            ULONG mode_reg = 0x24+(dev << 3);
+
+            for(i=udmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
+                    AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_udmatiming[udmamode]);
+                    return;
+                }
+            }
+            for(i=wdmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
+                    AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[wdmamode]);
+                    return;
+                }
+            }
+            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
+                AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[apiomode]);
                 return;
             }
-        }
-        for(i=wdmamode; i>=0; i--) {
-            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
-                AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_wdmatiming[wdmamode]);
+        } else
+        if(ChipType == CYRIX_OLD) {
+            UCHAR cyr_piotiming_old[] =
+                { 11, 6, 3, 2, 1 };
+            UCHAR timing;
+
+            for(i=wdmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
+                    return;
+                }
+            }
+            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
+                timing = (6-apiomode) | (cyr_piotiming_old[i]);
+                /* Channel command timing */
+                SetPciConfig1(0x62+Channel, timing);
+                /* Read command timing */
+                SetPciConfig1(0x64+Channel*4+dev, timing);
+                /* Write command timing */
+                SetPciConfig1(0x66+Channel*4+dev, timing);
+                return;
+            }
+        } else
+        if(ChipType == CYRIX_35) {
+/*
+            USHORT c35_pio_timings[5] = {
+                0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131
+            };
+            USHORT c35_pio_cmd_timings[5] = {
+                0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131
+            };
+            ULONG c35_udma_timings[5] = {
+            	0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061
+            };
+            ULONG c35_mwdma_timings[3] = {
+            	0x7F0FFFF3, 0x7F035352, 0x7F024241
+            };
+            ULONG mode_reg = 0x24+(dev << 3);
+*/
+            /* No MSR support yet, do not touch any regs */
+            for(i=udmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
+                    return;
+                }
+            }
+            for(i=wdmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
+                    return;
+                }
+            }
+            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
                 return;
             }
-        }
-        if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
-            AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0), mode_reg, cyr_piotiming[apiomode]);
-            return;
         }
         return;
 
@@ -1267,33 +1323,37 @@
         /************/
         /* National */
         /************/
-        ULONG nat_piotiming[] =
-           { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010,
-              0x00803020, 0x20102010, 0x00100010,
-              0x00100010, 0x00100010, 0x00100010 };
-        ULONG nat_dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 };
-        ULONG nat_udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 };
+        if(!ChipType) {
+            ULONG nat_piotiming[] =
+               { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010,
+                  0x00803020, 0x20102010, 0x00100010,
+                  0x00100010, 0x00100010, 0x00100010 };
+            ULONG nat_dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 };
+            ULONG nat_udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 };
 
-        if(apiomode >= 4)
-            apiomode = 4;
-        for(i=udmamode; i>=0; i--) {
-            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
-                SetPciConfig4(0x44 + (dev * 8), nat_udmatiming[i]);
-                SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+8]);
-                return;
+            if(apiomode >= 4)
+                apiomode = 4;
+            for(i=udmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
+                    SetPciConfig4(0x44 + (dev * 8), nat_udmatiming[i]);
+                    SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+8]);
+                    return;
+                }
             }
-        }
-        for(i=wdmamode; i>=0; i--) {
-            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
-                SetPciConfig4(0x44 + (dev * 8), nat_dmatiming[i]);
-                SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+5]);
+            for(i=wdmamode; i>=0; i--) {
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
+                    SetPciConfig4(0x44 + (dev * 8), nat_dmatiming[i]);
+                    SetPciConfig4(0x40 + (dev * 8), nat_piotiming[i+5]);
+                    return;
+                }
+            }
+            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
+                ChangePciConfig4(0x44 + (dev * 8), a | 0x80000000);
+                SetPciConfig4(0x40 + (dev * 8), nat_piotiming[apiomode]);
                 return;
             }
-        }
-        if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode)) {
-            ChangePciConfig4(0x44 + (dev * 8), a | 0x80000000);
-            SetPciConfig4(0x40 + (dev * 8), nat_piotiming[apiomode]);
-            return;
+        } else {
+            goto dma_cs55xx;
         }
         /* Use GENERIC PIO */
         break; }
diff -uN M:\work\UniATA\etc\v45g\driver\id_init.cpp M:\work\UniATA\BusMaster\driver\id_init.cpp
--- M:\work\UniATA\etc\v45g\driver\id_init.cpp	Thu Oct 30 09:28:52 2014
+++ M:\work\UniATA\BusMaster\driver\id_init.cpp	Tue Feb 24 01:49:37 2015
@@ -288,6 +288,21 @@
             KdPrint2((PRINT_PREFIX "New JMicron PATA 1 chan\n"));
         }
         break;
+    case ATA_CYRIX_ID:
+        if(ChipType == CYRIX_OLD) {
+            UCHAR tmp8;
+            ULONG slotNumber;
+            slotNumber = deviceExtension->slotNumber;
+            KdPrint2((PRINT_PREFIX "Cyrix slot %#x\n", slotNumber));
+            GetPciConfig1(0x60, tmp8);
+            if(tmp8 & (1 << BMList[deviceExtension->DevIndex].channel)) {
+                KdPrint2((PRINT_PREFIX "Old Cyrix chan %d ok\n", BMList[deviceExtension->DevIndex].channel));
+            } else {
+                KdPrint2((PRINT_PREFIX "Old Cyrix no chan %d\n", BMList[deviceExtension->DevIndex].channel));
+                return FALSE;
+            }
+        }
+        break;
     } // end switch(VendorID)
 
     i = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"NumberChannels", n);
@@ -2094,6 +2109,8 @@
             KdPrint2((PRINT_PREFIX "Intel SATA\n"));
             if(ChipFlags & UNIATA_AHCI) {
                 KdPrint2((PRINT_PREFIX "Do nothing for AHCI\n"));
+                /* enable PCI interrupt */
+                ChangePciConfig2(offsetof(PCI_COMMON_CONFIG, Command), (a & ~0x0400));
                 break;
             }
             if(c == CHAN_NOT_SPECIFIED) {
@@ -2641,6 +2658,19 @@
             }
         } else
         if(ChipType == ITE_133_NEW) {
+        }
+        break;
+    case ATA_CYRIX_ID:
+        KdPrint2((PRINT_PREFIX "Cyrix\n"));
+        if(ChipType == CYRIX_OLD) {
+            if(c == CHAN_NOT_SPECIFIED) {
+                GetPciConfig1(0x60, tmp8);
+                if(!(tmp8 & 0x40)) {
+                    KdPrint2((PRINT_PREFIX "Enable DMA\n"));
+                    tmp8 |= 0x40;
+                    SetPciConfig1(0x60, tmp8);
+                }
+            }
         }
         break;
     default:
diff -uN M:\work\UniATA\etc\v45g\driver\id_probe.cpp M:\work\UniATA\BusMaster\driver\id_probe.cpp
--- M:\work\UniATA\etc\v45g\driver\id_probe.cpp	Thu Feb 19 18:09:30 2015
+++ M:\work\UniATA\BusMaster\driver\id_probe.cpp	Sun Feb 22 23:26:34 2015
@@ -1,6 +1,6 @@
 /*++
 
-Copyright (c) 2002-2012 Alexandr A. Telyatnikov (Alter)
+Copyright (c) 2002-2015 Alexandr A. Telyatnikov (Alter)
 
 Module Name:
     id_probe.cpp
@@ -53,6 +53,10 @@
 ULONG         MCACount = 0;
 
 BOOLEAN FirstMasterOk = FALSE;
+// This is our own resource check,
+// ReactOS allows to allocate same I/O range for both PCI and ISA controllers
+BOOLEAN AtdiskPrimaryClaimed = FALSE;
+BOOLEAN AtdiskSecondaryClaimed = FALSE;
 
 #ifndef UNIATA_CORE
 
@@ -1721,6 +1725,7 @@
             KdPrint2((PRINT_PREFIX "claim Compatible controller\n"));
             if (channel == 0) {
                 KdPrint2((PRINT_PREFIX "claim Primary\n"));
+                AtdiskPrimaryClaimed =
                 ConfigInfo->AtdiskPrimaryClaimed = TRUE;
                 chan->PrimaryAddress = TRUE;
 
@@ -1729,10 +1734,24 @@
             } else
             if (channel == 1) {
                 KdPrint2((PRINT_PREFIX "claim Secondary\n"));
+                AtdiskSecondaryClaimed =
                 ConfigInfo->AtdiskSecondaryClaimed = TRUE;
 
                 FirstMasterOk = TRUE;
             }
+        } else {
+            if(chan->RegTranslation[IDX_IO1].Addr == IO_WD1 &&
+               !chan->RegTranslation[IDX_IO1].MemIo) {
+                KdPrint2((PRINT_PREFIX "claim Primary (PCI over ISA range)\n"));
+                AtdiskPrimaryClaimed =
+                ConfigInfo->AtdiskPrimaryClaimed = TRUE;
+            }
+            if(chan->RegTranslation[IDX_IO1].Addr == IO_WD2 &&
+               !chan->RegTranslation[IDX_IO1].MemIo) {
+                KdPrint2((PRINT_PREFIX "claim Secondary (PCI over ISA range)\n"));
+                AtdiskSecondaryClaimed =
+                ConfigInfo->AtdiskSecondaryClaimed = TRUE;
+            }
         }
 
         AtapiDmaAlloc(HwDeviceExtension, ConfigInfo, c);
@@ -2250,12 +2269,12 @@
         }
         // check if Primary/Secondary Master IDE claimed
         if((ioSpace == (PUCHAR)IO_WD1) &&
-           (ConfigInfo->AtdiskPrimaryClaimed)) {
+           (ConfigInfo->AtdiskPrimaryClaimed || AtdiskPrimaryClaimed)) {
             KdPrint2((PRINT_PREFIX "AtapiFindController: AtdiskPrimaryClaimed\n"));
             goto not_found;
         } else
         if((ioSpace == (PUCHAR)IO_WD2) &&
-           (ConfigInfo->AtdiskSecondaryClaimed)) {
+           (ConfigInfo->AtdiskSecondaryClaimed || AtdiskSecondaryClaimed)) {
             KdPrint2((PRINT_PREFIX "AtapiFindController: AtdiskSecondaryClaimed\n"));
             goto not_found;
         }
@@ -2714,6 +2733,20 @@
 
     if(ResetDev) {
         LunExt->PowerState = 0;
+    }
+
+    if((deviceExtension->HwFlags & UNIATA_SATA) &&
+        !UniataIsSATARangeAvailable(deviceExtension, lChannel) &&
+        deviceNumber) {
+        KdPrint2((PRINT_PREFIX "  SATA w/o i/o registers, check slave presence\n"));
+        SelectDrive(chan, deviceNumber & 0x01);
+        statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_DriveSelect);
+        KdPrint2((PRINT_PREFIX "  DriveSelect: %#x\n", statusByte));
+        if((statusByte & IDE_DRIVE_MASK) != IDE_DRIVE_SELECT_2) {
+            KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n"));
+            UniataForgetDevice(LunExt);
+            return 0;
+        }
     }
 
     if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) {
diff -uN M:\work\UniATA\etc\v45g\driver\id_sata.cpp M:\work\UniATA\BusMaster\driver\id_sata.cpp
--- M:\work\UniATA\etc\v45g\driver\id_sata.cpp	Thu Oct 30 09:09:06 2014
+++ M:\work\UniATA\BusMaster\driver\id_sata.cpp	Mon Feb 23 18:45:47 2015
@@ -728,12 +728,20 @@
     }
 
     /* re-enable AHCI mode */
+    /* Linux: Some controllers need AHCI_EN to be written multiple times.
+     * Try a few times before giving up.
+     */
     GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
-    if(!(GHC & AHCI_GHC_AE)) {
-        KdPrint2((PRINT_PREFIX "  re-enable AHCI mode, GHC %#x\n", GHC));
-        UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
-            GHC | AHCI_GHC_AE);
-        GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
+    for(i=0; i<5; i++) {
+        if(!(GHC & AHCI_GHC_AE)) {
+            KdPrint2((PRINT_PREFIX "  re-enable AHCI mode, GHC %#x\n", GHC));
+            UniataAhciWriteHostPort4(deviceExtension, IDX_AHCI_GHC,
+                GHC | AHCI_GHC_AE);
+            AtapiStallExecution(1000);
+            GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
+        } else {
+            break;
+        }
     }
     KdPrint2((PRINT_PREFIX "  AHCI GHC %#x\n", GHC));
     if(!(GHC & AHCI_GHC_AE)) {
@@ -1980,6 +1988,7 @@
     CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
     KdPrint2(("  CMD %#x\n", CMD));
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD | ATA_AHCI_P_CMD_FRE);
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
     return;
 } // end UniataAhciStartFR()
@@ -2039,6 +2048,7 @@
         CMD |
         ATA_AHCI_P_CMD_ST |
         ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0));
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
     return;
 } // end UniataAhciStart()
@@ -2187,15 +2197,24 @@
     if(CMD0 != CMD) {
         KdPrint2(("  send CMD %#x, entries %#x\n", CMD, AHCI_CL->prd_length));
         UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD);
+        UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
     }
 
     /* issue command to controller */
     //UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_ACT, 0x01 << tag);
+    KdPrint2(("  Set CI\n"));
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CI, 0x01 << tag);
     chan->AhciPrevCI |= 0x01 << tag;
 
+    KdPrint2(("  Send CMD START\n"));
+    UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD,
+        CMD |
+        ATA_AHCI_P_CMD_ST |
+        ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0));
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
+
     if(!ATAPI_DEVICE(chan, DeviceNumber)) {
-        // TODO: check if we send ATA_RESET and wait for ready of so.
+        // TODO: check if we send ATAPI_RESET and wait for ready of so.
         if(AtaReq->ahci.ahci_cmd_ptr->cfis[2] == IDE_COMMAND_ATAPI_RESET) {
             ULONG  TFD;
             ULONG  i;
@@ -2365,6 +2384,7 @@
 	     (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM)) ? ATA_AHCI_P_CMD_ALPE : 0) |
 	     (((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM2)) ? ATA_AHCI_P_CMD_ASP : 0 ))
 	     );
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
 #ifdef DBG
     //UniataDumpAhciPortRegs(chan);
@@ -2399,6 +2419,7 @@
     UniataAhciStop(chan);
     UniataAhciStopFR(chan);
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, 0);
+    UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
     /* Allow everything including partial and slumber modes. */
     UniataSataWritePort4(chan, IDX_SATA_SControl, 0, 0);
