diff -ruN v45j5\chglog.txt v46a1\chglog.txt
--- v45j5\chglog.txt	Sun Jan 24 14:59:18 2016
+++ v46a1\chglog.txt	Wed Mar 09 19:07:38 2016
@@ -549,7 +549,7 @@
 --
 2012.09.24 - v0.44b2
 
-*) experimental fix for SATA ATAPI, check for DRQ (appeared, it is not not asserted on error)
+*) experimental fix for SATA ATAPI, check for DRQ (appeared, it is not asserted on error)
 
 --
 2012.09.25 - v0.44b3
@@ -704,7 +704,7 @@
 see ReactOS BUG-7020
 
 !) Added LUN 1->2 reallocation in case of fall-back to 'compatible' mode on Intel chips
-acording to 0x90 PCI reg.
+according to 0x90 PCI reg.
 see ReactOS BUG-7020
 
 --
@@ -753,7 +753,7 @@
 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 
+e) Added extra wait for ready delay for SATA ATAPI reporting wrong 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.
@@ -992,7 +992,7 @@
 --
 2016.01.18 - v0.45j2
 
-e) detect wrong Boch ATA DMA behavior. Versions prior to 2.6.8 expect 
+e) detect wrong Bochs ATA DMA behavior. Versions prior to 2.6.8 expect 
 ATA_DMA_READ *after* DMA start, however BM DMA specs declare opposite order.
 CTRFLAGS_DMA_BEFORE_R flag is introduced in order to manage this.
 (ROS BUG-6774)
@@ -1000,7 +1000,7 @@
 --
 2016.01.24 - v0.45j3
 
-e) more logs for detect wrong Boch ATA DMA behavior. (ROS BUG-6774)
+e) more logs for detect wrong Bochs ATA DMA behavior. (ROS BUG-6774)
 
 --
 2016.01.24 - v0.45j4
@@ -1013,3 +1013,72 @@
 
 !) fixed bug with missing AtapiDmaStart() on HDD Read in IdeReadWrite()
 
+--
+2016.03.05 - v0.45j6
+
+e) try use CTRFLAGS_DMA_BEFORE_R for ATAPI too
+!) move CTRFLAGS_DMA_BEFORE_R to global g_opt_BochDmaReadWorkaround
+e) do not use DMA on ATAPI under Bochs
+(ROS BUG-6774)
+!) fixed bug with completly cleared ChannelCtrlFlags on bus reset. Permanent 
+bits are masked with CTRFLAGS_PERMANENT
+
+--
+2016.03.06 - v0.45j7
+
+!) use g_opt_AtapiNoDma = TRUE for Bochs by default (ROS BUG-6774)
+e) try use g_opt_BochDmaReadWorkaround for both Read and Write operations
+(ROS BUG-6774)
+
+--
+2016.03.07 - v0.45j8
+
+e) do not use g_opt_BochDmaReadWorkaround for Write operations
+since DMA Start before ATA WRITE cause Boch DMA command abort immediately 
+after DMA Start w/o any error reports after ATA WRITE.
+!) Fixed bug in DMA Start / ATA WRITE sequence (missing DMA Start) for Bochs 
+in workaround mode
+
+See ROS BUG-6774
+
+--
+2016.03.07 - v0.45j9
+
+e) try use DWORD-IO for ATAPI
+
+--
+2016.03.07 - v0.45j10
+
+*) added extra Bochs detection via ATA device S/N and FW (it is possible
+to meet no Boch VendorId on PCI bus)
+and absence of non-zero SubDevice/SubVendor on Intel chipsets
++) Added old PIIX DMA support
+
+--
+2016.03.08 - v0.46
+
+!) Fixed bug with PIO multiblock transfer (wordCount was not updated on each 
+iteration), which may cause buffer overflow
+!) Fixed bug with uninitialized max_bcount on PIO transfers on LBA-enabled devices,
+which could cause unnecessary request fragmentation in PIO mode.
+e) do not try automatically initialize CD-changers, since it may cause
+ATAPI CD-ROM freeze. Let CD-ROM driver do it itself for its own risk (and 
+knowledge). We shall jusy parse output on success.
+Original changer behavior can be reverted by UNIATA_INIT_CHANGERS define.
+(ROS BUG-9119)
+*) removed unnecessary calls of AtapiHwInitializeChanger()
+*) track last used Lun on the channel chan->last_cdev
+
+--
+2016.03.09 - v0.46a
+
+*) fixed KeNumberProcessors ROS/NT DDK incompatibility issue
+*) fixed g_opt_BochDmaReadWorkaround variable name (use 'Bochs')
+*) fixed DBG vs _DEBUG ROS compilation issue
+*) check for DRQ it taken back however, it is not always asserted on 
+error (v0.44b2), problem reported by RayeR
+
+--
+2016.03.09 - v0.46a1
+
+e) force PIO on SATA ATAPI (experiment for Pioneer)
diff -ruN v45j5\driver\bm_devs.h v46a1\driver\bm_devs.h
--- v45j5\driver\bm_devs.h	Wed Sep 23 19:05:02 2015
+++ v46a1\driver\bm_devs.h	Mon Mar 07 15:21:10 2016
@@ -609,13 +609,15 @@
 #define CHIPFLAG_MASK   0xffffff00
 
 #define UNIATA_RAID_CONTROLLER  0x80000000
-#define UNIATA_SIMPLEX_ONLY     0x40000000
+#define UNIATA_SIMPLEX_ONLY     0x40000000 /* contoller cannot perform operations
+                                              on both channels on the same time */
 #define UNIATA_NO_SLAVE         0x20000000
 #define UNIATA_SATA             0x10000000
 #define UNIATA_NO_DPC           0x08000000
 #define UNIATA_NO_DPC_ATAPI     0x04000000
 #define UNIATA_AHCI             0x02000000
 #define UNIATA_NO80CHK          0x01000000
+#define UNIATA_CHAN_TIMINGS     0x00800000 /* controller has common timing settings for master/slave */
 
 #define ATPOLD		0x0100
 
