Index: /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp	(revision 56425)
+++ /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp	(revision 56426)
@@ -3219,17 +3219,6 @@
     SSMR3PutBool  (pSSM, pBusLogic->fStrictRoundRobinMode);
     SSMR3PutBool  (pSSM, pBusLogic->fExtendedLunCCBFormat);
-    /* Now the data for the BIOS interface. */
-    SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.regIdentify);
-    SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.uTargetDevice);
-    SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.uTxDir);
-    SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.cbCDB);
-    SSMR3PutMem   (pSSM, pBusLogic->VBoxSCSI.abCDB, sizeof(pBusLogic->VBoxSCSI.abCDB));
-    SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.iCDB);
-    SSMR3PutU32   (pSSM, pBusLogic->VBoxSCSI.cbBuf);
-    SSMR3PutU32   (pSSM, pBusLogic->VBoxSCSI.iBuf);
-    SSMR3PutBool  (pSSM, pBusLogic->VBoxSCSI.fBusy);
-    SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.enmState);
-    if (pBusLogic->VBoxSCSI.cbBuf)
-        SSMR3PutMem(pSSM, pBusLogic->VBoxSCSI.pbBuf, pBusLogic->VBoxSCSI.cbBuf);
+
+    vboxscsiR3SaveExec(&pBusLogic->VBoxSCSI, pSSM);
 
     /*
@@ -3332,25 +3321,11 @@
     SSMR3GetBool  (pSSM, &pBusLogic->fStrictRoundRobinMode);
     SSMR3GetBool  (pSSM, &pBusLogic->fExtendedLunCCBFormat);
-    /* Now the data for the BIOS interface. */
-    SSMR3GetU8  (pSSM, &pBusLogic->VBoxSCSI.regIdentify);
-    SSMR3GetU8  (pSSM, &pBusLogic->VBoxSCSI.uTargetDevice);
-    SSMR3GetU8  (pSSM, &pBusLogic->VBoxSCSI.uTxDir);
-    SSMR3GetU8  (pSSM, &pBusLogic->VBoxSCSI.cbCDB);
-    SSMR3GetMem (pSSM, pBusLogic->VBoxSCSI.abCDB, sizeof(pBusLogic->VBoxSCSI.abCDB));
-    SSMR3GetU8  (pSSM, &pBusLogic->VBoxSCSI.iCDB);
-    SSMR3GetU32 (pSSM, &pBusLogic->VBoxSCSI.cbBuf);
-    SSMR3GetU32 (pSSM, &pBusLogic->VBoxSCSI.iBuf);
-    SSMR3GetBool(pSSM, (bool *)&pBusLogic->VBoxSCSI.fBusy);
-    SSMR3GetU8  (pSSM, (uint8_t *)&pBusLogic->VBoxSCSI.enmState);
-    if (pBusLogic->VBoxSCSI.cbBuf)
-    {
-        pBusLogic->VBoxSCSI.pbBuf = (uint8_t *)RTMemAllocZ(pBusLogic->VBoxSCSI.cbBuf);
-        if (!pBusLogic->VBoxSCSI.pbBuf)
-        {
-            LogRel(("BusLogic: Out of memory during restore.\n"));
-            return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY,
-                                    N_("BusLogic: Out of memory during restore\n"));
-        }
-        SSMR3GetMem(pSSM, pBusLogic->VBoxSCSI.pbBuf, pBusLogic->VBoxSCSI.cbBuf);
+
+    rc = vboxscsiR3LoadExec(&pBusLogic->VBoxSCSI, pSSM);
+    if (RT_FAILURE(rc))
+    {
+        LogRel(("BusLogic: Failed to restore BIOS state: %Rrc.\n", rc));
+        return PDMDEV_SET_ERROR(pDevIns, rc,
+                                N_("BusLogic: Failed to restore BIOS state\n"));
     }
 
Index: /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 56425)
+++ /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 56426)
@@ -4490,18 +4490,5 @@
         AssertMsgFailed(("Invalid controller type %d\n", pThis->enmCtrlType));
 
-    /* Now the data for the BIOS interface. */
-    SSMR3PutU8    (pSSM, pThis->VBoxSCSI.regIdentify);
-    SSMR3PutU8    (pSSM, pThis->VBoxSCSI.uTargetDevice);
-    SSMR3PutU8    (pSSM, pThis->VBoxSCSI.uTxDir);
-    SSMR3PutU8    (pSSM, pThis->VBoxSCSI.cbCDB);
-    SSMR3PutMem   (pSSM, pThis->VBoxSCSI.abCDB, sizeof(pThis->VBoxSCSI.abCDB));
-    SSMR3PutU8    (pSSM, pThis->VBoxSCSI.iCDB);
-    SSMR3PutU32   (pSSM, pThis->VBoxSCSI.cbBuf);
-    SSMR3PutU32   (pSSM, pThis->VBoxSCSI.iBuf);
-    SSMR3PutBool  (pSSM, pThis->VBoxSCSI.fBusy);
-    SSMR3PutU8    (pSSM, pThis->VBoxSCSI.enmState);
-    if (pThis->VBoxSCSI.cbBuf)
-        SSMR3PutMem(pSSM, pThis->VBoxSCSI.pbBuf, pThis->VBoxSCSI.cbBuf);
-
+    vboxscsiR3SaveExec(&pThis->VBoxSCSI, pSSM);
     return SSMR3PutU32(pSSM, ~0);
 }
@@ -4833,25 +4820,10 @@
     }
 
-    /* Now the data for the BIOS interface. */
-    SSMR3GetU8  (pSSM, &pThis->VBoxSCSI.regIdentify);
-    SSMR3GetU8  (pSSM, &pThis->VBoxSCSI.uTargetDevice);
-    SSMR3GetU8  (pSSM, &pThis->VBoxSCSI.uTxDir);
-    SSMR3GetU8  (pSSM, &pThis->VBoxSCSI.cbCDB);
-    SSMR3GetMem (pSSM, pThis->VBoxSCSI.abCDB, sizeof(pThis->VBoxSCSI.abCDB));
-    SSMR3GetU8  (pSSM, &pThis->VBoxSCSI.iCDB);
-    SSMR3GetU32 (pSSM, &pThis->VBoxSCSI.cbBuf);
-    SSMR3GetU32 (pSSM, &pThis->VBoxSCSI.iBuf);
-    SSMR3GetBool(pSSM, (bool *)&pThis->VBoxSCSI.fBusy);
-    SSMR3GetU8  (pSSM, (uint8_t *)&pThis->VBoxSCSI.enmState);
-    if (pThis->VBoxSCSI.cbBuf)
-    {
-        pThis->VBoxSCSI.pbBuf = (uint8_t *)RTMemAllocZ(pThis->VBoxSCSI.cbBuf);
-        if (!pThis->VBoxSCSI.pbBuf)
-        {
-            LogRel(("LsiLogic: Out of memory during restore.\n"));
-            return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY,
-                                    N_("LsiLogic: Out of memory during restore\n"));
-        }
-        SSMR3GetMem(pSSM, pThis->VBoxSCSI.pbBuf, pThis->VBoxSCSI.cbBuf);
+    rc = vboxscsiR3LoadExec(&pThis->VBoxSCSI, pSSM);
+    if (RT_FAILURE(rc))
+    {
+        LogRel(("LsiLogic: Failed to restore BIOS state: %Rrc.\n", rc));
+        return PDMDEV_SET_ERROR(pDevIns, rc,
+                                N_("LsiLogic: Failed to restore BIOS state\n"));
     }
 
Index: /trunk/src/VBox/Devices/Storage/VBoxSCSI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/VBoxSCSI.cpp	(revision 56425)
+++ /trunk/src/VBox/Devices/Storage/VBoxSCSI.cpp	(revision 56426)
@@ -105,5 +105,5 @@
             /* If we're not in the 'command ready' state, there may not even be a buffer yet. */
             if (   pVBoxSCSI->enmState == VBOXSCSISTATE_COMMAND_READY
-                && pVBoxSCSI->cbBuf > 0)
+                && pVBoxSCSI->cbBufLeft > 0)
             {
                 AssertMsg(pVBoxSCSI->pbBuf, ("pBuf is NULL\n"));
@@ -111,9 +111,9 @@
                 uVal = pVBoxSCSI->pbBuf[pVBoxSCSI->iBuf];
                 pVBoxSCSI->iBuf++;
-                pVBoxSCSI->cbBuf--;
+                pVBoxSCSI->cbBufLeft--;
 
                 /* When the guest reads the last byte from the data in buffer, clear
                    everything and reset command buffer. */
-                if (pVBoxSCSI->cbBuf == 0)
+                if (pVBoxSCSI->cbBufLeft == 0)
                     vboxscsiReset(pVBoxSCSI, false /*fEverything*/);
             }
