bool
CreateResources_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) none
     * \endverbatim
     */
    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw exception();

    SharedACQPtr acq = CAST_TO_ACQ(
        gRsrcMngr->AllocObj(Trackable::OBJ_ACQ, ACQ_GROUP_ID))
    acq->Init(5);

    SharedASQPtr asq = CAST_TO_ASQ(
        gRsrcMngr->AllocObj(Trackable::OBJ_ASQ, ASQ_GROUP_ID))
    asq->Init(5);

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw exception();

    return true;
}
bool
GrpAdminSetGetFeatCombo::RestoreTLER(SharedASQPtr asq, SharedACQPtr acq)
{
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());
    SharedSetFeaturesPtr setFeaturesCmd =
        SharedSetFeaturesPtr(new SetFeatures());

    LOG_NRM("Restoring state with TLER = 0x%04X", mTimeLimErrRec);
    setFeaturesCmd->SetFID(FID[FID_ERR_RECOVERY]);
    getFeaturesCmd->SetFID(FID[FID_ERR_RECOVERY]);

    setFeaturesCmd->SetDword(mTimeLimErrRec, 11);
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        setFeaturesCmd, "RestoreTLER", true);

    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "RestoreTLER", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);

    if (mTimeLimErrRec != ce.t.dw0) {
        LOG_ERR("TLER restore to original state failed. "
            "(Actual: Expected) = (0x%04X:0x%04X)", ce.t.dw0, mTimeLimErrRec);
        return false;
    }
    return true;
}
Exemple #3
0
bool
CreateACQASQ_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) This is the 1st within GrpBasicInit.
     * 2) The NVME device is disabled
     * 3) All interrupts are disabled.
     * \endverbatim
     */

    KernelAPI::DumpKernelMetrics(mFd,
        FileSystem::PrepLogFile(mGrpName, mTestName, "kmetrics", "before"));

    // After disabling the defaults for AMS & CSS are fine, no need to modify
    if (gCtrlrConfig->SetMPS() == false)
        throw exception();

    SharedACQPtr acq = CAST_TO_ACQ(
        gRsrcMngr->AllocObj(Trackable::OBJ_ACQ, ACQ_GROUP_ID))
    acq->Init(5);

    SharedASQPtr asq = CAST_TO_ASQ(
        gRsrcMngr->AllocObj(Trackable::OBJ_ASQ, ASQ_GROUP_ID))
    asq->Init(5);

    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw exception();

    KernelAPI::DumpKernelMetrics(mFd,
        FileSystem::PrepLogFile(mGrpName, mTestName, "kmetrics", "after"));
    return true;
}
bool
GrpAdminSetGetFeatCombo::RestoreAsyncEvent(SharedASQPtr asq, SharedACQPtr acq)
{
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());
    SharedSetFeaturesPtr setFeaturesCmd =
        SharedSetFeaturesPtr(new SetFeatures());

    LOG_NRM("Restoring state with mAsyncEvent = 0x%04X", mAsyncEvent);
    setFeaturesCmd->SetFID(FID[FID_ASYNC_EVENT_CONFIG]);
    getFeaturesCmd->SetFID(FID[FID_ASYNC_EVENT_CONFIG]);

    setFeaturesCmd->SetDword(mAsyncEvent, 11);
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        setFeaturesCmd, "RestoreWrAtomicity", true);

    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "RestoreAsyncEvent", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);

    if (mAsyncEvent != ce.t.dw0) {
        LOG_ERR("AsyncEvent restore to original state failed. "
            "(Actual: Expected) = (0x%04X:0x%04X)", ce.t.dw0, mAsyncEvent);
        return false;
    }
    return true;
}
void
CreateResources_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) none
     * \endverbatim
     */
    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    SharedACQPtr acq = CAST_TO_ACQ(
        gRsrcMngr->AllocObj(Trackable::OBJ_ACQ, ACQ_GROUP_ID))
    acq->Init(5);

    SharedASQPtr asq = CAST_TO_ASQ(
        gRsrcMngr->AllocObj(Trackable::OBJ_ASQ, ASQ_GROUP_ID))
    asq->Init(5);

    // All queues will use identical IRQ vector
    IRQ::SetAnySchemeSpecifyNum(1);     // throws upon error

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    gCtrlrConfig->SetIOCQES(gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_CQES) & 0xf);
    gCtrlrConfig->SetIOSQES(gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_SQES) & 0xf);
}
void
CIDAcceptedASQ_r10b::ReapVerifyCID(SharedASQPtr asq, SharedACQPtr acq,
    uint16_t currCID)
{
    uint32_t isrCount;
    uint32_t ceRemain;
    uint32_t numReaped;
    uint32_t numCE;

    if (acq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 1, numCE, isrCount)
        == false) {
        acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "acq.fail"),
            "Dump Entire ACQ");
        throw FrmwkEx(HERE, "Unable to see CEs for issued cmd");
    }

    SharedMemBufferPtr ceMem = SharedMemBufferPtr(new MemBuffer());
    if ((numReaped = acq->Reap(ceRemain, ceMem, isrCount, numCE, true)) != 1) {
        acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "acq.fail"),
            "Dump Entire ACQ");
        throw FrmwkEx(HERE, "Unable to reap on ACQ");
    }

    union CE *ce = (union CE *)ceMem->GetBuffer();
    ProcessCE::Validate(*ce);  // throws upon error
    if (ce->n.CID != currCID) {
        asq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "asq.fail"),
            "Dump Entire ASQ");
        acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "acq.fail"),
            "Dump Entire ACQ");
        throw FrmwkEx(HERE, "Received CID %d but expected %d", ce->n.CID,
            currCID);
    }
}
Exemple #7
0
void
InvalidQID_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * None.
     * \endverbatim
     */
    string work;
    bool enableLog;
    uint64_t maxIOQEntries = 2;

    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    LOG_NRM("Create admin queues ACQ and ASQ");
    SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd));
    acq->Init(5);

    SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd));
    asq->Init(5);

    // All queues will use identical IRQ vector
    IRQ::SetAnySchemeSpecifyNum(1);

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    // Calc X, max no. of IOCQ's DUT supports.
    uint32_t X = gInformative->GetFeaturesNumOfIOCQs();
    LOG_NRM("Maximum num of IOCQ's DUT will support = %d", X);

    LOG_NRM("Setup element size for the IOCQ");
    gCtrlrConfig->SetIOCQES(gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_CQES) & 0xf);

    LOG_NRM("Issue CreateIOCQ cmds with QID's ranging from %d to %d",
        (X + 1), MAX_IOQ_ID);

    list<uint32_t> illegalQIDs = GetIllegalQIDs(X + 1);
    for (list<uint32_t>::iterator qId = illegalQIDs.begin();
        qId != illegalQIDs.end(); qId++) {
        LOG_NRM("Process each CreateIOCQCmd with iocq id #%d", *qId);
        SharedIOCQPtr iocq = SharedIOCQPtr(new IOCQ(gDutFd));
        iocq->Init(*qId, maxIOQEntries, true, 0);
        SharedCreateIOCQPtr createIOCQCmd =
            SharedCreateIOCQPtr(new CreateIOCQ());
        createIOCQCmd->Init(iocq);

        work = str(boost::format("iocqId.%d") % *qId);
        enableLog = false;
        if ((*qId <= (X + 8)) || (*qId >= (MAX_IOQ_ID - 8)))
            enableLog = true;

        LOG_NRM("Send and reap cmd with CQ ID #%d", *qId);
        IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
            createIOCQCmd, work, enableLog, CESTAT_INVALID_QID);
    }
}
void
UnsupportRsvdFields_r11b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) none
     *  \endverbatim
     */
    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    LOG_NRM("Create admin queues ACQ and ASQ for test lifetime");
    SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd));
    acq->Init(5);

    SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd));
    asq->Init(5);

    // All queues will use identical IRQ vector
    IRQ::SetAnySchemeSpecifyNum(1);

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    // Test async events without setting the rsvd bits in the cmd.
    TestAsyncEvents(acq, asq, false);

    // Test async events by setting the rsvd bits in the cmd.
    TestAsyncEvents(acq, asq, true);

}
bool
GrpAdminSetGetFeatCombo::RestoreTMPTH(SharedASQPtr asq, SharedACQPtr acq)
{
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());
    SharedSetFeaturesPtr setFeaturesCmd =
        SharedSetFeaturesPtr(new SetFeatures());

    LOG_NRM("Restoring state with TMPTH = 0x%04X", mTmpThreshold);
    setFeaturesCmd->SetFID(BaseFeatures::FID_TEMP_THRESHOLD);
    getFeaturesCmd->SetFID(BaseFeatures::FID_TEMP_THRESHOLD);

    setFeaturesCmd->SetDword(mTmpThreshold, 11);
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        setFeaturesCmd, "RestoreTMPTH", true);

    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "RestoreTMPTH", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);

    if (mTmpThreshold != ce.t.dw0) {
        LOG_ERR("TMPTH restore to original state failed. "
            "(Actual: Expected) = (0x%04X:0x%04X)", ce.t.dw0, mTmpThreshold);
        return false;
    }
    return true;
}
bool
GrpAdminSetGetFeatCombo::RestoreIRQCoalescing(SharedASQPtr asq,
    SharedACQPtr acq)
{
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());
    SharedSetFeaturesPtr setFeaturesCmd =
        SharedSetFeaturesPtr(new SetFeatures());

    LOG_NRM("Restoring state with IRQCoalescing = 0x%04X", mIrqCoalescing);
    setFeaturesCmd->SetFID(FID[FID_IRQ_COALESCING]);
    getFeaturesCmd->SetFID(FID[FID_IRQ_COALESCING]);

    setFeaturesCmd->SetDword(mIrqCoalescing, 11);
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        setFeaturesCmd, "RestoreIRQCoalescing", true);

    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "RestoreIRQCoalescing", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);

    if (mIrqCoalescing != ce.t.dw0) {
        LOG_ERR("IRQCoalescing restore to original state failed. "
            "(Actual: Expected) = (0x%04X:0x%04X)", ce.t.dw0, mIrqCoalescing);
        return false;
    }
    return true;
}
bool
GrpAdminSetGetFeatCombo::RestoreVolWrCache(SharedASQPtr asq, SharedACQPtr acq)
{
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());
    SharedSetFeaturesPtr setFeaturesCmd =
        SharedSetFeaturesPtr(new SetFeatures());

    LOG_NRM("Restoring state with VWC = 0x%04X", mVolWrCache);
    setFeaturesCmd->SetFID(FID[FID_VOL_WR_CACHE]);
    getFeaturesCmd->SetFID(FID[FID_VOL_WR_CACHE]);

    setFeaturesCmd->SetDword(mVolWrCache, 11);
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        setFeaturesCmd, "RestoreVWC", true);

    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "RestoreVWC", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);

    if (mVolWrCache != ce.t.dw0) {
        LOG_ERR("VWC restore to original state failed. "
            "(Actual: Expected) = (0x%04X:0x%04X)", ce.t.dw0, mVolWrCache);
        return false;
    }
    return true;
}
void
CreateResources_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) This is the 1st within GrpBasicInit.
     * \endverbatim
     */
    static uint32_t NumEntriesIOQ = 2;


    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    SharedACQPtr acq = CAST_TO_ACQ(
        gRsrcMngr->AllocObj(Trackable::OBJ_ACQ, ACQ_GROUP_ID))
    acq->Init(5);

    SharedASQPtr asq = CAST_TO_ASQ(
        gRsrcMngr->AllocObj(Trackable::OBJ_ASQ, ASQ_GROUP_ID))
    asq->Init(5);

    // All queues will use identical IRQ vector
    IRQ::SetAnySchemeSpecifyNum(1);     // throws upon error

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    {
        uint64_t maxIOQEntries;
        // Determine the max IOQ entries supported
        if (gRegisters->Read(CTLSPC_CAP, maxIOQEntries) == false)
            throw FrmwkEx(HERE, "Unable to determine MQES");

        maxIOQEntries &= CAP_MQES;
        maxIOQEntries += 1;      // convert to 1-based
        if (maxIOQEntries < (uint64_t)NumEntriesIOQ) {
            LOG_NRM("Changing number of Q elements from %d to %lld",
                NumEntriesIOQ, (unsigned long long)maxIOQEntries);
            NumEntriesIOQ = maxIOQEntries;
        }


        gCtrlrConfig->SetIOCQES(gInformative->GetIdentifyCmdCtrlr()->
            GetValue(IDCTRLRCAP_CQES) & 0xf);
        Queues::CreateIOCQContigToHdw(mGrpName, mTestName,
            DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, NumEntriesIOQ, true,
            IOCQ_GROUP_ID, true, 0);

        gCtrlrConfig->SetIOSQES(gInformative->GetIdentifyCmdCtrlr()->
            GetValue(IDCTRLRCAP_SQES) & 0xf);
        Queues::CreateIOSQContigToHdw(mGrpName, mTestName,
            DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, NumEntriesIOQ, true,
            IOSQ_GROUP_ID, IOQ_ID, 0);
    }
}
void
CIDAcceptedIOSQ_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * None.
     * \endverbatim
     */
    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    LOG_NRM("Create ACQ and ASQ objects which have test life time");
    SharedACQPtr acq = CAST_TO_ACQ(SharedACQPtr(new ACQ(gDutFd)))
    acq->Init(5);
    SharedASQPtr asq = CAST_TO_ASQ(SharedASQPtr(new ASQ(gDutFd)))
    asq->Init(5);

    IRQ::SetAnySchemeSpecifyNum(2);     // throws upon error

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    vector<SharedIOSQPtr> iosqs;
    SharedIOCQPtr iocq;
    InitTstRsrcs(asq, acq, iosqs, iocq);
    SharedWritePtr writeCmd = CreateWriteCmd();

    LOG_NRM("Learn initial unique command id assigned by dnvme");
    uint16_t curCID;
    vector <SharedIOSQPtr>::iterator iosq;
    for (iosq = iosqs.begin(); iosq != iosqs.end(); iosq++)
        (*iosq)->Send(writeCmd, curCID);

    uint16_t prevCID = curCID;
    for (uint32_t nCmds = 0; nCmds < MAX_CMDS; nCmds++) {
        for (iosq = iosqs.begin(); iosq != iosqs.end(); iosq++) {
            LOG_NRM("(nCmds, curCID, prevCID, SQ ID) = (%d, %d, %d, %d)",
                nCmds, curCID, prevCID, (*iosq)->GetQId());
            (*iosq)->Ring();
            ReapVerifyCID(*iosq, iocq, prevCID);

            (*iosq)->Send(writeCmd, curCID);
            if (curCID != (uint16_t)(prevCID + 1)) {
                (*iosq)->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
                    "iosq.fail." + (*iosq)->GetQId()), "Dump Entire IOSQ");
                iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
                    "iocq.fail." + iocq->GetQId()), "Dump Entire IOCQ");
                throw FrmwkEx(HERE, "curCID(%d) != (prevCID + 1)(%d)", curCID,
                    (prevCID + 1));
            }
        }
        prevCID = curCID;
    }
}
void
DeleteIOQDiscontigPoll_r10b::DeleteIOSQDiscontigPoll(SharedASQPtr asq,
    SharedACQPtr acq)
{
    uint16_t numCE;

    LOG_NRM("Lookup IOSQ which was created in a prior test within group");
    SharedIOSQPtr iosq = CAST_TO_IOSQ(
        gRsrcMngr->GetObj(IOSQ_DISCONTIG_POLL_GROUP_ID))

    LOG_NRM("Create a Delete IOSQ cmd to perform the IOSQ deletion");
    SharedDeleteIOSQPtr deleteIOSQCmd =
        SharedDeleteIOSQPtr(new DeleteIOSQ(mFd));
    deleteIOSQCmd->Init(iosq);


    LOG_NRM("Send the Delete IOSQ cmd to hdw");
    asq->Send(deleteIOSQCmd);
    asq->Dump(FileSystem::PrepLogFile(mGrpName, mTestName, "asq",
        "deleteIOSQCmd"),
        "Just B4 ringing SQ0 doorbell, dump entire SQ contents");
    asq->Ring();


    LOG_NRM("Wait for the CE to arrive in ACQ");
    if (acq->ReapInquiryWaitSpecify(DEFAULT_CMD_WAIT_ms, 1, numCE) == false) {
        LOG_ERR("Unable to see completion of Delete IOSQ cmd");
        acq->Dump(
            FileSystem::PrepLogFile(mGrpName, mTestName, "acq","deleteIOSQCmd"),
            "Unable to see any CE's in CQ0, dump entire CQ contents");
        throw exception();
    }
    acq->Dump(FileSystem::PrepLogFile(mGrpName, mTestName, "acq",
        "deleteIOSQCmd"), "Just B4 reaping CQ0, dump entire CQ contents");


    {
        uint16_t ceRemain;
        uint16_t numReaped;

        LOG_NRM("Reaping CE from ACQ, requires memory to hold reaped CE");
        SharedMemBufferPtr ceMemIOSQ = SharedMemBufferPtr(new MemBuffer());
        if ((numReaped = acq->Reap(ceRemain, ceMemIOSQ, numCE, true)) != 1) {
            LOG_ERR("Verified there was 1 CE, but reaping produced %d",
                numReaped);
            throw exception();
        }
        LOG_NRM("The reaped identify CE is...");
        ceMemIOSQ->Log();
    }

    // Not explicitly necessary, but is more clean to free what is not needed
    gRsrcMngr->FreeObj(IOSQ_DISCONTIG_POLL_GROUP_ID);
}
bool
GrpAdminSetGetFeatCombo::RestoreState()
{
    // For the majority of test groups this feature most likely won't be needed
     if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd));
    acq->Init(5);

    SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd));
    asq->Init(5);

    // All queues will use identical IRQ vector
    IRQ::SetAnySchemeSpecifyNum(1);

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    if (RestoreArbitration(asq, acq) == false) {
        LOG_ERR("Arbitration restore failed");
        return false;
    }

    if (RestorePowerState(asq, acq) == false) {
        LOG_ERR("Power state restore failed");
        return false;
    }

    if (RestoreTMPTH(asq, acq) == false) {
        LOG_ERR("Temperature threshold restore failed");
        return false;
    }

    if (RestoreTLER(asq, acq) == false) {
        LOG_ERR("Time limited error recovery restore failed");
        return false;
    }

    if ((gInformative->GetIdentifyCmdCtrlr()->GetValue(IDCTRLRCAP_VWC)
        & BITMASK_VWC) == 0x1) {
        if (RestoreVolWrCache(asq, acq) == false) {
            LOG_ERR("Volatile write cache restore failed");
            return false;
        }
    }

    LOG_NRM("System restore successful.");
    return true;
}
void
GrpAdminSetGetFeatCombo::SaveTMPTH(SharedASQPtr asq, SharedACQPtr acq)
{
    LOG_NRM("Create Get features cmd");
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());
    getFeaturesCmd->SetFID(FID[FID_TEMP_THRESHOLD]);
    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "SaveFeatTmpThr", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);
    mTmpThreshold = ce.t.dw0;
    LOG_NRM("Default tmp threshold using Get Features = 0x%04X", mTmpThreshold);
}
void
GrpAdminSetGetFeatCombo::SavePowerState(SharedASQPtr asq, SharedACQPtr acq)
{
    LOG_NRM("Create Get features cmd");
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());
    getFeaturesCmd->SetFID(FID[FID_PWR_MGMT]);
    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "SaveFeatPwrMgmt", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);
    mPowerState = ce.t.dw0;
    LOG_NRM("Default power state using Get Features = 0x%04X", mPowerState);
}
void
AcceptQPriority_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * None.
     * \endverbatim
     */
    uint64_t maxIOQEntries = 2;

    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    LOG_NRM("Create admin queues ACQ and ASQ");
    SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd));
    acq->Init(5);

    SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd));
    asq->Init(5);

    // All queues will use identical IRQ vector
    IRQ::SetAnySchemeSpecifyNum(1);

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    LOG_NRM("Setup element sizes for the IOQ's");
    gCtrlrConfig->SetIOCQES(gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_CQES) & 0xf);
    gCtrlrConfig->SetIOSQES(gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_SQES) & 0xf);

    LOG_NRM("Create IOCQ with QID = %d", IOQ_ID);
    SharedIOCQPtr iocq = Queues::CreateIOCQContigToHdw(mGrpName, mTestName,
        CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, maxIOQEntries, false,
        IOCQ_GROUP_ID, true, 0);

    for (uint8_t priority = 0; priority < PRIORITY_RANGE; priority++) {
        LOG_NRM("Create IOSQ with QID = %d and priority #%d", IOQ_ID, priority);
        SharedIOSQPtr iosq = Queues::CreateIOSQContigToHdw(mGrpName,
            mTestName, CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, maxIOQEntries,
            false, IOSQ_GROUP_ID, IOQ_ID, priority);

        LOG_NRM("Delete IOSQ with QID = %d and priority #%d", IOQ_ID, priority);
        Queues::DeleteIOSQToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq,
            asq, acq, "", false);
    }
}
void
GrpAdminSetGetFeatCombo::SaveTLER(SharedASQPtr asq, SharedACQPtr acq)
{
    LOG_NRM("Create Get features cmd");
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());
    getFeaturesCmd->SetFID(FID[FID_ERR_RECOVERY]);
    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "SaveFeatTler", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);
    mTimeLimErrRec = ce.t.dw0;
    LOG_NRM("Default time limited err recovery using Get Features = 0x%04X",
        mTimeLimErrRec);
}
void
GrpAdminSetGetFeatCombo::SaveArbitration(SharedASQPtr asq, SharedACQPtr acq)
{
    LOG_NRM("Create Get features cmd");
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());
    getFeaturesCmd->SetFID(FID[FID_ARBITRATION]);
    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "SaveFeatArb", true);

    union CE ce = acq->PeekCE(acqMetrics.head_ptr);
    mArbitration = ce.t.dw0;
    LOG_NRM("Default arbitration using Get Features = 0x%04X", mArbitration);
}
void
GrpAdminSetGetFeatCombo::SaveWrAtomicity(SharedASQPtr asq, SharedACQPtr acq)
{
    LOG_NRM("Create Get features cmd");
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());

    getFeaturesCmd->SetFID(FID[FID_WRITE_ATOMICITY]);
    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "SaveFeatWrAtomicity", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);
    mWrAtomicity = ce.t.dw0;
    LOG_NRM("Default WrAtomicity using Get Features = 0x%04X", mWrAtomicity);
}
void
GrpAdminSetGetFeatCombo::SaveAsyncEvent(SharedASQPtr asq, SharedACQPtr acq)
{
    LOG_NRM("Create Get features cmd");
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());

    getFeaturesCmd->SetFID(FID[FID_ASYNC_EVENT_CONFIG]);
    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "SaveFeatAsyncEvent", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);
    mAsyncEvent = ce.t.dw0;
    LOG_NRM("Default Async Events using Get Features = 0x%04X", mAsyncEvent);
}
Exemple #23
0
/**
 * A function to issue consecutive admin cmd set format NVM cmds to a DUT.
 * @param format Pass formating instructions
 * @return true upon successful parsing, otherwise false.
 */
