diff -ruN v45e\chglog.txt v45h4\chglog.txt
--- v45e\chglog.txt	Thu Oct 30 09:07:56 2014
+++ v45h4\chglog.txt	Mon Apr 06 17:36:50 2015
@@ -736,3 +736,166 @@
 e) Added "PortMask" option for AHCI channels and partially for SATA (like "Exclude").
 This option can reduce available cannels.
 e) Added "NumberChannels" option for SATA, this option can only reduce available cannels.
+
+--
+2015.02.08 - v0.45f, v0.45f1
+
+*) Added logging of IR status for ATAPI
+
+--
+2015.02.08 - v0.45f2
+
+*) Added logging of WordCount status and interrupt processing points for ATAPI
+e) Added AtapiSoftReset() on ATAPI errors if device reports wrong/unexpected 
+state
+
+--
+2015.02.08 - v0.45f3
+
+e) Added UniataSataClearErr() on ATAPI errors and controller reset
+e) Added extra wait for ready delay for SATA ATAPI reporting wrond device 
+state after reset
+!) perform generic device reset for nVidia SATA controllers if device 
+reports valid state. Previously, reset was never performed for SATA nVidia.
+
+--
+2015.02.09 - v0.45f4
+
+e) Added UniataSataPhyEnable() with reset option for NVIDIA SATA controller reset
+!) fixed logical bug in nVidia device reset branch (still was never called)
+
+--
+2015.02.10 - v0.45f5
+
+e) Added experimental Phy interrupt masking code for NVIDIA SATA during controller reset
+
+--
+2015.02.17 - v0.45f6
+
+!) another experimental Phy interrupt masking code for NVIDIA SATA
+e) added experimental workaround for the case when the controller is fast enough to
+assert IRQ between sending PACKET command and GetBaseStatus().
+We catch ATAPI interrupt with specific status (DRQ+IDLE, 0 WordCount, Write 
+interrupt reason when Read is expected) and just continue execution.
+In general, we should mask interrupts around PACKET command and  
+sending the packet itself, but on virtal machines it definitly cause loss of
+Data interrupt. Also, there is no problem on old uni- and dual-core systems.
+I don't know if this problem is related to number of CPU cores or to overal 
+system performance. 
+Interrupt masking behavior is managed by AtapiSendDisableIntr registry 
+option and is defaulted to FALSE
+
+--
+2015.02.18 - v0.45f7
+
+e) removed ATAPI state workaround from v0.45f6 (doesn't help, no interrupt appeared)
+e) try to force read data from ATAPI device on 'strange' condition
+
+--
+2015.02.18 - v0.45f8
+
+e) try to wait for WordCount in DPC
+
+--
+2015.02.18 - v0.45f9
+
+e) force SATA ATAPI to send Packet in ISR
+
+--
+2015.02.18 - v0.45f10
+
+e) roll-back to v0.45f7
+e) do not use AtaSetTransferMode() for SATA ATAPI devices
+according to Linux ata drivers
+e) try blind reading data for ATAPI if no WordCount reported
+
+--
+2015.02.19 - v0.45f11
+
+e) revert usage of AtaSetTransferMode() for SATA ATAPI devices.
+Problem with zero wordCount persists, but we get PIO timing problem.
+!) force read data from ATAPI device on 'strange' (zero wordCount, but raised DRQ)
+condition seems to work properly
+
+--
+2015.02.19 - v0.45g
+
+!) added check for ATAPI if IDE identify fails
+
+--
+2015.02.22 - v0.45g1
+
+!) added check for Legacy ISA I/O ranges on non-MasterDev PCI controllers
+to avoid further conflict with ISA detection code (such condition was detected on QEmu)
+e) added check for valid value of DriveSelect register on SATA controllers 
+w/o SATA regs. QEmu ignores DriveSelect and reports clone of Master on 
+Slave.
+!) added delay between read cycles in AtapiSuckPort2() and 
+AtapiSuckPortBuffer2() to avoid condition when DRQ is not raised again immediately 
+after read.
+
+--
+2015.02.22 - v0.45g2
+
+!) AtapiSuckPort2() is not called automatically if AtapiSuckDataPort2() get 
+less data than expected. Rest of data may come later.
+
+--
+2015.02.22 - v0.45g3
+
+!) added workaround for lost value of ConfigInfo->AtdiskSecondaryClaimed
+under ReactOS and not detected resource conflict in ScsiPortGetDeviceBase()
+QEmu expose disk controller as both PCI SATA and ISA IDE.
+We should not try ISA detect if PCI succeed with same I/O range
+!) fix for AtapiSuckPort2() in AtapiSuckPortBuffer(). Rest of data may come later.
+
+--
+2015.02.23 - v0.45g4
+
+e) added setting of IDX_AHCI_P_CMD in UniataAhciBeginTransaction() along 
+with CI, probably we need this for VBox only
++) added read from AHCI registers after write to initiate flush (from Linux)
+
+--
+2015.02.23 - v0.45g5
+
+*) undone setting of IDX_AHCI_P_CMD in UniataAhciBeginTransaction() along 
+with CI. It doesn't help, interrupt is lost due to some other reason.
+e) used long wait for Drq in AtapiSuckPortBuffer(), short is not enough.
+We can't defer reading because no more interrupts will be generated and 
+because BUSY is not set while some data is still expected.
+
+--
+2015.02.24 - v0.45h
+
++) added Cyrix 5510/5520 support from Linux code
+
+--
+2015.02.24 - v0.45h1
+
++) added Cyrix 5530 and 5535 support from Linux code
++) added handler for BusReset condition after SCSIOP_MECHANISM_STATUS
+Now driver sets DFLAGS_CHANGER_INITED in this case to prevent automatic use
+of unsupported command.
+
+--
+2015.04.06 - v0.45h2
+
+!) setting of IDX_AHCI_P_CMD in UniataAhciBeginTransaction() along 
+with CI is removed again. According to specs both these actions will
+start command. According to VBox logs command is executed twice.
+Interrupt loss is really caused by some other reason, but this but should be 
+fixed anyway.
+
+--
+2015.04.06 - v0.45h3
+
+!) added AtapiWaitForDrq() in ATAPI interrupt handler.
+Looks like it may be raised with delay (e.g. in QEmu)
+
+--
+2015.04.06 - v0.45h4
+
+!) fixed bug with missing REQ_FLAG_DMA_OPERATION on succefull 
+reinit in AtapiDmaSetup(). This prevented fallback to UDMA2 when higher 
+modes doesn't work fine.
diff -ruN v45e\driver\atapi.h v45h4\driver\atapi.h
--- v45e\driver\atapi.h	Tue Aug 12 01:13:18 2014
+++ v45h4\driver\atapi.h	Sun Feb 22 09:48:12 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 -ruN v45e\driver\bm_devs.h v45h4\driver\bm_devs.h
--- v45e\driver\bm_devs.h	Tue Aug 12 00:59:48 2014
+++ v45h4\driver\bm_devs.h	Tue Feb 24 02:09:50 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 -ruN v45e\driver\Dist\2K\uata_2k.inf v45h4\driver\Dist\2K\uata_2k.inf
--- v45e\driver\Dist\2K\uata_2k.inf	Thu Oct 30 09:37:26 2014
+++ v45h4\driver\Dist\2K\uata_2k.inf	Mon Apr 06 17:37:18 2015
@@ -6,7 +6,7 @@
 ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
 Class=SCSIAdapter
 CatalogFile=uniata.cat