@@ -203,4 +203,5 @@
                     Log(("%s: Command ready for processing\n", __FUNCTION__));
                     pVBoxSCSI->enmState = VBOXSCSISTATE_COMMAND_READY;
+                    pVBoxSCSI->cbBufLeft = pVBoxSCSI->cbBuf;
                     if (pVBoxSCSI->uTxDir == VBOXSCSI_TXDIR_TO_DEVICE)
                     {
@@ -231,9 +232,9 @@
                 vboxscsiReset(pVBoxSCSI, true /*fEverything*/);
             }
-            else if (pVBoxSCSI->cbBuf > 0)
+            else if (pVBoxSCSI->cbBufLeft > 0)
             {
                 pVBoxSCSI->pbBuf[pVBoxSCSI->iBuf++] = uVal;
-                pVBoxSCSI->cbBuf--;
-                if (pVBoxSCSI->cbBuf == 0)
+                pVBoxSCSI->cbBufLeft--;
+                if (pVBoxSCSI->cbBufLeft == 0)
                 {
                     rc = VERR_MORE_DATA;
@@ -367,5 +368,5 @@
     int rc = VINF_SUCCESS;
     uint32_t cbTransfer = *pcTransfers * cb;
-    if (pVBoxSCSI->cbBuf > 0) /* Think cbBufLeft, not cbBuf! */
+    if (pVBoxSCSI->cbBufLeft > 0)
     {
         Assert(cbTransfer <= pVBoxSCSI->cbBuf);
@@ -380,10 +381,10 @@
 
         /* Advance current buffer position. */
-        pVBoxSCSI->iBuf  += cbTransfer;
-        pVBoxSCSI->cbBuf -= cbTransfer;
+        pVBoxSCSI->iBuf      += cbTransfer;
+        pVBoxSCSI->cbBufLeft -= cbTransfer;
 
         /* When the guest reads the last byte from the data in buffer, clear
            everything and reset command buffer. */
-        if (pVBoxSCSI->cbBuf == 0)
+        if (pVBoxSCSI->cbBufLeft == 0)
             vboxscsiReset(pVBoxSCSI, false /*fEverything*/);
     }
@@ -419,20 +420,15 @@
      */
     int rc = VINF_SUCCESS;
-    if (pVBoxSCSI->cbBuf > 0) /* Think cbBufLeft, not cbBuf! */
-    {
-        uint32_t cbTransfer = *pcTransfers * cb;
-        if (cbTransfer > pVBoxSCSI->cbBuf) /* Think cbBufLeft, not cbBuf! */
-        {
-            /** @todo the non-string version of the code would cause a reset here. */
-            cbTransfer = pVBoxSCSI->cbBuf;
-        }
+    if (pVBoxSCSI->cbBufLeft > 0)
+    {
+        uint32_t cbTransfer = RT_MIN(*pcTransfers * cb, pVBoxSCSI->cbBufLeft);
 
         /* Copy the data and adance the buffer position. */
         memcpy(pVBoxSCSI->pbBuf + pVBoxSCSI->iBuf, pbSrc, cbTransfer);
-        pVBoxSCSI->iBuf  += cbTransfer;
-        pVBoxSCSI->cbBuf -= cbTransfer;
+        pVBoxSCSI->iBuf      += cbTransfer;
+        pVBoxSCSI->cbBufLeft -= cbTransfer;
 
         /* If we've reached the end, tell the caller to submit the command. */
-        if (pVBoxSCSI->cbBuf == 0)
+        if (pVBoxSCSI->cbBufLeft == 0)
         {
             ASMAtomicXchgBool(&pVBoxSCSI->fBusy, true);
@@ -459,2 +455,60 @@
     }
 }
+
+DECLHIDDEN(int) vboxscsiR3LoadExec(PVBOXSCSI pVBoxSCSI, PSSMHANDLE pSSM)
+{
+    SSMR3GetU8  (pSSM, &pVBoxSCSI->regIdentify);
+    SSMR3GetU8  (pSSM, &pVBoxSCSI->uTargetDevice);
+    SSMR3GetU8  (pSSM, &pVBoxSCSI->uTxDir);
+    SSMR3GetU8  (pSSM, &pVBoxSCSI->cbCDB);
+    SSMR3GetMem (pSSM, &pVBoxSCSI->abCDB[0], sizeof(pVBoxSCSI->abCDB));
+    SSMR3GetU8  (pSSM, &pVBoxSCSI->iCDB);
+    SSMR3GetU32 (pSSM, &pVBoxSCSI->cbBufLeft);
+    SSMR3GetU32 (pSSM, &pVBoxSCSI->iBuf);
+    SSMR3GetBool(pSSM, (bool *)&pVBoxSCSI->fBusy);
+    SSMR3GetU8  (pSSM, (uint8_t *)&pVBoxSCSI->enmState);
+
+    /*
+     * Old saved states only save the size of the buffer left to read/write.
+     * To avoid changing the saved state version we can just calculate the original
+     * buffer size from the offset and remaining size.
+     */
+    pVBoxSCSI->cbBuf = pVBoxSCSI->cbBufLeft + pVBoxSCSI->iBuf;
+
+    if (pVBoxSCSI->cbBuf)
+    {
+        pVBoxSCSI->pbBuf = (uint8_t *)RTMemAllocZ(pVBoxSCSI->cbBuf);
+        if (!pVBoxSCSI->pbBuf)
+            return VERR_NO_MEMORY;
+
+        SSMR3GetMem(pSSM, pVBoxSCSI->pbBuf, pVBoxSCSI->cbBuf);
+    }
+
+    return VINF_SUCCESS;
+}
+
+DECLHIDDEN(int) vboxscsiR3SaveExec(PVBOXSCSI pVBoxSCSI, PSSMHANDLE pSSM)
+{
+    SSMR3PutU8    (pSSM, pVBoxSCSI->regIdentify);
+    SSMR3PutU8    (pSSM, pVBoxSCSI->uTargetDevice);
+    SSMR3PutU8    (pSSM, pVBoxSCSI->uTxDir);
+    SSMR3PutU8    (pSSM, pVBoxSCSI->cbCDB);
+    SSMR3PutMem   (pSSM, pVBoxSCSI->abCDB, sizeof(pVBoxSCSI->abCDB));
+    SSMR3PutU8    (pSSM, pVBoxSCSI->iCDB);
+    SSMR3PutU32   (pSSM, pVBoxSCSI->cbBufLeft);
+    SSMR3PutU32   (pSSM, pVBoxSCSI->iBuf);
+    SSMR3PutBool  (pSSM, pVBoxSCSI->fBusy);
+    SSMR3PutU8    (pSSM, pVBoxSCSI->enmState);
+
+    /*
+     * Old saved states only save the size of the buffer left to read/write.
+     * To avoid changing the saved state version we can just calculate the original
+     * buffer size from the offset and remaining size.
+     */
+    pVBoxSCSI->cbBuf = pVBoxSCSI->cbBufLeft + pVBoxSCSI->iBuf;
+
+    if (pVBoxSCSI->cbBuf)
+        SSMR3PutMem(pSSM, pVBoxSCSI->pbBuf, pVBoxSCSI->cbBuf);
+
+    return VINF_SUCCESS;
+}
Index: /trunk/src/VBox/Devices/Storage/VBoxSCSI.h
===================================================================
--- /trunk/src/VBox/Devices/Storage/VBoxSCSI.h	(revision 56425)
+++ /trunk/src/VBox/Devices/Storage/VBoxSCSI.h	(revision 56426)
@@ -111,11 +111,10 @@
     /** Pointer to the buffer holding the data. */
     R3PTRTYPE(uint8_t *) pbBuf;
-    /** Size of the buffer in bytes.
-     *
-     * @todo r=bird: Misleading docs and member name.  This is actually not the
-     *               buffer size, it's the number of bytes left to read/write in the
-     *               buffer.  It is decremented when the guest (BIOS) accesses
-     *               the buffer data. */
+    /** Size of the buffer in bytes. */
     uint32_t             cbBuf;
+    /** The number of bytes left to read/write in the
+     *  buffer.  It is decremented when the guest (BIOS) accesses
+     *  the buffer data. */
+    uint32_t             cbBufLeft;
     /** Current position in the buffer (offBuf if you like). */
     uint32_t             iBuf;
@@ -146,4 +145,7 @@
 int vboxscsiReadString(PPDMDEVINS pDevIns, PVBOXSCSI pVBoxSCSI, uint8_t iRegister,
                        uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb);
+
+DECLHIDDEN(int) vboxscsiR3LoadExec(PVBOXSCSI pVBoxSCSI, PSSMHANDLE pSSM);
+DECLHIDDEN(int) vboxscsiR3SaveExec(PVBOXSCSI pVBoxSCSI, PSSMHANDLE pSSM);
 RT_C_DECLS_END
 #endif /* IN_RING3 */
