bool GrpAdminSetGetFeatCombo::RestoreAsyncEvent(SharedASQPtr asq, SharedACQPtr acq) { SharedGetFeaturesPtr getFeaturesCmd = SharedGetFeaturesPtr(new GetFeatures()); SharedSetFeaturesPtr setFeaturesCmd = SharedSetFeaturesPtr(new SetFeatures()); LOG_NRM("Restoring state with mAsyncEvent = 0x%04X", mAsyncEvent); setFeaturesCmd->SetFID(FID[FID_ASYNC_EVENT_CONFIG]); getFeaturesCmd->SetFID(FID[FID_ASYNC_EVENT_CONFIG]); setFeaturesCmd->SetDword(mAsyncEvent, 11); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, setFeaturesCmd, "RestoreWrAtomicity", true); struct nvme_gen_cq acqMetrics = acq->GetQMetrics(); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, getFeaturesCmd, "RestoreAsyncEvent", true); union CE ce = acq->PeekCE(acqMetrics.head_ptr); if (mAsyncEvent != ce.t.dw0) { LOG_ERR("AsyncEvent restore to original state failed. " "(Actual: Expected) = (0x%04X:0x%04X)", ce.t.dw0, mAsyncEvent); return false; } return true; }
bool GrpAdminSetGetFeatCombo::RestoreIRQCoalescing(SharedASQPtr asq, SharedACQPtr acq) { SharedGetFeaturesPtr getFeaturesCmd = SharedGetFeaturesPtr(new GetFeatures()); SharedSetFeaturesPtr setFeaturesCmd = SharedSetFeaturesPtr(new SetFeatures()); LOG_NRM("Restoring state with IRQCoalescing = 0x%04X", mIrqCoalescing); setFeaturesCmd->SetFID(FID[FID_IRQ_COALESCING]); getFeaturesCmd->SetFID(FID[FID_IRQ_COALESCING]); setFeaturesCmd->SetDword(mIrqCoalescing, 11); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, setFeaturesCmd, "RestoreIRQCoalescing", true); struct nvme_gen_cq acqMetrics = acq->GetQMetrics(); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, getFeaturesCmd, "RestoreIRQCoalescing", true); union CE ce = acq->PeekCE(acqMetrics.head_ptr); if (mIrqCoalescing != ce.t.dw0) { LOG_ERR("IRQCoalescing restore to original state failed. " "(Actual: Expected) = (0x%04X:0x%04X)", ce.t.dw0, mIrqCoalescing); return false; } return true; }
bool GrpAdminSetGetFeatCombo::RestoreVolWrCache(SharedASQPtr asq, SharedACQPtr acq) { SharedGetFeaturesPtr getFeaturesCmd = SharedGetFeaturesPtr(new GetFeatures()); SharedSetFeaturesPtr setFeaturesCmd = SharedSetFeaturesPtr(new SetFeatures()); LOG_NRM("Restoring state with VWC = 0x%04X", mVolWrCache); setFeaturesCmd->SetFID(FID[FID_VOL_WR_CACHE]); getFeaturesCmd->SetFID(FID[FID_VOL_WR_CACHE]); setFeaturesCmd->SetDword(mVolWrCache, 11); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, setFeaturesCmd, "RestoreVWC", true); struct nvme_gen_cq acqMetrics = acq->GetQMetrics(); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, getFeaturesCmd, "RestoreVWC", true); union CE ce = acq->PeekCE(acqMetrics.head_ptr); if (mVolWrCache != ce.t.dw0) { LOG_ERR("VWC restore to original state failed. " "(Actual: Expected) = (0x%04X:0x%04X)", ce.t.dw0, mVolWrCache); return false; } return true; }
bool GrpAdminSetGetFeatCombo::RestoreTLER(SharedASQPtr asq, SharedACQPtr acq) { SharedGetFeaturesPtr getFeaturesCmd = SharedGetFeaturesPtr(new GetFeatures()); SharedSetFeaturesPtr setFeaturesCmd = SharedSetFeaturesPtr(new SetFeatures()); LOG_NRM("Restoring state with TLER = 0x%04X", mTimeLimErrRec); setFeaturesCmd->SetFID(FID[FID_ERR_RECOVERY]); getFeaturesCmd->SetFID(FID[FID_ERR_RECOVERY]); setFeaturesCmd->SetDword(mTimeLimErrRec, 11); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, setFeaturesCmd, "RestoreTLER", true); struct nvme_gen_cq acqMetrics = acq->GetQMetrics(); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, getFeaturesCmd, "RestoreTLER", true); union CE ce = acq->PeekCE(acqMetrics.head_ptr); if (mTimeLimErrRec != ce.t.dw0) { LOG_ERR("TLER restore to original state failed. " "(Actual: Expected) = (0x%04X:0x%04X)", ce.t.dw0, mTimeLimErrRec); return false; } return true; }
bool GrpAdminSetGetFeatCombo::RestoreTMPTH(SharedASQPtr asq, SharedACQPtr acq) { SharedGetFeaturesPtr getFeaturesCmd = SharedGetFeaturesPtr(new GetFeatures()); SharedSetFeaturesPtr setFeaturesCmd = SharedSetFeaturesPtr(new SetFeatures()); LOG_NRM("Restoring state with TMPTH = 0x%04X", mTmpThreshold); setFeaturesCmd->SetFID(BaseFeatures::FID_TEMP_THRESHOLD); getFeaturesCmd->SetFID(BaseFeatures::FID_TEMP_THRESHOLD); setFeaturesCmd->SetDword(mTmpThreshold, 11); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, setFeaturesCmd, "RestoreTMPTH", true); struct nvme_gen_cq acqMetrics = acq->GetQMetrics(); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, getFeaturesCmd, "RestoreTMPTH", true); union CE ce = acq->PeekCE(acqMetrics.head_ptr); if (mTmpThreshold != ce.t.dw0) { LOG_ERR("TMPTH restore to original state failed. " "(Actual: Expected) = (0x%04X:0x%04X)", ce.t.dw0, mTmpThreshold); return false; } return true; }
/** * A function to send Set Features admin cmd to a device sending the identifier * 0x07 to set number of queues. This value, according to the spec, shall NOT * change between resets, i.e. only set this value after a power up. Failure to * conform results in undefined behavior. * "<STS:PXDS:AERUCES:CSTS>". * @param numQueues Pass a struct to source the desired values to send to hdw * @return true upon successful parsing, otherwise false. */ bool SetFeaturesNumberOfQueues(NumQueues &numQueues) { try { // The objects to perform this work throw exceptions LOG_NRM("Setting number of Q's; ncqr=0x%04X, nsqr=0x%04X", numQueues.ncqr, numQueues.nsqr); FileSystem::SetBaseDumpDir(false); // Log into GrpPending if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false) throw FrmwkEx(HERE); LOG_NRM("Prepare the admin Q's to setup this request"); SharedACQPtr acq = SharedACQPtr(new ACQ(gDutFd)); acq->Init(2); SharedASQPtr asq = SharedASQPtr(new ASQ(gDutFd)); asq->Init(2); gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET); if (gCtrlrConfig->SetState(ST_ENABLE) == false) throw FrmwkEx(HERE); LOG_NRM("Create the cmd to carry this data to the DUT"); SharedSetFeaturesPtr sfNumOfQ = SharedSetFeaturesPtr(new SetFeatures()); sfNumOfQ->SetFID(BaseFeatures::FID_NUM_QUEUES); sfNumOfQ->SetNumberOfQueues(numQueues.ncqr, numQueues.nsqr); IO::SendAndReapCmd("tnvme", "queues", SYSTEMWIDE_CMD_WAIT_ms, asq, acq, sfNumOfQ, "", true); LOG_NRM("The operation succeeded to set number of queues"); } catch (...) { LOG_ERR("Operation failed to set number of queues"); gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY); return false; } gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY); return true; }
bool GrpAdminSetGetFeatCombo::RestoreSaveIvecConf(SharedASQPtr asq, SharedACQPtr acq) { SharedGetFeaturesPtr getFeaturesCmd = SharedGetFeaturesPtr(new GetFeatures()); SharedSetFeaturesPtr setFeaturesCmd = SharedSetFeaturesPtr(new SetFeatures()); uint16_t max_ivec = IRQ::GetMaxIRQsSupportedAnyScheme(); for (uint16_t ivec = 0; ivec < max_ivec; ivec++) { LOG_NRM("Restoring state for ivec = 0x%02X with IvecConf = 0x%04X", ivec, mIvecConf[ivec]); setFeaturesCmd->SetFID(FID[FID_IRQ_VEC_CONFIG]); getFeaturesCmd->SetFID(FID[FID_IRQ_VEC_CONFIG]); setFeaturesCmd->SetDword(mIvecConf[ivec], 11); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, setFeaturesCmd, "RestoreIvecConf", true); getFeaturesCmd->SetIntVecConfigIV(ivec); struct nvme_gen_cq acqMetrics = acq->GetQMetrics(); IO::SendAndReapCmd(mGrpName, mGrpName, CALC_TIMEOUT_ms(1), asq, acq, getFeaturesCmd, "RestoreIvecConf", true); union CE ce = acq->PeekCE(acqMetrics.head_ptr); if (mIvecConf[ivec] != ce.t.dw0) { LOG_ERR("mIvecConf restore to original state failed. " "(Actual: Expected) = (0x%04X:0x%04X)", ce.t.dw0, mIvecConf[ivec]); return false; } } return true; }
void FIDPwrMgmt_r10b::RunCoreTest() { /** \verbatim * Assumptions: * None. * \endverbatim */ string work; union CE ce; struct nvme_gen_cq acqMetrics; if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false) throw FrmwkEx(HERE); LOG_NRM("Create admin queues ACQ and ASQ for test lifetime"); 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); gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET); if (gCtrlrConfig->SetState(ST_ENABLE) == false) throw FrmwkEx(HERE); LOG_NRM("Create Get features and set features cmds"); SharedGetFeaturesPtr getFeaturesCmd = SharedGetFeaturesPtr(new GetFeatures()); SharedSetFeaturesPtr setFeaturesCmd = SharedSetFeaturesPtr(new SetFeatures()); LOG_NRM("Set and Get features PSD (FID = 0x%x)", BaseFeatures::FID_PWR_MGMT); getFeaturesCmd->SetFID(BaseFeatures::FID_PWR_MGMT); setFeaturesCmd->SetFID(BaseFeatures::FID_PWR_MGMT); uint8_t npss = gInformative->GetIdentifyCmdCtrlr()-> GetValue(IDCTRLRCAP_NPSS); // 0-based LOG_NRM("Number of power states supported by the ctrlr (NPSS) = %d", npss); uint8_t psMismatch = 0; for (uint16_t ps = 0; ps <= npss; ps++) { LOG_NRM("Set and Get features for PS # %d", ps); setFeaturesCmd->SetPowerManagementPS(ps); LOG_NRM("Issue set features cmd with PS = %d", ps); work = str(boost::format("ps.%d") % ps); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, setFeaturesCmd, work, true); acqMetrics = acq->GetQMetrics(); LOG_NRM("Issue get features cmd and check for ps = %d", ps); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getFeaturesCmd, work, false); ce = acq->PeekCE(acqMetrics.head_ptr); LOG_NRM("Power state descriptor using Get Features = %d", ce.t.dw0); if (ps != ce.t.dw0) { LOG_ERR("PSD get feat does not match set feat" "(expected, rcvd) = (%d, %d)", ps, ce.t.dw0); psMismatch = 0xFF; } } if (psMismatch) throw FrmwkEx(HERE, "Power state mismatched."); }
void FIDVolatileCash_r10b::RunCoreTest() { /** \verbatim * Assumptions: * None. * \endverbatim */ string work; union CE ce; struct nvme_gen_cq acqMetrics; if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false) throw FrmwkEx(HERE); LOG_NRM("Create admin queues ACQ and ASQ for test lifetime"); 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); gCtrlrConfig->SetCSS(CtrlrConfig::CSS_NVM_CMDSET); if (gCtrlrConfig->SetState(ST_ENABLE) == false) throw FrmwkEx(HERE); LOG_NRM("Create Get features and set features cmds"); SharedGetFeaturesPtr getFeaturesCmd = SharedGetFeaturesPtr(new GetFeatures()); SharedSetFeaturesPtr setFeaturesCmd = SharedSetFeaturesPtr(new SetFeatures()); LOG_NRM("Set and Get features for volatile write cache (FID = 0x%x)", BaseFeatures::FID_VOL_WR_CACHE); getFeaturesCmd->SetFID(BaseFeatures::FID_VOL_WR_CACHE); setFeaturesCmd->SetFID(BaseFeatures::FID_VOL_WR_CACHE); uint8_t wce = 0x0; // Disable volatile write cache LOG_NRM("Disable volatile wr cache # %d ", wce); setFeaturesCmd->SetVolatileWriteCacheWCE(wce); LOG_NRM("Issue set features cmd with WCE = %d", wce); work = str(boost::format("wce.%d") % wce); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, setFeaturesCmd, work, true); acqMetrics = acq->GetQMetrics(); LOG_NRM("Issue get features cmd & check wce = %d", wce); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getFeaturesCmd, work, false); ce = acq->PeekCE(acqMetrics.head_ptr); LOG_NRM("Get Features volatile wr cache = %d", ce.t.dw0); if (wce != ce.t.dw0) { throw FrmwkEx(HERE, "WCE get feat does not match set feat" "(expected, rcvd) = (%d, %d)", wce, ce.t.dw0); } wce = 0x1; // Enable volatile write cache LOG_NRM("Enable volatile wr cache # %d ", wce); setFeaturesCmd->SetVolatileWriteCacheWCE(wce); LOG_NRM("Issue set features cmd with WCE = %d", wce); work = str(boost::format("wce.%d") % wce); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, setFeaturesCmd, work, true); acqMetrics = acq->GetQMetrics(); LOG_NRM("Issue get features cmd & check wce = %d", wce); IO::SendAndReapCmd(mGrpName, mTestName, CALC_TIMEOUT_ms(1), asq, acq, getFeaturesCmd, work, false); ce = acq->PeekCE(acqMetrics.head_ptr); LOG_NRM("Get Features volatile wr cache = %d", ce.t.dw0); if (wce != ce.t.dw0) { throw FrmwkEx(HERE, "WCE get feat does not match set feat" "(expected, rcvd) = (%d, %d)", wce, ce.t.dw0); } }
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"); }
bool SetFeaturesNumberOfQueues(Queues &queues, int fd) { uint16_t numCE; uint16_t ceRemain; uint16_t numReaped; try { // The objects to perform this work throw exceptions LOG_NRM("Setting number of Q's; ncqr=0x%04X, nsqr=0x%04X", queues.ncqr, queues.nsqr); if (gCtrlrConfig->SetState(ST_DISABLE_COMPLETELY) == false) throw exception(); LOG_NRM("Prepare the admin Q's to setup this request"); SharedACQPtr acq = SharedACQPtr(new ACQ(fd)); acq->Init(2); SharedASQPtr asq = SharedASQPtr(new ASQ(fd)); asq->Init(2); if (gCtrlrConfig->SetState(ST_ENABLE) == false) throw exception(); LOG_NRM("Create the cmd to carry this data to the DUT"); SharedSetFeaturesPtr sfNumOfQ = SharedSetFeaturesPtr(new SetFeatures(fd)); sfNumOfQ->SetFID(BaseFeatures::FID_NUM_QUEUES); sfNumOfQ->SetNumberOfQueues(queues.ncqr, queues.nsqr); LOG_NRM("Send the cmd to the ASQ, wait for it to complete"); asq->Send(sfNumOfQ); asq->Ring(); if (acq->ReapInquiryWaitSpecify(2000, 1, numCE) == false) { LOG_ERR("Unable to see completion of Set Features cmd"); throw exception(); } else if (numCE != 1) { LOG_ERR("The ACQ should only have 1 CE as a result of a cmd"); throw exception(); } LOG_NRM("The CQ's metrics before reaping holds head_ptr needed"); struct nvme_gen_cq acqMetrics = acq->GetQMetrics(); KernelAPI::LogCQMetrics(acqMetrics); LOG_NRM("Reaping CE from ACQ, requires memory to hold reaped CE"); SharedMemBufferPtr ceMemIOCQ = SharedMemBufferPtr(new MemBuffer()); if ((numReaped = acq->Reap(ceRemain, ceMemIOCQ, numCE, true)) != 1) { LOG_ERR("Verified there was 1 CE, but reaping produced %d", numReaped); throw exception(); } LOG_NRM("The reaped get features CE is..."); acq->LogCE(acqMetrics.head_ptr); union CE ce = acq->PeekCE(acqMetrics.head_ptr); if (ce.n.status != 0) { LOG_ERR("CE shows cmd failed: status = 0x%02X", ce.n.status); throw exception(); } printf("The operation succeeded to set number of queues\n"); } catch (...) { printf("Operation failed to set number of queues\n"); return false; } return true; }