VirtualBox

Ignore:
Timestamp:
Apr 15, 2010 7:31:27 PM (15 years ago)
Author:
vboxsync
Message:

AHCI: Use async I/O flush API

File:
1 edited

Legend:

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

    r28380 r28388  
    226226
    227227/**
     228 * Transfer type.
     229 */
     230typedef enum AHCITXDIR
     231{
     232    /** Invalid */
     233    AHCITXDIR_INVALID = 0,
     234    /** None */
     235    AHCITXDIR_NONE,
     236    /** Read */
     237    AHCITXDIR_READ,
     238    /** Write */
     239    AHCITXDIR_WRITE,
     240    /** Flush */
     241    AHCITXDIR_FLUSH
     242} AHCITXDIR;
     243
     244/**
    228245 * A task state.
    229246 */
     
    243260    RTGCPHYS                   GCPhysCmdHdrAddr;
    244261    /** Data direction. */
    245     uint8_t                    uTxDir;
     262    AHCITXDIR                  enmTxDir;
    246263    /** Start offset. */
    247264    uint64_t                   uOffset;
     
    26962713    pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK;
    26972714    pAhciPortTaskState->cmdFis[AHCI_CMDFIS_SECTN] = (pAhciPortTaskState->cmdFis[AHCI_CMDFIS_SECTN] & ~7)
    2698         | ((pAhciPortTaskState->uTxDir != PDMBLOCKTXDIR_TO_DEVICE) ? ATAPI_INT_REASON_IO : 0)
     2715        | ((pAhciPortTaskState->enmTxDir != AHCITXDIR_WRITE) ? ATAPI_INT_REASON_IO : 0)
    26992716        | (!pAhciPortTaskState->cbTransfer ? ATAPI_INT_REASON_CD : 0);
    27002717    pAhciPort->uATAPISenseKey = SCSI_SENSE_NONE;
     
    35463563                }
    35473564                atapiReadSectors(pAhciPort, pAhciPortTaskState, iATAPILBA, cSectors, 2048);
    3548                 iTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
     3565                iTxDir = AHCITXDIR_READ;
    35493566            }
    35503567            break;
     
    35953612                        /* normal read */
    35963613                        atapiReadSectors(pAhciPort, pAhciPortTaskState, iATAPILBA, cSectors, 2048);
    3597                         iTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
     3614                        iTxDir = AHCITXDIR_READ;
    35983615                        break;
    35993616                    case 0xf8:
    36003617                        /* read all data */
    36013618                        atapiReadSectors(pAhciPort, pAhciPortTaskState, iATAPILBA, cSectors, 2352);
    3602                         iTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
     3619                        iTxDir = AHCITXDIR_READ;
    36033620                        break;
    36043621                    default:
     
    42094226    pAhciPortTaskState->paSGEntries[0].u.temp.pvBuf = pAhciPortTaskState->pvBufferUnaligned;
    42104227
    4211     if (pAhciPortTaskState->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
     4228    if (pAhciPortTaskState->enmTxDir == AHCITXDIR_WRITE)
    42124229        ahciCopyFromSGListIntoBuffer(pDevIns, &pAhciPortTaskState->paSGEntries[0]);
    42134230
     
    42614278    if (pAhciPortTaskState->pfnPostProcess)
    42624279    {
    4263         ahciLog(("%s: Request with post processing.\n"));
     4280        ahciLog(("%s: Request with post processing.\n", __FUNCTION__));
    42644281
    42654282        ahciScatterGatherListGetTotalBufferSize(pAhciPort, pAhciPortTaskState);
     
    43794396                                 * segments into the temporary buffer.
    43804397                                 */
    4381                                 if (pAhciPortTaskState->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
     4398                                if (pAhciPortTaskState->enmTxDir == AHCITXDIR_WRITE)
    43824399                                    ahciCopyFromSGListIntoBuffer(pDevIns, pSGInfoCurr);
    43834400
     
    46254642         * segments into the temporary buffer.
    46264643         */
    4627         if (pAhciPortTaskState->uTxDir == PDMBLOCKTXDIR_TO_DEVICE)
     4644        if (pAhciPortTaskState->enmTxDir == AHCITXDIR_WRITE)
    46284645            ahciCopyFromSGListIntoBuffer(pDevIns, pSGInfoCurr);
    46294646    }
     
    46674684            PDMDevHlpPhysReleasePageMappingLock(pDevIns, &pSGInfoCurr->u.direct.PageLock);
    46684685        }
    4669         else if (pAhciPortTaskState->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
     4686        else if (pAhciPortTaskState->enmTxDir == AHCITXDIR_READ)
    46704687        {
    46714688            /* Copy the data into the guest segments now. */
     
    48484865                       &pAhciPortTaskState->cmdHdr, sizeof(CmdHdr));
    48494866
    4850     if (pAhciPortTaskState->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
     4867    if (pAhciPortTaskState->enmTxDir == AHCITXDIR_READ)
    48514868    {
    48524869        STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesRead, pAhciPortTaskState->cbTransfer);
    48534870        pAhciPort->Led.Actual.s.fReading = 0;
    48544871    }
    4855     else
     4872    else if (pAhciPortTaskState->enmTxDir == AHCITXDIR_WRITE)
    48564873    {
    48574874        STAM_REL_COUNTER_ADD(&pAhciPort->StatBytesWritten, pAhciPortTaskState->cbTransfer);
     
    49084925 * @param   pCmdHdr Pointer to the command header.
    49094926 */
    4910 static int ahciProcessCmd(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, uint8_t *pCmdFis)
    4911 {
    4912     int rc = PDMBLOCKTXDIR_NONE;
     4927static AHCITXDIR ahciProcessCmd(PAHCIPort pAhciPort, PAHCIPORTTASKSTATE pAhciPortTaskState, uint8_t *pCmdFis)
     4928{
     4929    AHCITXDIR rc = AHCITXDIR_NONE;
    49134930    bool fLBA48 = false;
    49144931    CmdHdr   *pCmdHdr = &pAhciPortTaskState->cmdHdr;
     
    49244941                if (pAhciPort->pDrvBlock && !pAhciPort->fATAPI)
    49254942                {
     4943                    int rc2;
    49264944                    uint16_t u16Temp[256];
    49274945
     
    49304948
    49314949                    /* Create scatter gather list. */
    4932                     rc = ahciScatterGatherListCreate(pAhciPort, pAhciPortTaskState, false);
    4933                     if (RT_FAILURE(rc))
    4934                         AssertMsgFailed(("Creating list failed rc=%Rrc\n", rc));
     4950                    rc2 = ahciScatterGatherListCreate(pAhciPort, pAhciPortTaskState, false);
     4951                    if (RT_FAILURE(rc2))
     4952                        AssertMsgFailed(("Creating list failed rc=%Rrc\n", rc2));
    49354953
    49364954                    /* Copy the buffer. */
     
    49384956
    49394957                    /* Destroy list. */
    4940                     rc = ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState);
    4941                     if (RT_FAILURE(rc))
    4942                         AssertMsgFailed(("Freeing list failed rc=%Rrc\n", rc));
     4958                    rc2 = ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState);
     4959                    if (RT_FAILURE(rc2))
     4960                        AssertMsgFailed(("Freeing list failed rc=%Rrc\n", rc2));
    49434961
    49444962                    pAhciPortTaskState->uATARegError = 0;
     
    49714989                    break;
    49724990                case 0x82: /* write cache disable */
    4973                     rc = pAhciPort->pDrvBlock->pfnFlush(pAhciPort->pDrvBlock);
    4974                     pAhciPortTaskState->uATARegError = 0;
    4975                     pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK;
     4991                    rc = AHCITXDIR_FLUSH;
    49764992                    break;
    49774993                case 0x03:
     
    50005016        case ATA_FLUSH_CACHE_EXT:
    50015017        case ATA_FLUSH_CACHE:
    5002             rc = pAhciPort->pDrvBlock->pfnFlush(pAhciPort->pDrvBlock);
    5003             pAhciPortTaskState->uATARegError = 0;
    5004             pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK;
     5018            rc = AHCITXDIR_FLUSH;
    50055019            break;
    50065020        case ATA_PACKET:
     
    50125026            else
    50135027            {
    5014                 rc = atapiParseCmdVirtualATAPI(pAhciPort, pAhciPortTaskState);
     5028                int rc2 = atapiParseCmdVirtualATAPI(pAhciPort, pAhciPortTaskState);
    50155029            }
    50165030            break;
     
    50675081            pAhciPortTaskState->cbTransfer = ahciGetNSectors(pCmdFis, fLBA48) * 512;
    50685082            pAhciPortTaskState->uOffset = ahciGetSector(pAhciPort, pCmdFis, fLBA48) * 512;
    5069             rc = PDMBLOCKTXDIR_FROM_DEVICE;
     5083            rc = AHCITXDIR_READ;
    50705084            break;
    50715085        }
     
    50765090            pAhciPortTaskState->cbTransfer = ahciGetNSectors(pCmdFis, fLBA48) * 512;
    50775091            pAhciPortTaskState->uOffset = ahciGetSector(pAhciPort, pCmdFis, fLBA48) * 512;
    5078             rc = PDMBLOCKTXDIR_TO_DEVICE;
     5092            rc = AHCITXDIR_WRITE;
    50795093            break;
    50805094        }
     
    50835097            pAhciPortTaskState->cbTransfer = ahciGetNSectorsQueued(pCmdFis) * 512;
    50845098            pAhciPortTaskState->uOffset = ahciGetSectorQueued(pCmdFis) * 512;
    5085             rc = PDMBLOCKTXDIR_FROM_DEVICE;
     5099            rc = AHCITXDIR_READ;
    50865100            break;
    50875101        }
     
    50905104            pAhciPortTaskState->cbTransfer = ahciGetNSectorsQueued(pCmdFis) * 512;
    50915105            pAhciPortTaskState->uOffset = ahciGetSectorQueued(pCmdFis) * 512;
    5092             rc = PDMBLOCKTXDIR_TO_DEVICE;
     5106            rc = AHCITXDIR_WRITE;
    50935107            break;
    50945108        }
     
    51475161
    51485162    /* Set transfer direction. */
    5149     pAhciPortTaskState->uTxDir = (pAhciPortTaskState->cmdHdr.u32DescInf & AHCI_CMDHDR_W) ? PDMBLOCKTXDIR_TO_DEVICE : PDMBLOCKTXDIR_FROM_DEVICE;
     5163    pAhciPortTaskState->enmTxDir = (pAhciPortTaskState->cmdHdr.u32DescInf & AHCI_CMDHDR_W) ? AHCITXDIR_WRITE : AHCITXDIR_READ;
    51505164
    51515165    /* If this is an ATAPI command read the atapi command. */
     
    52165230    else
    52175231    {
    5218         int                iTxDir;
     5232        AHCITXDIR          enmTxDir;
    52195233        PAHCIPORTTASKSTATE pAhciPortTaskState;
    52205234
     
    52725286        }
    52735287
    5274         iTxDir = ahciProcessCmd(pAhciPort, pAhciPortTaskState, pAhciPortTaskState->cmdFis);
    5275 
    5276         if (iTxDir != PDMBLOCKTXDIR_NONE)
     5288        enmTxDir = ahciProcessCmd(pAhciPort, pAhciPortTaskState, pAhciPortTaskState->cmdFis);
     5289
     5290        if (enmTxDir != AHCITXDIR_NONE)
    52775291        {
    52785292            if (pAhciPortTaskState->fQueued)
     
    52835297            }
    52845298
    5285             STAM_REL_COUNTER_INC(&pAhciPort->StatDMA);
    5286 
    5287             rc = ahciScatterGatherListCreate(pAhciPort, pAhciPortTaskState, (iTxDir == PDMBLOCKTXDIR_FROM_DEVICE) ? false : true);
    5288             if (RT_FAILURE(rc))
    5289                 AssertMsgFailed(("%s: Failed to process command %Rrc\n", __FUNCTION__, rc));
    5290 
    5291             if (iTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
     5299            if (enmTxDir != AHCITXDIR_FLUSH)
     5300            {
     5301                STAM_REL_COUNTER_INC(&pAhciPort->StatDMA);
     5302
     5303                rc = ahciScatterGatherListCreate(pAhciPort, pAhciPortTaskState, (enmTxDir == AHCITXDIR_READ) ? false : true);
     5304                if (RT_FAILURE(rc))
     5305                    AssertMsgFailed(("%s: Failed to process command %Rrc\n", __FUNCTION__, rc));
     5306            }
     5307
     5308            if (enmTxDir == AHCITXDIR_FLUSH)
     5309            {
     5310                rc = pAhciPort->pDrvBlockAsync->pfnStartFlush(pAhciPort->pDrvBlockAsync,
     5311                                                              pAhciPortTaskState);
     5312            }
     5313            else if (enmTxDir == AHCITXDIR_READ)
    52925314            {
    52935315                pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1;
     
    54375459               && RT_LIKELY(!pAhciPort->fPortReset))
    54385460        {
    5439             int       iTxDir;
     5461            AHCITXDIR enmTxDir;
    54405462            uint8_t   uActTag;
    54415463
     
    54875509            else
    54885510            {
    5489                 iTxDir = ahciProcessCmd(pAhciPort, pAhciPortTaskState, &pAhciPortTaskState->cmdFis[0]);
    5490 
    5491                 if (iTxDir != PDMBLOCKTXDIR_NONE)
     5511                enmTxDir = ahciProcessCmd(pAhciPort, pAhciPortTaskState, &pAhciPortTaskState->cmdFis[0]);
     5512
     5513                if (enmTxDir == AHCITXDIR_FLUSH)
     5514                {
     5515                    rc = pAhciPort->pDrvBlock->pfnFlush(pAhciPort->pDrvBlock);
     5516
     5517                    /* Log the error. */
     5518                    if (   RT_FAILURE(rc)
     5519                        && pAhciPort->cErrors++ < MAX_LOG_REL_ERRORS)
     5520                    {
     5521                        LogRel(("AHCI#%u: Flush returned rc=%Rrc\n",
     5522                                pAhciPort->iLUN, rc));
     5523                    }
     5524
     5525                    if (RT_FAILURE(rc))
     5526                    {
     5527                        pAhciPortTaskState->uATARegError = ID_ERR;
     5528                        pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_ERR;
     5529                    }
     5530                    else
     5531                    {
     5532                        pAhciPortTaskState->uATARegError = 0;
     5533                        pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK;
     5534                    }
     5535
     5536                    if (pAhciPortTaskState->fQueued)
     5537                        uQueuedTasksFinished |= (1 << pAhciPortTaskState->uTag);
     5538                    else
     5539                    {
     5540                        /* Task is not queued send D2H FIS */
     5541                        ahciSendD2HFis(pAhciPort, pAhciPortTaskState, &pAhciPortTaskState->cmdFis[0], true);
     5542                    }
     5543                }
     5544                else if (enmTxDir != AHCITXDIR_NONE)
    54925545                {
    54935546                    uint64_t uOffset;
     
    54965549                    PAHCIPORTTASKSTATESGENTRY pSGInfoCurr;
    54975550
    5498                     rc = ahciScatterGatherListCreate(pAhciPort, pAhciPortTaskState, (iTxDir == PDMBLOCKTXDIR_FROM_DEVICE) ? false : true);
     5551                    rc = ahciScatterGatherListCreate(pAhciPort, pAhciPortTaskState, (enmTxDir == AHCITXDIR_READ) ? false : true);
    54995552                    if (RT_FAILURE(rc))
    55005553                        AssertMsgFailed(("%s: Failed to get number of list elments %Rrc\n", __FUNCTION__, rc));
     
    55185571                        AssertMsg(!(cbProcess % 512), ("Number of bytes to process is not sector aligned %lu\n", cbProcess));
    55195572
    5520                         if (iTxDir == PDMBLOCKTXDIR_FROM_DEVICE)
     5573                        if (enmTxDir == AHCITXDIR_READ)
    55215574                        {
    55225575                            pAhciPort->Led.Asserted.s.fReading = pAhciPort->Led.Actual.s.fReading = 1;
     
    55565609                        LogRel(("AHCI#%u: %s at offset %llu (%u bytes left) returned rc=%Rrc\n",
    55575610                                pAhciPort->iLUN,
    5558                                 iTxDir == PDMBLOCKTXDIR_FROM_DEVICE
     5611                                enmTxDir == AHCITXDIR_READ
    55595612                                ? "Read"
    55605613                                : "Write",
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