@@ -777,7 +779,7 @@
     PCI_DEV_HW_SPEC_BM( 0007, 1103, 0x01, ATA_UDMA6, "HighPoint HPT371" , HPT372 | 0x00   | UNIATA_RAID_CONTROLLER),
     PCI_DEV_HW_SPEC_BM( 0008, 1103, 0x07, ATA_UDMA6, "HighPoint HPT374" , HPT374 | 0x00   | UNIATA_RAID_CONTROLLER),
 
-    PCI_DEV_HW_SPEC_BM( 1230, 8086, 0x00, ATA_WDMA2, "Intel PIIX"       , 0                                       ),
+    PCI_DEV_HW_SPEC_BM( 1230, 8086, 0x00, ATA_WDMA2, "Intel PIIX"       , UNIATA_CHAN_TIMINGS                     ),
     PCI_DEV_HW_SPEC_BM( 7010, 8086, 0x00, ATA_WDMA2, "Intel PIIX3"      , 0                                       ),
     PCI_DEV_HW_SPEC_BM( 7111, 8086, 0x00, ATA_UDMA2, "Intel PIIX3"      , 0                                       ),
     PCI_DEV_HW_SPEC_BM( 7199, 8086, 0x00, ATA_UDMA2, "Intel PIIX4"      , 0                                       ),
diff -ruN v45j5\driver\bsmaster.h v46a1\driver\bsmaster.h
--- v45j5\driver\bsmaster.h	Sun Jan 24 12:51:36 2016
+++ v46a1\driver\bsmaster.h	Mon Mar 07 15:15:50 2016
@@ -1008,6 +1008,7 @@
 
     PATA_REQ            cur_req;
     ULONG               cur_cdev;
+    ULONG               last_cdev; /* device for which we have configured timings last time */
 /*    PATA_REQ            first_req;
     PATA_REQ            last_req;*/
     ULONG               queue_depth;
@@ -1123,7 +1124,7 @@
 #define CTRFLAGS_LBA48                  0x0040
 #define CTRFLAGS_DSC_BSY                0x0080
 #define CTRFLAGS_NO_SLAVE               0x0100
-#define CTRFLAGS_DMA_BEFORE_R           0x0200
+//#define CTRFLAGS_DMA_BEFORE_R           0x0200
 //#define CTRFLAGS_PATA                   0x0200
 //#define CTRFLAGS_NOT_PRESENT            0x0200
 #define CTRFLAGS_AHCI_PM                0x0400
diff -ruN v45j5\driver\Dist\2K\uata_2k.inf v46a1\driver\Dist\2K\uata_2k.inf
--- v45j5\driver\Dist\2K\uata_2k.inf	Sun Jan 24 15:05:14 2016
+++ v46a1\driver\Dist\2K\uata_2k.inf	Wed Mar 09 19:18:58 2016
@@ -6,7 +6,7 @@
 ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
 Class=SCSIAdapter
 CatalogFile=uniata.cat
-DriverVer=01/24/2016,0.45.10.5
+DriverVer=03/09/2016,0.46.1.1
 
 ;
 ; Source file information
diff -ruN v45j5\driver\Dist\2K\uata_2kh.inf v46a1\driver\Dist\2K\uata_2kh.inf
--- v45j5\driver\Dist\2K\uata_2kh.inf	Sun Jan 24 15:05:14 2016
+++ v46a1\driver\Dist\2K\uata_2kh.inf	Wed Mar 09 19:18:58 2016
@@ -6,7 +6,7 @@
 ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
 Class=hdc
 CatalogFile=uniata.cat
-DriverVer=01/24/2016,0.45.10.5
+DriverVer=03/09/2016,0.46.1.1
 
 ;
 ; Source file information
diff -ruN v45j5\driver\Dist\2K\uniata_w2k.reg v46a1\driver\Dist\2K\uniata_w2k.reg
--- v45j5\driver\Dist\2K\uniata_w2k.reg	Sun Jan 24 15:05:14 2016
+++ v46a1\driver\Dist\2K\uniata_w2k.reg	Wed Mar 09 19:18:58 2016
@@ -6,7 +6,7 @@
 "Start"=dword:00000000
 "Tag"=dword:00000019
 "Type"=dword:00000001
-"DisplayName"="Universal BusMaster SATA/ATA/ATAPI Driver v0.45.10.5"
+"DisplayName"="Universal BusMaster SATA/ATA/ATAPI Driver v0.46.1.1"
 "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 v45j5\driver\Dist\NT4\uata_nt4.inf v46a1\driver\Dist\NT4\uata_nt4.inf
--- v45j5\driver\Dist\NT4\uata_nt4.inf	Sun Jan 24 15:05:14 2016
+++ v46a1\driver\Dist\NT4\uata_nt4.inf	Wed Mar 09 19:18:58 2016
@@ -6,7 +6,7 @@
 ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
 Class=SCSIAdapter
 CatalogFile=uniata.cat
-DriverVer=01/24/2016,0.45.10.5
+DriverVer=03/09/2016,0.46.1.1
 
 ;
 ; Source file information
Binary files v45j5\driver\Dist\tools\build_inf.exe and v46a1\driver\Dist\tools\build_inf.exe differ
diff -ruN v45j5\driver\Dist\XP\uata_xp.inf v46a1\driver\Dist\XP\uata_xp.inf
--- v45j5\driver\Dist\XP\uata_xp.inf	Sun Jan 24 15:05:14 2016
+++ v46a1\driver\Dist\XP\uata_xp.inf	Wed Mar 09 19:18:58 2016
@@ -6,7 +6,7 @@
 ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
 Class=SCSIAdapter
 CatalogFile=uniata.cat
-DriverVer=01/24/2016,0.45.10.5
+DriverVer=03/09/2016,0.46.1.1
 
 ;
 ; Source file information
diff -ruN v45j5\driver\Dist\XP\uata_xph.inf v46a1\driver\Dist\XP\uata_xph.inf
--- v45j5\driver\Dist\XP\uata_xph.inf	Sun Jan 24 15:05:14 2016
+++ v46a1\driver\Dist\XP\uata_xph.inf	Wed Mar 09 19:18:58 2016
@@ -6,7 +6,7 @@
 ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
 Class=hdc
 CatalogFile=uniata.cat