-DriverVer=10/30/2014,0.45.5.0
+DriverVer=04/06/2015,0.45.8.4
 
 ;
 ; Source file information
@@ -66,6 +66,7 @@
 %PCI\VEN_1022&DEV_7411.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7411
 %PCI\VEN_1022&DEV_7441.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7441
 %PCI\VEN_1022&DEV_7469.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7469
+%PCI\VEN_1022&DEV_208f.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_208f
 %PCI\VEN_1022&DEV_209a.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_209a
 %PCI\VEN_1002&DEV_4349.DeviceDesc%=uniata_Inst, PCI\VEN_1002&DEV_4349
 %PCI\VEN_1002&DEV_4369.DeviceDesc%=uniata_Inst, PCI\VEN_1002&DEV_4369
@@ -327,6 +328,7 @@
 %PCI\VEN_10de&DEV_0d8e.DeviceDesc%=uniata_Inst, PCI\VEN_10de&DEV_0d8e
 %PCI\VEN_10de&DEV_0d8f.DeviceDesc%=uniata_Inst, PCI\VEN_10de&DEV_0d8f
 %PCI\VEN_100b&DEV_0502.DeviceDesc%=uniata_Inst, PCI\VEN_100b&DEV_0502
+%PCI\VEN_100b&DEV_002d.DeviceDesc%=uniata_Inst, PCI\VEN_100b&DEV_002d
 %PCI\VEN_105a&DEV_4d33.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_4d33
 %PCI\VEN_105a&DEV_4d38.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_4d38
 ;%PCI\VEN_105a&DEV_0d38.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_0d38
@@ -408,6 +410,8 @@
 %PCI\VEN_1106&DEV_3349.DeviceDesc%=uniata_Inst, PCI\VEN_1106&DEV_3349
 %PCI\VEN_1080&DEV_c693.DeviceDesc%=uniata_Inst, PCI\VEN_1080&DEV_c693
 %PCI\VEN_16ca&DEV_0001.DeviceDesc%=uniata_Inst, PCI\VEN_16ca&DEV_0001
+%PCI\VEN_1078&DEV_0000.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0000
+%PCI\VEN_1078&DEV_0002.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0002
 %PCI\VEN_1078&DEV_0102.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0102
 %PCI\VEN_1042&DEV_1000.DeviceDesc%=uniata_Inst, PCI\VEN_1042&DEV_1000
 %PCI\VEN_1042&DEV_1001.DeviceDesc%=uniata_Inst, PCI\VEN_1042&DEV_1001
@@ -506,6 +510,7 @@
 PCI\VEN_1022&DEV_7411.DeviceDesc="AMD 766 ATA-100 controller (SCSI)"
 PCI\VEN_1022&DEV_7441.DeviceDesc="AMD 768 ATA-100 controller (SCSI)"
 PCI\VEN_1022&DEV_7469.DeviceDesc="AMD 8111 ATA-133 controller (SCSI)"
+PCI\VEN_1022&DEV_208f.DeviceDesc="AMD CS5535 ATA-66 controller (SCSI)"
 PCI\VEN_1022&DEV_209a.DeviceDesc="AMD CS5536 ATA-100 controller (SCSI)"
 PCI\VEN_1002&DEV_4349.DeviceDesc="ATI IXP200 ATA-100 controller (SCSI)"
 PCI\VEN_1002&DEV_4369.DeviceDesc="ATI IXP300 ATA-133 controller (SCSI)"
@@ -767,6 +772,7 @@
 PCI\VEN_10de&DEV_0d8e.DeviceDesc="nVidia nForce MCP89 AA SATA2 controller (SCSI)"
 PCI\VEN_10de&DEV_0d8f.DeviceDesc="nVidia nForce MCP89 AB SATA2 controller (SCSI)"
 PCI\VEN_100b&DEV_0502.DeviceDesc="National Geode SC1100 ATA-33 controller (SCSI)"
