Index: trunk/src/VBox/Devices/PC/BIOS/buslogic.c
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/buslogic.c	(revision 89210)
+++ trunk/src/VBox/Devices/PC/BIOS/buslogic.c	(revision 89211)
@@ -32,6 +32,8 @@
 #endif
 
-#define BUSLOGICCOMMAND_EXECUTE_MAILBOX_COMMAND     0x02
-#define BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX 0x81
+#define BUSLOGICCOMMAND_EXECUTE_MAILBOX_COMMAND        0x02
+#define BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX    0x81
+#define BUSLOGICCOMMAND_DISABLE_HOST_ADAPTER_INTERRUPT 0x25
+
 
 #define RT_BIT(bit) (1 << (bit))
@@ -275,4 +277,6 @@
     /** I/O base of device. */
     uint16_t         u16IoBase;
+    /** The sink buf. */
+    void __far       *pvSinkBuf;
 } buslogic_t;
 
@@ -355,6 +359,6 @@
 
 int buslogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
-                            uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
-                            uint16_t skip_b)
+                            uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
+                            uint16_t skip_a)
 {
     buslogic_t __far *buslogic = (buslogic_t __far *)pvHba;
@@ -379,5 +383,5 @@
     {
         buslogic->aSge[idxSge].cbSegment = skip_b;
-        buslogic->aSge[idxSge].u32PhysAddrSegmentBase = 0; /* See ahci.c:sink_buf_phys */
+        buslogic->aSge[idxSge].u32PhysAddrSegmentBase = buslogic_addr_to_phys(buslogic->pvSinkBuf);
         idxSge++;
     }
@@ -391,5 +395,5 @@
     {
         buslogic->aSge[idxSge].cbSegment = skip_a;
-        buslogic->aSge[idxSge].u32PhysAddrSegmentBase = 0; /* See ahci.c:sink_buf_phys */
+        buslogic->aSge[idxSge].u32PhysAddrSegmentBase = buslogic_addr_to_phys(buslogic->pvSinkBuf);
         idxSge++;
     }
@@ -420,4 +424,6 @@
 static int buslogic_scsi_hba_init(buslogic_t __far *buslogic)
 {
+    int rc;
+    uint8_t bIrqOff = 0;
     ReqInitExtMbx       ReqInitMbx;
 
@@ -426,10 +432,19 @@
     while (!(inb(buslogic->u16IoBase + BUSLOGIC_REGISTER_STATUS) & BL_STAT_HARDY));
 
-    /* Initialize mailbox. */
-    ReqInitMbx.cMailbox = 1;
-    ReqInitMbx.uMailboxBaseAddress = buslogic_addr_to_phys(&buslogic->MbxOut32);
-    return buslogic_cmd(buslogic, BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX,
-                        (unsigned char __far *)&ReqInitMbx, sizeof(ReqInitMbx),
-                        NULL, 0);
+    /* Disable interrupts. */
+    rc = buslogic_cmd(buslogic, BUSLOGICCOMMAND_DISABLE_HOST_ADAPTER_INTERRUPT,
+                      (unsigned char __far *)&bIrqOff, sizeof(bIrqOff),
+                      NULL, 0);
+    if (!rc)
+    {
+        /* Initialize mailbox. */
+        ReqInitMbx.cMailbox = 1;
+        ReqInitMbx.uMailboxBaseAddress = buslogic_addr_to_phys(&buslogic->MbxOut32);
+        rc = buslogic_cmd(buslogic, BUSLOGICCOMMAND_INITIALIZE_EXTENDED_MAILBOX,
+                          (unsigned char __far *)&ReqInitMbx, sizeof(ReqInitMbx),
+                          NULL, 0);
+    }
+
+    return rc;
 }
 
@@ -437,5 +452,5 @@
  * Init the BusLogic SCSI driver and detect attached disks.
  */
-int buslogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn)
+int buslogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn)
 {
     buslogic_t __far *buslogic = (buslogic_t __far *)pvHba;
@@ -457,4 +472,5 @@
         DBG_BUSLOGIC("I/O base: 0x%x\n", u16IoBase);
         buslogic->u16IoBase = u16IoBase;
+        buslogic->pvSinkBuf = pvSinkBuf;
         return buslogic_scsi_hba_init(buslogic);
     }
Index: trunk/src/VBox/Devices/PC/BIOS/lsilogic.c
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/lsilogic.c	(revision 89210)
+++ trunk/src/VBox/Devices/PC/BIOS/lsilogic.c	(revision 89211)
@@ -289,6 +289,6 @@
     /** I/O base of device. */
     uint16_t           u16IoBase;