-DriverVer=01/24/2016,0.45.10.5
+DriverVer=03/09/2016,0.46.1.1
 
 ;
 ; Source file information
diff -ruN v45j5\driver\id_ata.cpp v46a1\driver\id_ata.cpp
--- v45j5\driver\id_ata.cpp	Sun Jan 24 14:57:52 2016
+++ v46a1\driver\id_ata.cpp	Wed Mar 09 19:13:58 2016
@@ -1,6 +1,6 @@
 /*++
 
-Copyright (c) 2002-2015 Alexandr A. Telyatnikov (Alter)
+Copyright (c) 2002-2016 Alexandr A. Telyatnikov (Alter)
 
 Module Name:
     id_ata.cpp
@@ -91,6 +91,8 @@
 ULONG  g_opt_MaxIsrWait = 40; //
 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
@@ -496,7 +498,7 @@
     UCHAR statusByte;
     ULONG i;
 
-    // Assume, proper drive is already seleted
+    // Assume, proper drive is already selected
     WaitOnBusyLong(chan);
     for (i = 0; i < 0x10000; i++) {
 
@@ -1682,7 +1684,7 @@
               KdPrint3((PRINT_PREFIX "IssueIdentify: wCount %x\n", j));
 
             }
-#endif //DBG
+#endif //_DEBUG
             // 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
@@ -1713,6 +1715,24 @@
     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));
@@ -2356,7 +2376,7 @@
                     }
 
                     if(!ATAPI_DEVICE(chan, i) && AtaReq->bcount && AtaReq->retry < MAX_RETRIES) {
-                        KdPrint2((PRINT_PREFIX "Save retry status %d\n", AtaReq->retry));
+                        KdPrint2((PRINT_PREFIX "Save IDE retry status %d\n", AtaReq->retry));
                         LunExt->errLastLba = AtaReq->lba;
                         LunExt->errBCount = AtaReq->bcount;
                         LunExt->errRetry = AtaReq->retry+1;
@@ -2367,7 +2387,23 @@
                            (ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) &&
                            (g_opt_VirtualMachine == VM_BOCHS)) {
                             KdPrint2((PRINT_PREFIX "set CTRFLAGS_DMA_BEFORE_R on BOCHS\n"));
-                            chan->ChannelCtrlFlags |= CTRFLAGS_DMA_BEFORE_R;
+                            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"));
                         }
@@ -2401,7 +2437,7 @@
         // Clear expecting interrupt flag.
         UniataExpectChannelInterrupt(chan, FALSE);
         chan->RDP = FALSE;
-        chan->ChannelCtrlFlags = 0;
+        chan->ChannelCtrlFlags = ChannelCtrlFlags & CTRFLAGS_PERMANENT;
         InterlockedExchange(&(chan->CheckIntr),
                                       CHECK_INTR_IDLE);
         
@@ -3461,6 +3497,8 @@
     ULONG DeviceNumber = GET_CDEV(Srb);
     PHW_LU_EXTENSION     LunExt = chan->lun[DeviceNumber];
 
+    //LunExt->DeviceFlags |= DFLAGS_CHANGER_INITED;
+    //KdPrint2((PRINT_PREFIX "AtapiHwInitializeChanger: set DFLAGS_CHANGER_INITED\n"));
     if (MechanismStatus) {
         LunExt->DiscsPresent = MechanismStatus->NumberAvailableSlots;
         if (LunExt->DiscsPresent > 1) {
@@ -3685,7 +3723,7 @@
         goto ReturnCallback;
     }
 
-#ifdef DBG
+#ifdef _DEBUG
     if (!IS_RDP((srb->Cdb[0]))) {
         KdPrint2((PRINT_PREFIX "AtapiCallBack: Invalid CDB marked as RDP - %#x\n", srb->Cdb[0]));
     }
@@ -4783,9 +4821,9 @@
 
     BOOLEAN atapiDev = FALSE;
 
-#ifdef DBG
+#ifdef _DEBUG
     UCHAR Channel;
-#endif //DBG
+#endif //_DEBUG
     UCHAR lChannel;
     UCHAR DeviceNumber;
     BOOLEAN DmaTransfer = FALSE;
@@ -4818,11 +4856,11 @@
 
     lChannel = c;
 
-#ifdef DBG
+#ifdef _DEBUG
     Channel = (UCHAR)(deviceExtension->Channel + lChannel);
 
     KdPrint2((PRINT_PREFIX "  cntrlr %#x:%d, irql %#x, c %d\n", deviceExtension->DevIndex, Channel, KeGetCurrentIrql(), c));
-#endif //DBG
+#endif //_DEBUG
 
     if((chan->ChannelCtrlFlags & CTRFLAGS_DMA_ACTIVE) ||
        (AtaReq && (AtaReq->Flags & REQ_FLAG_DMA_OPERATION)) ||
@@ -5580,7 +5618,7 @@
 
             statusByte = WaitOnBusy(chan);
 
-            if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/
+            if (/*atapiDev || */ !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/
                 || (wordCount & 1)) {
 
                 WriteBuffer(chan,
@@ -5653,6 +5691,7 @@
 
     } else if (interruptReason == ATAPI_IR_IO_toHost && (statusByte & IDE_STATUS_DRQ)) {
 
+continue_read_drq:
 
         if (atapiDev) {
 
@@ -5679,7 +5718,6 @@
             }
 
         } else {
-
             // Check if words left is at least 256.
             if (AtaReq->WordsLeft < wordsThisInterrupt) {
                // Transfer only words requested.
@@ -5710,7 +5748,6 @@
             chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
             goto CompleteRequest;
         }
-continue_read_drq:
         // Ensure that this is a read command.
         if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
 
@@ -5719,7 +5756,7 @@
 
             statusByte = WaitOnBusy(chan);
 
-            if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/
+            if (/*atapiDev ||*/ !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) /*!deviceExtension->DWordIO*/
                 || (wordCount & 1)) {
                 KdPrint2((PRINT_PREFIX 
                            "IdeIntr: Read %#x words\n", wordCount));
@@ -5728,30 +5765,6 @@
                           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 {
                 KdPrint2((PRINT_PREFIX 
                           "IdeIntr: Read %#x Dwords\n", wordCount/2));
@@ -5761,6 +5774,32 @@
                            wordCount / 2,
                            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 
@@ -5784,23 +5823,35 @@
             KdPrint2((PRINT_PREFIX "AtapiInterrupt: all transferred, AtaReq->WordsLeft == 0\n"));
             if (atapiDev) {
 
-                // 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) &&
-                    (LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM)) {
-
-                    AtaReq->DataBuffer -= wordCount;
-                    if (AtaReq->DataBuffer[0] == 0x00) {
+                if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM) {
 
-                        *((ULONG *) &(AtaReq->DataBuffer[0])) = 0xFFFFFF7F;
+                    // 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 -= wordCount;
+                        if (AtaReq->DataBuffer[0] == 0x00) {
+                            *((ULONG *) &(AtaReq->DataBuffer[0])) = 0xFFFFFF7F;
+                        }
 
+                        *((ULONG *) &(AtaReq->DataBuffer[2])) = 0x00080000;
+                        AtaReq->DataBuffer += wordCount;
                     }
+#ifndef UNIATA_INIT_CHANGERS
+                    else
+                    if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
 
-                    *((ULONG *) &(AtaReq->DataBuffer[2])) = 0x00080000;
-                    AtaReq->DataBuffer += wordCount;
+                        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
@@ -5946,7 +5997,8 @@
 
             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!!
@@ -5987,7 +6039,10 @@
                     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;
@@ -6003,7 +6058,9 @@
 
                 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));
@@ -6012,14 +6069,9 @@
                         srb = AtaReq->Srb = BuildMechanismStatusSrb (
                                                               HwDeviceExtension,
                                                               AtaReq->OriginalSrb);
-                    } else {
-
-                        // last request was illegal.  No point trying again.
-                        // Do-nothing call ?
-                        AtapiHwInitializeChanger (HwDeviceExtension,
-                                                  srb,
-                                                  (PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);
-
+                    } else
+#endif // UNIATA_INIT_CHANGERS
+                    {
                         // Get ready to issue the original srb
                         srb = AtaReq->Srb = AtaReq->OriginalSrb;
                         AtaReq->OriginalSrb = NULL;
@@ -6057,11 +6109,6 @@
             KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. complete OriginalSrb\n"));
 
             if (AtaReq->OriginalSrb) {
-                KdPrint2((PRINT_PREFIX "AtapiInterrupt: call AtapiHwInitializeChanger()\n"));
-                // Do-nothing call ?
-                AtapiHwInitializeChanger (HwDeviceExtension,
-                                          srb,
-                                          (PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);
                 srb = AtaReq->Srb = AtaReq->OriginalSrb;
                 AtaReq->OriginalSrb = NULL;
             }
@@ -6596,6 +6643,7 @@
     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;
@@ -6619,7 +6667,6 @@
         KdPrint2((PRINT_PREFIX "UniAtaCalculateLBARegs: C:H:S=%#x:%#x:%#x, max_bc %#x\n",
             cylinder, drvSelect, sectorNumber, (*max_bcount)));
     }
-        (*max_bcount) = 0;
 
     return (ULONG)(sectorNumber&0xff) | (((ULONG)cylinder&0xffff)<<8) | (((ULONG)drvSelect&0xf)<<24);
 } // end UniAtaCalculateLBARegs()
@@ -6685,7 +6732,7 @@
     //ULONG                ldev = GET_LDEV(Srb);
     UCHAR                DeviceNumber = GET_CDEV(Srb);;
     ULONGLONG            startingSector=0;
-    ULONG                max_bcount;
+    ULONG                max_bcount = 0;
     ULONG                wordCount = 0;
     UCHAR                statusByte,statusByte2;
     UCHAR                cmd;
@@ -6901,9 +6948,9 @@
         use_dma) {
         if(use_dma) {
             AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb);
-            if((chan->ChannelCtrlFlags & CTRFLAGS_DMA_BEFORE_R) &&
-               (Srb->SrbFlags & SRB_FLAGS_DATA_IN) /* probably, this is double-check, but keep it */) {
-                KdPrint2((PRINT_PREFIX "set CTRFLAGS_DMA_BEFORE_R on BOCHS\n"));
+            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);
             }
         }
@@ -6924,8 +6971,8 @@
             return SRB_STATUS_ERROR;
         }
         if(use_dma) {
-           if(!(chan->ChannelCtrlFlags & CTRFLAGS_DMA_BEFORE_R) &&
-               (Srb->SrbFlags & SRB_FLAGS_DATA_IN) /* probably, this is double-check, but keep it */) {
+           if(!g_opt_BochsDmaReadWorkaround ||
+              !(Srb->SrbFlags & SRB_FLAGS_DATA_IN)) {
                 //GetStatus(chan, statusByte2);
                 AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
             }
@@ -7262,20 +7309,30 @@
             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) {
 
@@ -7313,17 +7370,12 @@
             }
 
             // failed again ? should not get here
-
             AtaReq->Srb = AtaReq->OriginalSrb;
             AtaReq->OriginalSrb = NULL;
-
-            KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiHwInitializeChanger()\n"));
-            // Do-nothing call ?
-            AtapiHwInitializeChanger (HwDeviceExtension, Srb,
-                                      (PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);
             // fall out
         }
     }
+#endif // UNIATA_INIT_CHANGERS
 #endif //UNIATA_CORE
 
     if((CmdAction & CMD_ACTION_PREPARE) &&
@@ -7391,16 +7443,22 @@
         }
 
         // check if DMA read/write
+        //KdPrint2((PRINT_PREFIX "AtapiSendCommand: chan %#x flags %#x\n", chan, chan->ChannelCtrlFlags));
+        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;
+        if((deviceExtension->HwFlags & UNIATA_SATA) && (LunExt->OrigTransferMode >= ATA_DMA)) {
+            // experimental, see ROS BUG-9119, v0.46a1
+            KdPrint2((PRINT_PREFIX "AtapiSendCommand: force use PIO (sata)\n"));
+            use_dma = FALSE;
             goto setup_dma;
-        } else*/
+        } else
         if(Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
             KdPrint2((PRINT_PREFIX "AtapiSendCommand: SCSIOP_REQUEST_SENSE, no DMA setup\n"));
         } else
@@ -7852,7 +7910,7 @@
 #ifdef _DEBUG
     statusByte = (AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason) & ATAPI_IR_Mask);
     KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x\n", statusByte));
-#endif //DBG
+#endif //_DEBUG
 
     if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) {
         AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb);
@@ -7886,8 +7944,8 @@
         AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
         return MapError(deviceExtension, Srb);
     }
-/*    if(statusByte & IDE_STATUS_DSC) {
-        KdPrint3((PRINT_PREFIX "AtapiSendCommand: DSC on cmd: (%#x)\n", statusByte));
+    if(statusByte & IDE_STATUS_DRQ) {
+        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));
@@ -7897,7 +7955,7 @@
             return MapError(deviceExtension, Srb);
         }
     }
-*/
+
     if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) {
         AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
     }
@@ -10337,6 +10395,7 @@
         MajorVersion=0x04;
         MinorVersion=0x01;
         BuildNumber=1;
+        KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, KeNumberProcessors));
 #else
         // we are here for the 1st time
         // init CrossNT and get OS version
@@ -10345,8 +10404,8 @@
             //HalDisplayString((PUCHAR)"DbgPrnHkInitialize: CrNtInit failed\n");
             return status;
         }
-#endif // USE_REACTOS_DDK
         KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, *KeNumberProcessors));
+#endif // USE_REACTOS_DDK
 
         KeQuerySystemTime(&t0);
         do {
@@ -10456,6 +10515,9 @@
             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) {
@@ -10475,6 +10537,7 @@
         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
     }
 
diff -ruN v45j5\driver\id_dma.cpp v46a1\driver\id_dma.cpp
--- v45j5\driver\id_dma.cpp	Tue Sep 29 19:24:50 2015
+++ v46a1\driver\id_dma.cpp	Wed Mar 09 19:14:08 2016
@@ -378,7 +378,7 @@
             AtaReq->ahci.ahci_base64 = NULL;
             return FALSE;
         }
-        KdPrint2((PRINT_PREFIX "  get Phys(data[n=%d]=%x)\n", i, data ));
+        KdPrint2((PRINT_PREFIX "  get Phys(data[n=%d+%x]=%x)\n", i, dma_count0, data ));
         dma_base = AtapiVirtToPhysAddr(HwDeviceExtension, Srb, data, &dma_count, &dma_baseu);
         if(dma_baseu && dma_count) {
             KdPrint2((PRINT_PREFIX "AtapiDmaSetup: block of buffer above 4Gb: %8.8x%8.8x, cnt=%x\n", dma_baseu, dma_base, dma_count));
@@ -828,14 +828,15 @@
     if(/*!(LunExt->DeviceFlags & DFLAGS_FORCE_DOWNRATE) &&*/
         (LunExt->LimitedTransferMode >
          LunExt->TransferMode) ||
-         (LunExt->DeviceFlags & DFLAGS_REINIT_DMA)) {
+         (LunExt->DeviceFlags & DFLAGS_REINIT_DMA) ||
+         ((deviceExtension->HwFlags & UNIATA_CHAN_TIMINGS) && ((ULONG)LunExt->Lun != LunExt->chan->last_cdev))) {
         // restore IO mode
         KdPrint2((PRINT_PREFIX
-                    "AtapiDmaReinit: restore IO mode on Device %d\n", LunExt->Lun));
+                    "AtapiDmaReinit: restore IO mode on Device %d, last dev %d\n", LunExt->Lun, LunExt->chan->last_cdev));
         AtapiDmaInit__(deviceExtension, LunExt);
     } else {
         KdPrint2((PRINT_PREFIX
-                    "AtapiDmaReinit: LimitedTransferMode == TransferMode = %x (%x)\n", LunExt->TransferMode, LunExt->DeviceFlags));
+                    "AtapiDmaReinit: LimitedTransferMode == TransferMode = %x (%x), Device %d, last dev %d\n", LunExt->TransferMode, LunExt->DeviceFlags, LunExt->Lun, LunExt->chan->last_cdev));
     }
 
 exit:
@@ -892,6 +893,10 @@
     LONG statusByte = 0;
     CHAR apiomode;
 
+    if(deviceExtension->HwFlags & UNIATA_SATA) {
+        // experimental do nothing, see ROS BUG-9119, v0.46a1
+        statusByte = IDE_STATUS_IDLE;
+    } else
     if(LunExt->DeviceFlags & DFLAGS_MANUAL_CHS) {
         statusByte = mode <= ATA_PIO2 ? IDE_STATUS_IDLE : IDE_STATUS_ERROR;
     } else {
@@ -1049,6 +1054,7 @@
         }
     //}
 
+    chan->last_cdev = DeviceNumber;
     if(UniataIsSATARangeAvailable(deviceExtension, lChannel) ||
         (ChipFlags & UNIATA_AHCI) || (chan->MaxTransferMode >= ATA_SA150)
        ) {
@@ -1495,27 +1501,50 @@
         UCHAR  intel_timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23,
     		                   0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
         UCHAR  intel_utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
+	const UCHAR needed_pio[3] = {
+		ATA_PIO0, ATA_PIO3, ATA_PIO4
+	};
 
         if(deviceExtension->DevID == ATA_I82371FB) {
             KdPrint2((PRINT_PREFIX "  I82371FB\n"));
-            if (wdmamode >= 2 && apiomode >= 4) {
-                ULONG word40;
-
-                GetPciConfig4(0x40, word40);
-                word40 >>= Channel * 16;
-
-                /* Check for timing config usable for DMA on controller */
-                if (!((word40 & 0x3300) == 0x2300 &&
-                      ((word40 >> ((!(DeviceNumber & 1)) ? 0 : 4)) & 1) == 1)) {
-                    udmamode = wdmamode = -1;
+            USHORT reg4x;
+            USHORT control;
+            for(i=wdmamode; i>=0; i--) {
+                idx = 5+i;
+                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
+                    udma_ok = TRUE;
                     break;
                 }
-
-                if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA2)) {
-                    return;
+            }
+            if(!udma_ok) {
+                AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
+                idx = apiomode;
+            } else {
+                /* If the drive MWDMA is faster than it can do PIO then
+                   we must force PIO into PIO0 */
+                if (apiomode < needed_pio[wdmamode]) {
+                    /* Enable DMA timing only */
+                    control |= 8;	/* PIO cycles in PIO0 */
                 }
             }
-            break;
+            GetPciConfig2(0x40+Channel*2, reg4x);
+            if(apiomode > ATA_PIO0) {
+                control = 0x03;	/* IORDY|TIME0 */
+            } else {
+                control = 0x02;	/* IORDY */
+            }
+	    // if (ata_pio_need_iordy(adev))
+		//control |= 2;	/* IE */
+            if (!isAtapi) {
+                control |= 4;	/* PPE enable */
+            }
+            /* Mask out the relevant control and timing bits we will load. Also
+               clear the other drive TIME register as a precaution */
+            reg4x &= 0xCC00 | (0x0E << (DeviceNumber*4));
+            reg4x |= control << (DeviceNumber*4);
+            reg4x |= intel_timings[idx] << 8;
+            SetPciConfig2(0x40+Channel*2, reg4x);
+            return;
         }
 
         if(deviceExtension->DevID == ATA_ISCH) {
@@ -1558,7 +1587,7 @@
             tim |= (apiomode & 0x7);
             SetPciConfig4(0x80 + dev*4, tim);
 
-            break;
+            return;
         }
 
         GetPciConfig2(0x48, reg48);
diff -ruN v45j5\driver\id_probe.cpp v46a1\driver\id_probe.cpp
--- v45j5\driver\id_probe.cpp	Thu Sep 24 12:13:42 2015
+++ v46a1\driver\id_probe.cpp	Wed Mar 09 12:45:20 2016
@@ -330,6 +330,7 @@
     BOOLEAN found;
     BOOLEAN known;
     BOOLEAN NeedPciAltInit;
+    BOOLEAN NonZeroSubId = 0;
 
     UCHAR IrqForCompat = 10;
 
@@ -405,12 +406,17 @@
                 SubVendorID = pciData.u.type0.SubVendorID;
                 SubSystemID = pciData.u.type0.SubSystemID;
 
+                if(SubVendorID && SubSystemID) {
+                  NonZeroSubId = 1;
+                }
+
                 //KdPrint2((PRINT_PREFIX "DevId = %8.8X Class = %4.4X/%4.4X\n", dev_id, BaseClass, SubClass ));
 
                 // check for (g_opt_VirtualMachine == VM_AUTO) is performed inside each
                 // VM check for debug purposes
                 // Do not optimize :)
-                if(VendorID == 0x80ee && DeviceID == 0xcafe) {
+                if((VendorID == 0x80ee && DeviceID == 0xcafe) ||
+                   (VendorID == 0x80ee && DeviceID == 0xbeef)) {
                     KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - VirtualBox Guest Service\n",busNumber,slotNumber,funcNumber));
                     if(g_opt_VirtualMachine == VM_AUTO) {
                         g_opt_VirtualMachine = VM_VBOX;
@@ -434,6 +440,15 @@
                     if(g_opt_VirtualMachine == VM_AUTO) {
                         g_opt_VirtualMachine = VM_BOCHS;
                     }
+                } else
+                if(pass>0 && !NonZeroSubId &&
+                   VendorID == 0x8086 &&
+                     (DeviceID == 0x7010 ||
+                      DeviceID == 0x1230)) {
+                    KdPrint2((PRINT_PREFIX "-- BusID: %#x:%#x:%#x - Bochs PIIX emulation\n",busNumber,slotNumber,funcNumber));
+                    if(g_opt_VirtualMachine == VM_AUTO) {
+                        g_opt_VirtualMachine = VM_BOCHS;
+                    }
                 }
 
                 if(BaseClass != PCI_DEV_CLASS_STORAGE) {
@@ -3072,49 +3087,35 @@
             // garbage geometry in the IDENTIFY data.
             // This is ONLY for the crashdump environment as
             // these are ESDI devices.
-            if (LunExt->IdentifyData.SectorsPerTrack ==
-                    0x35 &&
-                LunExt->IdentifyData.NumberOfHeads ==
-                    0x07) {
+            if (LunExt->IdentifyData.SectorsPerTrack == 0x35 &&
+                LunExt->IdentifyData.NumberOfHeads == 0x07) {
 
-                KdPrint2((PRINT_PREFIX 
-                           "FindDevices: Found nasty Compaq ESDI!\n"));
+                KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n"));
 
                 // Change these values to something reasonable.
-                LunExt->IdentifyData.SectorsPerTrack =
-                    0x34;
-                LunExt->IdentifyData.NumberOfHeads =
-                    0x0E;
+                LunExt->IdentifyData.SectorsPerTrack = 0x34;
+                LunExt->IdentifyData.NumberOfHeads = 0x0E;
             }
 
-            if (LunExt->IdentifyData.SectorsPerTrack ==
-                    0x35 &&
-                LunExt->IdentifyData.NumberOfHeads ==
-                    0x0F) {
+            if (LunExt->IdentifyData.SectorsPerTrack == 0x35 &&
+                LunExt->IdentifyData.NumberOfHeads == 0x0F) {
 
-                KdPrint2((PRINT_PREFIX 
-                           "FindDevices: Found nasty Compaq ESDI!\n"));
+                KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n"));
 
                 // Change these values to something reasonable.
-                LunExt->IdentifyData.SectorsPerTrack =
-                    0x34;
-                LunExt->IdentifyData.NumberOfHeads =
-                    0x0F;
+                LunExt->IdentifyData.SectorsPerTrack = 0x34;
+                LunExt->IdentifyData.NumberOfHeads = 0x0F;
             }
 
 
-            if (LunExt->IdentifyData.SectorsPerTrack ==
-                    0x36 &&
-                LunExt->IdentifyData.NumberOfHeads ==
-                    0x07) {
+            if (LunExt->IdentifyData.SectorsPerTrack == 0x36 &&
+                LunExt->IdentifyData.NumberOfHeads == 0x07) {
 
                 KdPrint2((PRINT_PREFIX "FindDevices: Found nasty UltraStor ESDI!\n"));
 
                 // Change these values to something reasonable.
-                LunExt->IdentifyData.SectorsPerTrack =
-                    0x3F;
-                LunExt->IdentifyData.NumberOfHeads =
-                    0x10;
+                LunExt->IdentifyData.SectorsPerTrack = 0x3F;
+                LunExt->IdentifyData.NumberOfHeads = 0x10;
                 skipSetParameters = TRUE;
             }
 
diff -ruN v45j5\driver\id_queue.cpp v46a1\driver\id_queue.cpp
--- v45j5\driver\id_queue.cpp	Wed Jul 11 18:26:26 2012
+++ v46a1\driver\id_queue.cpp	Tue Mar 08 18:34:00 2016
@@ -228,6 +228,7 @@
         AtaReq->next_req = NULL;
         LunExt->first_req =
         LunExt->last_req = AtaReq;
+        chan->cur_cdev = GET_CDEV(Srb);
     }
     LunExt->queue_depth++;
     chan->queue_depth++;
diff -ruN v45j5\driver\id_sata.cpp v46a1\driver\id_sata.cpp
--- v45j5\driver\id_sata.cpp	Wed Sep 23 18:18:12 2015
+++ v46a1\driver\id_sata.cpp	Wed Mar 09 12:47:08 2016
@@ -576,7 +576,7 @@
 
 } // end UniataSataIdentifyPM()
 
-#ifdef DBG
+#ifdef _DEBUG
 VOID
 NTAPI
 UniataDumpAhciRegs(
@@ -631,7 +631,7 @@
     }
     return;
 } // end UniataDumpAhciPortRegs()
-#endif //DBG
+#endif //_DEBUG
 
 
 BOOLEAN
@@ -654,9 +654,9 @@
 
     KdPrint2((PRINT_PREFIX "  UniataAhciInit:\n"));
 
-#ifdef DBG
+#ifdef _DEBUG
     UniataDumpAhciRegs(deviceExtension);
-#endif //DBG
+#endif //_DEBUG
 
     CAP2 = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_CAP2);
     if(CAP2 & AHCI_CAP2_BOH) {
@@ -891,10 +891,10 @@
     ULONG CAP;
     ULONG CAP2;
     ULONG GHC, GHC0;
-#ifdef DBG
+#ifdef _DEBUG
     ULONG BOHC;
     ULONG v_Mn, v_Mj;
-#endif //DBG
+#endif //_DEBUG
     ULONG NumberChannels;
     ULONG BaseMemAddress;
     BOOLEAN MemIo = FALSE;
@@ -919,9 +919,9 @@
     deviceExtension->BaseIoAHCI_0.Addr  = BaseMemAddress;
     deviceExtension->BaseIoAHCI_0.MemIo = MemIo;
 
-#ifdef DBG
+#ifdef _DEBUG
     UniataDumpAhciRegs(deviceExtension);
-#endif //DBG
+#endif //_DEBUG
 
     GHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_GHC);
     if(GHC & AHCI_GHC_HR) {
@@ -961,12 +961,12 @@
         KdPrint2((PRINT_PREFIX "  64bit"));
         //deviceExtension->Host64 = TRUE; // this is just DETECT, do not update anything
     }
-#ifdef DBG
+#ifdef _DEBUG
     if(CAP2 & AHCI_CAP2_BOH) {
         BOHC = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_BOHC);
         KdPrint2((PRINT_PREFIX "  BOHC %#x", BOHC));
     }
-#endif //DBG
+#endif //_DEBUG
     if(CAP & AHCI_CAP_NCQ) {
         KdPrint2((PRINT_PREFIX "  NCQ"));
     }
@@ -1031,7 +1031,7 @@
     }
     KdPrint2((PRINT_PREFIX "  Adjusted Channels %d\n", NumberChannels));
 
-#ifdef DBG
+#ifdef _DEBUG
     v_Mj = ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f);
     v_Mn = ((version >> 4) & 0xf0) + (version & 0x0f);
 