bool
FormatDevice(Format &format)
{
    try {   // The objects to perform this work throw exceptions
        FileSystem::SetBaseDumpDir(false);   // Log into GrpPending
        if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
            throw FrmwkEx(HERE);

        LOG_NRM("Prepare the admin Q's to setup this request");
        SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd));
        acq->Init(2);
        SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd));
        asq->Init(2);
        gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
        if (gCtrlrConfig->SetState(ST_ENABLE) == false)
            throw FrmwkEx(HERE);

        for (size_t i = 0; i < format.cmds.size(); i++) {
            LOG_NRM("Formatting namespace: %d", format.cmds[i].nsid);
            LOG_NRM("  FormatNVM:DW10.ses = 0x%02x", format.cmds[i].ses);
            LOG_NRM("  FormatNVM:DW10.pil = %c", format.cmds[i].pil ? 'T' :'F');
            LOG_NRM("  FormatNVM:DW10.pi = 0x%02x", format.cmds[i].pi);
            LOG_NRM("  FormatNVM:DW10.ms = %c", format.cmds[i].ms ? 'T' : 'F');
            LOG_NRM("  FormatNVM:DW10.lbaf = 0x%02x", format.cmds[i].lbaf);

            LOG_NRM("Create the cmd to carry this data to the DUT");
            SharedFormatNVMPtr formatNVM =
                SharedFormatNVMPtr(new FormatNVM());
            formatNVM->SetNSID(format.cmds[i].nsid);
            formatNVM->SetSES(format.cmds[i].ses);
            formatNVM->SetPIL(format.cmds[i].pil);
            formatNVM->SetPI(format.cmds[i].pi);
            formatNVM->SetMS(format.cmds[i].ms);
            formatNVM->SetLBAF(format.cmds[i].lbaf);

            IO::SendAndReapCmd("tnvme", "format", SYSTEMWIDE_CMD_WAIT_ms,
                asq, acq, formatNVM, "", true);
        }
        LOG_NRM("The operation succeeded to format device");
    } catch (...) {
        LOG_ERR("Operation failed to format device");
        gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY);
        return false;
    }

    gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY);
    return true;
}
void
GrpAdminSetGetFeatCombo::SaveVolWrCache(SharedASQPtr asq, SharedACQPtr acq)
{
    LOG_NRM("Create Get features cmd");
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());

    getFeaturesCmd->SetFID(FID[FID_VOL_WR_CACHE]);
    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "SaveFeatVWC", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);
    mVolWrCache = ce.t.dw0;
    LOG_NRM("Default volatile write cache using Get Features = 0x%04X",
        mVolWrCache);
}
void
GrpAdminSetGetFeatCombo::SaveIRQCoalescing(SharedASQPtr asq, SharedACQPtr acq)
{
    LOG_NRM("Create Get features cmd");
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());

    getFeaturesCmd->SetFID(FID[FID_IRQ_COALESCING]);
    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
    IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
        getFeaturesCmd, "SaveFeatIRQCoalescing", true);
    union CE ce = acq->PeekCE(acqMetrics.head_ptr);
    mIrqCoalescing = ce.t.dw0;
    LOG_NRM("Default irq coalescing using Get Features = 0x%04X",
        mIrqCoalescing);
}
bool
GrpAdminSetGetFeatCombo::SaveState()
{
    LOG_NRM("Saving system state using getfeatures before group starts");

    // Reset saved value to account for regression
    mArbitration = 0;
    mPowerState = 0;
    mTmpThreshold = 0;
    mTimeLimErrRec = 0;
    mVolWrCache = 0;
    mIrqCoalescing = 0;
    mWrAtomicity = 0;
    memset(mIvecConf, 0, sizeof(mIvecConf));
    mAsyncEvent = 0;

    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd));
    acq->Init(5);
    SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd));
    asq->Init(5);

    // All queues will use identical IRQ vector
    IRQ::SetAnySchemeSpecifyNum(1);

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    SaveArbitration(asq, acq);
    SavePowerState(asq, acq);
    SaveTMPTH(asq, acq);
    SaveTLER(asq, acq);

    if ((gInformative->GetIdentifyCmdCtrlr()->GetValue(IDCTRLRCAP_VWC)
        & BITMASK_VWC) == 0x1) {
        SaveVolWrCache(asq, acq);
    }
    SaveIRQCoalescing(asq, acq);
    SaveIvecConf(asq, acq);
    SaveWrAtomicity(asq, acq);
    SaveAsyncEvent(asq, acq);
    return true;
}
void
AdminQFull_r10b::AdminQFull(uint16_t numASQEntries, uint16_t numACQEntries,
    SharedIdentifyPtr idCmdCtrlr)
{
    uint32_t numCE;
    uint32_t isrCount;
    uint16_t uniqueId;

    if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
        throw FrmwkEx(HERE);

    // Create Admin Q Objects for test lifetime
    SharedACQPtr acq = CAST_TO_ACQ(SharedACQPtr(new ACQ(mFd)))
    acq->Init(numACQEntries);

    SharedASQPtr asq = CAST_TO_ASQ(SharedASQPtr(new ASQ(mFd)))
    asq->Init(numASQEntries);

    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    uint32_t nCmdsToSubmit = numASQEntries - 1;
    LOG_NRM("Send #%d cmds to hdw via ASQ", nCmdsToSubmit);
    for (uint32_t nCmds = 0; nCmds < nCmdsToSubmit; nCmds++) {
        LOG_NRM("Sending #%d of #%d Identify Cmds thru ASQ", nCmds + 1,
            nCmdsToSubmit);
        asq->Send(idCmdCtrlr, uniqueId);
        asq->Ring();

        LOG_NRM("Wait for the CE to arrive in ACQ");
        if (acq->ReapInquiryWaitSpecify(DEFAULT_CMD_WAIT_ms, (nCmds + 1), numCE,
            isrCount) == false) {

            // when asq size = acq size + 1, last CE will never arrive.
            if ((numASQEntries == numACQEntries + 1) &&
                (nCmds == nCmdsToSubmit - 1)) {
                // Reap one element from IOCQ to make room for last CE.
                IO::ReapCE(acq, 1, isrCount, mGrpName, mTestName, "ACQCE",
                    CESTAT_SUCCESS);
                if (acq->ReapInquiryWaitSpecify(DEFAULT_CMD_WAIT_ms, nCmds,
                    numCE, isrCount) == false) {
                    acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
                        "acq." + idCmdCtrlr->GetName()), "Dump entire ACQ");
                    throw FrmwkEx(HERE, "Unable to see last CE as expected");
                }
                break;
            }
            acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
                "acq." + idCmdCtrlr->GetName()), "Dump Entire ACQ");
            throw FrmwkEx(HERE, "Unable to see CE for issued cmd #%d", nCmds + 1);

        } else if (numCE != nCmds + 1) {
            acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
                "acq." + idCmdCtrlr->GetName()), "Dump Entire ACQ");
            throw FrmwkEx(HERE, "Missing last CE, #%d cmds of #%d received",
                nCmds + 1, numCE);
        }
    }
}
void
AdminQRollChkDiff_r10b::VerifyCESQValues(SharedACQPtr acq,
    uint16_t expectedVal)
{
    union CE ce;
    struct nvme_gen_cq acqMetrics = acq->GetQMetrics();

    // The CQ's metrics after reaping holds head_ptr plus 1 needed. Also Take
    // Q roll over into account
    if (acqMetrics.head_ptr == 0) {
        ce = acq->PeekCE(acq->GetNumEntries() - 1);
    } else {
        ce = acq->PeekCE(acqMetrics.head_ptr - 1);
    }

    if (ce.n.SQID != 0) {
        acq->Dump(
            FileSystem::PrepDumpFile(mGrpName, mTestName, "acq", "CE.SQID"),
            "CE SQ ID Inconsistent");
        throw FrmwkEx(HERE, "Expected CE.SQID = 0 in ACQ completion entry but actual "
            "CE.SQID  = 0x%04X", ce.n.SQID);
    }

    if (ce.n.SQHD != expectedVal) {
        acq->Dump(
            FileSystem::PrepDumpFile(mGrpName, mTestName, "acq", "CE.SQHD"),
            "CE SQ Head Pointer Inconsistent");
        throw FrmwkEx(HERE, 
            "Expected CE.SQHD = 0x%04X in ACQ completion entry but actual "
            "CE.SQHD  = 0x%04X", expectedVal, ce.n.SQHD);
    }
}
Exemple #29
0
/**
 * A function to send Set Features admin cmd to a device sending the identifier
 * 0x07 to set number of queues. This value, according to the spec, shall NOT
 * change between resets, i.e. only set this value after a power up. Failure to
 * conform results in undefined behavior.
 * "<STS:PXDS:AERUCES:CSTS>".
 * @param numQueues Pass a struct to source the desired values to send to hdw
 * @return true upon successful parsing, otherwise false.
 */
