Index: trunk/src/VBox/Devices/Storage/DevATA.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 81858)
+++ trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 81859)
@@ -676,6 +676,6 @@
 
 # ifdef IN_RING3
-typedef void (*PBeginTransferFunc)(ATADevState *);
-typedef bool (*PSourceSinkFunc)(ATADevState *);
+typedef void (*PFNBEGINTRANSFER)(ATADevState *);
+typedef bool (*PFNSOURCESINK)(ATADevState *);
 
 static void ataR3ReadWriteSectorsBT(ATADevState *);
@@ -730,5 +730,5 @@
  * Make sure ATAFNET and this array match!
  */
-static const PBeginTransferFunc g_apfnBeginTransFuncs[ATAFN_BT_MAX] =
+static const PFNBEGINTRANSFER g_apfnBeginTransFuncs[ATAFN_BT_MAX] =
 {
     NULL,
@@ -780,5 +780,5 @@
  * Make sure ATAFNSS and this array match!
  */
-static const PSourceSinkFunc g_apfnSourceSinkFuncs[ATAFN_SS_MAX] =
+static const PFNSOURCESINK g_apfnSourceSinkFuncs[ATAFN_SS_MAX] =
 {
     NULL,
@@ -4823,5 +4823,7 @@
          * very similarly by not continuing with the current instruction
          * until the transfer to/from the storage medium is completed. */
-        if (s->iSourceSink != ATAFN_SS_NULL)
+        uint8_t const iSourceSink = s->iSourceSink;
+        if (   iSourceSink != ATAFN_SS_NULL
+            && iSourceSink < RT_ELEMENTS(g_apfnSourceSinkFuncs))
         {
             bool fRedo;
@@ -4829,5 +4831,5 @@
             ataSetStatusValue(s, ATA_STAT_BUSY);
             Log2(("%s: calling source/sink function\n", __FUNCTION__));
-            fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
+            fRedo = g_apfnSourceSinkFuncs[iSourceSink](s);
             pCtl->fRedo = fRedo;
             if (RT_UNLIKELY(fRedo))
@@ -4837,4 +4839,6 @@
             s->iIOBufferEnd = s->cbElementaryTransfer;
         }
+        else
+            Assert(iSourceSink == ATAFN_SS_NULL);
 # else
         AssertReleaseFailed();
@@ -5441,5 +5445,7 @@
                  * the guest can continue in parallel). If so, the state
                  * is already set up so the loop is exited immediately. */
-                if (s->iSourceSink != ATAFN_SS_NULL)
+                uint8_t const iSourceSink = s->iSourceSink;
+                if (   iSourceSink != ATAFN_SS_NULL
+                    && iSourceSink < RT_ELEMENTS(g_apfnSourceSinkFuncs))
                 {
                     s->iIOBufferCur = iIOBufferCur;
@@ -5448,5 +5454,5 @@
                     s->cbTotalTransfer = cbTotalTransfer;
                     Log2(("%s: calling source/sink function\n", __FUNCTION__));
-                    fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
+                    fRedo = g_apfnSourceSinkFuncs[iSourceSink](s);
                     if (RT_UNLIKELY(fRedo))
                     {
@@ -5471,4 +5477,5 @@
                 {
                     /* This forces the loop to exit immediately. */
+                    Assert(iSourceSink == ATAFN_SS_NULL);
                     GCPhysDesc = pCtl->GCPhysLastDMADesc + 1;
                 }
@@ -5636,5 +5643,5 @@
         {
             case ATA_AIO_NEW:
-
+            {
                 pCtl->iAIOIf = pReq->u.t.iIf;
                 s = &pCtl->aIfs[pCtl->iAIOIf & ATA_SELECTED_IF_MASK];
@@ -5668,8 +5675,10 @@
                 pCtl->fChainedTransfer = false;
 
-                if (s->iBeginTransfer != ATAFN_BT_NULL)
+                uint8_t const iBeginTransfer = s->iBeginTransfer;
+                if (   iBeginTransfer != ATAFN_BT_NULL
+                    && iBeginTransfer < RT_ELEMENTS(g_apfnBeginTransFuncs))
                 {
                     Log2(("%s: Ctl#%d: calling begin transfer function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
-                    g_apfnBeginTransFuncs[s->iBeginTransfer](s);
+                    g_apfnBeginTransFuncs[iBeginTransfer](s);
                     s->iBeginTransfer = ATAFN_BT_NULL;
                     if (s->uTxDir != PDMMEDIATXDIR_FROM_DEVICE)
@@ -5678,4 +5687,5 @@
                 else
                 {
+                    Assert(iBeginTransfer == ATAFN_BT_NULL);
                     s->cbElementaryTransfer = s->cbTotalTransfer;
                     s->iIOBufferEnd = s->cbTotalTransfer;
@@ -5685,9 +5695,11 @@
                 if (s->uTxDir != PDMMEDIATXDIR_TO_DEVICE)
                 {
-                    if (s->iSourceSink != ATAFN_SS_NULL)
+                    uint8_t const iSourceSink = s->iSourceSink;
+                    if (   iSourceSink != ATAFN_SS_NULL
+                        && iSourceSink < RT_ELEMENTS(g_apfnSourceSinkFuncs))
                     {
                         bool fRedo;
                         Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
-                        fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
+                        fRedo = g_apfnSourceSinkFuncs[iSourceSink](s);
                         pCtl->fRedo = fRedo;
                         if (RT_UNLIKELY(fRedo && !pCtl->fReset))
@@ -5702,5 +5714,8 @@
                     }
                     else
+                    {
+                        Assert(iSourceSink == ATAFN_SS_NULL);
                         ataR3CmdOK(s, 0);
+                    }
                     s->iIOBufferEnd = s->cbElementaryTransfer;
 
@@ -5778,4 +5793,5 @@
                 }
                 break;
+            }
 
             case ATA_AIO_DMA:
@@ -5836,11 +5852,14 @@
 
             case ATA_AIO_PIO:
+            {
                 s = &pCtl->aIfs[pCtl->iAIOIf & ATA_SELECTED_IF_MASK]; /* Do not remove or there's an instant crash after loading the saved state */
 
-                if (s->iSourceSink != ATAFN_SS_NULL)
+                uint8_t const iSourceSink = s->iSourceSink;
+                if (   iSourceSink != ATAFN_SS_NULL
+                    && iSourceSink < RT_ELEMENTS(g_apfnSourceSinkFuncs))
                 {
                     bool fRedo;
                     Log2(("%s: Ctl#%d: calling source/sink function\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
-                    fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
+                    fRedo = g_apfnSourceSinkFuncs[iSourceSink](s);
                     pCtl->fRedo = fRedo;
                     if (RT_UNLIKELY(fRedo && !pCtl->fReset))
@@ -5856,4 +5875,5 @@
                 {
                     /* Continue a previously started transfer. */
+                    Assert(iSourceSink == ATAFN_SS_NULL);
                     ataUnsetStatus(s, ATA_STAT_BUSY);
                     ataSetStatus(s, ATA_STAT_READY);
@@ -5905,4 +5925,5 @@
                 }
                 break;
+            }
 
             case ATA_AIO_RESET_ASSERTED:
