void FunctionalityBare_r10b::ResizeDataBuf(SharedReadPtr &readCmd, SharedWritePtr &writeCmd, ConstSharedIdentifyPtr namSpcPtr, uint64_t maxWrBlks, send_64b_bitmask prpBitmask) { LBAFormat lbaFormat = namSpcPtr->GetLBAFormat(); uint64_t lbaDataSize = (1 << lbaFormat.LBADS); SharedMemBufferPtr readMem = readCmd->GetRWPrpBuffer(); SharedMemBufferPtr writeMem = writeCmd->GetRWPrpBuffer(); switch (gInformative->IdentifyNamespace(namSpcPtr)) { case Informative::NS_BARE: case Informative::NS_METAS: LOG_NRM("Resized max rd/wr blks to %ld for separate meta or bare", maxWrBlks); writeMem->Init(maxWrBlks * lbaDataSize); readMem->Init(maxWrBlks * lbaDataSize); break; case Informative::NS_METAI: LOG_NRM("Resized max rd/wr blks to %ld for integrated meta", maxWrBlks); 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->SetNLB(maxWrBlks - 1); // 0 based value. readCmd->SetPrpBuffer(prpBitmask, readMem); readCmd->SetNLB(maxWrBlks - 1); // 0 based value. }
void UnsupportRrvdFields_r10b::ReadLogPage(SharedACQPtr &acq, SharedASQPtr &asq, uint8_t logId) { string work; LOG_NRM("Reading log page with LID = %d to clear the event mask", logId); ConstSharedIdentifyPtr idCtrlrStruct = gInformative->GetIdentifyCmdCtrlr(); uint8_t X = idCtrlrStruct->GetValue(IDCTRLRCAP_ELPE) + 1; LOG_NRM("Identify controller ELPE = %d (1-based)", X); LOG_NRM("Create get log page cmd and assoc some buffer memory"); SharedGetLogPagePtr getLogPgCmd = SharedGetLogPagePtr(new GetLogPage()); LOG_NRM("Create memory buffer for log page to request error information"); SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer()); send_64b_bitmask prpReq = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); LOG_NRM("Get log page to request error information logId = %d", logId); getLogPgCmd->SetLID(logId); getLogPageMem->Init(GetLogPage::ERRINFO_DATA_SIZE * X, true); getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem); getLogPgCmd->SetNUMD((GetLogPage::ERRINFO_DATA_SIZE * X / 4) - 1); //0-based work = str(boost::format("ErrorLog%d") % (uint32_t)logId); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getLogPgCmd, work, true); }
void MandatorySMART_r10b::IssueGetLogPgCmdLessDwords(SharedASQPtr asq, SharedACQPtr acq, SharedGetLogPagePtr getLogPgCmd, SharedMemBufferPtr getLogPageMem) { string work; send_64b_bitmask prpReq = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); for (uint32_t numd = 1; numd <= SMART_HEALTH_NUMD; numd++) { LOG_NRM("Issue get log page for smart info with NUMD = %d", numd); getLogPageMem->Init(GetLogPage::SMART_DATA_SIZE, true); getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem); getLogPgCmd->SetNUMD(numd - 1); // 0-based work = str(boost::format("Smart.NSID.%Xh.NUMD.%d") % getLogPgCmd->GetNSID() % numd); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getLogPgCmd, work, true); LOG_NRM("Verify the buffer's non-retrieved = 0x00"); SharedMemBufferPtr cmdPayload = getLogPgCmd->GetRWPrpBuffer(); uint32_t offset = (numd * 4); uint8_t *cmdPayloadBuff = (uint8_t *)cmdPayload->GetBuffer() + offset; for (; offset < GetLogPage::SMART_DATA_SIZE; offset++) { LOG_NRM("Verify data at offset = 0x%X", offset); if (*cmdPayloadBuff != 0x0) { throw FrmwkEx(HERE, "Invalid data at buffer offset = 0x%08X, " "value = 0x%08X", cmdPayloadBuff, *cmdPayloadBuff); } cmdPayloadBuff++; } } }
void MandatoryErrInfo_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ string work; uint64_t i; // Lookup objs which were created in a prior test within group SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)) SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)) ConstSharedIdentifyPtr idCtrlrStruct = gInformative->GetIdentifyCmdCtrlr(); uint8_t X = idCtrlrStruct->GetValue(IDCTRLRCAP_ELPE) + 1; LOG_NRM("Identify controller ELPE = %d (1-based)", X); LOG_NRM("Create get log page cmd and assoc some buffer memory"); SharedGetLogPagePtr getLogPgCmd = SharedGetLogPagePtr(new GetLogPage()); LOG_NRM("Create memory buffer for log page to request error information"); SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer()); send_64b_bitmask prpReq = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); LOG_NRM("Get log page to request error information"); getLogPgCmd->SetLID(ERRINFO_LID); // loop for all log entries supported by controller for (uint32_t numd = ERRINFO_NUMD; numd <= (X * ERRINFO_NUMD); numd += ERRINFO_NUMD) { LOG_NRM("Issue Get log page cmd with NUMD = %d and log entries = %d", numd, (numd/ERRINFO_NUMD)); getLogPageMem->Init(GetLogPage::ERRINFO_DATA_SIZE * X, true); getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem); getLogPgCmd->SetNUMD(numd - 1); // 0-based getLogPgCmd->SetNSID(0xFFFFFFFF); work = str(boost::format("logEnties%d") % (numd / ERRINFO_NUMD)); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getLogPgCmd, work, true); // Verify the buffer's non-retrieved log entries = 0x00. SharedMemBufferPtr cmdPayload = getLogPgCmd->GetRWPrpBuffer(); uint32_t offset = (numd * 4); uint8_t *cmdPayloadBuff = (uint8_t *)cmdPayload->GetBuffer() + offset; for (; offset < (X * GetLogPage::ERRINFO_DATA_SIZE); offset++) { LOG_NRM("Verify data at offset = 0x%X", offset); if (*cmdPayloadBuff != 0x0) { throw FrmwkEx(HERE, "Invalid data at buffer offset = 0x%08X, " "value = 0x%08X", cmdPayloadBuff, *cmdPayloadBuff); } cmdPayloadBuff++; } } }
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 LBAOutOfRangeBare_r12::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ uint64_t nsze; char work[256]; 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)); vector<uint32_t> bare = gInformative->GetBareNamespaces(); for (size_t i = 0; i < bare.size(); i++) { namSpcPtr = gInformative->GetIdentifyCmdNamspc(bare[i]); if (namSpcPtr->isZeroFilled()) { LOG_NRM("Namespace %lu is inactive", i); } else { nsze = namSpcPtr->GetValue(IDNAMESPC_NSZE); LOG_NRM("Create memory to contain write payload"); SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer()); uint64_t lbaDataSize = namSpcPtr->GetLBADataSize(); writeMem->Init(WR_NUM_BLKS * lbaDataSize); LOG_NRM("Create a write cmd to write data to namspc %d", bare[i]); 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->SetNSID(bare[i]); writeCmd->SetNLB(WR_NUM_BLKS - 1); // convert to 0-based value LOG_NRM( "Issue cmd where 1st block starts at LBA (Identify.NSZE-2)"); snprintf(work, sizeof(work), "nsze-2.%01d", (uint32_t)i); writeCmd->SetSLBA(nsze - 2); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, writeCmd, work, true); LOG_NRM( "Issue cmd where 1st block starts at LBA (Identify.NSZE-1)"); snprintf(work, sizeof(work), "nsze-1.%d01d", (uint32_t)i); writeCmd->SetSLBA(nsze - 1); SendCmdToHdw(iosq, iocq, writeCmd, work); LOG_NRM("Issue cmd where 1st block starts at LBA (Identify.NSZE)"); snprintf(work, sizeof(work), "nsze.%01d", (uint32_t)i); writeCmd->SetSLBA(nsze); SendCmdToHdw(iosq, iocq, writeCmd, work); } } }
bool LBAOutOfRangeBare_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ uint64_t nsze; ConstSharedIdentifyPtr namSpcPtr; // 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)) vector<uint32_t> bare = gInformative->GetBareNamespaces(); for (size_t i = 1; i < bare.size(); i++) { namSpcPtr = gInformative->GetIdentifyCmdNamspc(i); if (namSpcPtr == Identify::NullIdentifyPtr) { LOG_ERR("Identify namspc struct #%d doesn't exist", bare[i]); throw exception(); } nsze = namSpcPtr->GetValue(IDNAMESPC_NSZE); LOG_NRM("Create memory to contain read payload"); SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer()); uint64_t lbaDataSize = namSpcPtr->GetLBADataSize(); readMem->Init(RD_NUM_BLKS * lbaDataSize); LOG_NRM("Create a read cmd to read data from namspc %d", bare[i]); SharedReadPtr readCmd = SharedReadPtr(new Read(mFd)); send_64b_bitmask prpBitmask = (send_64b_bitmask) (MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST); readCmd->SetPrpBuffer(prpBitmask, readMem); readCmd->SetNSID(bare[i]); readCmd->SetNLB(RD_NUM_BLKS - 1); // convert to 0-based value LOG_NRM("Issue cmd where 1st block starts at LBA (Identify.NSZE-2)"); readCmd->SetSLBA(nsze - 2); IO::SendCmdToHdw(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosqContig, iocqContig, readCmd, "nsze-2", true); LOG_NRM("Issue cmd where 1st block starts at LBA (Identify.NSZE-1)"); readCmd->SetSLBA(nsze - 1); SendCmdToHdw(iosqContig, iocqContig, readCmd, "nsze-1"); LOG_NRM("Issue cmd where 1st block starts at LBA (Identify.NSZE)"); readCmd->SetSLBA(nsze); SendCmdToHdw(iosqContig, iocqContig, readCmd, "nsze"); } return true; }
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); } }
SharedWritePtr SQCQSizeMismatch_r10b::SetWriteCmd() { Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E(); LOG_NRM("Processing write cmd using namspc id %d", namspcData.id); LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat(); LOG_NRM("Create data pattern to write to media"); SharedMemBufferPtr dataPat = SharedMemBufferPtr(new MemBuffer()); uint64_t lbaDataSize = namspcData.idCmdNamspc->GetLBADataSize(); SharedWritePtr writeCmd = SharedWritePtr(new Write()); send_64b_bitmask prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST); switch (namspcData.type) { case Informative::NS_BARE: dataPat->Init(lbaDataSize); break; case Informative::NS_METAS: dataPat->Init(lbaDataSize); if (gRsrcMngr->SetMetaAllocSize(lbaFormat.MS) == false) throw FrmwkEx(HERE); writeCmd->AllocMetaBuffer(); break; case Informative::NS_METAI: dataPat->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, dataPat); writeCmd->SetNSID(namspcData.id); writeCmd->SetNLB(0); return writeCmd; }
void ReadWriteToUnacquiredReservation::RunCoreTest() { /** \verbatim * Assumptions: * None. * \endverbatim */ LOG_NRM("Start ReadWriteToUnacquiredReservation::RunCoreTest") SharedIOSQPtr iosq = CAST_TO_IOSQ(gRsrcMngr->GetObj(IOSQ_GROUP_ID)); SharedIOCQPtr iocq = CAST_TO_IOCQ(gRsrcMngr->GetObj(IOCQ_GROUP_ID)); SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)); SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)); SharedWritePtr writeCmd = SharedWritePtr(new Write()); SharedReadPtr readCmd = SharedReadPtr(new Read()); SharedMemBufferPtr lbaWriteBuffer = SharedMemBufferPtr(new MemBuffer()); SharedMemBufferPtr lbaReadBuffer = SharedMemBufferPtr(new MemBuffer()); LOG_NRM("Create nvmeWrite Cmd and write 1 block of data to LBA 5, expecting 0:0x83 for HostB"); lbaWriteBuffer->Init(512, true, 0xDD); writeCmd->SetPrpBuffer( (send_64b_bitmask)( MASK_PRP1_PAGE | MASK_PRP2_PAGE), lbaWriteBuffer); writeCmd->SetNSID(1); writeCmd->SetSLBA(5); writeCmd->SetNLB(0); // 0's based! IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, writeCmd, "write 0xDD's to LBA5 using hostB", true, CESTAT_RSRV_CONFLICT); LOG_NRM("Create nvmeRead Cmd and read back 1 block of data to LBA 5, expecting 0:0x83 for HostA"); lbaReadBuffer->Init(512, true, 0x00); readCmd->SetPrpBuffer( (send_64b_bitmask) (MASK_PRP1_PAGE | MASK_PRP2_PAGE), lbaReadBuffer); readCmd->SetNSID(1); readCmd->SetSLBA(5); readCmd->SetNLB(0); // 0's based! IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, readCmd, "read from LBA5 using hostB", true, CESTAT_RSRV_CONFLICT); LOG_NRM("Completed ReadWriteToUnacquiredReservation::RunCoreTest") }
SharedReadPtr FUA_r10b::CreateCmd() { Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E(); LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat(); LOG_NRM("Processing read cmd using namspc id %d", namspcData.id); ConstSharedIdentifyPtr namSpcPtr = namspcData.idCmdNamspc; uint64_t lbaDataSize = namSpcPtr->GetLBADataSize();; SharedMemBufferPtr dataPat = SharedMemBufferPtr(new MemBuffer()); SharedReadPtr readCmd = SharedReadPtr(new Read()); send_64b_bitmask prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST); switch (namspcData.type) { case Informative::NS_BARE: dataPat->Init(lbaDataSize); break; case Informative::NS_METAS: dataPat->Init(lbaDataSize); if (gRsrcMngr->SetMetaAllocSize(lbaFormat.MS) == false) throw FrmwkEx(HERE); readCmd->AllocMetaBuffer(); break; case Informative::NS_METAI: dataPat->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; } readCmd->SetPrpBuffer(prpBitmask, dataPat); readCmd->SetNSID(namspcData.id); readCmd->SetNLB(0); return readCmd; }
void ProtInfoIgnoreBare_r10b::RunCoreTest() { /** \verbatim * Assumptions: * None. * \endverbatim */ char context[256]; 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)); vector<uint32_t> bare = gInformative->GetBareNamespaces(); for (size_t i = 0; i < bare.size(); i++) { namSpcPtr = gInformative->GetIdentifyCmdNamspc(bare[i]); if (namSpcPtr == Identify::NullIdentifyPtr) { throw FrmwkEx(HERE, "Identify namspc struct #%d doesn't exist", bare[i]); } LOG_NRM("Create memory to contain write payload"); SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer()); uint64_t lbaDataSize = namSpcPtr->GetLBADataSize(); writeMem->Init(lbaDataSize); LOG_NRM("Create a write cmd to read data from namspc %d", bare[i]); 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->SetNSID(bare[i]); writeCmd->SetNLB(0); // convert to 0-based value for (uint16_t protInfo = 0; protInfo <= 0x0f; protInfo++) { uint8_t work = writeCmd->GetByte(12, 3); work &= ~0x3c; // PRINFO specific bits work |= (protInfo << 2); writeCmd->SetByte(work, 12, 3); snprintf(context, sizeof(context), "ns%d.protInfo0x%02X", (uint32_t)i, protInfo); IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq, iocq, writeCmd, context, true); } } }
SharedWritePtr CIDAcceptedIOSQ_r10b::CreateWriteCmd() { Informative::Namspc namspcData = gInformative->Get1stBareMetaE2E(); LBAFormat lbaFormat = namspcData.idCmdNamspc->GetLBAFormat(); SharedMemBufferPtr wrMemBuf = SharedMemBufferPtr(new MemBuffer()); uint64_t lbaDataSize = namspcData.idCmdNamspc->GetLBADataSize(); SharedWritePtr writeCmd = SharedWritePtr(new Write()); send_64b_bitmask prpBitmask = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST); switch (namspcData.type) { case Informative::NS_BARE: wrMemBuf->Init(lbaDataSize); break; case Informative::NS_METAS: wrMemBuf->Init(lbaDataSize); if (gRsrcMngr->SetMetaAllocSize(lbaFormat.MS) == false) throw FrmwkEx(HERE); writeCmd->AllocMetaBuffer(); break; case Informative::NS_METAI: wrMemBuf->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, wrMemBuf); writeCmd->SetNSID(namspcData.id); return writeCmd; }
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"); } } }
void ProtInfoIgnoreBare_r12::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ char context[256]; 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)); vector<uint32_t> bare = gInformative->GetBareNamespaces(); for (size_t i = 0; i < bare.size(); i++) { namSpcPtr = gInformative->GetIdentifyCmdNamspc(bare[i]); if (namSpcPtr->isZeroFilled()) { LOG_NRM("Namespace %lu is inactive", i); } else { LOG_NRM("Create memory to contain read payload"); SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer()); uint64_t lbaDataSize = namSpcPtr->GetLBADataSize(); readMem->Init(lbaDataSize); LOG_NRM("Create a read cmd to read data from namspc %d", bare[i]); SharedReadPtr readCmd = SharedReadPtr(new Read()); send_64b_bitmask prpBitmask = (send_64b_bitmask) (MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST); readCmd->SetPrpBuffer(prpBitmask, readMem); readCmd->SetNSID(bare[i]); readCmd->SetNLB(0); // convert to 0-based value for (uint16_t protInfo = 0; protInfo <= 0x0f; protInfo++) { uint8_t work = readCmd->GetByte(12, 3); work &= ~0x3c; // PRINFO specific bits work |= (protInfo << 2); readCmd->SetByte(work, 12, 3); snprintf(context, sizeof(context), "ns%d.protInfo0x%02X", (uint32_t)i, protInfo); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, readCmd, context, true); } } } }
void IgnoreMetaPtrBare_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ string work; ConstSharedIdentifyPtr namSpcPtr; 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)); LOG_NRM("For all bare namspc's issue cmd with non-zero meta ptr"); vector<uint32_t> bare = gInformative->GetBareNamespaces(); for (size_t i = 0; i < bare.size(); i++) { namSpcPtr = gInformative->GetIdentifyCmdNamspc(bare[i]); if (namSpcPtr == Identify::NullIdentifyPtr) { throw FrmwkEx(HERE, "Identify namspc struct #%d doesn't exist", bare[i]); } LOG_NRM("Setup write cmd's values that won't change per namspc"); SharedMemBufferPtr writeMem = SharedMemBufferPtr(new MemBuffer()); uint64_t lbaDataSize = namSpcPtr->GetLBADataSize(); 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("Set MPTR in cmd to max value"); writeCmd->SetDword(0xffffffff, 4); writeCmd->SetDword(0xffffffff, 5); writeCmd->SetNSID(bare[i]); work = str(boost::format("namspc%d") % bare[i]); IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq, iocq, writeCmd, work, true); } }
void IgnoreMetaPtrBare_r12::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ string work; 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)); LOG_NRM("For all bare namspc's issue cmd with non-zero meta ptr"); vector<uint32_t> bare = gInformative->GetBareNamespaces(); for (size_t i = 0; i < bare.size(); i++) { namSpcPtr = gInformative->GetIdentifyCmdNamspc(bare[i]); if (namSpcPtr->isZeroFilled()) { LOG_NRM("Namespace %lu is inactive", i); } else { LOG_NRM("Setup read cmd's values that won't change per namspc"); SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer()); uint64_t lbaDataSize = namSpcPtr->GetLBADataSize(); readMem->Init(lbaDataSize); SharedReadPtr readCmd = SharedReadPtr(new Read()); send_64b_bitmask prpBitmask = (send_64b_bitmask) (MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST); readCmd->SetPrpBuffer(prpBitmask, readMem); readCmd->SetNLB(0); // convert to 0-based value readCmd->SetSLBA(0); LOG_NRM("Set MPTR in cmd to max value"); readCmd->SetDword(0xffffffff, 4); readCmd->SetDword(0xffffffff, 5); readCmd->SetNSID(bare[i]); work = str(boost::format("namspc%d") % bare[i]); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, readCmd, work, true); } } }
void UnsupportRsvdFields_r11b::ReadLogPage(SharedACQPtr &acq, SharedASQPtr &asq, uint8_t logId) { string work; LOG_NRM("Reading log page with LID = %d to clear the event mask", logId); ConstSharedIdentifyPtr idCtrlrStruct = gInformative->GetIdentifyCmdCtrlr(); uint16_t elpeVal = idCtrlrStruct->GetValue(IDCTRLRCAP_ELPE) + 1; LOG_NRM("Identify controller ELPE = %d (1-based)", elpeVal); uint16_t totalBytes = elpeVal * GetLogPage::ERRINFO_DATA_SIZE; LOG_NRM("Total bytes available for error info log page: %d", totalBytes); uint8_t mps; if (!gCtrlrConfig->GetMPS(mps)) throw FrmwkEx(HERE, "Failed to retrieve CC.MPS value"); uint32_t twoPages = 2 * (1 << (mps + 12)); LOG_NRM("Size of two memory pages (i.e. PRP1 & PRP2): %d bytes", twoPages); // PRP2 cannot be pointer to PRP list, so don't ask for more than 2 pages if (totalBytes > twoPages) { LOG_NRM("Can only utilize two memory pages; reducing total bytes"); totalBytes = twoPages; } uint16_t totalDwords = totalBytes / 4; LOG_NRM("Create get log page cmd and assoc some buffer memory"); SharedGetLogPagePtr getLogPgCmd = SharedGetLogPagePtr(new GetLogPage()); LOG_NRM("Create memory buffer for log page to request error information"); SharedMemBufferPtr getLogPageMem = SharedMemBufferPtr(new MemBuffer()); send_64b_bitmask prpReq = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); LOG_NRM("Get log page to request error information logId = %d", logId); getLogPgCmd->SetLID(logId); getLogPageMem->Init(totalBytes, true); getLogPgCmd->SetPrpBuffer(prpReq, getLogPageMem); getLogPgCmd->SetNUMD(totalDwords - 1); //0-based work = str(boost::format("ErrorLog%d") % (uint32_t)logId); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getLogPgCmd, work, true); }
uint16_t CQ::Reap(uint16_t &ceRemain, SharedMemBufferPtr memBuffer, uint32_t &isrCount, uint16_t ceDesire, bool zeroMem) { int rc; struct nvme_reap reap; // The tough part of reaping all which can be reaped, indicated by // (ceDesire == 0), is that CE's can be arriving from hdw between the time // one calls ReapInquiry() and Reap(). In essence this indicates we really // can never know for certain how many there are to be reaped, and thus // never really knowing how large to make a buffer to reap CE's into. // The solution is to enforce brute force methods by allocating max CE's if (ceDesire == 0) { // Per NVME spec: 1 empty CE implies a full CQ, can't truly fill all ceDesire = (GetNumEntries() - 1); } else if (ceDesire > (GetNumEntries() - 1)) { // Per NVME spec: 1 empty CE implies a full CQ, can't truly fill all LOG_NRM("Requested num of CE's exceeds max can fit, resizing"); ceDesire = (GetNumEntries() - 1); } // Allocate enough space to contain the CE's memBuffer->Init(GetEntrySize()*ceDesire); if (zeroMem) memBuffer->Zero(); reap.q_id = GetQId(); reap.elements = ceDesire; reap.size = memBuffer->GetBufSize(); reap.buffer = memBuffer->GetBuffer(); if ((rc = ioctl(mFd, NVME_IOCTL_REAP, &reap)) < 0) { LOG_ERR("Error during reaping CE's, rc =%d", rc); throw exception(); } isrCount = reap.isr_count; ceRemain = reap.num_remaining; LOG_NRM("Reaped %d CE's, %d remain, from CQ %d, ISR count: %d", reap.num_reaped, reap.num_remaining, GetQId(), isrCount); return reap.num_reaped; }
void IgnoreMetaPtrMeta_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ string work; ConstSharedIdentifyPtr namSpcPtr; 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)); LOG_NRM("For all imeta namspc's issue read cmd with non-zero meta ptr"); vector<uint32_t> imeta = gInformative->GetMetaINamespaces(); for (size_t i = 0; i < imeta.size(); i++) { namSpcPtr = gInformative->GetIdentifyCmdNamspc(imeta[i]); LOG_NRM("Setup read cmd's values that won't change per namspc"); SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer()); uint64_t lbaDataSize = namSpcPtr->GetLBADataSize(); LBAFormat lbaFormat = namSpcPtr->GetLBAFormat(); readMem->Init(lbaDataSize + lbaFormat.MS); SharedReadPtr readCmd = SharedReadPtr(new Read()); send_64b_bitmask prpBitmask = (send_64b_bitmask) (MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST); readCmd->SetPrpBuffer(prpBitmask, readMem); readCmd->SetNLB(0); // convert to 0-based value LOG_NRM("Set MPTR in cmd to max value"); readCmd->SetDword(0xffffffff, 4); readCmd->SetDword(0xffffffff, 5); readCmd->SetNSID(imeta[i]); work = str(boost::format("namspc%d") % imeta[i]); IO::SendAndReapCmd(mGrpName, mTestName, DEFAULT_CMD_WAIT_ms, iosq, iocq, readCmd, work, true); } }
void ProtInfoIgnoreMeta_r10b::RunCoreTest() { /** \verbatim * Assumptions: * 1) None. * \endverbatim */ string context; ConstSharedIdentifyPtr namSpcPtr; SharedIOSQPtr iosq; SharedIOCQPtr iocq; send_64b_bitmask prpBitmask = (send_64b_bitmask) (MASK_PRP1_PAGE | MASK_PRP2_PAGE | MASK_PRP2_LIST); 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); LOG_NRM("Get all the supported meta namespaces"); vector<uint32_t> meta = gInformative->GetMetaNamespaces(); for (size_t i = 0; i < meta.size(); i++) { 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); LOG_NRM("Create a read cmd to read data from namspc %d", meta[i]); SharedReadPtr readCmd = SharedReadPtr(new Read()); LOG_NRM("Create memory to contain read payload"); SharedMemBufferPtr readMem = SharedMemBufferPtr(new MemBuffer()); Informative::NamspcType nsType = gInformative->IdentifyNamespace(namSpcPtr); switch (nsType) { case Informative::NS_BARE: throw FrmwkEx(HERE, "Namspc type cannot be BARE."); case Informative::NS_METAS: readMem->Init(lbaDataSize); if (gRsrcMngr->SetMetaAllocSize(lbaFormat.MS) == false) throw FrmwkEx(HERE); readCmd->AllocMetaBuffer(); break; case Informative::NS_METAI: 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; } readCmd->SetPrpBuffer(prpBitmask, readMem); readCmd->SetNSID(meta[i]); readCmd->SetNLB(0); // convert to 0-based value for (uint16_t protInfo = 0; protInfo <= 0x0f; protInfo++) { uint8_t work = readCmd->GetByte(12, 3); work &= ~0x3c; // PRINFO specific bits work |= (protInfo << 2); readCmd->SetByte(work, 12, 3); context = str(boost::format("ns%d.protInfo0x%02X") % (uint32_t)i % protInfo); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, readCmd, context, true); } } }
void UnsupportRsvdFields_r11b::RunCoreTest() { /** \verbatim * Assumptions: * 1) Test CreateResources_r10b has run prior. * \endverbatim */ // Lookup objs which were created in a prior test within group SharedIOSQPtr iosq = CAST_TO_IOSQ(gRsrcMngr->GetObj(IOSQ_GROUP_ID)); SharedIOCQPtr iocq = CAST_TO_IOCQ(gRsrcMngr->GetObj(IOCQ_GROUP_ID)); SharedDatasetMgmtPtr datasetMgmtCmd = SharedDatasetMgmtPtr(new DatasetMgmt()); uint16_t timeout; if (gCmdLine.setAD) timeout = 1000; else timeout = 1; ConstSharedIdentifyPtr idCtrlr = gInformative->GetIdentifyCmdCtrlr(); for (uint64_t i = 1; i <= idCtrlr->GetValue(IDCTRLRCAP_NN); i++) { LOG_NRM("Processing namspc %ld", i); datasetMgmtCmd->SetNSID(i); LOG_NRM("Create memory to contain 1 dataset range def"); SharedMemBufferPtr rangeMem = SharedMemBufferPtr(new MemBuffer()); rangeMem->Init(sizeof(RangeDef), true); send_64b_bitmask prpReq = (send_64b_bitmask)(MASK_PRP1_PAGE | MASK_PRP2_PAGE); datasetMgmtCmd->SetPrpBuffer(prpReq, rangeMem); LOG_NRM("Setup generic range def guidelines"); RangeDef *rangeDef = (RangeDef *)rangeMem->GetBuffer(); rangeDef->length = 1; if (gCmdLine.setAD) datasetMgmtCmd->SetAD(true); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(timeout), iosq, iocq, datasetMgmtCmd, "none.set", true); LOG_NRM("Set all cmd's rsvd bits"); uint32_t work = datasetMgmtCmd->GetDword(0); work |= 0x00007c00; // Set DW0_b14:10 bits datasetMgmtCmd->SetDword(work, 0); datasetMgmtCmd->SetDword(0xffffffff, 2); datasetMgmtCmd->SetDword(0xffffffff, 3); datasetMgmtCmd->SetDword(0xffffffff, 4); datasetMgmtCmd->SetDword(0xffffffff, 5); datasetMgmtCmd->SetDword(0xffffffff, 8); datasetMgmtCmd->SetDword(0xffffffff, 9); work = datasetMgmtCmd->GetDword(10); work |= 0xffffff00; // Set DW10_b31:8 bits datasetMgmtCmd->SetDword(work, 10); work = datasetMgmtCmd->GetDword(11); work |= 0xfffffff8; // Set DW11_b31:3 bits if (gCmdLine.setAD) work |= 0x4; // Set Bit2 AD=1 (Deallocate) datasetMgmtCmd->SetDword(work, 11); datasetMgmtCmd->SetDword(0xffffffff, 12); datasetMgmtCmd->SetDword(0xffffffff, 13); datasetMgmtCmd->SetDword(0xffffffff, 14); datasetMgmtCmd->SetDword(0xffffffff, 15); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(timeout), iosq, iocq, datasetMgmtCmd, "all.set", true); } }
void RegisterReservation::RunCoreTest() { /** \verbatim * Assumptions: * None. * \endverbatim */ LOG_NRM("Start RegisterReservationHostB::RunCoreTest"); SharedIOSQPtr iosq = CAST_TO_IOSQ(gRsrcMngr->GetObj(IOSQ_GROUP_ID)); SharedIOCQPtr iocq = CAST_TO_IOCQ(gRsrcMngr->GetObj(IOCQ_GROUP_ID)); SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)); SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)); //uint8_t keyToRegister[16]; //uint32_t memAlignment = sysconf(_SC_PAGESIZE); CEStat retStat; LOG_NRM("Create Set features cmd to set HostID"); SharedSetFeaturesPtr setFeaturesCmd = SharedSetFeaturesPtr(new SetFeatures()); setFeaturesCmd->SetFID(0x81); // Host Identifier LOG_NRM("Create memory to contain HostID payload"); SharedMemBufferPtr writeHostIDmem = SharedMemBufferPtr(new MemBuffer()); // Init(uint32_t bufSize, bool initMem = false, uint8_t initVal = 0) writeHostIDmem->Init(8, true, 0xBB); //writeHostIDmem->InitAlignment(8, true, true, 0xAA); // HostID = 0xAAAAAAAAAAAAAAAA send_64b_bitmask prpBitmask = (send_64b_bitmask) MASK_PRP1_PAGE; setFeaturesCmd->SetPrpBuffer(prpBitmask, writeHostIDmem); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, setFeaturesCmd, "Set 0xBBs hostID", true, CESTAT_SUCCESS); LOG_NRM("Create Get features cmd to read back HostID"); SharedGetFeaturesPtr getFeaturesCmd = SharedGetFeaturesPtr(new GetFeatures()); getFeaturesCmd->SetFID(0x81); // Host Identifier SharedMemBufferPtr readHostIDmem = SharedMemBufferPtr(new MemBuffer()); readHostIDmem->Init(8, true, 0x00); // HostID = 0xAAAAAAAAAAAAAAAA getFeaturesCmd->SetPrpBuffer(prpBitmask, readHostIDmem); std::vector<CEStat> acceptableReturnStatuses = {CESTAT_SUCCESS, CESTAT_IGNORE}; retStat = IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getFeaturesCmd, "Read back hostID", true, acceptableReturnStatuses); if(retStat != CESTAT_SUCCESS) { LOG_NRM("Was unable to get back HostId after setting..."); } else { LOG_NRM("Compare returned HostID to what was just previously set..."); if (writeHostIDmem->Compare(readHostIDmem) == false) { LOG_NRM("HostID MISMATCH!!!"); writeHostIDmem->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "WriteHostID"), "setFeatures HostID"); readHostIDmem->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "ReadHostId"), "getFeatures HostID"); throw FrmwkEx(HERE, "Data miscompare"); } } // HostID should be set... now we can register a key, first we will try to release SharedMemBufferPtr writeRegKey = SharedMemBufferPtr(new MemBuffer()); SharedReservationRegisterPtr reservationRegisterCmd = SharedReservationRegisterPtr(new ReservationRegister()); LOG_NRM("Release any current key with IKEY=1. If pass we cleared a key, else was already clear."); reservationRegisterCmd->SetNSID(1); reservationRegisterCmd->SetCPTPL(0); // No PTPL change reservationRegisterCmd->SetIEKEY(1); reservationRegisterCmd->SetRREGA(1); // Unregister Key writeRegKey->Init(16, true, 0); // 0's in buffer, IKEY will ignore CKEY/NKEY reservationRegisterCmd->SetPrpBuffer(prpBitmask, writeRegKey); std::vector<CEStat> possibleReturnStatuses = {CESTAT_SUCCESS, CESTAT_RSRV_CONFLICT, CESTAT_IGNORE}; retStat = IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, reservationRegisterCmd, "Release Any Key HostB", true, possibleReturnStatuses); switch(retStat) { case CESTAT_SUCCESS: LOG_NRM("Success status returned, a key was assumed to have been present and is now cleared."); break; case CESTAT_RSRV_CONFLICT: LOG_NRM("Rsrv Conflict status returned, a key was assumed have not been present to be able to be cleared."); break; default: LOG_NRM("Unknown stat returned back while attempting to unregister a potential exhisting key... continuing."); } LOG_NRM("Register our key (0xBD's), expecting pass"); reservationRegisterCmd->SetNSID(1); reservationRegisterCmd->SetCPTPL(0); // No PTPL change reservationRegisterCmd->SetIEKEY(1); reservationRegisterCmd->SetRREGA(0); // Register Key writeRegKey->Init(16, true, 0xBD); // 0xAF's as arbitrary new key reservationRegisterCmd->SetPrpBuffer(prpBitmask, writeRegKey); retStat = IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, reservationRegisterCmd, "Register Key 0xBD HostB", true, CESTAT_SUCCESS); //LOG_NRM("Try to register (not replace) a new key. Should always fail even with IEKEY=1 and same key as before... Expecting Rsvr Conflict."); // Same command as before... /* reservationRegisterCmd->SetNSID(1); reservationRegisterCmd->SetCPTPL(0); // No PTPL change reservationRegisterCmd->SetIEKEY(1); reservationRegisterCmd->SetRREGA(0); // Register Key writeRegKey->InitAlignment(16, true, 0xAE); // 0xAF's as arbitrary new key reservationRegisterCmd->SetPrpBuffer(prpBitmask, writeRegKey); */ //retStat = IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, reservationRegisterCmd, "Register Key 0xBD HostB", true, CESTAT_RSRV_CONFLICT); LOG_NRM("Completed RegisterReservationHostB::RunCoreTest"); }
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 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); } }
void AcquireReservation::RunCoreTest() { /** \verbatim * Assumptions: * None. * \endverbatim */ LOG_NRM("Start AcquireReservation::RunCoreTest") SharedIOSQPtr iosq = CAST_TO_IOSQ(gRsrcMngr->GetObj(IOSQ_GROUP_ID)); SharedIOCQPtr iocq = CAST_TO_IOCQ(gRsrcMngr->GetObj(IOCQ_GROUP_ID)); SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)); SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)); SharedWritePtr writeCmd = SharedWritePtr(new Write()); SharedReadPtr readCmd = SharedReadPtr(new Read()); SharedMemBufferPtr writeRegKey = SharedMemBufferPtr(new MemBuffer()); SharedMemBufferPtr lbaWriteBuffer = SharedMemBufferPtr(new MemBuffer()); SharedMemBufferPtr lbaReadBuffer = SharedMemBufferPtr(new MemBuffer()); uint8_t keyToRegister[16]; uint32_t memAlignment = sysconf(_SC_PAGESIZE); LOG_NRM("Create ReservationAcquire Cmd and attempt to acquire NSID using wrong key (0xFA versus current 0xAD"); SharedReservationAcquirePtr reservationAcquireCmd = SharedReservationAcquirePtr(new ReservationAcquire()); reservationAcquireCmd->SetNSID(1); reservationAcquireCmd->SetRTYPE(2); reservationAcquireCmd->SetIEKEY(0); reservationAcquireCmd->SetRACQA(0); for(uint8_t keyIndex = 0; keyIndex < 8; keyIndex++) keyToRegister[keyIndex] = 0xFA; writeRegKey->InitAlignment(8, memAlignment, false, 0x0, keyToRegister); // 0xAD should be current key... reservationAcquireCmd->SetPrpBuffer( (send_64b_bitmask)MASK_PRP1_PAGE, writeRegKey); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, reservationAcquireCmd, "Acquire NSID using wrong key", true, CESTAT_RSRV_CONFLICT); LOG_NRM("Create ReservationAcquire Cmd and attempt to acquire NSID using right key (0xAD"); for(uint8_t keyIndex = 0; keyIndex < 8; keyIndex++) keyToRegister[keyIndex] = 0xAD; writeRegKey->InitAlignment(8, memAlignment, false, 0x0, keyToRegister); // 0xAD should be current key... reservationAcquireCmd->SetPrpBuffer( (send_64b_bitmask)MASK_PRP1_PAGE, writeRegKey); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, reservationAcquireCmd, "Acquire NSID using right key", true, CESTAT_SUCCESS); LOG_NRM("Create nvmeWrite Cmd and write 1 block of data to LBA 5, expecting a pass for HostA"); lbaWriteBuffer->Init(512, true, 0xCC); writeCmd->SetPrpBuffer( (send_64b_bitmask)( MASK_PRP1_PAGE | MASK_PRP2_PAGE), lbaWriteBuffer); writeCmd->SetNSID(1); writeCmd->SetSLBA(5); writeCmd->SetNLB(0); // 0's based! IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, writeCmd, "write 0xCC's to LBA5", true, CESTAT_SUCCESS); LOG_NRM("Create nvmeRead Cmd and read back 1 block of data to LBA 5, expecting a pass for HostA"); lbaReadBuffer->Init(512, true, 0x00); readCmd->SetPrpBuffer( (send_64b_bitmask) (MASK_PRP1_PAGE | MASK_PRP2_PAGE), lbaReadBuffer); readCmd->SetNSID(1); readCmd->SetSLBA(5); readCmd->SetNLB(0); // 0's based! IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), iosq, iocq, readCmd, "read from LBA5", true, CESTAT_SUCCESS); LOG_NRM("Ensure the data read back matches the expected data written (0xCC's)") if (lbaWriteBuffer->Compare(lbaReadBuffer) == false) { LOG_NRM("Data MISMATCH!!!") lbaWriteBuffer->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "Write Data"), "write after acquire"); lbaReadBuffer->Dump( FileSystem::PrepDumpFile(mGrpName, mTestName, "Read Data"), "read after acquire"); throw FrmwkEx(HERE, "Data miscompare"); } LOG_NRM("Completed AcquireReservation::RunCoreTest") }
void CreateAndAttachMaxNamespacesAndVerify::RunCoreTest() { /** \verbatim * Assumptions: * None. * \endverbatim */ LOG_NRM("Start CreateAndAttachMaxNamespacesAndVerify::RunCoreTest"); SharedIOSQPtr iosq = CAST_TO_IOSQ(gRsrcMngr->GetObj(IOSQ_GROUP_ID)); SharedIOCQPtr iocq = CAST_TO_IOCQ(gRsrcMngr->GetObj(IOCQ_GROUP_ID)); SharedASQPtr asq = CAST_TO_ASQ(gRsrcMngr->GetObj(ASQ_GROUP_ID)); SharedACQPtr acq = CAST_TO_ACQ(gRsrcMngr->GetObj(ACQ_GROUP_ID)); //uint8_t keyToRegister[16]; //uint32_t memAlignment = sysconf(_SC_PAGESIZE); //CEStat retStat; send_64b_bitmask prpBitmask = (send_64b_bitmask) (MASK_PRP1_PAGE | MASK_PRP2_PAGE); uint8_t userBuffer[4096]; if (userBuffer == 0){} // Suppress unused variable warning const uint32_t *namespaceIdListBuffer32BitPtr = NULL; const uint16_t *controllerIdListBuffer16BitPtr; ConstSharedIdentifyPtr idCtrlrCap = gInformative->GetIdentifyCmdCtrlr(); uint32_t identifyControllerMaxNSID = (uint32_t)idCtrlrCap->GetValue(IDCTRLRCAP_NN); // BUGBUG large assumption that NVMCAP values will not be larger than 64bit num bytes, which is 16384 PETAbytes // BUGBUG Also assume we need to create on GB multiples uint64_t identifyControllerUnallocatedCapacity = idCtrlrCap->GetValue(IDCTRLRCAP_UNVMCAP_LOWER); uint64_t identifyControllerTotalCapacity = idCtrlrCap->GetValue(IDCTRLRCAP_TNVMCAP_LOWER); uint64_t individualNamespaceCapacityInGB = (uint64_t) floor( identifyControllerUnallocatedCapacity / 1024.0 / 1024.0 / 1024.0 / identifyControllerMaxNSID); // In GB units uint64_t individualNamespaceCapacity = individualNamespaceCapacityInGB * 1024 * 1024 * 1024 / 512; // In 512B LBA units uint32_t newlyCreatedNSID = 0; if( identifyControllerUnallocatedCapacity != identifyControllerTotalCapacity) { LOG_NRM("TNVMCAP != UNVMCAP, which points to a namespace being allocated but the previous test should have deleted all"); } LOG_NRM("Create Identify Command To Get All Present NSIDs"); SharedIdentifyPtr identifyCmd = SharedIdentifyPtr(new Identify()); SharedMemBufferPtr identifyControllerStruct = SharedMemBufferPtr(new MemBuffer()); identifyControllerStruct->Init(4096, true, 0x0); SharedMemBufferPtr identifyNamespaceStruct = SharedMemBufferPtr(new MemBuffer()); identifyNamespaceStruct->Init(4096, true, 0x0); SharedMemBufferPtr identifyNamespaceList = SharedMemBufferPtr(new MemBuffer()); identifyNamespaceList->Init(4096, true, 0x0); SharedMemBufferPtr identifyControllerList = SharedMemBufferPtr(new MemBuffer()); identifyControllerList->Init(4096, true, 0x0); // Figure 86 in 1.2 spec CNS NSID CNTID Returns // CNS_Namespace 0x00 X - (Identify Namespace from NSID X. If attached, receive struct, else all 0's, else invalid namespace ID) // CNS_Controller 0x01 - - (Identify Controller struct) // CNS_NamespaceListAttached 0x02 Y - (Identify Namespace LIST, starting at NSID Y and in an increasing order) // CNS_NamespaceListSubsystem 0x10 Z - (Identify Namespace LIST, starting at NSID Z present in subsystem that may or may not be attached) // CNS_NamespaceStructSubsystem 0x11 X - (Identify Namespace from NSID A. If attached or not, receive the struct, else invalid namespace ID) // CNS_ControllerListAttachedToNSID 0x12 X A (Controller List that are attached to NSID X, starting with CNTID greater than A) // CNS_ControllerListSubsystem 0x13 - B (Controller List present in subsystem starting with CNTID greater than B) LOG_NRM("First ensure there are no namespaces present, as this test depends on deleteAllNamespacesAndVerify to complete successfully"); // See 8.11 in 1.2 spec for describing the process this test is following identifyCmd->SetPrpBuffer(prpBitmask, identifyNamespaceList); identifyCmd->SetNSID( 0 ); identifyCmd->SetCNS( CNS_NamespaceListSubsystem ); // Get all NSIDs attached (or not) to controllers identifyCmd->SetCNTID(0); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, identifyCmd, "Reading back (up to) 1024 NSIDs attached to this controller (CNS=2). Command should pass, with 0 NSIDs to be returned", false, CESTAT_SUCCESS); namespaceIdListBuffer32BitPtr = (uint32_t*) identifyCmd->GetROPrpBuffer(); if( namespaceIdListBuffer32BitPtr[0] != 0) { throw FrmwkEx(HERE, "Before creating any namespaces, subsystem was expected to have no NSIDs active and present, but Identify CNS=0x10 returned at least one NSID."); } LOG_NRM("No namespaces are active, test can continue. Pull back the controller list to be used to attach all NSIDs to all controllers on subsystem"); identifyCmd->SetPrpBuffer(prpBitmask, identifyControllerList); identifyCmd->SetNSID( 0 ); identifyCmd->SetCNS( CNS_ControllerListSubsystem ); // Get all controllers in this subsystem identifyCmd->SetCNTID(0); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, identifyCmd, "Reading back what controllers are on this subsystem (CNS=0x13), should find at LEAST one.", false, CESTAT_SUCCESS); controllerIdListBuffer16BitPtr = (uint16_t*) identifyCmd->GetROPrpBuffer(); if( controllerIdListBuffer16BitPtr[0] == 0) { throw FrmwkEx(HERE, "Before creating any namespaces, subsystem was expected to have at least one controller ID present, but found zero."); } SharedNamespaceAttachPtr namespaceAttachCmd = SharedNamespaceAttachPtr(new NamespaceAttach() ); /* //BUGBUG APL is returning an improper list (Ctrlr IDs 1/2 wheras they ID themselves as actually 0/1) for(uint32_t bufferIndex = 0; bufferIndex < 4096; bufferIndex++) { userBuffer[bufferIndex]=0; } userBuffer[0] = 2; // 2 Controllers userBuffer[4] = 1; // 1st (byte 2) is 0 and 2nd (byte 4) is 1 to match APL identifyControllerList->InitAlignment(4096, 4096, false, 0, userBuffer); LOG_NRM("Controller list hardcoded to 0/1 for the time being... BUGBUG"); // END BUG BUG */ // Set attach namespace buffer to be the full controller list, to attach all new NSIDs to to all on this subsystem namespaceAttachCmd->SetPrpBuffer(prpBitmask, identifyControllerList); LOG_NRM("Create Namespace Management to create all namespaces before attaching to all contollers"); SharedNamespaceManagementPtr namespaceManagementCmd = SharedNamespaceManagementPtr(new NamespaceManagement() ); SharedMemBufferPtr managementBuffer = SharedMemBufferPtr(new MemBuffer() ); NamespaceManagementCreateStruct nscreate; nscreate.NSZE = individualNamespaceCapacity; nscreate.NCAP = individualNamespaceCapacity; nscreate.FLBAS = 0; nscreate.DPS = 0; nscreate.NMIC = 1; //NamespaceManagementCreateStruct nscreate( individualNamespaceCapacity, individualNamespaceCapacity, 0, 0, 1 ); // BUGBUG we are going to assume a 512B size and barenamespace as FLBAS=0... otherwise we need to determine what format via namespace structs... //CreateNamespaceManagementStructure( individualNamespaceCapacity, individualNamespaceCapacity, 0, 0, 1, userBuffer); LOG_NRM("Each of the %d namespaces will be of 0x%llx size", identifyControllerMaxNSID, (long long unsigned int) individualNamespaceCapacity); nscreate.print(); managementBuffer->InitAlignment(384, 4096, false, 0x0, (uint8_t*) &nscreate); // Contains namespace struct info for namespace management to consume (384B) namespaceManagementCmd->SetPrpBuffer(prpBitmask, managementBuffer); namespaceAttachCmd->SetSEL( 0 ); namespaceAttachCmd->SetNSID( 0 ); LOG_NRM("Start main loop over valid NSIDs to create/attach them."); for(uint64_t currentNamespaceIdToCreate = 0; currentNamespaceIdToCreate < identifyControllerMaxNSID; currentNamespaceIdToCreate++ ) { // Get the current // Create this namespace using 1/NNth amount of the total available space. namespaceManagementCmd->SetSEL(0); namespaceManagementCmd->SetNSID(0); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, namespaceManagementCmd, "Creating namespace that is 1/NNth size of total NVM capacity, 512B bare LBAs.", false, CESTAT_SUCCESS); newlyCreatedNSID = (acq->PeekCEwithCID( namespaceManagementCmd->GetCID() ) ).t.dw0; LOG_NRM("Newly created NS has NSID of 0x%llu", (long long unsigned) newlyCreatedNSID); // ID this namespace and see if it is all 0s. Namespace should be created but 'inactive'. identifyCmd->SetCNS(CNS_Namespace ); // Standard Namespace ID, should also be attached to this controller identifyCmd->SetNSID( newlyCreatedNSID ); // identifyCmd->SetCNTID(0); identifyCmd->SetPrpBuffer(prpBitmask, identifyNamespaceStruct); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, identifyCmd, "Read Identify Controller struct from created NSID, expecting it to be all 0's since it has not yet attached", false, CESTAT_SUCCESS); // Currently fails on FW for(uint32_t bufferIndex = 0; bufferIndex < 4096; bufferIndex++) { if ( identifyCmd->GetROPrpBuffer()[bufferIndex] != 0) { throw FrmwkEx(HERE, "Expected Identify Namespace to returned all zero buffer as namespace should be inactive and non-attached"); } } // Now attach the drive to all controllers on the subsystem namespaceAttachCmd->SetNSID( newlyCreatedNSID ); namespaceAttachCmd->SetSEL(0); // Should already have the ControllerList associated with the NamespaceAttach command IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, namespaceAttachCmd, "Attaching NSID to all controllers on subsystem", false, CESTAT_SUCCESS); // Reread this NS struct back and make sure the values match what we had requested... IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, identifyCmd, "Read Identify Controller struct from created NSID, expecting non-zero since it is now attached", false, CESTAT_SUCCESS); // First ensure the buffer is not completely non-zero bool identifyNamespaceBufferIsZeroFilled = true; for(uint32_t bufferIndex = 0; bufferIndex < 4096; bufferIndex++) { if ( identifyCmd->GetROPrpBuffer()[bufferIndex] != 0) { identifyNamespaceBufferIsZeroFilled = false; break; } } if( identifyNamespaceBufferIsZeroFilled == true) { throw FrmwkEx(HERE, "Expected Identify Namespace to returned a non-zero buffer as namespace should now be attached"); } // Now check a couple fields (BUGBUG should check all!) IdNamespcStruct *currentNamespaceStruct = (IdNamespcStruct*) identifyCmd->GetROPrpBuffer(); if(currentNamespaceStruct->NSZE != individualNamespaceCapacity) { LOG_NRM("Namespace NSZE 0x%llx != what was passed to namespaceManagement 0x%08llx", (long long unsigned) currentNamespaceStruct->NSZE, (long long unsigned) individualNamespaceCapacity); throw FrmwkEx(HERE, "Newly created namespace's NSZE does not match what was sent to namespaceManagement"); } if(currentNamespaceStruct->NCAP != individualNamespaceCapacity) { LOG_NRM("Namespace NCAP 0x%llx != what was passed to namespaceManagement 0x%08llx", (long long unsigned) currentNamespaceStruct->NCAP, (long long unsigned) individualNamespaceCapacity); throw FrmwkEx(HERE, "Newly created namespace's NCAP does not match what was sent to namespaceManagement"); } // Repull the Identify Controller information and make sure the UNVMCAP values have decreased the amount we just allocatd for this create namespace identifyCmd->SetCNS(CNS_Controller); identifyCmd->SetNSID(0); identifyCmd->SetCNTID(0); identifyCmd->SetPrpBuffer(prpBitmask, identifyControllerStruct); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, identifyCmd, "Pull Identify Controller to check usage sizes have changed.", false, CESTAT_SUCCESS); IdCtrlrCapStruct *currentControllerStruct = (IdCtrlrCapStruct*) identifyCmd->GetROPrpBuffer(); uint64_t expectedNVMCAP = identifyControllerTotalCapacity - (individualNamespaceCapacity * (currentNamespaceIdToCreate+1) * 512); if(currentControllerStruct->UNVMCAP_LOWER != expectedNVMCAP) { LOG_NRM("Expecting UNVMCAP to decrease by last allocated namespace. UNVMCAP = 0x%llx expecting 0x%llx", (long long unsigned) currentControllerStruct->UNVMCAP_LOWER, (long long unsigned) expectedNVMCAP); throw FrmwkEx(HERE, "Identify Controller UNVMCAP is not adjusted after creating a namespace of 1/NNth size"); } // Try to retry the attachment again and ensure a proper fail case IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, namespaceAttachCmd, "Attaching an already attached NSID to all controllers again to check fail case", false, CESTAT_NS_ALREADY_ATTACHED); } // At this point we can double sanity check. // 1) Controller should state 0 bytes available // 2) Should be Cntrl.NN namespaces active and attached to all controllers on the subsystem LOG_NRM("Completed CreateAndAttachMaxNamespacesAndVerify::RunCoreTest"); }
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); } }
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 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); } } }