예제 #1
0
void
WriteDataPat_r10b::WriteDataPattern()
{
    uint64_t regVal;


    LOG_NRM("Calc buffer size to write %d logical blks to media",
        WRITE_DATA_PAT_NUM_BLKS);
    ConstSharedIdentifyPtr namSpcPtr = gInformative->GetIdentifyCmdNamspc(1);
    if (namSpcPtr == Identify::NullIdentifyPtr) {
        LOG_ERR("Namespace #1 must exist");
        throw exception();
    }
    uint64_t lbaDataSize = namSpcPtr->GetLBADataSize();


    LOG_NRM("Create data pattern to write to media");
    SharedMemBufferPtr dataPat = SharedMemBufferPtr(new MemBuffer());
    dataPat->Init(WRITE_DATA_PAT_NUM_BLKS * lbaDataSize);
    dataPat->SetDataPattern(MemBuffer::DATAPAT_INC_16BIT);
    dataPat->Dump(FileSystem::PrepLogFile(mGrpName, mTestName, "DataPat"),
        "Write buffer's data pattern");
    

    LOG_NRM("Create a generic write cmd to send data pattern to namspc 1");
    SharedWritePtr writeCmd = SharedWritePtr(new Write(mFd));
    send_64b_bitmask prpBitmask = (send_64b_bitmask)
        (MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST);
    writeCmd->SetPrpBuffer(prpBitmask, dataPat);
    writeCmd->SetNSID(1);
    writeCmd->SetNLB(WRITE_DATA_PAT_NUM_BLKS-1);    // convert to 0-based value

    // Lookup objs which were created in a prior test within group
    SharedIOSQPtr iosqContig = CAST_TO_IOSQ(
        gRsrcMngr->GetObj(IOSQ_CONTIG_GROUP_ID))
    SharedIOCQPtr iocqContig = CAST_TO_IOCQ(
        gRsrcMngr->GetObj(IOCQ_CONTIG_GROUP_ID))
    SharedIOSQPtr iosqDiscontig = CAST_TO_IOSQ(
        gRsrcMngr->GetObj(IOSQ_DISCONTIG_GROUP_ID))
    SharedIOCQPtr iocqDiscontig = CAST_TO_IOCQ(
        gRsrcMngr->GetObj(IOCQ_DISCONTIG_GROUP_ID))

    LOG_NRM("Send the cmd to hdw via the contiguous IOQ's");
    SendToIOSQ(iosqContig, iocqContig, writeCmd, "contig");

    // To run the discontig part of this test, the hdw must support that feature
    if (gRegisters->Read(CTLSPC_CAP, regVal) == false) {
        LOG_ERR("Unable to determine Q memory requirements");
        throw exception();
    } else if (regVal & CAP_CQR) {
        LOG_NRM("Unable to utilize discontig Q's, DUT requires contig");
        return;
    }

    LOG_NRM("Send the cmd to hdw via the discontiguous IOQ's");
    SendToIOSQ(iosqDiscontig, iocqDiscontig, writeCmd, "discontig");
}
void
PRPOffsetDualPgMultiBlk_r10b::VerifyDataPat(SharedReadPtr readCmd,
    DataPattern dataPat, uint64_t wrVal, uint64_t metabufSz)
{
    LOG_NRM("Compare read vs written data to verify");
    SharedMemBufferPtr wrPayload = SharedMemBufferPtr(new MemBuffer());
    wrPayload->Init(readCmd->GetPrpBufferSize());
    wrPayload->SetDataPattern(dataPat, wrVal);

    SharedMemBufferPtr rdPayload = readCmd->GetRWPrpBuffer();
    if (rdPayload->Compare(wrPayload) == false) {
        rdPayload->Dump(
            FileSystem::PrepDumpFile(mGrpName, mTestName, "ReadPayload"),
            "Data read from media miscompared from written");
        wrPayload->Dump(
            FileSystem::PrepDumpFile(mGrpName, mTestName, "WrittenPayload"),
            "Data read from media miscompared from written");
        throw FrmwkEx(HERE, "Data miscompare");
    }

    if (readCmd->GetMetaBuffer() != NULL) {
        SharedMemBufferPtr metaWrPayload = SharedMemBufferPtr(new MemBuffer());
        metaWrPayload->Init(metabufSz);
        metaWrPayload->SetDataPattern(dataPat, wrVal);

        if (readCmd->CompareMetaBuffer(metaWrPayload) == false) {
            readCmd->Dump(
                FileSystem::PrepDumpFile(mGrpName, mTestName, "MetaRdPayload"),
                "Meta Data read from media miscompared from written");
            metaWrPayload->Dump(
                FileSystem::PrepDumpFile(mGrpName, mTestName, "MetaWrPayload"),
                "Meta Data read from media miscompared from written");
            throw FrmwkEx(HERE, "Meta Data miscompare");
        }
    }
}
예제 #3
0
void
UnsupportRsvdFields_r10b::WriteReadVerify(SharedIOSQPtr iosq,
    SharedIOCQPtr iocq)
{
    Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E();
    LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat();
    uint64_t lbaDataSize = namspcData.idCmdNamspc->GetLBADataSize();

    SharedWritePtr writeCmd = SharedWritePtr(new Write());
    SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());

    SharedReadPtr readCmd = SharedReadPtr(new Read());
    SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer());

    send_64b_bitmask prpBitmask = (send_64b_bitmask)
        (MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST);

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

    writeCmd->SetPrpBuffer(prpBitmask, writeMem);
    writeCmd->SetNSID(namspcData.id);
    writeCmd->SetNLB(0);

    readCmd->SetPrpBuffer(prpBitmask, readMem);
    readCmd->SetNSID(namspcData.id);
    readCmd->SetNLB(0);

    switch (namspcData.type) {
    case Informative::NS_BARE:
        writeMem->SetDataPattern(DATAPAT_INC_32BIT);
        break;
    case Informative::NS_METAS:
        writeMem->SetDataPattern(DATAPAT_INC_32BIT);
        writeCmd->SetMetaDataPattern(DATAPAT_INC_32BIT);
        break;
    case Informative::NS_METAI:
        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;
    }

    IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq,
        iocq, writeCmd, "", true);

    IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq,
        iocq, readCmd, "", true);

    VerifyDataPat(readCmd, writeCmd);
}
void
PRPOffsetSinglePgSingleBlk_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     * \endverbatim
     */
    string work;
    int64_t X;
    bool enableLog;

    LOG_NRM("Initialize random seed");
    srand (17);

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

    LOG_NRM("Get namspc and determine LBA size");
    Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E();
    send_64b_bitmask prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE);
    LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat();
    uint64_t lbaDataSize = namspcData.idCmdNamspc->GetLBADataSize();

    uint8_t mpsRegVal;
    if (gCtrlrConfig->GetMPS(mpsRegVal) == false)
        throw FrmwkEx(HERE, "Unable to get MPS value from CC.");

    switch (namspcData.type) {
    case Informative::NS_BARE:
        X =  (int64_t)(1 << (mpsRegVal + 12)) - lbaDataSize;
        break;
    case Informative::NS_METAS:
        if (gRsrcMngr->SetMetaAllocSize(lbaFormat.MS) == false)
            throw FrmwkEx(HERE);
        X =  (int64_t)(1 << (mpsRegVal + 12)) - lbaDataSize;
        break;
    case Informative::NS_METAI:
        X =  (int64_t)(1 << (mpsRegVal + 12)) - (lbaDataSize + lbaFormat.MS);
        break;
    case Informative::NS_E2ES:
    case Informative::NS_E2EI:
        throw FrmwkEx(HERE, "Deferring work to handle this case in future");
        break;
    }
    if (X <= 0) {
        LOG_WARN("CC.MPS (0x%04X) < lba data size(LBADS) + MS "
            "(0x08%lX + 0x04%X) ; Can't run test.", (1 << (mpsRegVal + 12)),
            lbaDataSize, lbaFormat.MS);
        return;
    }

    LOG_NRM("Prepare cmds to send to the queues.");
    SharedWritePtr writeCmd = CreateWriteCmd(namspcData);
    SharedReadPtr readCmd = CreateReadCmd(namspcData);

    DataPattern dataPattern;
    uint64_t wrVal;
    uint32_t prp2RandVal[2];
    for (int64_t pgOff = 0; pgOff <= X; pgOff += 4) {
        LOG_NRM("Processing at page offset #%ld", pgOff);
        if ((pgOff % 8) != 0) {
            dataPattern = DATAPAT_CONST_8BIT;
            wrVal = pgOff;
            prp2RandVal[0] = rand();
            prp2RandVal[1] = rand();
            work = str(boost::format("dataPat.constb.memOff.%d") % pgOff);
        } else {
            dataPattern = DATAPAT_INC_16BIT;
            wrVal = pgOff;
            prp2RandVal[0] = 0;
            prp2RandVal[1] = 0;
            work = str(boost::format("dataPat.incw.memOff.%d") % pgOff);
        }
        SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());

        switch (namspcData.type) {
        case Informative::NS_BARE:
            writeMem->InitOffset1stPage(lbaDataSize, pgOff, false);
            break;
        case Informative::NS_METAS:
            writeMem->InitOffset1stPage(lbaDataSize, pgOff, false);
            writeCmd->SetMetaDataPattern(dataPattern, wrVal);
            break;
        case Informative::NS_METAI:
            writeMem->InitOffset1stPage
                (lbaDataSize + lbaFormat.MS, pgOff, false);
            break;
        case Informative::NS_E2ES:
        case Informative::NS_E2EI:
            throw FrmwkEx(HERE, "Deferring work to handle this case in future");
            break;
        }
        writeCmd->SetPrpBuffer(prpBitmask, writeMem);
        writeMem->SetDataPattern(dataPattern, wrVal);

        LOG_NRM("Set 64 bits of PRP2 CDW 8 & 9 with random or 0 for wr cmd.");
        writeCmd->SetDword(prp2RandVal[0], 8);
        writeCmd->SetDword(prp2RandVal[1], 9);

        enableLog = false;
        if ((pgOff <= 8) || (pgOff >= (X - 8)))
            enableLog = true;

        IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq, iocq,
            writeCmd, work, enableLog);

        SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer());
        switch (namspcData.type) {
        case Informative::NS_BARE:
            readMem->InitOffset1stPage(lbaDataSize, pgOff, false);
            break;
        case Informative::NS_METAS:
            readMem->InitOffset1stPage(lbaDataSize, pgOff, false);
            break;
        case Informative::NS_METAI:
            readMem->InitOffset1stPage
                (lbaDataSize + lbaFormat.MS, pgOff, false);
            break;
        case Informative::NS_E2ES:
        case Informative::NS_E2EI:
            throw FrmwkEx(HERE, "Deferring work to handle this case in future");
            break;
        }
        readCmd->SetPrpBuffer(prpBitmask, readMem);

        LOG_NRM("Set 64 bits of PRP2 CDW 8 & 9 with random or 0 for rd cmd.");
        readCmd->SetDword(prp2RandVal[0], 8);
        readCmd->SetDword(prp2RandVal[1], 9);

        IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq, iocq,
            readCmd, work, enableLog);

        VerifyDataPattern(readCmd, dataPattern, wrVal);
    }
}
void
PRPOffsetDualPgMultiBlk_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * None.
     * \endverbatim
     */
    string work;
    int64_t X;
    bool enableLog;

    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(mFd)))
    acq->Init(5);
    SharedASQPtr asq = CAST_TO_ASQ(SharedASQPtr(new ASQ(mFd)))
    asq->Init(5);

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

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

    SharedIOCQPtr iocq;
    SharedIOSQPtr iosq;
    InitTstRsrcs(asq, acq, iosq, iocq);

    LOG_NRM("Compute memory page size from CC.MPS.");
    uint8_t mpsRegVal;
    if (gCtrlrConfig->GetMPS(mpsRegVal) == false)
        throw FrmwkEx(HERE, "Unable to get MPS value from CC.");
    uint64_t ccMPS = (uint64_t)(1 << (mpsRegVal + 12));

    LOG_NRM("Get namspc and determine LBA size");
    Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E();
    send_64b_bitmask prpBitmask =
        (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE);
    LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat();
    uint64_t lbaDataSize = (1 << lbaFormat.LBADS);
    LOG_NRM("LBA data size is %ld.", lbaDataSize);

    LOG_NRM("Seeking max data xfer size for chosen namspc");
    ConstSharedIdentifyPtr idCmdCtrlr = gInformative->GetIdentifyCmdCtrlr();
    uint32_t maxDtXferSz = idCmdCtrlr->GetMaxDataXferSize();

    SharedWritePtr writeCmd = SharedWritePtr(new Write());
    writeCmd->SetNSID(namspcData.id);

    SharedReadPtr readCmd = SharedReadPtr(new Read());
    readCmd->SetNSID(namspcData.id);

    SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());
    SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer());

    switch (namspcData.type) {
    case Informative::NS_BARE:
        X =  ccMPS - lbaDataSize;
        break;
    case Informative::NS_METAS:
        X =  ccMPS - lbaDataSize;
        LOG_NRM("Allocating separate meta data buffer.");
        if (gRsrcMngr->SetMetaAllocSize(
            lbaFormat.MS * ((2 * ccMPS) / lbaDataSize)) == false) {
            throw FrmwkEx(HERE, "Unable to allocate Meta buffers.");
        }
        writeCmd->AllocMetaBuffer();
        readCmd->AllocMetaBuffer();
        break;
    case Informative::NS_METAI:
        X =  ccMPS - (lbaDataSize + lbaFormat.MS);
        break;
    case Informative::NS_E2ES:
    case Informative::NS_E2EI:
        throw FrmwkEx(HERE, "Deferring work to handle this case in future");
        break;
    }
    if (X < 0) {
        LOG_WARN("CC.MPS < lba data size(LBADS); Can't run test.");
        return;
    }

    DataPattern dataPat;
    uint64_t wrVal;
    uint64_t Y;

    for (int64_t pgOff = 0; pgOff <= X; pgOff += 4) {
        switch (namspcData.type) {
        case Informative::NS_BARE:
        case Informative::NS_METAS:
            Y = ((2 * ccMPS) - pgOff) / lbaDataSize;
            break;
        case Informative::NS_METAI:
            Y = ((2 * ccMPS) - pgOff) / (lbaDataSize + lbaFormat.MS);
            break;
        case Informative::NS_E2ES:
        case Informative::NS_E2EI:
            throw FrmwkEx(HERE, "Deferring work to handle this case in future");
            break;
        }
        for (uint64_t nLBAs = 1; nLBAs <= Y; nLBAs++) {
            LOG_NRM("Sending LBA #%ld of #%ld", nLBAs, Y);
            if ((maxDtXferSz != 0) && (maxDtXferSz < (lbaDataSize * nLBAs))) {
                // If the total data xfer exceeds the maximum data xfer
                // allowed then we break from the inner loop and continue
                // test with next offset (outer loop).
                LOG_WARN("Data xfer size exceeds max allowed, continuing..");
                break;
            }
            if ((nLBAs % 2) != 0) {
                dataPat = DATAPAT_INC_32BIT;
                wrVal = pgOff + nLBAs;
            } else {
                dataPat = DATAPAT_CONST_16BIT;
                wrVal = pgOff + nLBAs;
            }

            uint64_t metabufSz = nLBAs * lbaFormat.MS;
            switch (namspcData.type) {
            case Informative::NS_BARE:
                writeMem->InitOffset1stPage((lbaDataSize * nLBAs), pgOff,
                    false);
                readMem->InitOffset1stPage((lbaDataSize * nLBAs), pgOff, false);
                break;
            case Informative::NS_METAS:
                writeMem->InitOffset1stPage((lbaDataSize * nLBAs), pgOff,
                    false);
                readMem->InitOffset1stPage((lbaDataSize * nLBAs), pgOff, false);
                writeCmd->SetMetaDataPattern(dataPat, wrVal, 0, metabufSz);
                break;
            case Informative::NS_METAI:
                writeMem->InitOffset1stPage(
                    ((lbaDataSize + lbaFormat.MS) * nLBAs), pgOff, false);
                readMem->InitOffset1stPage(
                    ((lbaDataSize + lbaFormat.MS) * nLBAs), pgOff, false);
                break;
            case Informative::NS_E2ES:
            case Informative::NS_E2EI:
                throw FrmwkEx(HERE,
                    "Deferring work to handle this case in future");
                break;
            }
            work = str(boost::format("pgOff.%d.nlba.%d") % pgOff % nLBAs);
            writeCmd->SetPrpBuffer(prpBitmask, writeMem);
            writeMem->SetDataPattern(dataPat, wrVal);
            writeCmd->SetNLB(nLBAs - 1); // convert to 0 based.

            enableLog = false;
            if ((pgOff <= 8) || (pgOff >= (X - 8)))
                enableLog = true;

            IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq,
                iocq, writeCmd, work, enableLog);

            readCmd->SetPrpBuffer(prpBitmask, readMem);
            readCmd->SetNLB(nLBAs - 1); // convert to 0 based.

            IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq,
                iocq, readCmd, work, enableLog);

            VerifyDataPat(readCmd, dataPat, wrVal, metabufSz);
        }
    }
}
예제 #6
0
void
StartingLBABare_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     * \endverbatim
     */
    string work;
    bool enableLog;
    ConstSharedIdentifyPtr namSpcPtr;

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

    ConstSharedIdentifyPtr idCmdCtrlr = gInformative->GetIdentifyCmdCtrlr();
    uint32_t maxDtXferSz = idCmdCtrlr->GetMaxDataXferSize();
    if (maxDtXferSz == 0)
        maxDtXferSz = MAX_DATA_TX_SIZE;

    LOG_NRM("Prepare cmds to be send through Q's.");
    SharedWritePtr writeCmd = SharedWritePtr(new Write());
    SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());
    send_64b_bitmask prpBitmask = (send_64b_bitmask)
        (MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST);

    SharedReadPtr readCmd = SharedReadPtr(new Read());
    SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer());

    DataPattern dataPat[] = {
        DATAPAT_INC_8BIT,
        DATAPAT_CONST_8BIT,
        DATAPAT_INC_16BIT,
        DATAPAT_CONST_16BIT,
        DATAPAT_INC_32BIT,
        DATAPAT_CONST_32BIT
    };
    uint64_t dpArrSize = sizeof(dataPat) / sizeof(dataPat[0]);

    LOG_NRM("Seeking all bare namspc's.");
    vector<uint32_t> bare = gInformative->GetBareNamespaces();
    for (size_t i = 0; i < bare.size(); i++) {
        LOG_NRM("Processing for BARE name space id #%d", bare[i]);
        namSpcPtr = gInformative->GetIdentifyCmdNamspc(bare[i]);
        uint64_t ncap = namSpcPtr->GetValue(IDNAMESPC_NCAP);
        uint64_t lbaDataSize = namSpcPtr->GetLBADataSize();
        uint64_t maxWrBlks = maxDtXferSz / lbaDataSize;

        writeMem->Init(maxWrBlks * lbaDataSize);
        writeCmd->SetPrpBuffer(prpBitmask, writeMem);
        writeCmd->SetNSID(bare[i]);
        writeCmd->SetNLB(maxWrBlks - 1);  // 0 based value.

        readMem->Init(maxWrBlks * lbaDataSize);
        readCmd->SetPrpBuffer(prpBitmask, readMem);
        readCmd->SetNSID(bare[i]);
        readCmd->SetNLB(maxWrBlks - 1);  // 0 based value.

        for (uint64_t nWrBlks = 0; nWrBlks < (ncap - 1); nWrBlks += maxWrBlks) {
            LOG_NRM("Sending #%ld blks of #%ld", nWrBlks, (ncap -1));
            for (uint64_t nLBA = 0; nLBA < maxWrBlks; nLBA++) {
                writeMem->SetDataPattern(dataPat[nLBA % dpArrSize],
                    (nWrBlks + nLBA + 1), (nLBA * lbaDataSize), lbaDataSize);
            }
            writeCmd->SetSLBA(nWrBlks);
            readCmd->SetSLBA(nWrBlks);

            enableLog = false;
            if ((nWrBlks <= maxWrBlks) || (nWrBlks >= (ncap - 2 * maxWrBlks)))
                enableLog = true;
            work = str(boost::format("NSID.%d.SLBA.%ld") % bare[i] % nWrBlks);

            IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq,
                iocq, writeCmd, work, enableLog);

            IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq,
                iocq, readCmd, work, enableLog);

            VerifyDataPat(readCmd, writeMem);
        }
    }
}
예제 #7
0
void
FunctionalityMeta_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * None.
     * \endverbatim
     */
    string work;
    bool enableLog;
    ConstSharedIdentifyPtr namSpcPtr;
    SharedIOSQPtr iosq;
    SharedIOCQPtr iocq;
    uint64_t maxWrBlks;

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

    ConstSharedIdentifyPtr idCmdCtrlr = gInformative->GetIdentifyCmdCtrlr();
    uint32_t maxDtXferSz = idCmdCtrlr->GetMaxDataXferSize();
    if (maxDtXferSz == 0)
        maxDtXferSz = MAX_DATA_TX_SIZE;

    LOG_NRM("Prepare cmds to be send through Q's.");
    SharedWritePtr writeCmd = SharedWritePtr(new Write());
    SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());

    SharedReadPtr readCmd = SharedReadPtr(new Read());
    SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer());

    SharedFlushPtr flushCmd = SharedFlushPtr(new Flush());

    DataPattern dataPat[] = {
        DATAPAT_INC_8BIT,
        DATAPAT_CONST_8BIT,
        DATAPAT_INC_16BIT,
        DATAPAT_CONST_16BIT,
        DATAPAT_INC_32BIT,
        DATAPAT_CONST_32BIT
    };
    uint64_t dpArrSize = sizeof(dataPat) / sizeof(dataPat[0]);
    send_64b_bitmask prpBitmask = (send_64b_bitmask)
        (MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST);

    LOG_NRM("Seeking all meta namspc's.");
    vector<uint32_t> meta = gInformative->GetMetaNamespaces();
    for (size_t i = 0; i < meta.size(); i++) {
        LOG_NRM("Processing meta namspc id #%d of %ld", meta[i], meta.size());
        if (gCtrlrConfig->SetState(ST_DISABLE) == false)
            throw FrmwkEx(HERE);

        // 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("Create IOSQ and IOCQ with ID #%d", IOQ_ID);
        CreateIOQs(asq, acq, IOQ_ID, iosq, iocq);

        LOG_NRM("Get LBA format and lba data size for namespc #%d", meta[i]);
        namSpcPtr = gInformative->GetIdentifyCmdNamspc(meta[i]);
        LBAFormat lbaFormat = namSpcPtr->GetLBAFormat();
        uint64_t lbaDataSize = (1 << lbaFormat.LBADS);
        uint64_t ncap = namSpcPtr->GetValue(IDNAMESPC_NCAP);
        uint64_t metaBuffSz = 0;

        LOG_NRM("Set read and write buffers based on the namspc type");
        switch (gInformative->IdentifyNamespace(namSpcPtr)) {
        case Informative::NS_BARE:
            throw FrmwkEx(HERE, "Namspc type cannot be BARE.");
        case Informative::NS_METAS:
            maxWrBlks = maxDtXferSz / lbaDataSize;
            metaBuffSz = maxWrBlks * lbaFormat.MS;
            if (gRsrcMngr->SetMetaAllocSize(metaBuffSz) == false)
                throw FrmwkEx(HERE);
            LOG_NRM("Max rd/wr blks %ld using separate meta buff of ncap %ld",
                maxWrBlks, ncap);
            writeMem->Init(maxWrBlks * lbaDataSize);
            readMem->Init(maxWrBlks * lbaDataSize);
            writeCmd->AllocMetaBuffer();
            readCmd->AllocMetaBuffer();
            break;
        case Informative::NS_METAI:
            maxWrBlks = maxDtXferSz / (lbaDataSize + lbaFormat.MS);
            LOG_NRM("Max rd/wr blks %ld using integrated meta buff of ncap %ld",
                maxWrBlks, ncap);
            writeMem->Init(maxWrBlks * (lbaDataSize + lbaFormat.MS));
            readMem->Init(maxWrBlks * (lbaDataSize + lbaFormat.MS));
            break;
        case Informative::NS_E2ES:
        case Informative::NS_E2EI:
            throw FrmwkEx(HERE, "Deferring work to handle this case in future");
            break;
        }

        writeCmd->SetPrpBuffer(prpBitmask, writeMem);
        writeCmd->SetNSID(meta[i]);
        writeCmd->SetNLB(maxWrBlks - 1);  // 0 based value.

        readCmd->SetPrpBuffer(prpBitmask, readMem);
        readCmd->SetNSID(meta[i]);
        readCmd->SetNLB(maxWrBlks - 1);  // 0 based value.

        flushCmd->SetNSID(meta[i]);

        for (uint64_t sLBA = 0; sLBA < maxWrBlks/*(ncap - 1)*/; sLBA += maxWrBlks) {
            LOG_NRM("Processing at #%ld blk of %ld", sLBA, (ncap -1));
            if ((sLBA + maxWrBlks) >= ncap) {
                maxWrBlks = ncap - sLBA;
                LOG_NRM("Resize max write blocks to #%ld", maxWrBlks);
                ResizeDataBuf(readCmd, writeCmd, namSpcPtr, maxWrBlks,
                    prpBitmask);
                metaBuffSz = maxWrBlks * lbaFormat.MS;
            }
            LOG_NRM("Sending #%ld blks starting at #%ld", maxWrBlks, sLBA);
            for (uint64_t nLBA = 0; nLBA < maxWrBlks; nLBA++) {
                writeMem->SetDataPattern(dataPat[nLBA % dpArrSize],
                    (sLBA + nLBA + 1), (nLBA * lbaDataSize), lbaDataSize);
                writeCmd->SetMetaDataPattern(dataPat[nLBA % dpArrSize],
                    (sLBA + nLBA + 1), (nLBA * lbaFormat.MS), lbaFormat.MS);
            }
            writeCmd->SetSLBA(sLBA);
            readCmd->SetSLBA(sLBA);

            enableLog = false;
            if ((sLBA <= maxWrBlks) || (sLBA >= (ncap - 2 * maxWrBlks)))
                enableLog = true;
            work = str(boost::format("metaID.%d.SLBA.%ld") % meta[i] % sLBA);

            LOG_NRM("Sending write and read commands through ioq's");
            IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq,
                iocq, writeCmd, work, enableLog);

            IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq,
                iocq, flushCmd, work, enableLog);

            IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq,
                iocq, readCmd, work, enableLog);

            VerifyDataPat(readCmd, writeCmd, metaBuffSz);
        }
    }
}
예제 #8
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);
    }
}
예제 #9
0
void
MaxIOQMSIXManyTo1_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     * \endverbatim
     */
    bool capable;
    uint16_t numIrqSupport;
    const uint16_t numIrqs = 1;
    const uint32_t numEntries = 2;
    uint32_t anticipatedIrqs = 0;

    LOG_NRM("Only allowed to execute if DUT supports MSI-X IRQ's");
    if (gCtrlrConfig->IsMSIXCapable(capable, numIrqSupport) == false)
        throw FrmwkEx(HERE);
    else if (capable == false) {
        LOG_NRM("DUT does not support MSI-X IRQ's; unable to execute test");
        return;
    }

    LOG_NRM("Setup the necessary IRQ's");
    if (gCtrlrConfig->SetState(ST_DISABLE) == false)
        throw FrmwkEx(HERE);
    if (gCtrlrConfig->SetIrqScheme(INT_MSIX, numIrqs) == false) {
        throw FrmwkEx(HERE,
            "Unable to use %d IRQ's, but DUT reports it supports", numIrqs);
    }
    gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET);
    if (gCtrlrConfig->SetState(ST_ENABLE) == false)
        throw FrmwkEx(HERE);

    LOG_NRM("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))

    Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E();
    LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat();
    uint64_t lbaDataSize = namspcData.idCmdNamspc->GetLBADataSize();

    SharedWritePtr writeCmd = SharedWritePtr(new Write());
    SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());

    SharedReadPtr readCmd = SharedReadPtr(new Read());
    SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer());

    send_64b_bitmask prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE
        | MASK_PRP2_PAGE | MASK_PRP2_LIST);

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

    readCmd->SetPrpBuffer(prpBitmask, readMem);
    readCmd->SetNSID(namspcData.id);

    gCtrlrConfig->SetIOCQES((gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_CQES) & 0xf));
    gCtrlrConfig->SetIOSQES((gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_SQES) & 0xf));

    vector<SharedIOSQPtr> iosqs;
    vector<SharedIOCQPtr> iocqs;

    uint32_t numIOQPairs = MIN(gInformative->GetFeaturesNumOfIOCQs(),
        gInformative->GetFeaturesNumOfIOSQs());

    LOG_NRM("Created IOQ's and increment anticipated IRQs.");
    for (uint32_t ioqId = 1; ioqId <= numIOQPairs; ioqId++) {
        SharedIOCQPtr iocq = Queues::CreateIOCQContigToHdw(mGrpName, mTestName,
            DEFAULT_CMD_WAIT_ms, asq, acq, ioqId, numEntries, false,
            IOCQ_GROUP_ID, true, 0);
        SharedIOSQPtr iosq = Queues::CreateIOSQContigToHdw(mGrpName, mTestName,
            DEFAULT_CMD_WAIT_ms, asq, acq, ioqId, numEntries, false,
            IOSQ_GROUP_ID, ioqId, 0);
        iosqs.push_back(iosq);
        iocqs.push_back(iocq);
        anticipatedIrqs += 2;
    }

    for(uint16_t i = 0; i < iosqs.size(); i++) {
        LOG_NRM("Processing for iosq size %d", i);
        writeMem->SetDataPattern(DATAPAT_CONST_16BIT, (iosqs[i])->GetQId());
        writeCmd->SetMetaDataPattern(DATAPAT_CONST_16BIT, (iosqs[i])->GetQId());

        SendCmdAndReap(iosqs[i], iocqs[i], writeCmd, ++anticipatedIrqs);
        SendCmdAndReap(iosqs[i], iocqs[i], readCmd, ++anticipatedIrqs);
        VerifyData(readCmd, writeCmd);
    }
}
예제 #10
0
void
DatasetMgmt_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * 1) Test CreateResources_r10b has run prior.
     * \endverbatim
     */
    string work;

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

    Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E();
    LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat();
    uint64_t lbaDataSize = namspcData.idCmdNamspc->GetLBADataSize();

    SharedWritePtr writeCmd = SharedWritePtr(new Write());
    SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());

    SharedReadPtr readCmd = SharedReadPtr(new Read());
    SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer());

    send_64b_bitmask prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE
        | MASK_PRP2_PAGE | MASK_PRP2_LIST);

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

    writeCmd->SetPrpBuffer(prpBitmask, writeMem);
    writeCmd->SetNSID(namspcData.id);
    writeCmd->SetNLB(0);

    readCmd->SetPrpBuffer(prpBitmask, readMem);
    readCmd->SetNSID(namspcData.id);
    readCmd->SetNLB(0);

    DataPattern dataPat[] = {
        DATAPAT_INC_32BIT,
        DATAPAT_CONST_32BIT
    };
    uint64_t dpArrSize = sizeof(dataPat) / sizeof(dataPat[0]);

    for (uint64_t dsmAtr = 0; dsmAtr < (1 << CDW13_DSM_BITS); dsmAtr++) {
        // skip reserved bits in dataset management attributes.
        if ((dsmAtr & 0xF) >= 0x09)
            continue;

        switch (namspcData.type) {
        case Informative::NS_BARE:
            writeMem->SetDataPattern(dataPat[dsmAtr % dpArrSize], dsmAtr);
            break;
        case Informative::NS_METAS:
            writeMem->SetDataPattern(dataPat[dsmAtr % dpArrSize], dsmAtr);
            writeCmd->SetMetaDataPattern(dataPat[dsmAtr % dpArrSize], dsmAtr);
            break;
        case Informative::NS_METAI:
            writeMem->SetDataPattern(dataPat[dsmAtr % dpArrSize], dsmAtr);
            break;
        case Informative::NS_E2ES:
        case Informative::NS_E2EI:
            throw FrmwkEx(HERE, "Deferring work to handle this case in future");
            break;
        }

        // Set CDW13.DSM field to different values.
        writeCmd->SetByte((uint8_t)dsmAtr, 13, 0);
        readCmd->SetByte((uint8_t)dsmAtr, 13, 0);

        work = str(boost::format("dsm.%Xh") % dsmAtr);
        IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq,
            iocq, writeCmd, work, true);

        IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq,
            iocq, readCmd, work, true);

        VerifyDataPat(readCmd, writeCmd);
    }
}
예제 #11
0
void
PRPLessPageDiscontig_r10b::RunCoreTest()
{
    /** \verbatim
     * Assumptions:
     * None
     * \endverbatim
     */
    string work;
    bool enableLog;

    if (Queues::SupportDiscontigIOQ() == false) {
        LOG_WARN("DUT must support discontig Q's for this test.");
        return;
    }

    uint64_t ctrlCapReg;
    LOG_NRM("Determine the max IOQ entries supported");
    if (gRegisters->Read(CTLSPC_CAP, ctrlCapReg) == false)
        throw FrmwkEx(HERE, "Unable to determine MQES");
    uint32_t maxIOQEntries = (ctrlCapReg & CAP_MQES);
    maxIOQEntries += 1;      // convert to 1-based

    LOG_NRM("Compute memory page size from CC.MPS.");
    uint8_t mps;
    if (gCtrlrConfig->GetMPS(mps) == false)
        throw FrmwkEx(HERE, "Unable to get MPS value from CC.");
    uint64_t capMPS = (uint64_t)(1 << (mps + 12));

    LOG_NRM("Determine element sizes for the IOCQ's");
    uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_CQES) & 0xf);
    uint32_t Y = ((capMPS / (1 << iocqes)) - 1);
    if (maxIOQEntries < Y) {
        LOG_WARN("Desired to support >= %d elements in IOCQ for this test", Y);
        return;
    }

    LOG_NRM("Determine element sizes for the IOSQ's");
    uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()->
        GetValue(IDCTRLRCAP_SQES) & 0xf);
    uint32_t Z = ((capMPS / (1 << iosqes)) - 1);

    LOG_NRM("Computed memory page size from CC.MPS = %ld", capMPS);
    LOG_NRM("Max IOQ entries supported CAP.MQES = %d", maxIOQEntries);
    LOG_NRM("Number of IOCQ elements = %d", Y);
    LOG_NRM("Number of IOSQ elements = %d", Z);

    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);     // throws upon error

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

    Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E();
    LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat();
    uint64_t lbaDataSize = namspcData.idCmdNamspc->GetLBADataSize();

    LOG_NRM("Setup element sizes for the IOQ's");
    gCtrlrConfig->SetIOCQES(iocqes);
    gCtrlrConfig->SetIOSQES(iosqes);

    LOG_NRM("Create discontig IOSQ and IOCQ with IDs 1");
    SharedMemBufferPtr iocqBackedMem = SharedMemBufferPtr(new MemBuffer());
    iocqBackedMem->InitOffset1stPage((Y * (1 << iocqes)), 0, true);
    SharedIOCQPtr iocq = Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName,
        DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, Y, false, IOCQ_GROUP_ID,
        true, 0, iocqBackedMem);

    SharedMemBufferPtr iosqBackedMem = SharedMemBufferPtr(new MemBuffer());
    iosqBackedMem->InitOffset1stPage((Z * (1 << iosqes)), 0,true);
    SharedIOSQPtr iosq = Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName,
        DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, Z, false, IOSQ_GROUP_ID,
        IOQ_ID, 0, iosqBackedMem);

    SharedWritePtr writeCmd = SharedWritePtr(new Write());
    SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer());

    SharedReadPtr readCmd = SharedReadPtr(new Read());
    SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer());

    send_64b_bitmask prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE |
        MASK_PRP2_PAGE | MASK_PRP2_LIST);

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

    writeCmd->SetPrpBuffer(prpBitmask, writeMem);
    writeCmd->SetNSID(namspcData.id);
    writeCmd->SetNLB(0);

    readCmd->SetPrpBuffer(prpBitmask, readMem);
    readCmd->SetNSID(namspcData.id);
    readCmd->SetNLB(0);

    // Fill the IOSQ and roll over
    for (int64_t X = 1; X <= (iosq->GetNumEntries() + 1); X++) {
        LOG_NRM("Processing #%ld of %d cmds", X, (iosq->GetNumEntries() + 1));
        switch (namspcData.type) {
        case Informative::NS_BARE:
            writeMem->SetDataPattern(DATAPAT_INC_32BIT, X);
            break;
        case Informative::NS_METAS:
            writeMem->SetDataPattern(DATAPAT_INC_32BIT, X);
            writeCmd->SetMetaDataPattern(DATAPAT_INC_32BIT, X);
            break;
        case Informative::NS_METAI:
            writeMem->SetDataPattern(DATAPAT_INC_32BIT, X);
            break;
        case Informative::NS_E2ES:
        case Informative::NS_E2EI:
            throw FrmwkEx(HERE, "Deferring work to handle this case in future");
            break;
        }

        enableLog = false;
        if ((X <= 8) || (X >= (X - 8)))
            enableLog = true;

        work = str(boost::format("X.%d") % X);
        IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq,
            iocq, writeCmd, work, enableLog);

        IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq,
            iocq, readCmd, work, enableLog);

        VerifyDataPat(readCmd, writeCmd);
    }
}
예제 #12
0
void
WriteDataPat_r10b::WriteDataPattern()
{
    uint64_t regVal;

    LOG_NRM("Calc buffer size to write %d logical blks to media",
        WRITE_DATA_PAT_NUM_BLKS);
    Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E();
    ConstSharedIdentifyPtr namSpcPtr = namspcData.idCmdNamspc;
    if (namSpcPtr == Identify::NullIdentifyPtr)
        throw FrmwkEx(HERE, "Namespace #%d must exist", namspcData.id);

    LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat();
    if (namspcData.type == Informative::NS_METAS) {
        if (gRsrcMngr->SetMetaAllocSize(lbaFormat.MS * WRITE_DATA_PAT_NUM_BLKS)
            == false) {
            throw FrmwkEx(HERE);
        }
    }
    uint64_t lbaDataSize = namSpcPtr->GetLBADataSize();

    LOG_NRM("Create a generic write cmd to send data pattern to namspc #%d",
        namspcData.id);
    SharedWritePtr writeCmd = SharedWritePtr(new Write());
    send_64b_bitmask prpBitmask = (send_64b_bitmask)
        (MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST);

    LOG_NRM("Create data pattern to write to media");
    SharedMemBufferPtr dataPat = SharedMemBufferPtr(new MemBuffer());

    switch (namspcData.type) {
    case Informative::NS_BARE:
        dataPat->Init(WRITE_DATA_PAT_NUM_BLKS * lbaDataSize);
        break;
    case Informative::NS_METAS:
        dataPat->Init(WRITE_DATA_PAT_NUM_BLKS * lbaDataSize);
        writeCmd->AllocMetaBuffer();
        writeCmd->SetMetaDataPattern(DATAPAT_INC_16BIT);
        break;
    case Informative::NS_METAI:
        dataPat->Init(WRITE_DATA_PAT_NUM_BLKS * (lbaDataSize + lbaFormat.MS));
        break;
    case Informative::NS_E2ES:
    case Informative::NS_E2EI:
        throw FrmwkEx(HERE, "Deferring work to handle this case in future");
        break;
    }

    dataPat->SetDataPattern(DATAPAT_INC_16BIT);
    dataPat->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "DataPat"),
        "Write buffer's data pattern");

    writeCmd->SetPrpBuffer(prpBitmask, dataPat);
    writeCmd->SetNSID(namspcData.id);
    writeCmd->SetNLB(WRITE_DATA_PAT_NUM_BLKS - 1);  // convert to 0-based value

    // Lookup objs which were created in a prior test within group
    SharedIOSQPtr iosqContig = CAST_TO_IOSQ(
        gRsrcMngr->GetObj(IOSQ_CONTIG_GROUP_ID))
    SharedIOCQPtr iocqContig = CAST_TO_IOCQ(
        gRsrcMngr->GetObj(IOCQ_CONTIG_GROUP_ID))
    SharedIOSQPtr iosqDiscontig = CAST_TO_IOSQ(
        gRsrcMngr->GetObj(IOSQ_DISCONTIG_GROUP_ID))
    SharedIOCQPtr iocqDiscontig = CAST_TO_IOCQ(
        gRsrcMngr->GetObj(IOCQ_DISCONTIG_GROUP_ID))

    LOG_NRM("Send the cmd to hdw via the contiguous IOQ's");
    SendToIOSQ(iosqContig, iocqContig, writeCmd, "contig");

    // To run the discontig part of this test, the hdw must support that feature
    if (gRegisters->Read(CTLSPC_CAP, regVal) == false) {
        throw FrmwkEx(HERE, "Unable to determine Q memory requirements");
    } else if (regVal & CAP_CQR) {
        LOG_NRM("Unable to utilize discontig Q's, DUT requires contig");
        return;
    }

    LOG_NRM("Send the cmd to hdw via the discontiguous IOQ's");
    SendToIOSQ(iosqDiscontig, iocqDiscontig, writeCmd, "discontig");
}