@@ -1039,7 +1039,7 @@
 		  v_Mj, v_Mn,
 		  NumberChannels, PI));
     KdPrint(("  AHCI SATA Gen %d\n", (((CAP & AHCI_CAP_ISS_MASK) >> 20)) ));
-#endif //DBG
+#endif //_DEBUG
 
     if(CAP & AHCI_CAP_SPM) {
         KdPrint2((PRINT_PREFIX "  PM supported\n"));
@@ -1138,9 +1138,9 @@
     KdPrint((" AHCI: complete mask %#x\n", chan->AhciCompleteCI));
     chan->AhciLastIS = IS.Reg;
     if(CI & (1 << tag)) {
-#ifdef DBG
+#ifdef _DEBUG
         UniataDumpAhciPortRegs(chan);
-#endif //DBG
+#endif //_DEBUG
         //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
         if(IS.Reg &
             (ATA_AHCI_P_IX_OF | ATA_AHCI_P_IX_INF | ATA_AHCI_P_IX_IF |
@@ -1438,7 +1438,7 @@
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IS, IS.Reg);
 
     if (timeout && (i >= timeout)) {
-#ifdef DBG
+#ifdef _DEBUG
         ULONG TFD;
 
         SError = AtapiReadPort4(chan, IDX_SATA_SError);
@@ -1446,7 +1446,7 @@
 
         TFD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_TFD);
         KdPrint2(("  TFD %#x\n", TFD));
-#endif //DBG
+#endif //_DEBUG
         
         return IDE_STATUS_WRONG;
     }
@@ -1532,9 +1532,9 @@
         KdPrint(("  length/DEV_BSIZE != bcount\n"));
     }
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     if(!Srb) {
         Srb = BuildAhciInternalSrb(HwDeviceExtension, DeviceNumber, lChannel, data, length);
@@ -1590,15 +1590,15 @@
 
     AtaReq->ahci.io_cmd_flags = ahci_flags;
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     if(wait_flags == ATA_IMMEDIATE) {
         statusByte = 0;
@@ -1645,9 +1645,9 @@
 //        KdPrint(("  length/DEV_BSIZE != bcount\n"));
 //    }
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     if(!Srb) {
         KdPrint(("  !Srb\n"));
@@ -1700,15 +1700,15 @@
 
     AtaReq->ahci.io_cmd_flags = ahci_flags;
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     if(wait_flags == ATA_IMMEDIATE) {
         statusByte = 0;
@@ -1863,9 +1863,9 @@
     }
     KdPrint(("  TFD %#x\n", TFD));
 
-#ifdef DBG
+#ifdef _DEBUG
     UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     (*signature) = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_SIG);
     KdPrint(("  sig: %#x\n", *signature));
@@ -2178,10 +2178,10 @@
         return 0;
     }
 
-#ifdef DBG
+#ifdef _DEBUG
     KdPrint2(("  prd_length %#x, flags %#x, base %I64x\n", AHCI_CL->prd_length, AHCI_CL->cmd_flags, 
             AHCI_CL->cmd_table_phys));
-#endif // DBG
+#endif // _DEBUG
 
     CMD0 = CMD = UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD);
     KdPrint2(("  CMD %#x\n", CMD));
@@ -2350,9 +2350,9 @@
 
     KdPrint2(("UniataAhciResume: lChan %d\n", chan->lChannel));
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     /* Disable port interrupts */
     UniataAhciWriteChannelPort4(chan, IDX_AHCI_P_IE, 0);
@@ -2390,16 +2390,16 @@
 	     );
     UniataAhciReadChannelPort4(chan, IDX_AHCI_P_CMD); /* flush */
 