-    /** Saved high bits of EAX. */
-    uint16_t           saved_eax_hi;
+    /** The sink buf. */
+    void __far         *pvSinkBuf;
 } lsilogic_t;
 
@@ -426,6 +426,6 @@
 
 int lsilogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
-                              uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
-                              uint16_t skip_b)
+                              uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
+                              uint16_t skip_a)
 {
     lsilogic_t __far *lsilogic = (lsilogic_t __far *)pvHba;
@@ -459,5 +459,5 @@
         lsilogic->aSge[idxSge].fEndOfBuffer            = 0;
         lsilogic->aSge[idxSge].fLastElement            = 0;
-        lsilogic->aSge[idxSge].u32DataBufferAddressLow = 0; /* See ahci.c:sink_buf_phys */
+        lsilogic->aSge[idxSge].u32DataBufferAddressLow = lsilogic_addr_to_phys(lsilogic->pvSinkBuf);
 
         idxSge++;
@@ -479,5 +479,5 @@
     if (skip_a)
     {
-        lsilogic->aSge[idxSge].u24Length               = length;
+        lsilogic->aSge[idxSge].u24Length               = skip_a;
         lsilogic->aSge[idxSge].fEndOfList              = 1;
         lsilogic->aSge[idxSge].f64BitAddress           = 0;
@@ -487,5 +487,5 @@
         lsilogic->aSge[idxSge].fEndOfBuffer            = 1;
         lsilogic->aSge[idxSge].fLastElement            = 1;
-        lsilogic->aSge[idxSge].u32DataBufferAddressLow = 0; /* See ahci.c:sink_buf_phys */
+        lsilogic->aSge[idxSge].u32DataBufferAddressLow = lsilogic_addr_to_phys(lsilogic->pvSinkBuf);
         idxSge++;
     }
@@ -536,5 +536,5 @@
  * Init the LsiLogic SCSI driver and detect attached disks.
  */
-int lsilogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn)
+int lsilogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn)
 {
     lsilogic_t __far *lsilogic = (lsilogic_t __far *)pvHba;
@@ -556,4 +556,5 @@
         DBG_LSILOGIC("I/O base: 0x%x\n", u16IoBase);
         lsilogic->u16IoBase = u16IoBase;
+        lsilogic->pvSinkBuf = pvSinkBuf;
         return lsilogic_scsi_hba_init(lsilogic);
     }
Index: trunk/src/VBox/Devices/PC/BIOS/scsi.c
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/scsi.c	(revision 89210)
+++ trunk/src/VBox/Devices/PC/BIOS/scsi.c	(revision 89211)
@@ -35,5 +35,5 @@
 #define VBOX_SCSI_NO_HBA 0xffff
 
-typedef int (* scsi_hba_init)(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn);
+typedef int (* scsi_hba_init)(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn);
 typedef int (* scsi_hba_cmd_data_out)(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
                                       uint8_t cbCDB, uint8_t __far *buffer, uint32_t length);
@@ -112,4 +112,27 @@
 
     return hba_seg;
+}
+
+/**
+ * Allocates 1K of conventional memory.
+ */
+static uint16_t scsi_sink_buf_alloc(void)
+{
+    uint16_t    base_mem_kb;
+    uint16_t    sink_seg;
+
+    base_mem_kb = read_word(0x00, 0x0413);
+
+    DBG_SCSI("SCSI: %dK of base mem\n", base_mem_kb);
+
+    if (base_mem_kb == 0)
+        return 0;
+
+    base_mem_kb -= 2; /* Allocate 2K block. */
+    sink_seg = (((uint32_t)base_mem_kb * 1024) >> 4); /* Calculate start segment. */
+
+    write_word(0x00, 0x0413, base_mem_kb);
+
+    return sink_seg;
 }
 
