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