VirtualBox

Changeset 51638 in vbox for trunk/src


Ignore:
Timestamp:
Jun 17, 2014 9:49:43 PM (10 years ago)
Author:
vboxsync
Message:

AHCI: Fix request cancelling logic if the log page containing details about the failed request is read

File:
1 edited

Legend:

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

    r51624 r51638  
    942942static size_t ahciCopyFromPrdtl(PPDMDEVINS pDevIns, PAHCIREQ pAhciReq,
    943943                                void *pvBuf, size_t cbBuf);
    944 static bool ahciCancelActiveTasks(PAHCIPort pAhciPort);
     944static bool ahciCancelActiveTasks(PAHCIPort pAhciPort, PAHCIREQ pAhciReqExcept);
    945945#endif
    946946RT_C_DECLS_END
     
    10681068{
    10691069    /* Cancel all tasks first. */
    1070     bool fAllTasksCanceled = ahciCancelActiveTasks(pAhciPort);
     1070    bool fAllTasksCanceled = ahciCancelActiveTasks(pAhciPort, NULL);
    10711071    Assert(fAllTasksCanceled);
    10721072
     
    20142014
    20152015    /* Cancel all tasks first. */
    2016     fAllTasksCanceled = ahciCancelActiveTasks(pAhciPort);
     2016    fAllTasksCanceled = ahciCancelActiveTasks(pAhciPort, NULL);
    20172017    Assert(fAllTasksCanceled);
    20182018
     
    56525652 *
    56535653 * @returns Whether all active tasks were canceled.
    5654  * @param   pAhciPort   The ahci port.
    5655  */
    5656 static bool ahciCancelActiveTasks(PAHCIPort pAhciPort)
     5654 * @param   pAhciPort        The ahci port.
     5655 * @param   pAhciReqExcept   The given request is excepted from the cancelling
     5656 *                           (used for error page reading).
     5657 */
     5658static bool ahciCancelActiveTasks(PAHCIPort pAhciPort, PAHCIREQ pAhciReqExcept)
    56575659{
    56585660    for (unsigned i = 0; i < RT_ELEMENTS(pAhciPort->aCachedTasks); i++)
     
    56605662        PAHCIREQ pAhciReq = pAhciPort->aCachedTasks[i];
    56615663
    5662         if (VALID_PTR(pAhciReq))
     5664        if (   VALID_PTR(pAhciReq)
     5665            && pAhciReq != pAhciReqExcept)
    56635666        {
    56645667            bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pAhciReq->enmTxState, AHCITXSTATE_CANCELED, AHCITXSTATE_ACTIVE);
     
    56855688    }
    56865689
    5687     AssertRelease(!ASMAtomicReadU32(&pAhciPort->cTasksActive));
     5690    AssertRelease(   !ASMAtomicReadU32(&pAhciPort->cTasksActive)
     5691                  || (pAhciReqExcept && ASMAtomicReadU32(&pAhciPort->cTasksActive) == 1));
    56885692    return true; /* always true for now because tasks don't use guest memory as the buffer which makes canceling a task impossible. */
    56895693}
     
    63616365                            aBuf[511] = (uint8_t)-(int8_t)uChkSum;
    63626366
    6363                             /*
    6364                              * Reading this log page results in an abort of all outstanding commands
    6365                              * and clearing the SActive register and TaskFile register.
    6366                              */
    6367                             ahciSendSDBFis(pAhciPort, 0xffffffff, true);
     6367                            if (pTaskErr->enmTxDir == AHCITXDIR_TRIM)
     6368                                ahciTrimRangesDestroy(pTaskErr);
     6369                            else if (pTaskErr->enmTxDir != AHCITXDIR_FLUSH)
     6370                                ahciIoBufFree(pAhciPort->pDevInsR3, pTaskErr, false /* fCopyToGuest */);
     6371
     6372                            /* Finally free the error task state structure because it is completely unused now. */
     6373                            RTMemFree(pTaskErr);
    63686374                        }
     6375
     6376                        /*
     6377                         * Reading this log page results in an abort of all outstanding commands
     6378                         * and clearing the SActive register and TaskFile register.
     6379                         *
     6380                         * See SATA2 1.2 spec chapter 4.2.3.4
     6381                         */
     6382                        bool fAbortedAll = ahciCancelActiveTasks(pAhciPort, pAhciReq);
     6383                        Assert(fAbortedAll);
     6384                        ahciSendSDBFis(pAhciPort, 0xffffffff, true);
     6385
    63696386                        break;
    63706387                    }
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