void PRP1PRP2_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ 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)) LOG_NRM("Determine if DUT has atleast one namespace support"); ConstSharedIdentifyPtr idCmdCtrlr = gInformative->GetIdentifyCmdCtrlr(); if ((idCmdCtrlr->GetValue(IDCTRLRCAP_NN)) == 0) throw FrmwkEx(HERE, "Required to support >= 1 namespace"); LOG_NRM("Form identify namespace cmd and associate some buffer"); SharedIdentifyPtr idCmdNamSpc = SharedIdentifyPtr(new Identify()); idCmdNamSpc->SetCNS(false); idCmdNamSpc->SetNSID(1); SharedMemBufferPtr idMemNamSpc = SharedMemBufferPtr(new MemBuffer()); idMemNamSpc->InitOffset1stPage(Identify::IDEAL_DATA_SIZE, PRP_BUFFER_OFFSET, true); LOG_NRM("Allow PRP1 and PRP2"); send_64b_bitmask idPrpNamSpc = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmdNamSpc->SetPrpBuffer(idPrpNamSpc, idMemNamSpc); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "prp1Prp2", true); }
void PRP1PRP2_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(PRP1_ONLY_NUMD - 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); 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, "prp1prp2", true); }
void InvalidLogPageNVMSet_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 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()); SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer()); send_64b_bitmask prpReq = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); getLogPageMem->InitOffset1stPage(BUFFER_SIZE, 0, true); getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem); getLogPgCmd->SetNUMD(NUMD - 1); // 0-based getLogPgCmd->SetNSID(0xFFFFFFFF); list<uint32_t> invalidLIDs = GetInvalidLIDs(); for (list<uint32_t>::iterator invalidLID = invalidLIDs.begin(); invalidLID != invalidLIDs.end(); invalidLID++) { LOG_NRM("Processing for invalid LID = 0x%04X", *invalidLID); getLogPgCmd->SetLID(*invalidLID); work = str(boost::format("invalidLID.%d") % *invalidLID); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getLogPgCmd, work, true, CESTAT_INVAL_LOG_PAGE); } }
void CIDAcceptedIOSQ_r10b::InitTstRsrcs(SharedASQPtr asq, SharedACQPtr acq, vector <SharedIOSQPtr> &iosqs, SharedIOCQPtr &iocq) { uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_CQES) & 0xf); uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_SQES) & 0xf); gCtrlrConfig->SetIOCQES(iocqes); gCtrlrConfig->SetIOSQES(iosqes); uint32_t numIOSQs = (NUM_IO_SQS <= gInformative->GetFeaturesNumOfIOSQs()) ? NUM_IO_SQS : gInformative->GetFeaturesNumOfIOSQs(); LOG_NRM("Initialize test resources."); const uint32_t nEntriesIOQ = 2; // minimum Q entries always supported. SharedIOSQPtr iosq; if (Queues::SupportDiscontigIOQ() == true) { SharedMemBufferPtr iocqMem = SharedMemBufferPtr(new MemBuffer()); iocqMem->InitOffset1stPage((nEntriesIOQ * (1 << iocqes)), 0, true); iocq = Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, nEntriesIOQ, false, IOCQ_GROUP_ID, true, 1, iocqMem); for (uint32_t iosqId = 1; iosqId <= numIOSQs; iosqId++) { SharedMemBufferPtr iosqMem = SharedMemBufferPtr(new MemBuffer()); iosqMem->InitOffset1stPage((nEntriesIOQ * (1 << iosqes)), 0, true); iosq = Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, iosqId, nEntriesIOQ, false, IOSQ_GROUP_ID, IOQ_ID, 0, iosqMem); iosqs.push_back(iosq); } } else { iocq = Queues::CreateIOCQContigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, nEntriesIOQ, false, IOCQ_GROUP_ID, true, 1); for (uint32_t iosqId = 1; iosqId <= numIOSQs; iosqId++) { iosq = Queues::CreateIOSQContigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, iosqId, nEntriesIOQ, false, IOSQ_GROUP_ID, IOQ_ID, 0); iosqs.push_back(iosq); } } }
void UnsupportRsvdFields_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ // Lookup objs which were created in a prior test within group string globalWork; //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(PRP1_ONLY_NUMD - 1); // 0-based getLogPgCmd->SetLID(FIRM_SLOT_INFO_LID); getLogPgCmd->SetNSID(0xFFFFFFFF); SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer()); getLogPageMem->InitOffset1stPage(GetLogPage::FIRMSLOT_DATA_SIZE, BUFFER_OFFSET, true); send_64b_bitmask prpReq = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem); LOG_NRM("Issue GetLogPage cmd without setting reserved bits."); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getLogPgCmd, "rsvd.notset", true); LOG_NRM("Set all cmd's rsvd bits"); uint32_t work = getLogPgCmd->GetDword(0); work |= 0x0000fc00; // Set DW0_b15:10 bits getLogPgCmd->SetDword(work, 0); getLogPgCmd->SetDword(0xffffffff, 2); getLogPgCmd->SetDword(0xffffffff, 3); getLogPgCmd->SetDword(0xffffffff, 4); getLogPgCmd->SetDword(0xffffffff, 5); work = getLogPgCmd->GetDword(10); work |= 0xf0000000; // Set DW10_b31:28 bits getLogPgCmd->SetDword(work, 10); getLogPgCmd->SetDword(0xffffffff, 11); getLogPgCmd->SetDword(0xffffffff, 12); getLogPgCmd->SetDword(0xffffffff, 13); getLogPgCmd->SetDword(0xffffffff, 14); getLogPgCmd->SetDword(0xffffffff, 15); LOG_NRM("Issue GetLogPage cmd after setting reserved bits."); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getLogPgCmd, "rsvd.set", true); }
void UnsupportRsvdFields_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ 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)) LOG_NRM("Determine if DUT has atleast one namespace support"); ConstSharedIdentifyPtr idCmdCtrlr = gInformative->GetIdentifyCmdCtrlr(); if ((idCmdCtrlr->GetValue(IDCTRLRCAP_NN)) == 0) throw FrmwkEx(HERE, "Required to support >= 1 namespace"); LOG_NRM("Form identify namespace cmd and associate some buffer"); SharedIdentifyPtr idCmdNamSpc = SharedIdentifyPtr(new Identify()); idCmdNamSpc->SetCNS(0); idCmdNamSpc->SetNSID(1); SharedMemBufferPtr idMemNamSpc = SharedMemBufferPtr(new MemBuffer()); idMemNamSpc->InitOffset1stPage(Identify::IDEAL_DATA_SIZE, PRP_BUFFER_OFFSET, true); LOG_NRM("Allow PRP1 and PRP2"); send_64b_bitmask idPrpNamSpc = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmdNamSpc->SetPrpBuffer(idPrpNamSpc, idMemNamSpc); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdnone.set", true); LOG_NRM("Set all cmd's rsvd bits"); uint32_t work = idCmdNamSpc->GetDword(0); work |= 0x0000fc00; // Set DW0_b15:10 bits idCmdNamSpc->SetDword(work, 0); idCmdNamSpc->SetDword(0xffffffff, 2); idCmdNamSpc->SetDword(0xffffffff, 3); idCmdNamSpc->SetDword(0xffffffff, 4); idCmdNamSpc->SetDword(0xffffffff, 5); work = idCmdNamSpc->GetDword(10); work |= 0xfffffffe; // Set DW10_b31:1 bits idCmdNamSpc->SetDword(work, 10); idCmdNamSpc->SetDword(0xffffffff, 11); idCmdNamSpc->SetDword(0xffffffff, 12); idCmdNamSpc->SetDword(0xffffffff, 13); idCmdNamSpc->SetDword(0xffffffff, 14); idCmdNamSpc->SetDword(0xffffffff, 15); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdall.set", true); }
void ProtInfoIgnoreMeta_r10b::CreateIOQs(SharedASQPtr asq, SharedACQPtr acq, uint32_t ioqId, SharedIOSQPtr &iosq, SharedIOCQPtr &iocq) { uint32_t numEntries = 2; gCtrlrConfig->SetIOCQES((gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_CQES) & 0xf)); gCtrlrConfig->SetIOSQES((gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_SQES) & 0xf)); if (Queues::SupportDiscontigIOQ() == true) { uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_CQES) & 0xf); uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_SQES) & 0xf); SharedMemBufferPtr iocqBackedMem = SharedMemBufferPtr(new MemBuffer()); iocqBackedMem->InitOffset1stPage((numEntries * (1 << iocqes)), 0, true); iocq = Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, ioqId, numEntries, false, IOCQ_GROUP_ID, true, 0, iocqBackedMem); SharedMemBufferPtr iosqBackedMem = SharedMemBufferPtr(new MemBuffer()); iosqBackedMem->InitOffset1stPage((numEntries * (1 << iosqes)), 0,true); iosq = Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, ioqId, numEntries, false, IOSQ_GROUP_ID, ioqId, 0, iosqBackedMem); } else { iocq = Queues::CreateIOCQContigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, ioqId, numEntries, false, IOCQ_GROUP_ID, true, 0); iosq = Queues::CreateIOSQContigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, ioqId, numEntries, false, IOSQ_GROUP_ID, ioqId, 0); } }
void PRPOffsetDualPgMultiBlk_r10b::InitTstRsrcs(SharedASQPtr asq, SharedACQPtr acq, SharedIOSQPtr &iosq, SharedIOCQPtr &iocq) { uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_CQES) & 0xf); uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_SQES) & 0xf); gCtrlrConfig->SetIOCQES(iocqes); gCtrlrConfig->SetIOSQES(iosqes); const uint32_t nEntriesIOQ = 2; // minimum Q entries always supported. if (Queues::SupportDiscontigIOQ() == true) { SharedMemBufferPtr iocqBackMem = SharedMemBufferPtr(new MemBuffer()); iocqBackMem->InitOffset1stPage((nEntriesIOQ * (1 << iocqes)), 0, true); iocq = Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, nEntriesIOQ, false, IOCQ_GROUP_ID, true, 1, iocqBackMem); SharedMemBufferPtr iosqBackMem = SharedMemBufferPtr(new MemBuffer()); iosqBackMem->InitOffset1stPage((nEntriesIOQ * (1 << iosqes)), 0, true); iosq = Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, nEntriesIOQ, false, IOSQ_GROUP_ID, IOQ_ID, 0, iosqBackMem); } else { iocq = Queues::CreateIOCQContigToHdw(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, nEntriesIOQ, false, IOCQ_GROUP_ID, true, 1); iosq = Queues::CreateIOSQContigToHdw(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, asq, acq, IOQ_ID, nEntriesIOQ, false, IOSQ_GROUP_ID, IOQ_ID, 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++; } }
void CreateResources_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) This is the 1st within GrpNVMWriteReadCombo. * \endverbatim */ if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false) throw FrmwkEx(HERE); SharedACQPtr acq = CAST_TO_ACQ( gRsrcMngr->AllocObj(Trackable::OBJ_ACQ, ACQ_GROUP_ID)) acq->Init(5); SharedASQPtr asq = CAST_TO_ASQ( gRsrcMngr->AllocObj(Trackable::OBJ_ASQ, ASQ_GROUP_ID)) asq->Init(5); // All queues will use identical IRQ vector IRQ::SetAnySchemeSpecifyNum(1); // throws upon error gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET); if (gCtrlrConfig->SetState(ST_ENABLE) == false) throw FrmwkEx(HERE); { uint64_t maxIOQEntries; // Determine the max IOQ entries supported if (gRegisters->Read(CTLSPC_CAP, maxIOQEntries) == false) throw FrmwkEx(HERE, "Unable to determine MQES"); maxIOQEntries &= CAP_MQES; maxIOQEntries += 1; // convert to 1-based if (maxIOQEntries < (uint64_t)NumEntriesIOQ) { LOG_NRM("Changing number of Q elements from %d to %lld", NumEntriesIOQ, (unsigned long long)maxIOQEntries); NumEntriesIOQ = maxIOQEntries; } uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_CQES) & 0xf); uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_SQES) & 0xf); gCtrlrConfig->SetIOCQES(iocqes); gCtrlrConfig->SetIOSQES(iosqes); if (Queues::SupportDiscontigIOQ() == true) { SharedMemBufferPtr iocqBackedMem = SharedMemBufferPtr(new MemBuffer()); iocqBackedMem->InitOffset1stPage ((NumEntriesIOQ * (1 << iocqes)), 0, true); Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, NumEntriesIOQ, true, IOCQ_GROUP_ID, true, 0, iocqBackedMem); SharedMemBufferPtr iosqBackedMem = SharedMemBufferPtr(new MemBuffer()); iosqBackedMem->InitOffset1stPage ((NumEntriesIOQ * (1 << iosqes)), 0, true); Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, NumEntriesIOQ, true, IOSQ_GROUP_ID, IOQ_ID, 0, iosqBackedMem); } else { Queues::CreateIOCQContigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, NumEntriesIOQ, true, IOCQ_GROUP_ID, true, 0); Queues::CreateIOSQContigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, IOQ_ID, NumEntriesIOQ, true, IOSQ_GROUP_ID, IOQ_ID, 0); } } }
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); } } }
void UnsupportRsvdFields_r12::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ 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)) LOG_NRM("Determine if DUT has atleast one namespace support"); ConstSharedIdentifyPtr idCmdCtrlr = gInformative->GetIdentifyCmdCtrlr(); if ((idCmdCtrlr->GetValue(IDCTRLRCAP_NN)) == 0) throw FrmwkEx(HERE, "Required to support >= 1 namespace"); LOG_NRM("Form identify namespace cmd and associate some buffer"); SharedIdentifyPtr idCmdNamSpc = SharedIdentifyPtr(new Identify()); idCmdNamSpc->SetCNS(CNS_Namespace); idCmdNamSpc->SetNSID(1); SharedMemBufferPtr idMemNamSpc = SharedMemBufferPtr(new MemBuffer()); idMemNamSpc->InitOffset1stPage(Identify::IDEAL_DATA_SIZE, PRP_BUFFER_OFFSET, true); LOG_NRM("Allow PRP1 and PRP2"); send_64b_bitmask idPrpNamSpc = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); idCmdNamSpc->SetPrpBuffer(idPrpNamSpc, idMemNamSpc); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdnone.set", true); LOG_NRM("Set all cmd's rsvd bits"); uint32_t work = idCmdNamSpc->GetDword(0); work |= 0x00003c00; // Set DW0_b13:10 bits idCmdNamSpc->SetDword(work, 0); idCmdNamSpc->SetDword(0xffffffff, 2); idCmdNamSpc->SetDword(0xffffffff, 3); idCmdNamSpc->SetDword(0xffffffff, 4); idCmdNamSpc->SetDword(0xffffffff, 5); work = idCmdNamSpc->GetDword(10); //work |= 0xfffffffc; // Set DW10_b31:2 bits work |= 0x0000ff00; // Set DW10_b31:8 bits idCmdNamSpc->SetDword(work, 10); idCmdNamSpc->SetDword(0xffffffff, 11); idCmdNamSpc->SetDword(0xffffffff, 12); idCmdNamSpc->SetDword(0xffffffff, 13); idCmdNamSpc->SetDword(0xffffffff, 14); idCmdNamSpc->SetDword(0xffffffff, 15); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdall.set", true); LOG_NRM("Set CNS field reserved coded value"); uint32_t cdw10 = idCmdNamSpc->GetDword(10); //work = cdw10 | 0x3; //idCmdNamSpc->SetDword(work, 10); const uint32_t cnsNonRsvdVal[] = { 0x00, 0x01, 0x02, 0x10, 0x11, 0x12, 0x13 }; const uint32_t cnsNonRevdValCnt = sizeof(cnsNonRsvdVal) / sizeof(uint32_t); /*IO::SendAndReapCmdNot(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdall.val.set", true, CESTAT_SUCCESS); */ for (uint32_t cnsVal = 0; cnsVal <= 0xff; cnsVal++){ uint32_t idx = 0; while ((idx < cnsNonRevdValCnt) && (cnsVal != cnsNonRsvdVal[idx])){ ++idx; } if (idx == cnsNonRevdValCnt) { work = cdw10 | cnsVal; idCmdNamSpc->SetDword(work, 10); IO::SendAndReapCmdNot(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, idCmdNamSpc, "rsvdall.val.set", true, CESTAT_SUCCESS); } } }
void InvalidNamspc_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ string work; uint64_t inc, 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)) LOG_NRM("Create get log page cmd and assoc some buffer memory"); SharedGetLogPagePtr getLogPgCmd = SharedGetLogPagePtr(new GetLogPage()); SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer()); send_64b_bitmask prpReq = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); getLogPageMem->InitOffset1stPage(GetLogPage::SMART_DATA_SIZE, 0, true); getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem); getLogPgCmd->SetLID(SMART_HEALTH_INFO_LID); getLogPgCmd->SetNUMD(SMART_NUMD - 1); // 0 - based ConstSharedIdentifyPtr idCtrlrStruct = gInformative->GetIdentifyCmdCtrlr(); uint32_t nn = (uint32_t)idCtrlrStruct->GetValue(IDCTRLRCAP_NN); if (nn == 0 ) throw FrmwkEx(HERE, "Required to support >= 1 namespace"); uint8_t logPageAttr = (uint8_t)idCtrlrStruct->GetValue(IDCTRLRCAP_LPA); // bits 7:1 are reserved, need bit 0 uint8_t suppSmartPerNamspc = logPageAttr & 0x1; if(suppSmartPerNamspc > 0) { LOG_NRM("IDCTRLRCAP_LPA bit0 is set. Per Namespace Smart Pages supported") } else { LOG_NRM("IDCTRLRCAP_LPA bit0 is not set. Per Namespace Smart Pages is not supported") } // for all illegal nsid's verify get log page cmd. for (i = (nn + 1), inc = 1; i < 0xffffffff; i += (2 * inc), inc += 1327) { LOG_NRM("Issue Get log page cmd with illegal namspc ID = 0x%llX", (unsigned long long)i); getLogPgCmd->SetNSID(i); work = str(boost::format("namspc%d") % i); // Determine the status based on the per namespace mask bit. // While the 1.1+ spec requires the device to return invalid field // the 1.0 spec does NOT require the device to return SUCCESS and // a global log page no matter what value of NSID is provided // Instead only the global 0xFFFFFFFF NSID MUST be supported IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getLogPgCmd, work, true, CESTAT_INVAL_NAMSPC); } // If per namespc smart log is supported, check all legal nn. if (suppSmartPerNamspc) { for (i = 1; i <= nn; i++) { LOG_NRM("Issue Get log page cmd with legal namspc ID = 0x%llX (per namespace smart log supported)", (unsigned long long)i); getLogPgCmd->SetNSID(i); work = str(boost::format("namspc%d") % i); // Determine the status based on the per namespace mask bit. IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getLogPgCmd, work, true); } } // GetLogPage of NSID == 0 is not expected to pass when LPA bit 0 is not set // The only requirement is that 0xFFFFFFFF is supported, not that the NSID field // is completely ignored and a global page is always returned... /* else { i = 0; getLogPgCmd->SetNSID(i); work = str(boost::format("namspc%d") % i); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getLogPgCmd, work, true); } */ // If name space is 0xffffffff, then we should get the global log info. i = 0xffffffff; getLogPgCmd->SetNSID(i); work = str(boost::format("namspc%d") % i); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getLogPgCmd, work, true); }
void QIDVariations_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ uint16_t uniqueId; // 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)) uint64_t maxIOQEntries; LOG_NRM("Determine the max IOQ entries supported"); if (gRegisters->Read(CTLSPC_CAP, maxIOQEntries) == false) throw FrmwkEx(HERE, "Unable to determine MQES"); maxIOQEntries &= CAP_MQES; maxIOQEntries += 1; // convert to 1-based SharedWritePtr writeCmd = SetWriteCmd(); uint32_t maxIOQSupport = MIN(gInformative->GetFeaturesNumOfIOSQs(), gInformative->GetFeaturesNumOfIOCQs()); uint32_t NumEntriesIOSQ = 2; // IOSQ range: 2 to X + 2 uint32_t NumEntriesIOCQ = ((maxIOQSupport + 2) > maxIOQEntries) ? maxIOQEntries : (maxIOQSupport + 2); // IOCQ range: X + 2 to 2 uint8_t iocqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_CQES) & 0xf); uint8_t iosqes = (gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_SQES) & 0xf); vector<SharedIOSQPtr> IOSQVec; vector<SharedIOCQPtr> IOCQVec; // Create all supported queues. for (uint32_t ioqId = 1; ioqId <= maxIOQSupport; ioqId++) { SharedIOCQPtr iocq; SharedIOSQPtr iosq; LOG_NRM("Create IOSQ and IOCQ with IDs #%d of maximum IDs %d", ioqId, maxIOQSupport); if (Queues::SupportDiscontigIOQ() == true) { SharedMemBufferPtr iocqBackedMem = SharedMemBufferPtr(new MemBuffer()); iocqBackedMem->InitOffset1stPage ((NumEntriesIOCQ * (1 << iocqes)), 0, true); iocq = Queues::CreateIOCQDiscontigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, ioqId, NumEntriesIOCQ, false, IOCQ_CONTIG_GROUP_ID, false, 0, iocqBackedMem); SharedMemBufferPtr iosqBackedMem = SharedMemBufferPtr(new MemBuffer()); iosqBackedMem->InitOffset1stPage ((NumEntriesIOSQ * (1 << iosqes)), 0,true); iosq = Queues::CreateIOSQDiscontigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, ((maxIOQSupport - ioqId) + 1), NumEntriesIOSQ, false, IOSQ_CONTIG_GROUP_ID, ioqId, 0, iosqBackedMem); } else { iocq = Queues::CreateIOCQContigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, ioqId, NumEntriesIOCQ, false, IOCQ_CONTIG_GROUP_ID, false, 0); iosq = Queues::CreateIOSQContigToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, ((maxIOQSupport - ioqId) + 1), NumEntriesIOSQ, false, IOSQ_CONTIG_GROUP_ID, ioqId, 0); } IOSQVec.push_back(iosq); IOCQVec.push_back(iocq); if (NumEntriesIOSQ < maxIOQEntries) { NumEntriesIOSQ++; NumEntriesIOCQ--; } } vector <SharedIOSQPtr>::iterator iosq; vector <SharedIOCQPtr>::iterator iocq; LOG_NRM("Send cmds until all SQs fill up."); for (iosq = IOSQVec.begin(); iosq != IOSQVec.end(); iosq++) { for (uint32_t numCmds = 1; numCmds < ((*iosq)->GetNumEntries()); numCmds++) { (*iosq)->Send(writeCmd, uniqueId); } (*iosq)->Ring(); } LOG_NRM("Reap and verify all cmds submitted."); iosq = IOSQVec.begin(); for (iocq = IOCQVec.begin(); iocq != IOCQVec.end(); iocq++, iosq++) ReapVerifyOnCQ(*iocq, *iosq); // Clean up after the test by deleting all the Q's created. iocq = IOCQVec.begin(); for (iosq = IOSQVec.begin(); iosq != IOSQVec.end(); iosq++, iocq++) { // Delete IOSQ before the IOCQ to comply with spec. Queues::DeleteIOSQToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), *iosq, asq, acq); Queues::DeleteIOCQToHdw(mGrpName, mTestName, CALC_TIMEOUT_ms(1), *iocq, asq, acq); } }
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); } }