bool
SetFeaturesNumberOfQueues(NumQueues &numQueues)
{
    try {   // The objects to perform this work throw exceptions

        LOG_NRM("Setting number of Q's; ncqr=0x%04X, nsqr=0x%04X",
            numQueues.ncqr, numQueues.nsqr);

        FileSystem::SetBaseDumpDir(false);   // Log into GrpPending
        if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false)
            throw FrmwkEx(HERE);

        LOG_NRM("Prepare the admin Q's to setup this request");
        SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd));
        acq->Init(2);
        SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd));
        asq->Init(2);
        gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
        if (gCtrlrConfig->SetState(ST_ENABLE) == false)
            throw FrmwkEx(HERE);

        LOG_NRM("Create the cmd to carry this data to the DUT");
        SharedSetFeaturesPtr sfNumOfQ =
            SharedSetFeaturesPtr(new SetFeatures());
        sfNumOfQ->SetFID(BaseFeatures::FID_NUM_QUEUES);
        sfNumOfQ->SetNumberOfQueues(numQueues.ncqr, numQueues.nsqr);

        IO::SendAndReapCmd("tnvme", "queues", SYSTEMWIDE_CMD_WAIT_ms,
            asq, acq, sfNumOfQ, "", true);
        LOG_NRM("The operation succeeded to set number of queues");
    } catch (...) {
        LOG_ERR("Operation failed to set number of queues");
        gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY);
        return false;
    }

    gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY);
    return true;
}
void
GrpAdminSetGetFeatCombo::SaveIvecConf(SharedASQPtr asq, SharedACQPtr acq)
{
    LOG_NRM("Create Get features cmd");
    SharedGetFeaturesPtr getFeaturesCmd =
        SharedGetFeaturesPtr(new GetFeatures());

    getFeaturesCmd->SetFID(FID[FID_IRQ_VEC_CONFIG]);

    uint16_t max_ivec = IRQ::GetMaxIRQsSupportedAnyScheme();

    for (uint16_t ivec = 0; ivec < max_ivec; ivec++) {
        getFeaturesCmd->SetIntVecConfigIV(ivec);
        struct nvme_gen_cq acqMetrics = acq->GetQMetrics();
        IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq,
            getFeaturesCmd, "SaveFeatIvecCOnf", true);
        union CE ce = acq->PeekCE(acqMetrics.head_ptr);
        mIvecConf[ivec] = ce.t.dw0;
        LOG_NRM("Default conf = 0x%04X using Get Features for ivec = 0x%02X",
            mIvecConf[ivec], ivec);
    }
}