+PCI\VEN_100b&DEV_002d.DeviceDesc="National Geode CS5535 ATA-66 controller (SCSI)"
 PCI\VEN_105a&DEV_4d33.DeviceDesc="Promise PDC20246 ATA-33 controller (SCSI)"
 PCI\VEN_105a&DEV_4d38.DeviceDesc="Promise PDC20262 ATA-66 controller (SCSI)"
 ;PCI\VEN_105a&DEV_0d38.DeviceDesc="Promise PDC20263 ATA-66 controller (SCSI)"
@@ -848,6 +854,8 @@
 PCI\VEN_1106&DEV_3349.DeviceDesc="VIA 8251  controller (SCSI)"
 PCI\VEN_1080&DEV_c693.DeviceDesc="Cypress 82C693 IDE DMA controller (SCSI)"
 PCI\VEN_16ca&DEV_0001.DeviceDesc="Cenatek Rocket Drive IDE DMA controller (SCSI)"
+PCI\VEN_1078&DEV_0000.DeviceDesc="Cyrix 5510 IDE DMA controller (SCSI)"
+PCI\VEN_1078&DEV_0002.DeviceDesc="Cyrix 5520 IDE DMA controller (SCSI)"
 PCI\VEN_1078&DEV_0102.DeviceDesc="Cyrix 5530 ATA-33 controller (SCSI)"
 PCI\VEN_1042&DEV_1000.DeviceDesc="RZ 100x IDE controller (SCSI)"
 PCI\VEN_1042&DEV_1001.DeviceDesc="RZ 100x IDE controller (SCSI)"
diff -ruN v45e\driver\Dist\2K\uata_2kh.inf v45h4\driver\Dist\2K\uata_2kh.inf
--- v45e\driver\Dist\2K\uata_2kh.inf	Thu Oct 30 09:37:26 2014
+++ v45h4\driver\Dist\2K\uata_2kh.inf	Mon Apr 06 17:37:18 2015
@@ -6,7 +6,7 @@
 ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
 Class=hdc
 CatalogFile=uniata.cat
-DriverVer=10/30/2014,0.45.5.0
+DriverVer=04/06/2015,0.45.8.4
 
 ;
 ; Source file information
@@ -66,6 +66,7 @@
 %PCI\VEN_1022&DEV_7411.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7411
 %PCI\VEN_1022&DEV_7441.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7441
 %PCI\VEN_1022&DEV_7469.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7469
+%PCI\VEN_1022&DEV_208f.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_208f
 %PCI\VEN_1022&DEV_209a.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_209a
 %PCI\VEN_1002&DEV_4349.DeviceDesc%=uniata_Inst, PCI\VEN_1002&DEV_4349
 %PCI\VEN_1002&DEV_4369.DeviceDesc%=uniata_Inst, PCI\VEN_1002&DEV_4369
@@ -327,6 +328,7 @@
 %PCI\VEN_10de&DEV_0d8e.DeviceDesc%=uniata_Inst, PCI\VEN_10de&DEV_0d8e
 %PCI\VEN_10de&DEV_0d8f.DeviceDesc%=uniata_Inst, PCI\VEN_10de&DEV_0d8f
 %PCI\VEN_100b&DEV_0502.DeviceDesc%=uniata_Inst, PCI\VEN_100b&DEV_0502
+%PCI\VEN_100b&DEV_002d.DeviceDesc%=uniata_Inst, PCI\VEN_100b&DEV_002d
 %PCI\VEN_105a&DEV_4d33.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_4d33
 %PCI\VEN_105a&DEV_4d38.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_4d38
 ;%PCI\VEN_105a&DEV_0d38.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_0d38
@@ -408,6 +410,8 @@
 %PCI\VEN_1106&DEV_3349.DeviceDesc%=uniata_Inst, PCI\VEN_1106&DEV_3349
 %PCI\VEN_1080&DEV_c693.DeviceDesc%=uniata_Inst, PCI\VEN_1080&DEV_c693
 %PCI\VEN_16ca&DEV_0001.DeviceDesc%=uniata_Inst, PCI\VEN_16ca&DEV_0001
+%PCI\VEN_1078&DEV_0000.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0000
+%PCI\VEN_1078&DEV_0002.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0002
 %PCI\VEN_1078&DEV_0102.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0102
 %PCI\VEN_1042&DEV_1000.DeviceDesc%=uniata_Inst, PCI\VEN_1042&DEV_1000
 %PCI\VEN_1042&DEV_1001.DeviceDesc%=uniata_Inst, PCI\VEN_1042&DEV_1001
@@ -506,6 +510,7 @@
 PCI\VEN_1022&DEV_7411.DeviceDesc="AMD 766 ATA-100 controller"
 PCI\VEN_1022&DEV_7441.DeviceDesc="AMD 768 ATA-100 controller"
 PCI\VEN_1022&DEV_7469.DeviceDesc="AMD 8111 ATA-133 controller"
+PCI\VEN_1022&DEV_208f.DeviceDesc="AMD CS5535 ATA-66 controller"
 PCI\VEN_1022&DEV_209a.DeviceDesc="AMD CS5536 ATA-100 controller"
 PCI\VEN_1002&DEV_4349.DeviceDesc="ATI IXP200 ATA-100 controller"
 PCI\VEN_1002&DEV_4369.DeviceDesc="ATI IXP300 ATA-133 controller"
@@ -767,6 +772,7 @@
 PCI\VEN_10de&DEV_0d8e.DeviceDesc="nVidia nForce MCP89 AA SATA2 controller"
 PCI\VEN_10de&DEV_0d8f.DeviceDesc="nVidia nForce MCP89 AB SATA2 controller"
 PCI\VEN_100b&DEV_0502.DeviceDesc="National Geode SC1100 ATA-33 controller"
