VirtualBox

Changeset 2876 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 25, 2007 2:45:47 PM (18 years ago)
Author:
vboxsync
Message:

Back out fixed fix again.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevATA.cpp

    r2875 r2876  
    36073607#ifdef IN_RING3
    36083608
    3609 static void ataPIOTransfer(PATACONTROLLER pCtl)
    3610 {
    3611     ATADevState *s;
    3612 
    3613     s = &pCtl->aIfs[pCtl->iAIOIf];
    3614     Log3(("%s: if=%p\n", __FUNCTION__, s));
    3615 
    3616     if (s->cbTotalTransfer && s->iIOBufferCur > s->iIOBufferEnd)
    3617     {
    3618         LogRel(("PIIX3 ATA: LUN#%d: %s data in the middle of a PIO transfer - VERY SLOW\n", s->iLUN, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "storing" : "loading"));
    3619         /* Any guest OS that triggers this case has a pathetic ATA driver.
    3620          * In a real system it would block the CPU via IORDY, here we do it
    3621          * very similarly by not continuing with the current instruction
    3622          * until the transfer to/from the storage medium is completed. */
    3623         if (s->iSourceSink != ATAFN_SS_NULL)
    3624         {
    3625             bool fRedo;
    3626             uint8_t status = s->uATARegStatus;
    3627             ataSetStatusValue(s, ATA_STAT_BUSY);
    3628             Log2(("%s: calling source/sink function\n", __FUNCTION__));
    3629             fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
    3630             pCtl->fRedo = fRedo;
    3631             if (RT_UNLIKELY(fRedo))
    3632                 return;
    3633             ataSetStatusValue(s, status);
    3634             s->iIOBufferCur = 0;
    3635             s->iIOBufferEnd = s->cbElementaryTransfer;
    3636         }
    3637     }
    3638     if (s->cbTotalTransfer)
    3639     {
    3640         if (s->fATAPITransfer)
    3641             ataPIOTransferLimitATAPI(s);
    3642 
    3643         if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
    3644             s->cbElementaryTransfer = s->cbTotalTransfer;
    3645 
    3646         Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
    3647              __FUNCTION__, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
    3648              s->cbTotalTransfer, s->cbElementaryTransfer,
    3649              s->iIOBufferCur, s->iIOBufferEnd));
    3650         ataPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);
    3651         s->cbTotalTransfer -= s->cbElementaryTransfer;
    3652         s->iIOBufferCur += s->cbElementaryTransfer;
    3653 
    3654         if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
    3655             s->cbElementaryTransfer = s->cbTotalTransfer;
    3656     }
    3657     else
    3658         ataPIOTransferStop(s);
    3659 }
    3660 
    3661 
    36623609DECLINLINE(void) ataPIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s)
    36633610{
     
    36703617    }
    36713618
    3672     if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
    3673     {
    3674         /* Need to continue the transfer in the async I/O thread. This is
    3675          * the case for write operations or generally for not yet finished
    3676          * transfers (some data might need to be read). */
    3677         ataUnsetStatus(s, ATA_STAT_READY | ATA_STAT_DRQ);
    3678         ataSetStatus(s, ATA_STAT_BUSY);
    3679 
    3680         Log2(("%s: Ctl#%d: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
    3681         ataAsyncIOPutRequest(pCtl, &ataPIORequest);
    3682     }
    3683     else
    3684     {
    3685         /* Everything finished, mark device as ready. */
    3686         ataUnsetStatus(s, ATA_STAT_DRQ);
    3687 
    3688         Log2(("%s: Ctl#%d: skipping message to async I/O thread, ending PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
    3689         ataPIOTransfer(pCtl);
    3690         Assert(!pCtl->fRedo);
    3691         if (!s->fATAPITransfer)
    3692             ataSetIRQ(s);
    3693     }
     3619    ataUnsetStatus(s, ATA_STAT_READY | ATA_STAT_DRQ);
     3620    ataSetStatus(s, ATA_STAT_BUSY);
     3621
     3622    Log2(("%s: Ctl#%d: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl)));
     3623    ataAsyncIOPutRequest(pCtl, &ataPIORequest);
    36943624}
    36953625
     
    39913921    s->iIOBufferCur = iIOBufferCur;
    39923922    s->iIOBufferEnd = iIOBufferEnd;
     3923}
     3924
     3925
     3926static void ataPIOTransfer(PATACONTROLLER pCtl)
     3927{
     3928    ATADevState *s;
     3929
     3930    s = &pCtl->aIfs[pCtl->iAIOIf];
     3931    Log3(("%s: if=%p\n", __FUNCTION__, s));
     3932
     3933    if (s->cbTotalTransfer && s->iIOBufferCur > s->iIOBufferEnd)
     3934    {
     3935        LogRel(("PIIX3 ATA: LUN#%d: %s data in the middle of a PIO transfer - VERY SLOW\n", s->iLUN, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "storing" : "loading"));
     3936        /* Any guest OS that triggers this case has a pathetic ATA driver.
     3937         * In a real system it would block the CPU via IORDY, here we do it
     3938         * very similarly by not continuing with the current instruction
     3939         * until the transfer to/from the storage medium is completed. */
     3940        if (s->iSourceSink != ATAFN_SS_NULL)
     3941        {
     3942            bool fRedo;
     3943            uint8_t status = s->uATARegStatus;
     3944            ataSetStatusValue(s, ATA_STAT_BUSY);
     3945            Log2(("%s: calling source/sink function\n", __FUNCTION__));
     3946            fRedo = g_apfnSourceSinkFuncs[s->iSourceSink](s);
     3947            pCtl->fRedo = fRedo;
     3948            if (RT_UNLIKELY(fRedo))
     3949                return;
     3950            ataSetStatusValue(s, status);
     3951            s->iIOBufferCur = 0;
     3952            s->iIOBufferEnd = s->cbElementaryTransfer;
     3953        }
     3954    }
     3955    if (s->cbTotalTransfer)
     3956    {
     3957        if (s->fATAPITransfer)
     3958            ataPIOTransferLimitATAPI(s);
     3959
     3960        if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
     3961            s->cbElementaryTransfer = s->cbTotalTransfer;
     3962
     3963        Log2(("%s: %s tx_size=%d elem_tx_size=%d index=%d end=%d\n",
     3964             __FUNCTION__, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "T2I" : "I2T",
     3965             s->cbTotalTransfer, s->cbElementaryTransfer,
     3966             s->iIOBufferCur, s->iIOBufferEnd));
     3967        ataPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);
     3968        s->cbTotalTransfer -= s->cbElementaryTransfer;
     3969        s->iIOBufferCur += s->cbElementaryTransfer;
     3970
     3971        if (s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer)
     3972            s->cbElementaryTransfer = s->cbTotalTransfer;
     3973    }
     3974    else
     3975        ataPIOTransferStop(s);
    39933976}
    39943977
     
    41854168                            ataSetIRQ(s);
    41864169
    4187                         if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
    4188                         {
    4189                             /* Write operations and not yet finished transfers
    4190                              * must be completed in the async I/O thread. */
    4191                             pCtl->uAsyncIOState = ATA_AIO_PIO;
    4192                         }
    4193                         else
    4194                         {
    4195                             /* Finished read operation can be handled inline
    4196                              * in the end of PIO transfer handling code. Linux
    4197                              * depends on this, as it waits only briefly for
    4198                              * devices to become ready after incoming data
    4199                              * transfer. Cannot find anything in the ATA spec
    4200                              * that backs this assumption, but as all kernels
    4201                              * are affected (though most of the time it does
    4202                              * not cause any harm) this must work. */
    4203                             pCtl->uAsyncIOState = ATA_AIO_NEW;
    4204                         }
     4170                        pCtl->uAsyncIOState = ATA_AIO_PIO;
    42054171                    }
    42064172                    else
     
    43134279                    ataSetIRQ(s);
    43144280
    4315                     if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL)
    4316                     {
    4317                         /* Write operations and not yet finished transfers
    4318                          * must be completed in the async I/O thread. */
    4319                         pCtl->uAsyncIOState = ATA_AIO_PIO;
    4320                     }
    4321                     else
    4322                     {
    4323                         /* Finished read operation can be handled inline
    4324                          * in the end of PIO transfer handling code. Linux
    4325                          * depends on this, as it waits only briefly for
    4326                          * devices to become ready after incoming data
    4327                          * transfer. Cannot find anything in the ATA spec
    4328                          * that backs this assumption, but as all kernels
    4329                          * are affected (though most of the time it does
    4330                          * not cause any harm) this must work. */
    4331                         pCtl->uAsyncIOState = ATA_AIO_NEW;
    4332                     }
     4281                    pCtl->uAsyncIOState = ATA_AIO_PIO;
    43334282                }
    43344283                else
     
    43364285                    /* Finish PIO transfer. */
    43374286                    ataPIOTransfer(pCtl);
    4338                     if (    !pCtl->fChainedTransfer
    4339                         &&  !s->fATAPITransfer
    4340                         &&  s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
     4287                    pCtl->uAsyncIOState = ATA_AIO_NEW;
     4288                    if (!pCtl->fChainedTransfer)
    43414289                    {
     4290                        if (!s->fATAPITransfer && s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE)
    43424291                            ataSetIRQ(s);
    43434292                    }
    4344                     pCtl->uAsyncIOState = ATA_AIO_NEW;
    43454293                }
    43464294                break;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette