void CIDAcceptedIOSQ_r10b::RunCoreTest() { /** \verbatim * Assumptions: * None. * \endverbatim */ if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false) throw FrmwkEx(HERE); LOG_NRM("Create ACQ and ASQ objects which have test life time"); SharedACQPtr acq = CAST_TO_ACQ(SharedACQPtr(new ACQ(gDutFd))) acq->Init(5); SharedASQPtr asq = CAST_TO_ASQ(SharedASQPtr(new ASQ(gDutFd))) asq->Init(5); IRQ::SetAnySchemeSpecifyNum(2); // throws upon error gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET); if (gCtrlrConfig->SetState(ST_ENABLE) == false) throw FrmwkEx(HERE); vector<SharedIOSQPtr> iosqs; SharedIOCQPtr iocq; InitTstRsrcs(asq, acq, iosqs, iocq); SharedWritePtr writeCmd = CreateWriteCmd(); LOG_NRM("Learn initial unique command id assigned by dnvme"); uint16_t curCID; vector <SharedIOSQPtr>::iterator iosq; for (iosq = iosqs.begin(); iosq != iosqs.end(); iosq++) (*iosq)->Send(writeCmd, curCID); uint16_t prevCID = curCID; for (uint32_t nCmds = 0; nCmds < MAX_CMDS; nCmds++) { for (iosq = iosqs.begin(); iosq != iosqs.end(); iosq++) { LOG_NRM("(nCmds, curCID, prevCID, SQ ID) = (%d, %d, %d, %d)", nCmds, curCID, prevCID, (*iosq)->GetQId()); (*iosq)->Ring(); ReapVerifyCID(*iosq, iocq, prevCID); (*iosq)->Send(writeCmd, curCID); if (curCID != (uint16_t)(prevCID + 1)) { (*iosq)->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq.fail." + (*iosq)->GetQId()), "Dump Entire IOSQ"); iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.fail." + iocq->GetQId()), "Dump Entire IOCQ"); throw FrmwkEx(HERE, "curCID(%d) != (prevCID + 1)(%d)", curCID, (prevCID + 1)); } } prevCID = curCID; } }
void InvalidNamspc_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ uint64_t inc, i; string work; uint32_t numCE; uint32_t isrCountB4; LOG_NRM("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)); if ((numCE = iocq->ReapInquiry(isrCountB4, true)) != 0) { iocq->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", "notEmpty"), "Test assumption have not been met"); throw FrmwkEx(HERE, "Require 0 CE's within CQ %d, not upheld, found %d", iocq->GetQId(), numCE); } LOG_NRM("Setup write cmd's values that won't change per namspc"); SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer()); uint64_t lbaDataSize = 512; writeMem->Init(lbaDataSize); SharedWritePtr writeCmd = SharedWritePtr(new Write()); send_64b_bitmask prpBitmask = (send_64b_bitmask) (MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST); writeCmd->SetPrpBuffer(prpBitmask, writeMem); writeCmd->SetNLB(0); // convert to 0-based value writeCmd->SetSLBA(0); LOG_NRM("For all namspc's issue cmd to an illegal namspc"); ConstSharedIdentifyPtr idCtrlrStruct = gInformative->GetIdentifyCmdCtrlr(); uint32_t nn = (uint32_t)idCtrlrStruct->GetValue(IDCTRLRCAP_NN); if (nn == 0 ) { throw FrmwkEx(HERE, "Required to support >= 1 namespace"); } for (i = (nn + 1), inc = 1; i <= 0xffffffff; i += (2 * inc), inc += 1327) { LOG_NRM("Issue flush cmd with illegal namspc ID=%llu", (unsigned long long)i); writeCmd->SetNSID(i); work = str(boost::format("namspc%d") % i); SendCmdToHdw(iosq, iocq, writeCmd, work); } }
void IOQRollChkDiff_r10b::ReapAndVerifyCE(SharedIOCQPtr iocq, uint32_t expectedVal) { uint32_t numCE; uint32_t ceRemain; uint32_t numReaped; uint32_t isrCount; LOG_NRM("Wait for the CE to arrive in IOCQ %d", iocq->GetQId()); if (iocq->ReapInquiryWaitSpecify(DEFAULT_CMD_WAIT_ms, 1, numCE, isrCount) == false) { iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", "reapInq"), "Unable to see any CE's in IOCQ, dump entire CQ contents"); throw FrmwkEx(HERE, "Unable to see completion of cmd"); } else if (numCE != 1) { throw FrmwkEx(HERE, "The IOCQ should only have 1 CE as a result of a cmd"); } LOG_NRM("The CQ's metrics before reaping holds head_ptr"); struct nvme_gen_cq iocqMetrics = iocq->GetQMetrics(); LOG_NRM("Reaping CE from IOCQ, requires memory to hold reaped CE"); SharedMemBufferPtr ceMemIOCQ = SharedMemBufferPtr(new MemBuffer()); if ((numReaped = iocq->Reap(ceRemain, ceMemIOCQ, isrCount, numCE, true)) != 1) { throw FrmwkEx(HERE, "Verified there was 1 CE, but reaping produced %d", numReaped); } union CE ce = iocq->PeekCE(iocqMetrics.head_ptr); ProcessCE::Validate(ce, CESTAT_SUCCESS); // throws upon error if (ce.n.SQID != IOQ_ID) { iocq->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", "CE.SQID"), "CE SQ ID Inconsistent"); throw FrmwkEx(HERE, "Expected CE.SQID = 0x%04X in IOCQ CE but actual " "CE.SQID = 0x%04X", IOQ_ID, ce.n.SQID); } if (ce.n.SQHD != expectedVal) { iocq->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq", "CE.SQHD"), "CE SQ Head Pointer Inconsistent"); throw FrmwkEx(HERE, "Expected CE.SQHD = 0x%04X in IOCQ CE but actual " "CE.SQHD = 0x%04X", expectedVal, ce.n.SQHD); } }
void MaxIOQMSIXManyTo1_r10b::SendCmdAndReap(SharedIOSQPtr iosq, SharedIOCQPtr iocq, SharedCmdPtr cmd, uint32_t anticipatedIrqs) { uint16_t uniqueId; uint32_t numCE; string work; uint32_t isrCount; LOG_NRM("Send the cmd to hdw via IOSQ #%d", iosq->GetQId()); iosq->Send(cmd, uniqueId); work = str(boost::format("ioqId.%d.%s") % iosq->GetQId() % cmd->GetName().c_str()); iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq", work), "Just B4 ringing doorbell, dump IOSQ"); iosq->Ring(); LOG_NRM("Wait for the CE to arrive in CQ %d", iocq->GetQId()); if (iocq->ReapInquiryWaitSpecify(DEFAULT_CMD_WAIT_ms, 1, numCE, isrCount) == false) { iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.fail", work), "Dump Entire IOCQ"); iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq.fail", work), "Dump Entire IOSQ"); throw FrmwkEx(HERE, "Unable to see CEs for issued cmd"); } work = str(boost::format("iocq.%d") % uniqueId); IO::ReapCE(iocq, 1, isrCount, mGrpName, mTestName, work); if (isrCount != anticipatedIrqs) { iocq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iocq.fail", work), "Dump Entire IOCQ"); iosq->Dump(FileSystem::PrepDumpFile(mGrpName, mTestName, "iosq.fail", work), "Dump Entire IOSQ"); throw FrmwkEx(HERE, "Anticipated ISRs #%d but fired #%d", anticipatedIrqs, isrCount); } }
void CreateIOCQ::Init(const SharedIOCQPtr iocq) { // Setup the PRP buffer based upon contig or non-contig memory int prpField = MASK_PRP1_PAGE; if (iocq->GetIsContig() == false) prpField |= MASK_PRP1_LIST; SetPrpBuffer((send_64b_bitmask)prpField, iocq->GetQBuffer(), iocq->GetQSize()); { // Handle DWORD 10 uint32_t dword10 = GetDword(10); // Handle q size dword10 &= ~0xffff0000; dword10 |= (((uint32_t)(iocq->GetNumEntries() - 1)) << 16); // Handle Q ID dword10 &= ~0x0000ffff; dword10 |= (uint32_t)iocq->GetQId(); SetDword(dword10, 10); } // Handle DWORD 10 { // Handle DWORD 11 uint32_t dword11 = GetDword(11); // Handle the PC bit if (iocq->GetIsContig()) dword11 |= 0x00000001; else dword11 &= ~0x00000001; // Handle IRQ support if (iocq->GetIrqEnabled()) { dword11 |= 0x00000002; dword11 &= ~0xffff0000; // clear it, then set it enum nvme_irq_type irq; uint16_t numIrqs; if (gCtrlrConfig->GetIrqScheme(irq, numIrqs) == false) throw FrmwkEx(HERE, "Unable to retrieve current IRQ scheme"); switch (irq) { case INT_MSI_MULTI: case INT_MSIX: dword11 |= (((uint32_t)iocq->GetIrqVector()) << 16); break; case INT_MSI_SINGLE: case INT_NONE: ; // Required to be zero break; default: throw FrmwkEx(HERE, "Unsupported IRQ scheme, what to do?"); } } else { dword11 &= ~0x00000002; dword11 &= ~0xffff0000; } SetDword(dword11, 11); } // Handle DWORD 11 }