+PCI\VEN_100b&DEV_002d.DeviceDesc="National Geode CS5535 ATA-66 controller"
 PCI\VEN_105a&DEV_4d33.DeviceDesc="Promise PDC20246 ATA-33 controller"
 PCI\VEN_105a&DEV_4d38.DeviceDesc="Promise PDC20262 ATA-66 controller"
 ;PCI\VEN_105a&DEV_0d38.DeviceDesc="Promise PDC20263 ATA-66 controller"
@@ -848,6 +854,8 @@
 PCI\VEN_1106&DEV_3349.DeviceDesc="VIA 8251  controller"
 PCI\VEN_1080&DEV_c693.DeviceDesc="Cypress 82C693 IDE DMA controller"
 PCI\VEN_16ca&DEV_0001.DeviceDesc="Cenatek Rocket Drive IDE DMA controller"
+PCI\VEN_1078&DEV_0000.DeviceDesc="Cyrix 5510 IDE DMA controller"
+PCI\VEN_1078&DEV_0002.DeviceDesc="Cyrix 5520 IDE DMA controller"
 PCI\VEN_1078&DEV_0102.DeviceDesc="Cyrix 5530 ATA-33 controller"
 PCI\VEN_1042&DEV_1000.DeviceDesc="RZ 100x IDE controller"
 PCI\VEN_1042&DEV_1001.DeviceDesc="RZ 100x IDE controller"
diff -ruN v45e\driver\Dist\2K\uniata_w2k.reg v45h4\driver\Dist\2K\uniata_w2k.reg
--- v45e\driver\Dist\2K\uniata_w2k.reg	Thu Oct 30 09:37:26 2014
+++ v45h4\driver\Dist\2K\uniata_w2k.reg	Mon Apr 06 17:37:18 2015
@@ -6,7 +6,7 @@
 "Start"=dword:00000000
 "Tag"=dword:00000019
 "Type"=dword:00000001
-"DisplayName"="Universal BusMaster SATA/ATA/ATAPI Driver v0.45.5.0"
+"DisplayName"="Universal BusMaster SATA/ATA/ATAPI Driver v0.45.8.4"
 "ImagePath"=hex(2):53,79,73,74,65,6d,33,32,5c,44,52,49,56,45,52,53,5c,75,6e,69,\
   61,74,61,2e,73,79,73,00
 
diff -ruN v45e\driver\Dist\NT4\uata_nt4.inf v45h4\driver\Dist\NT4\uata_nt4.inf
--- v45e\driver\Dist\NT4\uata_nt4.inf	Thu Oct 30 09:37:26 2014
+++ v45h4\driver\Dist\NT4\uata_nt4.inf	Mon Apr 06 17:37:16 2015
@@ -6,7 +6,7 @@
 ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
 Class=SCSIAdapter
 CatalogFile=uniata.cat
-DriverVer=10/30/2014,0.45.5.0
+DriverVer=04/06/2015,0.45.8.4
 
 ;
 ; Source file information
Binary files v45e\driver\Dist\tools\build_inf.exe and v45h4\driver\Dist\tools\build_inf.exe differ
diff -ruN v45e\driver\Dist\XP\uata_xp.inf v45h4\driver\Dist\XP\uata_xp.inf
--- v45e\driver\Dist\XP\uata_xp.inf	Thu Oct 30 09:37:26 2014
+++ v45h4\driver\Dist\XP\uata_xp.inf	Mon Apr 06 17:37:18 2015
@@ -6,7 +6,7 @@
 ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
 Class=SCSIAdapter
 CatalogFile=uniata.cat
-DriverVer=10/30/2014,0.45.5.0
+DriverVer=04/06/2015,0.45.8.4
 
 ;
 ; Source file information
@@ -58,6 +58,7 @@
 %PCI\VEN_1022&DEV_7411.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7411
 %PCI\VEN_1022&DEV_7441.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7441
 %PCI\VEN_1022&DEV_7469.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7469
+%PCI\VEN_1022&DEV_208f.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_208f
 %PCI\VEN_1022&DEV_209a.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_209a
 %PCI\VEN_1002&DEV_4349.DeviceDesc%=uniata_Inst, PCI\VEN_1002&DEV_4349
 %PCI\VEN_1002&DEV_4369.DeviceDesc%=uniata_Inst, PCI\VEN_1002&DEV_4369
@@ -319,6 +320,7 @@
 %PCI\VEN_10de&DEV_0d8e.DeviceDesc%=uniata_Inst, PCI\VEN_10de&DEV_0d8e
 %PCI\VEN_10de&DEV_0d8f.DeviceDesc%=uniata_Inst, PCI\VEN_10de&DEV_0d8f
 %PCI\VEN_100b&DEV_0502.DeviceDesc%=uniata_Inst, PCI\VEN_100b&DEV_0502
+%PCI\VEN_100b&DEV_002d.DeviceDesc%=uniata_Inst, PCI\VEN_100b&DEV_002d
 %PCI\VEN_105a&DEV_4d33.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_4d33
 %PCI\VEN_105a&DEV_4d38.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_4d38
 ;%PCI\VEN_105a&DEV_0d38.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_0d38
@@ -400,6 +402,8 @@
 %PCI\VEN_1106&DEV_3349.DeviceDesc%=uniata_Inst, PCI\VEN_1106&DEV_3349
 %PCI\VEN_1080&DEV_c693.DeviceDesc%=uniata_Inst, PCI\VEN_1080&DEV_c693
 %PCI\VEN_16ca&DEV_0001.DeviceDesc%=uniata_Inst, PCI\VEN_16ca&DEV_0001