@@ -521,4 +544,5 @@
 {
     int i;
+    uint16_t sink_seg = 0;
     bio_dsk_t __far     *bios_dsk;
 
@@ -538,9 +562,16 @@
                 break;
 
+            if (!sink_seg) /* Allocate a sink buffer for throwing away data when accessing CD/DVD drives. */
+            {
+                sink_seg = scsi_sink_buf_alloc();
+                if (!sink_seg)
+                    break;
+            }
+
             u8Bus = (busdevfn & 0xff00) >> 8;
             u8DevFn = busdevfn & 0x00ff;
 
             DBG_SCSI("SCSI HBA at Bus %u DevFn 0x%x (raw 0x%x)\n", u8Bus, u8DevFn, busdevfn);
-            rc = hbaacc[i].init(hba_seg :> 0, u8Bus, u8DevFn);
+            rc = hbaacc[i].init(hba_seg :> 0, sink_seg :> 0, u8Bus, u8DevFn);
             if (!rc)
                 scsi_enumerate_attached_devices(hba_seg, i);
Index: trunk/src/VBox/Devices/PC/BIOS/scsi.h
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/scsi.h	(revision 89210)
+++ trunk/src/VBox/Devices/PC/BIOS/scsi.h	(revision 89211)
@@ -57,24 +57,24 @@
 ct_assert(sizeof(cdb_rw16) == 16);
 
-extern int lsilogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn);
+extern int lsilogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn);
 extern int lsilogic_scsi_cmd_data_out(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
                                       uint8_t cbCDB, uint8_t __far *buffer, uint32_t length);
 extern int lsilogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
-                                     uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
-                                     uint16_t skip_b);
+                                     uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
+                                     uint16_t skip_a);
 
-extern int buslogic_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn);
+extern int buslogic_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn);
 extern int buslogic_scsi_cmd_data_out(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
                                       uint8_t cbCDB, uint8_t __far *buffer, uint32_t length);
 extern int buslogic_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
-                                     uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
-                                     uint16_t skip_b);
+                                     uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
+                                     uint16_t skip_a);
 
-extern int virtio_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn);
+extern int virtio_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn);
 extern int virtio_scsi_cmd_data_out(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
                                     uint8_t cbCDB, uint8_t __far *buffer, uint32_t length);
 extern int virtio_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
-                                   uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
-                                   uint16_t skip_b);
+                                   uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
+                                   uint16_t skip_a);
 
 #endif /* !VBOX_INCLUDED_SRC_PC_BIOS_scsi_h */
Index: trunk/src/VBox/Devices/PC/BIOS/virtio.c
===================================================================
--- trunk/src/VBox/Devices/PC/BIOS/virtio.c	(revision 89210)
+++ trunk/src/VBox/Devices/PC/BIOS/virtio.c	(revision 89211)
@@ -209,6 +209,6 @@
     /** Device/Function number. */
     uint8_t          u8DevFn;
-    /** Saved high bits of EAX. */
-    uint16_t         saved_eax_hi;
+    /** The sink buf. */
+    void __far       *pvSinkBuf;
     /** The current executed command structure. */
     virtio_scsi_req_hdr_t ScsiReqHdr;
@@ -435,6 +435,6 @@
 
 int virtio_scsi_cmd_data_in(void __far *pvHba, uint8_t idTgt, uint8_t __far *aCDB,
-                            uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_a,
-                            uint16_t skip_b)
+                            uint8_t cbCDB, uint8_t __far *buffer, uint32_t length, uint16_t skip_b,
+                            uint16_t skip_a)
 {
     virtio_t __far *virtio = (virtio_t __far *)pvHba;
@@ -470,5 +470,5 @@
     if (skip_b)
     {
-        virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow  = 0; /* See ahci.c:sink_buf_phys */
+        virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow  = virtio_addr_to_phys(virtio->pvSinkBuf);
         virtio->Queue.aDescTbl[idxDesc].GCPhysBufHigh = 0;
         virtio->Queue.aDescTbl[idxDesc].cbBuf         = skip_b;
@@ -491,5 +491,5 @@
         virtio->Queue.aDescTbl[idxDesc - 1].idxNext = idxDesc;
 
-        virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow  = 0; /* See ahci.c:sink_buf_phys */
+        virtio->Queue.aDescTbl[idxDesc].GCPhysBufLow  = virtio_addr_to_phys(virtio->pvSinkBuf);
         virtio->Queue.aDescTbl[idxDesc].GCPhysBufHigh = 0;
         virtio->Queue.aDescTbl[idxDesc].cbBuf         = skip_a;
@@ -662,5 +662,5 @@
  * Init the VirtIO SCSI driver and detect attached disks.
  */
-int virtio_scsi_init(void __far *pvHba, uint8_t u8Bus, uint8_t u8DevFn)
+int virtio_scsi_init(void __far *pvHba, void __far *pvSinkBuf, uint8_t u8Bus, uint8_t u8DevFn)
 {
     virtio_t __far *virtio = (virtio_t __far *)pvHba;
@@ -715,4 +715,5 @@
         pci_write_config_word(u8Bus, u8DevFn, 4, 0x7);
 
+        virtio->pvSinkBuf = pvSinkBuf;
         return virtio_scsi_hba_init(virtio, u8Bus, u8DevFn, u8PciCapOffVirtIo);
     }
