예제 #1
0
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);
    }
}
예제 #2
0
void
MandatorySMART_r10b::IssueGetLogPgCmdLessDwords(SharedASQPtr asq,
    SharedACQPtr acq, SharedGetLogPagePtr getLogPgCmd,
    SharedMemBufferPtr getLogPageMem)
{
    string work;

    send_64b_bitmask prpReq =
        (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);

    for (uint32_t numd = 1; numd <= SMART_HEALTH_NUMD; numd++) {
        LOG_NRM("Issue get log page for smart info with NUMD = %d", numd);
        getLogPageMem->Init(GetLogPage::SMART_DATA_SIZE, true);
        getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem);
        getLogPgCmd->SetNUMD(numd - 1); // 0-based

        work = str(boost::format("Smart.NSID.%Xh.NUMD.%d") %
            getLogPgCmd->GetNSID() % numd);
        IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
            getLogPgCmd, work, true);

        LOG_NRM("Verify the buffer's non-retrieved = 0x00");
        SharedMemBufferPtr cmdPayload = getLogPgCmd->GetRWPrpBuffer();
        uint32_t offset = (numd * 4);
        uint8_t *cmdPayloadBuff = (uint8_t *)cmdPayload->GetBuffer() + offset;
        for (; offset < GetLogPage::SMART_DATA_SIZE; offset++) {
            LOG_NRM("Verify data at offset = 0x%X", offset);
            if (*cmdPayloadBuff != 0x0) {
                throw FrmwkEx(HERE, "Invalid data at buffer offset = 0x%08X, "
                    "value = 0x%08X", cmdPayloadBuff, *cmdPayloadBuff);
            }
            cmdPayloadBuff++;
        }
    }
}
예제 #3
0
void
MandatoryErrInfo_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     *  \endverbatim
     */
    string work;
    uint64_t i;
    // Lookup objs which were created in a prior test within group
    SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID))
    SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID))

    ConstSharedIdentifyPtr idCtrlrStruct = gInformative->GetIdentifyCmdCtrlr();
    uint8_t X = idCtrlrStruct->GetValue(IDCTRLRCAP_ELPE) + 1;
    LOG_NRM("Identify controller ELPE = %d (1-based)", X);

    LOG_NRM("Create get log page cmd and assoc some buffer memory");
    SharedGetLogPagePtr getLogPgCmd = SharedGetLogPagePtr(new GetLogPage());

    LOG_NRM("Create memory buffer for log page to request error information");
    SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer());
    send_64b_bitmask prpReq =
        (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);

    LOG_NRM("Get log page to request error information");
    getLogPgCmd->SetLID(ERRINFO_LID);

    // loop for all log entries supported by controller
    for (uint32_t numd = ERRINFO_NUMD; numd <= (X * ERRINFO_NUMD);
        numd += ERRINFO_NUMD) {
        LOG_NRM("Issue Get log page cmd with NUMD = %d and log entries = %d",
            numd, (numd/ERRINFO_NUMD));

        getLogPageMem->Init(GetLogPage::ERRINFO_DATA_SIZE * X, true);
        getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem);
        getLogPgCmd->SetNUMD(numd - 1); // 0-based
        getLogPgCmd->SetNSID(0xFFFFFFFF);
        
        work = str(boost::format("logEnties%d") % (numd / ERRINFO_NUMD));
        IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
            getLogPgCmd, work, true);

        // Verify the buffer's non-retrieved log entries = 0x00.
        SharedMemBufferPtr cmdPayload = getLogPgCmd->GetRWPrpBuffer();
        uint32_t offset = (numd * 4);
        uint8_t *cmdPayloadBuff = (uint8_t *)cmdPayload->GetBuffer() + offset;
        for (; offset < (X * GetLogPage::ERRINFO_DATA_SIZE); offset++) {
            LOG_NRM("Verify data at offset = 0x%X", offset);
            if (*cmdPayloadBuff != 0x0) {
                throw FrmwkEx(HERE, "Invalid data at buffer offset = 0x%08X, "
                    "value = 0x%08X", cmdPayloadBuff, *cmdPayloadBuff);
            }
            cmdPayloadBuff++;
        }
    }
}
예제 #4
0
void
UnsupportRsvdFields_r11b::TestAsyncEvents(SharedACQPtr &acq, SharedASQPtr &asq,
    bool rsvd)
{
    uint32_t isrCount;
    uint32_t ceRemain;
    uint32_t numReaped;
    uint32_t numCE;

    SendAsyncEventRequests(asq, 1, rsvd);

    sleep(5);
    if (acq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 1, numCE, isrCount)
        == true) {
        acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "acq.fail1"),
            "Dump Entire ACQ");
        throw FrmwkEx(HERE, "0 CE's expected in ACQ but found %d CE's", numCE);
    }

    InvalidSQWriteDoorbell();
    sleep(1);
    if (acq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 1, numCE, isrCount)
        == false) {
        acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "acq.fail2"),
            "Dump Entire ACQ");
        throw FrmwkEx(HERE, "1 CE expected in ACQ but found %d CE's", numCE);
    }

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

    union CE *ce = (union CE *)ceMem->GetBuffer();

    if (ce->n.async.asyncEventType != EVENT_TYPE_ERROR_STS) {
        throw FrmwkEx(HERE, "Invalid async event error status, "
            "(Expected : Received) :: (%d : %d)", EVENT_TYPE_ERROR_STS,
            ce->n.async.asyncEventType);
    } else if (ce->n.async.asyncEventInfo != ERR_STS_INVALID_SQ) {
        throw FrmwkEx(HERE, "Invalid async event info, "
            "(Expected : Received) :: (%d : %d)", ERR_STS_INVALID_SQ,
            ce->n.async.asyncEventInfo);
    }
    LOG_NRM("Associated Log page = %d", ce->n.async.assocLogPage);

    ReadLogPage(acq, asq, ce->n.async.assocLogPage);
}
예제 #5
0
파일: memBuffer.cpp 프로젝트: yanma/tnvme
bool
MemBuffer::Compare(const SharedMemBufferPtr compTo)
{
    if (compTo->GetBufSize() != GetBufSize()) {
        throw FrmwkEx(HERE, "Compare buffers not same size: %d != %d",
                      compTo->GetBufSize(), GetBufSize());
    }

    if (memcmp(compTo->GetBuffer(), GetBuffer(), GetBufSize()) != 0) {
        LOG_ERR("Detected data miscompare");
        return false;
    }
    return true;
}
예제 #6
0
void
CIDAcceptedIOSQ_r10b::ReapVerifyCID(SharedIOSQPtr iosq, SharedIOCQPtr iocq,
    uint16_t expCID)
{
    uint32_t isrCount;
    uint32_t ceRemain;
    uint32_t numReaped;
    uint32_t numCE;

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

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

    union CE *ce = (union CE *)ceMem->GetBuffer();
    ProcessCE::Validate(*ce);  // throws upon error

    if (ce->n.CID != expCID) {
        iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.fail"),
            "Dump Entire IOCQ");
        iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq.fail"),
            "Dump Entire IOSQ");
        throw FrmwkEx(HERE, "Received CID %d but expected %d", ce->n.CID,
            expCID);
    }

    if (ce->n.SQID != iosq->GetQId()) {
        iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.fail"),
            "Dump Entire IOCQ");
        iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq.fail"),
            "Dump Entire IOSQ");
        throw FrmwkEx(HERE, "Rx'd SDID %d but expt'd %d", ce->n.SQID,
            iosq->GetQId());
    }

}
예제 #7
0
void
NUMDIsAdhered_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     *  \endverbatim
     */
    // Lookup objs which were created in a prior test within group
    string work;
    uint64_t i;
    
    SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID))
    SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID))

    LOG_NRM("Create get log page cmd and assoc some buffer memory");
    SharedGetLogPagePtr getLogPgCmd = SharedGetLogPagePtr(new GetLogPage());

    LOG_NRM("Get log page to request firmware slot information");
    getLogPgCmd->SetNUMD(NUMDW_ADHERED - 1);  // 0-based
    getLogPgCmd->SetLID(FIRM_SLOT_INFO_LID);
    getLogPgCmd->SetNSID(0xFFFFFFFF);
    
    LOG_NRM("Set the offset into the buffer at 0x%04X", BUFFER_OFFSET);
    SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer());
    getLogPageMem->InitOffset1stPage(GetLogPage::FIRMSLOT_DATA_SIZE,
        BUFFER_OFFSET, true, BUFFER_INIT_VAL);
    send_64b_bitmask prpReq =
        (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);
    getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem);

    IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
        getLogPgCmd, "NUMD.adhered", true);

    LOG_NRM("Compare cmd buffer to verify the last half of buffer = 0xA5");
    SharedMemBufferPtr cmdPayload = getLogPgCmd->GetRWPrpBuffer();
    uint16_t offset = (NUMDW_ADHERED * 4);
    uint8_t *cmdPayloadBuff = (uint8_t *)cmdPayload->GetBuffer() + offset;
    for (; offset < (GetLogPage::FIRMSLOT_DATA_SIZE); offset++) {
        LOG_NRM("Verify data at offset = 0x%X", offset);
        if (*cmdPayloadBuff != BUFFER_INIT_VAL) {
            throw FrmwkEx(HERE, "NUMD not adhered at offset = 0x%08X, "
                "value = 0x%08X", cmdPayloadBuff, *cmdPayloadBuff);
        }
        cmdPayloadBuff++;
    }
}
예제 #8
0
파일: cq.cpp 프로젝트: Kurusamy/tnvme
uint16_t
CQ::Reap(uint16_t &ceRemain, SharedMemBufferPtr memBuffer, uint32_t &isrCount,
    uint16_t ceDesire, bool zeroMem)
{
    int rc;
    struct nvme_reap reap;

    // The tough part of reaping all which can be reaped, indicated by
    // (ceDesire == 0), is that CE's can be arriving from hdw between the time
    // one calls ReapInquiry() and Reap(). In essence this indicates we really
    // can never know for certain how many there are to be reaped, and thus
    // never really knowing how large to make a buffer to reap CE's into.
    // The solution is to enforce brute force methods by allocating max CE's
    if (ceDesire == 0) {
        // Per NVME spec: 1 empty CE implies a full CQ, can't truly fill all
        ceDesire = (GetNumEntries() - 1);
    } else if (ceDesire > (GetNumEntries() - 1)) {
        // Per NVME spec: 1 empty CE implies a full CQ, can't truly fill all
        LOG_NRM("Requested num of CE's exceeds max can fit, resizing");
        ceDesire = (GetNumEntries() - 1);
    }

    // Allocate enough space to contain the CE's
    memBuffer->Init(GetEntrySize()*ceDesire);
    if (zeroMem)
        memBuffer->Zero();

    reap.q_id = GetQId();
    reap.elements = ceDesire;
    reap.size = memBuffer->GetBufSize();
    reap.buffer = memBuffer->GetBuffer();
    if ((rc = ioctl(mFd, NVME_IOCTL_REAP, &reap)) < 0) {
        LOG_ERR("Error during reaping CE's, rc =%d", rc);
        throw exception();
    }

    isrCount = reap.isr_count;
    ceRemain = reap.num_remaining;
    LOG_NRM("Reaped %d CE's, %d remain, from CQ %d, ISR count: %d",
        reap.num_reaped, reap.num_remaining, GetQId(), isrCount);
    return reap.num_reaped;
}
예제 #9
0
void
UnsupportRsvdFields_r11b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     * \endverbatim
     */

    // Lookup objs which were created in a prior test within group
    SharedIOSQPtr iosq = CAST_TO_IOSQ(gRsrcMngr->GetObj(IOSQ_GROUP_ID));
    SharedIOCQPtr iocq = CAST_TO_IOCQ(gRsrcMngr->GetObj(IOCQ_GROUP_ID));

    SharedDatasetMgmtPtr datasetMgmtCmd =
        SharedDatasetMgmtPtr(new DatasetMgmt());

    uint16_t timeout;
    if (gCmdLine.setAD)
        timeout = 1000;
    else
        timeout = 1;

    ConstSharedIdentifyPtr idCtrlr = gInformative->GetIdentifyCmdCtrlr();
    for (uint64_t i = 1; i <= idCtrlr->GetValue(IDCTRLRCAP_NN); i++) {
        LOG_NRM("Processing namspc %ld", i);
        datasetMgmtCmd->SetNSID(i);

        LOG_NRM("Create memory to contain 1 dataset range def");
        SharedMemBufferPtr rangeMem = SharedMemBufferPtr(new MemBuffer());
        rangeMem->Init(sizeof(RangeDef), true);
        send_64b_bitmask prpReq =
            (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);
        datasetMgmtCmd->SetPrpBuffer(prpReq, rangeMem);

        LOG_NRM("Setup generic range def guidelines");
        RangeDef *rangeDef = (RangeDef *)rangeMem->GetBuffer();
        rangeDef->length = 1;

        if (gCmdLine.setAD)
            datasetMgmtCmd->SetAD(true);

        IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(timeout), iosq,
            iocq, datasetMgmtCmd, "none.set", true);

        LOG_NRM("Set all cmd's rsvd bits");
        uint32_t work = datasetMgmtCmd->GetDword(0);
        work |= 0x00007c00;      // Set DW0_b14:10 bits
        datasetMgmtCmd->SetDword(work, 0);

        datasetMgmtCmd->SetDword(0xffffffff, 2);
        datasetMgmtCmd->SetDword(0xffffffff, 3);
        datasetMgmtCmd->SetDword(0xffffffff, 4);
        datasetMgmtCmd->SetDword(0xffffffff, 5);
        datasetMgmtCmd->SetDword(0xffffffff, 8);
        datasetMgmtCmd->SetDword(0xffffffff, 9);

        work = datasetMgmtCmd->GetDword(10);
        work |= 0xffffff00;     // Set DW10_b31:8 bits
        datasetMgmtCmd->SetDword(work, 10);

        work = datasetMgmtCmd->GetDword(11);
        work |= 0xfffffff8;     // Set DW11_b31:3 bits
        if (gCmdLine.setAD)
            work |= 0x4; // Set Bit2 AD=1 (Deallocate)
        datasetMgmtCmd->SetDword(work, 11);

        datasetMgmtCmd->SetDword(0xffffffff, 12);
        datasetMgmtCmd->SetDword(0xffffffff, 13);
        datasetMgmtCmd->SetDword(0xffffffff, 14);
        datasetMgmtCmd->SetDword(0xffffffff, 15);

        IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(timeout), iosq,
            iocq, datasetMgmtCmd, "all.set", true);
    }
}
예제 #10
0
void
VerifyNUSE_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     * \endverbatim
     */
    string work;

    LOG_NRM("Lookup Q'S which were created in a prior test within group");
    SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID))
    SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID))
    SharedIOSQPtr iosq = CAST_TO_IOSQ(gRsrcMngr->GetObj(IOSQ_GROUP_ID));
    SharedIOCQPtr iocq = CAST_TO_IOCQ(gRsrcMngr->GetObj(IOCQ_GROUP_ID));

    LOG_NRM("Search for 1st bare/meta or e2e namespace.");
    Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E();
    uint64_t ncap = namspcData.idCmdNamspc->GetValue(IDNAMESPC_NCAP);
    LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat();
    uint64_t lbaDataSize = namspcData.idCmdNamspc->GetLBADataSize();
    LOG_NRM("For namespace ID #%d; NCAP = 0x%08lX; LBA Size (B): %lu; NCAP*LBA "
        "Size (GB): %.2f", namspcData.id, ncap, lbaDataSize,
        ncap * lbaDataSize / 1e9);

    LOG_NRM("Create dataset mgmt cmd to be used subsequently");
    SharedDatasetMgmtPtr datasetMgmtCmd =
        SharedDatasetMgmtPtr(new DatasetMgmt());
    SharedMemBufferPtr rangeMem = SharedMemBufferPtr(new MemBuffer());
    rangeMem->Init((NUM_RANGES * sizeof(RangeDef)), true);

    send_64b_bitmask prpBitmask =
            (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);
    datasetMgmtCmd->SetNSID(namspcData.id);
    datasetMgmtCmd->SetNR(NUM_RANGES - 1);  // convert to 0-based
    datasetMgmtCmd->SetPrpBuffer(prpBitmask, rangeMem);
    datasetMgmtCmd->SetAD(true);

    LOG_NRM("Deallocate every LBA in namespace ID #%d", namspcData.id);
    RangeDef *rangePtr = (RangeDef *)rangeMem->GetBuffer();
    rangePtr->slba = 0;
    rangePtr->length = ncap;

    const double deallocRate = 1.6e8; // bytes / ms
    work = str(boost::format("deallocate.%08Xh") % ncap);
    IO::SendAndReapCmd(mGrpName, mTestName, ncap * lbaDataSize / deallocRate
        + 10000, iosq, iocq, datasetMgmtCmd, work, true);

    LOG_NRM("Create identify cmd & assoc some buffer memory");
    SharedIdentifyPtr idCmdNamSpc = SharedIdentifyPtr(new Identify());
    LOG_NRM("Force identify to request namespace struct");
    idCmdNamSpc->SetCNS(CNS_Namespace);
    idCmdNamSpc->SetNSID(namspcData.id);
    SharedMemBufferPtr idMemNamSpc = SharedMemBufferPtr(new MemBuffer());
    idMemNamSpc->InitAlignment(Identify::IDEAL_DATA_SIZE, PRP_BUFFER_ALIGNMENT,
        true, 0);
    send_64b_bitmask idPrpNamSpc =
        (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);
    idCmdNamSpc->SetPrpBuffer(idPrpNamSpc, idMemNamSpc);

    work = str(boost::format("IdentifyNamspc.nsid.%d.lba.all") % namspcData.id);
    IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
        idCmdNamSpc, work, true);

    LOG_NRM("Verify namespace utilization is zero after de-allocation.");
    uint64_t nuse = idCmdNamSpc->GetValue(IDNAMESPC_NUSE);
    uint64_t nsfeat = idCmdNamSpc->GetValue(IDNAMESPC_NSFEAT);
    if (nuse != 0x0 && ((nsfeat & 0x1) == 0x1)) {
        throw FrmwkEx(HERE, "Expected namspc utilization = 0x0 but found "
            "namspc utilization = 0x%08X", nuse);
    }

    LOG_NRM("Write data pattern and issue a single block to LBA 0");
    SharedWritePtr writeCmd = SharedWritePtr(new Write());
    SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());

    switch (namspcData.type) {
    case Informative::NS_BARE:
        writeMem->Init(lbaDataSize);
        writeMem->SetDataPattern(DATAPAT_INC_32BIT);
        break;
    case Informative::NS_METAS:
        writeMem->Init(lbaDataSize);
        if (gRsrcMngr->SetMetaAllocSize(lbaFormat.MS) == false)
            throw FrmwkEx(HERE);
        writeCmd->AllocMetaBuffer();
        writeMem->SetDataPattern(DATAPAT_INC_32BIT);
        writeCmd->SetMetaDataPattern(DATAPAT_INC_32BIT);
        break;
    case Informative::NS_METAI:
        writeMem->Init(lbaDataSize + lbaFormat.MS);
        writeMem->SetDataPattern(DATAPAT_INC_32BIT);
        break;
    case Informative::NS_E2ES:
    case Informative::NS_E2EI:
        throw FrmwkEx(HERE, "Deferring work to handle this case in future");
        break;
    }

    prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE |
        MASK_PRP2_LIST);
    writeCmd->SetPrpBuffer(prpBitmask, writeMem);
    writeCmd->SetNSID(namspcData.id);
    writeCmd->SetNLB(0);

    work = str(boost::format("write.nsid.%d.nlba.0") % namspcData.id);
    IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq,
        iocq, writeCmd, work, true);

    work = str(boost::format("IdentifyNamspc.nsid.%d.nlba.0") % namspcData.id);
    IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq,
        idCmdNamSpc, work, true);

    LOG_NRM("Verify namespace utilization is one after single LBA write cmd.");
    nuse = idCmdNamSpc->GetValue(IDNAMESPC_NUSE);
    nsfeat = idCmdNamSpc->GetValue(IDNAMESPC_NSFEAT);
    if (nuse != 0x1  && ((nsfeat & 0x1) == 0x1)) {
        throw FrmwkEx(HERE, "Expected namspc utilization = 0x1 but found "
            "namspc utilization = 0x%08X", nuse);
    }
}
예제 #11
0
void
VerifyMaxEvents_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) none
     *  \endverbatim
     */
    uint32_t isrCount;
    uint32_t ceRemain;
    uint32_t numReaped;
    uint32_t numCE;

    LOG_NRM("Issue Identify.AERL to get Async Event Req Limit (AERL)");
    uint8_t nAerlimit = gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_AERL) + 1; // Convert to 1-based.

    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(nAerlimit + 2); // one extra space than Q full condition

    SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd));
    asq->Init(nAerlimit + 2); // one extra space than Q full condition

    // 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("Issue one more than %d (async event req limit)", nAerlimit);
    SendAsyncEventRequests(asq, (nAerlimit + 1));

    LOG_NRM("Delay 5 sec");
    sleep(5);

    if (acq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 1, numCE, isrCount)
        == false) {
        acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "acq.fail1"),
            "Dump Entire ACQ");
        throw FrmwkEx(HERE, "1 CE's expected in ACQ but found %d CE's", numCE);
    }

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

    LOG_NRM("verify SC = Async Event Limit Exceeded");
    union CE *ce = (union CE *)ceMem->GetBuffer();
    ProcessCE::Validate(*ce, CESTAT_ASYNC_REQ_EXCEED);

    for (uint8_t nAer = 0; nAer < nAerlimit; nAer++) {
        LOG_NRM("Ring doorbell for IOSQ #1");
        InvalidSQWriteDoorbell();
        sleep(1);
        LOG_NRM("verify CE exists in ACQ for invalid SQID doorbell write");
        if (acq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 1, numCE, isrCount)
            == false) {
            acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
                "acq.fail4"), "Dump Entire ACQ");
            throw FrmwkEx(HERE, "1 CE expected in ACQ but found %d CEs", numCE);
        }

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

        union CE *ce = (union CE *)ceMem->GetBuffer();
        if (ce->n.async.asyncEventType != EVENT_TYPE_ERROR_STS) {
            throw FrmwkEx(HERE, "Invalid async event error status, "
                "(Expected : Received) :: (%d : %d)", EVENT_TYPE_ERROR_STS,
                ce->n.async.asyncEventType);
        } else if (ce->n.async.asyncEventInfo != ERR_STS_INVALID_SQ) {
            throw FrmwkEx(HERE, "Invalid async event info, "
                "(Expected : Received) :: (%d : %d)", ERR_STS_INVALID_SQ,
                ce->n.async.asyncEventInfo);
        }
        LOG_NRM("Associated Log page = %d", ce->n.async.assocLogPage);
        ReadLogPage(acq, asq, ce->n.async.assocLogPage);
    }
}
예제 #12
0
void
VerifyMasking_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) none
     *  \endverbatim
     */
    uint32_t isrCount;
    uint32_t ceRemain;
    uint32_t numReaped;
    uint32_t numCE;

    LOG_NRM("Issue Identify.AERL to get Async Event Req Limit (AERL)");
    uint8_t nAerlimit = gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_AERL) + 1; // Convert to 1-based.

    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(nAerlimit + 1); // one extra space than Q full condition

    SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd));
    asq->Init(nAerlimit + 1); // one extra space than Q full condition

    // 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("Issue %d async event requests", nAerlimit);
    SendAsyncEventRequests(asq, nAerlimit);

    for (uint8_t nAer = 1; nAer <= nAerlimit; nAer++) {
        LOG_NRM("Ring doorbell for IOSQ #1");
        InvalidSQWriteDoorbell();
        sleep(5);
        if (nAer == 1) {
            LOG_NRM("Verify only 1 CE exists for invalid SQID doorbell write");
            if (acq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 1, numCE,
                isrCount) == false) {
                acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
                    "acq.fail.reapinq1"), "Dump Entire ACQ");
                throw FrmwkEx(HERE, "1 CE expected in but found %d CEs", numCE);
            }
            SharedMemBufferPtr ceMem = SharedMemBufferPtr(new MemBuffer());
            if ((numReaped = acq->Reap(ceRemain, ceMem, isrCount, numCE, true))
                != 1) {
                acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
                    "acq.fail.reap1"), "Dump Entire ACQ");
                throw FrmwkEx(HERE, "Unable to reap on ACQ");
            }

            union CE *ce = (union CE *)ceMem->GetBuffer();
            if (ce->n.async.asyncEventType != EVENT_TYPE_ERROR_STS) {
                throw FrmwkEx(HERE, "Invalid async event error status, "
                    "(Expected : Received) :: (%d : %d)", EVENT_TYPE_ERROR_STS,
                    ce->n.async.asyncEventType);
            } else if (ce->n.async.asyncEventInfo != ERR_STS_INVALID_SQ) {
                throw FrmwkEx(HERE, "Invalid async event info, "
                    "(Expected : Received) :: (%d : %d)", ERR_STS_INVALID_SQ,
                    ce->n.async.asyncEventInfo);
            }
        } else {
            LOG_NRM("Verify only 1 CE exists for %d cmds as "
                "async events are masked (GetLogPage not called)", nAer);
            if (acq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 2, numCE,
                isrCount) == true) {
                acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
                    "acq.fail.reapinq2"), "Dump Entire ACQ");
                throw FrmwkEx(HERE, "1 CE expected but found %d CEs", numCE);
            }
        }
    }
}
예제 #13
0
void
VerifyEventQueueing_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) none
     *  \endverbatim
     */
    uint32_t isrCount;
    uint32_t ceRemain;
    uint32_t numReaped;
    uint32_t numCE;

    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);

    LOG_NRM("Ring doorbell for IOSQ #1");
    InvalidSQWriteDoorbell();

    LOG_NRM("Delay 5 sec");
    sleep(5);

    LOG_NRM("Verify no CE's exist in ACQ");
    if (acq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 1, numCE, isrCount)
        == true) {
        acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
            "acq.fail.0rinq"), "Dump Entire ACQ");
        throw FrmwkEx(HERE, "0 CE's expected in ACQ but found %d CE's", numCE);
    }

    LOG_NRM("Issue one async event ");
    SendAsyncEventRequests(asq, 1);

    LOG_NRM("verify CE exists in ACQ for invalid SQID doorbell write");
    if (acq->ReapInquiryWaitSpecify(CALC_TIMEOUT_ms(1), 1, numCE, isrCount)
        == false) {
        acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
            "acq.fail.1rinq"), "Dump Entire ACQ");
        throw FrmwkEx(HERE, "1 CE expected in ACQ but found %d CEs", numCE);
    }

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

    union CE *ce = (union CE *)ceMem->GetBuffer();
    if (ce->n.async.asyncEventType != EVENT_TYPE_ERROR_STS) {
        acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
            "acq.fail.sts"), "Dump Entire ACQ");
        throw FrmwkEx(HERE, "Invalid async event error status, "
            "(Expected : Received) :: (%d : %d)", EVENT_TYPE_ERROR_STS,
            ce->n.async.asyncEventType);
    } else if (ce->n.async.asyncEventInfo != ERR_STS_INVALID_SQ) {
        acq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName,
            "acq.fail.sc"), "Dump Entire ACQ");
        throw FrmwkEx(HERE, "Invalid async event info, "
            "(Expected : Received) :: (%d : %d)", ERR_STS_INVALID_SQ,
            ce->n.async.asyncEventInfo);
    }
}