+%PCI\VEN_1078&DEV_0000.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0000
+%PCI\VEN_1078&DEV_0002.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0002
 %PCI\VEN_1078&DEV_0102.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0102
 %PCI\VEN_1042&DEV_1000.DeviceDesc%=uniata_Inst, PCI\VEN_1042&DEV_1000
 %PCI\VEN_1042&DEV_1001.DeviceDesc%=uniata_Inst, PCI\VEN_1042&DEV_1001
@@ -506,6 +510,7 @@
 PCI\VEN_1022&DEV_7411.DeviceDesc="AMD 766 ATA-100 controller (SCSI)"
 PCI\VEN_1022&DEV_7441.DeviceDesc="AMD 768 ATA-100 controller (SCSI)"
 PCI\VEN_1022&DEV_7469.DeviceDesc="AMD 8111 ATA-133 controller (SCSI)"
+PCI\VEN_1022&DEV_208f.DeviceDesc="AMD CS5535 ATA-66 controller (SCSI)"
 PCI\VEN_1022&DEV_209a.DeviceDesc="AMD CS5536 ATA-100 controller (SCSI)"
 PCI\VEN_1002&DEV_4349.DeviceDesc="ATI IXP200 ATA-100 controller (SCSI)"
 PCI\VEN_1002&DEV_4369.DeviceDesc="ATI IXP300 ATA-133 controller (SCSI)"
@@ -767,6 +772,7 @@
 PCI\VEN_10de&DEV_0d8e.DeviceDesc="nVidia nForce MCP89 AA SATA2 controller (SCSI)"
 PCI\VEN_10de&DEV_0d8f.DeviceDesc="nVidia nForce MCP89 AB SATA2 controller (SCSI)"
 PCI\VEN_100b&DEV_0502.DeviceDesc="National Geode SC1100 ATA-33 controller (SCSI)"
+PCI\VEN_100b&DEV_002d.DeviceDesc="National Geode CS5535 ATA-66 controller (SCSI)"
 PCI\VEN_105a&DEV_4d33.DeviceDesc="Promise PDC20246 ATA-33 controller (SCSI)"
 PCI\VEN_105a&DEV_4d38.DeviceDesc="Promise PDC20262 ATA-66 controller (SCSI)"
 ;PCI\VEN_105a&DEV_0d38.DeviceDesc="Promise PDC20263 ATA-66 controller (SCSI)"
@@ -848,6 +854,8 @@
 PCI\VEN_1106&DEV_3349.DeviceDesc="VIA 8251  controller (SCSI)"
 PCI\VEN_1080&DEV_c693.DeviceDesc="Cypress 82C693 IDE DMA controller (SCSI)"
 PCI\VEN_16ca&DEV_0001.DeviceDesc="Cenatek Rocket Drive IDE DMA controller (SCSI)"
+PCI\VEN_1078&DEV_0000.DeviceDesc="Cyrix 5510 IDE DMA controller (SCSI)"
+PCI\VEN_1078&DEV_0002.DeviceDesc="Cyrix 5520 IDE DMA controller (SCSI)"
 PCI\VEN_1078&DEV_0102.DeviceDesc="Cyrix 5530 ATA-33 controller (SCSI)"
 PCI\VEN_1042&DEV_1000.DeviceDesc="RZ 100x IDE controller (SCSI)"
 PCI\VEN_1042&DEV_1001.DeviceDesc="RZ 100x IDE controller (SCSI)"
diff -ruN v45e\driver\Dist\XP\uata_xph.inf v45h4\driver\Dist\XP\uata_xph.inf
--- v45e\driver\Dist\XP\uata_xph.inf	Thu Oct 30 09:37:26 2014
+++ v45h4\driver\Dist\XP\uata_xph.inf	Mon Apr 06 17:37:18 2015
@@ -6,7 +6,7 @@
 ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
 Class=hdc
 CatalogFile=uniata.cat
-DriverVer=10/30/2014,0.45.5.0
+DriverVer=04/06/2015,0.45.8.4
 
 ;
 ; Source file information
@@ -58,6 +58,7 @@
 %PCI\VEN_1022&DEV_7411.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7411
 %PCI\VEN_1022&DEV_7441.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7441
 %PCI\VEN_1022&DEV_7469.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_7469
+%PCI\VEN_1022&DEV_208f.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_208f
 %PCI\VEN_1022&DEV_209a.DeviceDesc%=uniata_Inst, PCI\VEN_1022&DEV_209a
 %PCI\VEN_1002&DEV_4349.DeviceDesc%=uniata_Inst, PCI\VEN_1002&DEV_4349
 %PCI\VEN_1002&DEV_4369.DeviceDesc%=uniata_Inst, PCI\VEN_1002&DEV_4369
@@ -319,6 +320,7 @@
 %PCI\VEN_10de&DEV_0d8e.DeviceDesc%=uniata_Inst, PCI\VEN_10de&DEV_0d8e
 %PCI\VEN_10de&DEV_0d8f.DeviceDesc%=uniata_Inst, PCI\VEN_10de&DEV_0d8f
 %PCI\VEN_100b&DEV_0502.DeviceDesc%=uniata_Inst, PCI\VEN_100b&DEV_0502
+%PCI\VEN_100b&DEV_002d.DeviceDesc%=uniata_Inst, PCI\VEN_100b&DEV_002d
 %PCI\VEN_105a&DEV_4d33.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_4d33
 %PCI\VEN_105a&DEV_4d38.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_4d38
 ;%PCI\VEN_105a&DEV_0d38.DeviceDesc%=uniata_Inst, PCI\VEN_105a&DEV_0d38