-#ifdef DBG
+#ifdef _DEBUG
     //UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     UniataAhciStartFR(chan);
     UniataAhciStart(chan);
 
-#ifdef DBG
+#ifdef _DEBUG
     UniataDumpAhciPortRegs(chan);
-#endif // DBG
+#endif // _DEBUG
 
     return;
 } // end UniataAhciResume()
@@ -2575,9 +2575,9 @@
         PUCHAR prd_base0;
         ULONGLONG prd_base64_0;
     };
-#ifdef DBG
+#ifdef _DEBUG
     ULONG d;
-#endif // DBG
+#endif // _DEBUG
 
     prd_base64_0 = prd_base64 = 0;
     prd_base = (PUCHAR)(&AtaReq->ahci_cmd0);
@@ -2585,10 +2585,10 @@
 
     prd_base64 = (prd_base64 + max(FIELD_OFFSET(ATA_REQ, ahci_cmd0), AHCI_CMD_ALIGNEMENT_MASK+1)) & ~AHCI_CMD_ALIGNEMENT_MASK;
 
-#ifdef DBG
+#ifdef _DEBUG
     d = (ULONG)(prd_base64 - prd_base64_0);
     KdPrint2((PRINT_PREFIX "  AtaReq %#x: cmd aligned %I64x, d=%x\n", AtaReq, prd_base64, d));
-#endif // DBG
+#endif // _DEBUG
 
     AtaReq->ahci.ahci_cmd_ptr = (PIDE_AHCI_CMD)prd_base64;
     KdPrint2((PRINT_PREFIX "  ahci_cmd_ptr %#x\n", AtaReq->ahci.ahci_cmd_ptr));
diff -ruN v45j5\driver\id_sata.h v46a1\driver\id_sata.h
--- v45j5\driver\id_sata.h	Wed Sep 23 18:18:02 2015
+++ v46a1\driver\id_sata.h	Wed Mar 09 12:47:16 2016
@@ -414,7 +414,7 @@
     IN ULONG c
     )
 {
-#ifdef DBG
+#ifdef _DEBUG
     KdPrint2((PRINT_PREFIX "imp: %#x & %#x\n", (deviceExtension)->AHCI_PI, (1<<c) ));
 #endif
     return (((deviceExtension)->AHCI_PI) & ((ULONG)1 << c)) ? TRUE : FALSE;
diff -ruN v45j5\driver\uniata_ver.h v46a1\driver\uniata_ver.h
--- v45j5\driver\uniata_ver.h	Sun Jan 24 15:05:08 2016
+++ v46a1\driver\uniata_ver.h	Wed Mar 09 19:18:50 2016
@@ -1,10 +1,10 @@
-#define UNIATA_VER_STR         "45j5"
-#define UNIATA_VER_DOT         0.45.10.5
+#define UNIATA_VER_STR         "46a1"
+#define UNIATA_VER_DOT         0.46.1.1
 #define UNIATA_VER_MJ          0
-#define UNIATA_VER_MN          45
-#define UNIATA_VER_SUB_MJ      10
-#define UNIATA_VER_SUB_MN      5
-#define UNIATA_VER_DOT_COMMA   0,45,10,5
-#define UNIATA_VER_DOT_STR     "0.45.10.5"
+#define UNIATA_VER_MN          46
+#define UNIATA_VER_SUB_MJ      1
+#define UNIATA_VER_SUB_MN      1
+#define UNIATA_VER_DOT_COMMA   0,46,1,1
+#define UNIATA_VER_DOT_STR     "0.46.1.1"
 #define UNIATA_VER_YEAR        2016
 #define UNIATA_VER_YEAR_STR    "2016"