@@ -400,6 +402,8 @@
 %PCI\VEN_1106&DEV_3349.DeviceDesc%=uniata_Inst, PCI\VEN_1106&DEV_3349
 %PCI\VEN_1080&DEV_c693.DeviceDesc%=uniata_Inst, PCI\VEN_1080&DEV_c693
 %PCI\VEN_16ca&DEV_0001.DeviceDesc%=uniata_Inst, PCI\VEN_16ca&DEV_0001
+%PCI\VEN_1078&DEV_0000.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0000
+%PCI\VEN_1078&DEV_0002.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0002
 %PCI\VEN_1078&DEV_0102.DeviceDesc%=uniata_Inst, PCI\VEN_1078&DEV_0102
 %PCI\VEN_1042&DEV_1000.DeviceDesc%=uniata_Inst, PCI\VEN_1042&DEV_1000
 %PCI\VEN_1042&DEV_1001.DeviceDesc%=uniata_Inst, PCI\VEN_1042&DEV_1001
@@ -506,6 +510,7 @@
 PCI\VEN_1022&DEV_7411.DeviceDesc="AMD 766 ATA-100 controller"
 PCI\VEN_1022&DEV_7441.DeviceDesc="AMD 768 ATA-100 controller"
 PCI\VEN_1022&DEV_7469.DeviceDesc="AMD 8111 ATA-133 controller"
+PCI\VEN_1022&DEV_208f.DeviceDesc="AMD CS5535 ATA-66 controller"
 PCI\VEN_1022&DEV_209a.DeviceDesc="AMD CS5536 ATA-100 controller"
 PCI\VEN_1002&DEV_4349.DeviceDesc="ATI IXP200 ATA-100 controller"
 PCI\VEN_1002&DEV_4369.DeviceDesc="ATI IXP300 ATA-133 controller"
@@ -767,6 +772,7 @@
 PCI\VEN_10de&DEV_0d8e.DeviceDesc="nVidia nForce MCP89 AA SATA2 controller"
 PCI\VEN_10de&DEV_0d8f.DeviceDesc="nVidia nForce MCP89 AB SATA2 controller"
 PCI\VEN_100b&DEV_0502.DeviceDesc="National Geode SC1100 ATA-33 controller"
+PCI\VEN_100b&DEV_002d.DeviceDesc="National Geode CS5535 ATA-66 controller"
 PCI\VEN_105a&DEV_4d33.DeviceDesc="Promise PDC20246 ATA-33 controller"
 PCI\VEN_105a&DEV_4d38.DeviceDesc="Promise PDC20262 ATA-66 controller"
 ;PCI\VEN_105a&DEV_0d38.DeviceDesc="Promise PDC20263 ATA-66 controller"
@@ -848,6 +854,8 @@
 PCI\VEN_1106&DEV_3349.DeviceDesc="VIA 8251  controller"
 PCI\VEN_1080&DEV_c693.DeviceDesc="Cypress 82C693 IDE DMA controller"
 PCI\VEN_16ca&DEV_0001.DeviceDesc="Cenatek Rocket Drive IDE DMA controller"
+PCI\VEN_1078&DEV_0000.DeviceDesc="Cyrix 5510 IDE DMA controller"
+PCI\VEN_1078&DEV_0002.DeviceDesc="Cyrix 5520 IDE DMA controller"
 PCI\VEN_1078&DEV_0102.DeviceDesc="Cyrix 5530 ATA-33 controller"
 PCI\VEN_1042&DEV_1000.DeviceDesc="RZ 100x IDE controller"
 PCI\VEN_1042&DEV_1001.DeviceDesc="RZ 100x IDE controller"
diff -ruN v45e\driver\id_ata.cpp v45h4\driver\id_ata.cpp
--- v45e\driver\id_ata.cpp	Mon Oct 20 18:19:54 2014
+++ v45h4\driver\id_ata.cpp	Mon Apr 06 17:02:34 2015
@@ -1,6 +1,6 @@
 /*++
 
-Copyright (c) 2002-2014 Alexandr A. Telyatnikov (Alter)
+Copyright (c) 2002-2015 Alexandr A. Telyatnikov (Alter)
 
 Module Name:
     id_ata.cpp
@@ -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;
         }
@@ -508,6 +509,50 @@
     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
 WaitOnBusy(
@@ -1594,11 +1639,24 @@
         if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) {
 
             KdPrint2((PRINT_PREFIX "  use 16bit IO\n"));
+#if DBG
+            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 //DBG
             // 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
@@ -2003,10 +2061,12 @@
             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"));
     }
@@ -2142,7 +2202,7 @@
     //ULONG RevID    =  deviceExtension->RevID;
     ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
     //UCHAR tmp8;
-    UCHAR tmp16;
+    USHORT tmp16;
 
     KdPrint2((PRINT_PREFIX "AtapiResetController: Reset IDE %#x/%#x @ %#x\n", VendorID, DeviceID, slotNumber));
     KdPrint2((PRINT_PREFIX "simplexOnly %d\n", deviceExtension->simplexOnly));
@@ -2171,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));
@@ -2324,9 +2397,40 @@
                 break; }
             case ATA_SIS_ID:
             case ATA_NVIDIA_ID: {
+                ULONG offs;
+                ULONG Channel = deviceExtension->Channel + j;
                 KdPrint2((PRINT_PREFIX "  SIS/nVidia\n"));
-                if(!(ChipFlags & UNIATA_SATA))
+                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; }
             case ATA_SILICON_IMAGE_ID: {
                 ULONG offset;
@@ -2458,6 +2562,22 @@
 
                 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,
@@ -4261,7 +4381,7 @@
             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\n", pr_status));
+        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)) ) {
@@ -5094,6 +5214,15 @@
             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) {
@@ -5356,24 +5485,24 @@
         // Ensure that this is a write command.
         if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
 
-           KdPrint2((PRINT_PREFIX 
-                      "AtapiInterrupt: Write interrupt\n"));
+            KdPrint2((PRINT_PREFIX 
+                       "AtapiInterrupt: Write interrupt\n"));
 
-           statusByte = WaitOnBusy(chan);
+            statusByte = WaitOnBusy(chan);
 
-           if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) {
+            if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/) {
 
-               WriteBuffer(chan,
-                           AtaReq->DataBuffer,
-                           wordCount,
-                           UniataGetPioTiming(LunExt));
-           } else {
+                WriteBuffer(chan,
+                            AtaReq->DataBuffer,
+                            wordCount,
+                            UniataGetPioTiming(LunExt));
+            } else {
 
-               WriteBuffer2(chan,
-                           (PULONG)(AtaReq->DataBuffer),
-                           wordCount / 2,
-                           UniataGetPioTiming(LunExt));
-           }
+                WriteBuffer2(chan,
+                            (PULONG)(AtaReq->DataBuffer),
+                            wordCount / 2,
+                            UniataGetPioTiming(LunExt));
+            }
         } else {
 
             KdPrint3((PRINT_PREFIX 
@@ -5381,8 +5510,43 @@
                         interruptReason,
                         srb));
 
+            if(!wordCount && atapiDev && 
+                !(statusByte & (IDE_STATUS_ERROR | IDE_STATUS_BUSY)) &&
+                 (statusByte & IDE_STATUS_DRQ)) {
+                // this can be late Packet interrupt after packet sending
+                KdPrint2((PRINT_PREFIX "  unreliable wordCount ?\n"));
+
+                wordCount = AtapiSuckPortBuffer2(chan,
+                                                 AtaReq->DataBuffer,
+                                                 AtaReq->WordsLeft);
+                KdPrint2((PRINT_PREFIX "  transferred %#x\n", wordCount));
+                GetBaseStatus(chan, statusByte);
+                KdPrint2((PRINT_PREFIX "  status %#x, statusByte\n"));
+                if(wordCount) {
+                    interruptReason = ATAPI_IR_IO_toHost;
+#if DBG
+                    UniataDumpATARegs(chan);
+#endif
+                }
+                if(wordCount && AtaReq->WordsLeft) {
+                    goto continue_atapi_pio_read;
+                }
+            }
             // 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.
@@ -5516,7 +5680,7 @@
             status = SRB_STATUS_ERROR;
             goto CompleteRequest;
         }
-
+continue_atapi_pio_read:
         // Advance data buffer pointer and bytes left.
         AtaReq->DataBuffer += wordCount;
         AtaReq->WordsLeft -= wordCount;
@@ -6117,6 +6281,15 @@
                     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"));
@@ -7554,8 +7727,14 @@
                                   CHECK_INTR_IDLE);
     AtaReq->ReqState = REQ_STATE_ATAPI_EXPECTING_DATA_INTR;
 
+    // clear interrupt
     GetBaseStatus(chan, statusByte);
 
+#if DBG
+    statusByte = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
+    KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x\n", statusByte));
+#endif //DBG
+
     if(g_opt_AtapiSendDisableIntr) {
         AtapiEnableInterrupts(deviceExtension, lChannel);
     }
@@ -10038,7 +10217,7 @@
             return status;
         }
 #endif // USE_REACTOS_DDK
-        KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, *KeNumberProcessors));
+        KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, KeNumberProcessors));
 
         KeQuerySystemTime(&t0);
         do {
@@ -10145,7 +10324,7 @@
             g_opt_WaitDrqDelay  = 100;
             g_opt_WaitBusyLongCount = 20000;
             g_opt_MaxIsrWait = 200;
-            g_opt_AtapiSendDisableIntr = 0;
+            g_opt_AtapiSendDisableIntr = FALSE;
             g_opt_AtapiDmaRawRead = FALSE;
             break;
         }
@@ -10165,8 +10344,8 @@
         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);  // 1 vs 0
-        g_opt_AtapiDmaRawRead      = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"AtapiDmaRawRead",       g_opt_AtapiDmaRawRead);       // 1 vs 0
+        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_MaxIsrWait    = AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"MaxIsrWait",       g_opt_MaxIsrWait);       // 40 vs xxx
     }
 
diff -ruN v45e\driver\id_dma.cpp v45h4\driver\id_dma.cpp
--- v45e\driver\id_dma.cpp	Wed Oct 29 22:58:56 2014
+++ v45h4\driver\id_dma.cpp	Mon Apr 06 17:33:04 2015
@@ -254,11 +254,12 @@
     BOOLEAN use_AHCI = (deviceExtension->HwFlags & UNIATA_AHCI) ? TRUE : FALSE;
     ULONG orig_count = count;
     ULONG max_entries = use_AHCI ? ATA_AHCI_DMA_ENTRIES : ATA_DMA_ENTRIES;
-    //ULONG max_frag = use_AHCI ? (0x3fffff+1) : (4096); // DEBUG, replace 4096 for procer chipset-specific value
+    //ULONG max_frag = use_AHCI ? (0x3fffff+1) : (4096); // DEBUG, replace 4096 for proper chipset-specific value
     ULONG max_frag = deviceExtension->DmaSegmentLength;
     ULONG seg_align = deviceExtension->DmaSegmentAlignmentMask;
 
     if(AtaReq->dma_entries) {
+        AtaReq->Flags |= REQ_FLAG_DMA_OPERATION;
         KdPrint2((PRINT_PREFIX "AtapiDmaSetup: already setup, %d entries\n", AtaReq->dma_entries));
         return TRUE;
     }
@@ -1013,6 +1014,7 @@
         /****************/
 
         KdPrint2((PRINT_PREFIX "SATA Generic\n"));
+
         if((udmamode >= 5) || (ChipFlags & UNIATA_AHCI) || ((udmamode >= 0) && (chan->MaxTransferMode >= ATA_SA150))) {
             /* some drives report UDMA6, some UDMA5 */
             /* ATAPI may not have SataCapabilities set in IDENTIFY DATA */
@@ -1235,29 +1237,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;
 
@@ -1266,33 +1324,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 -ruN v45e\driver\id_init.cpp v45h4\driver\id_init.cpp
--- v45e\driver\id_init.cpp	Thu Oct 30 09:28:52 2014
+++ v45h4\driver\id_init.cpp	Tue Feb 24 01:49:38 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 -ruN v45e\driver\id_probe.cpp v45h4\driver\id_probe.cpp
--- v45e\driver\id_probe.cpp	Thu Oct 30 08:14:18 2014
+++ v45h4\driver\id_probe.cpp	Sun Feb 22 23:26:36 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;
         }
@@ -2697,6 +2716,7 @@
     UCHAR                statusByte;
     ULONG                RetVal=0;
     ULONG                waitCount = 10000;
+    ULONG                at_home = 0;
 
     KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x\n",
                deviceNumber));
@@ -2705,7 +2725,7 @@
         return 0;
     }
     if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
+        if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
             return 0;
         }
     }
@@ -2715,6 +2735,20 @@
         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)) {
         KdPrint2((PRINT_PREFIX "CheckDevice: reset AHCI dev\n"));
         if(UniataAhciSoftReset(HwDeviceExtension, chan->lChannel, deviceNumber) == (ULONG)(-1)) {
@@ -2729,7 +2763,7 @@
         // Reset device
         AtapiSoftReset(chan, deviceNumber);
 
-        if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
+        if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
             //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 1\n"));
             return 0;
         }
@@ -2787,7 +2821,7 @@
         // Select the device.
         SelectDrive(chan, deviceNumber);
 
-        if(!UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
+        if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
             //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 2\n"));
             return 0;
         }
@@ -2842,7 +2876,7 @@
         // ATAPI signature found.
         // Issue the ATAPI identify command if this
         // is not for the crash dump utility.
-
+try_atapi:
         if (!deviceExtension->DriverMustPoll) {
 
             // Issue ATAPI packet identify command.
@@ -2872,7 +2906,7 @@
                 }
 
             } else {
-
+forget_device:
                 // Indicate no working device.
                 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x not responding\n",
                            deviceNumber));
@@ -2906,6 +2940,16 @@
             RetVal = DFLAGS_DEVICE_PRESENT;
             LunExt->DeviceFlags |= DFLAGS_DEVICE_PRESENT;
             LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
+        } else {
+            // This can be ATAPI on broken hardware
+            GetBaseStatus(chan, statusByte);
+            if(!at_home && UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
+                KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home post IDE\n"));
+                goto forget_device;
+            }
+            KdPrint2((PRINT_PREFIX "CheckDevice: try ATAPI %#x, status %#x\n",
+                       deviceNumber, statusByte));
+            goto try_atapi;
         }
         GetBaseStatus(chan, statusByte);
     }
diff -ruN v45e\driver\id_sata.cpp v45h4\driver\id_sata.cpp
--- v45e\driver\id_sata.cpp	Thu Oct 30 09:09:06 2014
+++ v45h4\driver\id_sata.cpp	Mon Apr 06 16:26:54 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,28 @@
     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;
 
+    CMD0 = CMD;
+    CMD |= ATA_AHCI_P_CMD_ST |
+          ((chan->ChannelCtrlFlags & CTRFLAGS_AHCI_PM) ? ATA_AHCI_P_CMD_PMA : 0);
+    if(CMD != CMD0) {
+      KdPrint2(("  Send CMD START\n"));
+      UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_CMD, CMD);
+      UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
+    } else {
+      KdPrint2(("  No CMD START, already active\n"));
+    }
+
     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 +2388,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 +2423,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);
diff -ruN v45e\driver\uniata_ver.h v45h4\driver\uniata_ver.h
--- v45e\driver\uniata_ver.h	Thu Oct 30 09:37:14 2014
+++ v45h4\driver\uniata_ver.h	Mon Apr 06 17:37:10 2015
@@ -1,10 +1,10 @@
-#define UNIATA_VER_STR         "45e"
-#define UNIATA_VER_DOT         0.45.5.0
+#define UNIATA_VER_STR         "45h4"
+#define UNIATA_VER_DOT         0.45.8.4
 #define UNIATA_VER_MJ          0
 #define UNIATA_VER_MN          45
-#define UNIATA_VER_SUB_MJ      5
-#define UNIATA_VER_SUB_MN      0
-#define UNIATA_VER_DOT_COMMA   0,45,5,0
-#define UNIATA_VER_DOT_STR     "0.45.5.0"
-#define UNIATA_VER_YEAR        2014
-#define UNIATA_VER_YEAR_STR    "2014"
+#define UNIATA_VER_SUB_MJ      8
+#define UNIATA_VER_SUB_MN      4
+#define UNIATA_VER_DOT_COMMA   0,45,8,4
+#define UNIATA_VER_DOT_STR     "0.45.8.4"
+#define UNIATA_VER_YEAR        2015
+#define UNIATA_VER_YEAR_STR    "2015"
