#include "NVMeMi.hpp"

#include "NVMeError.hpp"
#include "NVMeUtil.hpp"

#include <endian.h>

#include <boost/endian.hpp>
#include <phosphor-logging/lg2.hpp>

#include <cassert>
#include <cerrno>
#include <deque>
#include <fstream>
#include <stdexcept>

namespace common_err = sdbusplus::xyz::openbmc_project::Common::Error;

// NVMe Admin Opcode for Lockdown (Opcode 0x24 in NVMe Base Spec 2.0a)
constexpr uint8_t nvmeAdminOpcLockdown = 0x24;
// Opcode for Vendor Unique Lockdown
constexpr uint8_t nvmeAdminOpcSamsungVULockdown = 0xCC;

// NVMe Lockdown Scope values (CDW10, bits [3:0] and LSP bits [3:0])
constexpr uint8_t lockdownScopeAdminCmd = 0x0;
constexpr uint8_t lockdownScopeFeatureId = 0x2;
constexpr uint8_t lockdownScopeLogPage = 0x5;

// NVMe Lockdown Log Page LSP List State (LSP bit 4)
constexpr uint8_t lockdownLspListActive = 0x0 << 4;
constexpr uint8_t lockdownLspListSupported = 0x1 << 4;

// NVMe Lockdown Log LSPs to sequentially fetch
constexpr std::array<uint8_t, 6> lockdownLogPageLsps = {
    static_cast<uint8_t>(lockdownScopeAdminCmd | lockdownLspListActive),
    static_cast<uint8_t>(lockdownScopeFeatureId | lockdownLspListActive),
    static_cast<uint8_t>(lockdownScopeLogPage | lockdownLspListActive),
    static_cast<uint8_t>(lockdownScopeAdminCmd | lockdownLspListSupported),
    static_cast<uint8_t>(lockdownScopeFeatureId | lockdownLspListSupported),
    static_cast<uint8_t>(lockdownScopeLogPage | lockdownLspListSupported)};

// CDW10 Bit Masks and Shifts
constexpr uint8_t lockdownPrhbtMask = 0x1;
constexpr uint8_t lockdownPrhbtShift = 4;

constexpr uint8_t lockdownIfcMask = 0x3;
constexpr uint8_t lockdownIfcShift = 5;

constexpr uint8_t lockdownScopeMask = 0xF;
constexpr uint8_t lockdownScopeShift = 0;

constexpr uint8_t lockdownOfiShift = 8;

// Default Interface Field (IFC) value: 00b = Admin Submission Queue (ASQ) only
constexpr uint8_t lockdownIfcAsq = 0x00;

static inline std::string scopeToString(uint8_t scope)
{
    switch (scope)
    {
        case 0x0:
            return "AdminCmd";
        case 0x2:
            return "FeatureCmd";
        case 0x5:
            return "LogPageCmd";
        default:
            return "Unknown";
    }
}
// libnvme-mi root service
nvme_root_t NVMeMi::nvmeRoot = nvme_mi_create_root(stderr, DEFAULT_LOGLEVEL);

constexpr size_t maxNVMeMILength = 4096;
constexpr int tcgDefaultTimeoutMS = 20 * 1000;
constexpr int namespaceDefaultTimeoutMS = 20 * 1000;
constexpr int sanitizeDefaultTimeoutMS = 20 * 1000;
constexpr int downloadDefaultTimeoutMS = 10 * 1000;
constexpr int initCmdTimeoutMS = 1000;

NVMeMi::NVMeMi(boost::asio::io_context& io,
               const std::shared_ptr<sdbusplus::asio::connection>& conn,
               const std::shared_ptr<const MctpDevice>& device,
               const std::shared_ptr<NVMeMiWorker>& worker,
               PowerState readState) :
    io(io), device(device), readState(readState), mctpStatus(Status::Reset),
    mtu(64), nvmeEP(nullptr), restart(false), worker(worker)
{
    // set update the worker thread
    if (nvmeRoot == nullptr)
    {
        throw std::runtime_error("invalid NVMe root");
    }

    // setup the power state
    if (readState == PowerState::on || readState == PowerState::biosPost ||
        readState == PowerState::chassisOn)
    {
        // life time of the callback is binding to the NVMeMi instance, so only
        // this capture is required.
        powerCallback = setupPowerMatchCallback(conn, [this](PowerState, bool) {
            if (!::readingStateGood(this->readState))
            {
                recover();
            }
        });
    }
}

void NVMeMi::epReset()
{
    switch (mctpStatus)
    {
        case Status::Reset:
            return;
        case Status::Initiated:
            if (optimizeTimer)
            {
                lg2::info("Cancel the optimization Timer for the endpoint",
                          "ENDPOINT", endpoint->describe());
                optimizeTimer->cancel();
            }
            [[fallthrough]];
        case Status::Connected:
            if (nvmeEP == nullptr)
            {
                throw std::logic_error(
                    "nvmeEP was unpopulated in Status::Initiated state");
            }
            mctpStatus = Status::Terminating;
            lg2::info("start MCTP closure", "ENDPOINT", endpoint->describe());
            // Immediately reset endpoint so that we can capture the parameter
            // from a subsequent invocation of start() while in
            // Status::Terminating
            endpoint.reset();
            // Invoke nvme_mi_close() via a lambda that we schedule via
            // flushOperations(). Using flushOperations() ensures that any
            // outstanding tasks are executed before nvme_mi_close() is invoked,
            // invalidating their controller reference.
            flushOperations([self{shared_from_this()}]() {
                nvme_mi_close(self->nvmeEP);
                self->mtu = 64;
                self->nvmeEP = nullptr;
                self->mctpStatus = Status::Reset;
                lg2::info("end MCTP closure", "DEVICE",
                          self->device->describe());
                if (self->restart)
                {
                    // If restart is true then we've captured the updated
                    // endpoint. We pass it to start() to recreate the
                    // connection.
                    self->restart = false;
                    self->start(self->endpoint);
                }
            });
            return;
        case Status::Terminating:
            return;
    }
    throw std::logic_error("Unreachable");
}

bool NVMeMi::epConnect(int lnid, uint8_t leid)
{
    switch (mctpStatus)
    {
        case Status::Reset:
            if (nvmeEP != nullptr)
            {
                throw std::logic_error(
                    "nvmeEP populated in Status::Reset state");
            }
            nvmeEP = nvme_mi_open_mctp(nvmeRoot, lnid, leid);
            if (nvmeEP != nullptr)
            {
                mctpStatus = Status::Initiated;
                return true;
            }
            return false;
        case Status::Initiated:
        case Status::Connected:
            return true;
        case Status::Terminating:
            // This isn't an error so much as we're just not ready yet
            return false;
    }
    throw std::logic_error("Unreachable");
}

void NVMeMi::epOptimize()
{
    switch (mctpStatus)
    {
        case Status::Reset:
            throw std::logic_error("optimize called from Status::Reset");
        case Status::Initiated:
            /* Continue with optimization below */
            break;
        case Status::Connected:
            /* Already optimized */
            return;
        case Status::Terminating:
            throw std::logic_error("optimize called from Status::Terminating");
    }

    // If the device is behind a bridge (so not directly I2C accessible), we
    // skip MTU and SMBus frequency configuration.
    if (!endpoint->isI2cAccessible())
    {
        mctpStatus = Status::Connected;
        return;
    }

    optimizeTimer = std::make_shared<boost::asio::steady_timer>(
        io, std::chrono::milliseconds(500));
    optimizeTimer->async_wait([this](boost::system::error_code ec) {
        if (ec)
        {
            lg2::error("Endpoint optimize timer error: {ERROR}", "ERROR",
                       ec.what());
            return;
        }
        miSetMCTPConfiguration(
            [self{shared_from_this()}](const std::error_code& ec) {
            self->optimizeTimer = nullptr;
            if (ec)
            {
                lg2::error("Failed setting up MTU for the MCTP endpoint.",
                           "DEVICE", self->device->describe());
                self->recover();
                return;
            }
            self->configureLocalRouteMtu([self](const std::error_code& ec) {
                if (ec)
                {
                    self->recover();
                    return;
                }
                self->mctpStatus = Status::Connected;
            });
        });
    });
}

void NVMeMi::recover()
{
    switch (mctpStatus)
    {
        case Status::Reset:
            return;
        case Status::Initiated:
        case Status::Connected:
            endpoint->recover();
            return;
        case Status::Terminating:
            return;
    }
    throw std::logic_error("Unreachable");
}

void NVMeMi::start(const std::shared_ptr<MctpEndpoint>& ep)
{
    if (mctpStatus == Status::Terminating)
    {
        endpoint = ep;
        this->restart = true;
        return;
    }

    if (mctpStatus == Status::Reset)
    {
        endpoint = ep;
        // open mctp endpoint
        if (!epConnect(endpoint->network(), endpoint->eid()))
        {
            epReset();
            lg2::error("can't open MCTP endpoint", "ENDPOINT", ep->describe());
            return;
        }
    }

    if (mctpStatus == Status::Initiated)
    {
        epOptimize();
    }
}

void NVMeMi::stop()
{
    restart = false;
    epReset();
}

std::optional<std::error_code> NVMeMi::isEndpointDegraded() const
{
    switch (mctpStatus)
    {
        case Status::Reset:
            return std::make_error_code(std::errc::no_such_device);
        case Status::Initiated:
            return std::make_error_code(std::errc::not_connected);
        case Status::Connected:
            return std::nullopt;
        case Status::Terminating:
            return std::make_error_code(std::errc::not_connected);
    }
    throw std::logic_error("Unreachable");
}

NVMeMiWorker::NVMeMiWorker()
{ // start worker thread
    thread = std::thread([&io = workerIO, &stop = workerStop, &mtx = workerMtx,
                          &cv = workerCv, &isNotified = workerIsNotified]() {
        // With BOOST_ASIO_DISABLE_THREADS, boost::asio::executor_work_guard
        // issues null_event across the thread, which caused invalid invokation.
        // We implement a simple invoke machenism based std::condition_variable.
        while (true)
        {
            io.run();
            io.restart();
            {
                std::unique_lock<std::mutex> lock(mtx);
                cv.wait(lock, [&]() { return isNotified; });
                isNotified = false;

                if (stop)
                {
                    // exhaust all tasks and exit
                    io.run();
                    break;
                }
            }
        }
    });
}

NVMeMiWorker::~NVMeMiWorker()
{
    // close worker
    workerStop = true;
    {
        std::unique_lock<std::mutex> lock(workerMtx);
        workerIsNotified = true;
        workerCv.notify_all();
    }
    thread.join();
}

NVMeMi::~NVMeMi()
{
    // If we're being destructed the only thing left to do is to clean up the
    // endpoint connection. We're in the destructor because the last shared
    // reference has been dropped, which means it must be the case that no
    // worker jobs remain queued that reference the instance.
    //
    // We can't call epReset() here via stop() as was originally the case.
    // epReset() prepares the NVMeMi instance for a subsequent epConnect() using
    // shared_from_this(), which will yield a std::bad_weak_ptr now that we're
    // in the destructor. Moreover, a subsequent epConnect() is not possible
    // beyond this point.
    if (nvmeEP != nullptr)
    {
        nvme_mi_close(nvmeEP);
    }
}

void NVMeMiWorker::post(std::function<void(void)>&& func)
{
    if (!workerStop)
    {
        std::unique_lock<std::mutex> lock(workerMtx);
        if (!workerStop)
        {
            workerIsNotified = true;
            boost::asio::post(workerIO, std::move(func));
            workerCv.notify_all();
            return;
        }
    }
    throw std::runtime_error("NVMeMi has been stopped");
}

void NVMeMi::post(std::function<void(void)>&& func)
{
    worker->post([func{std::move(func)}]() { func(); });
}

// Calls .post(), catching runtime_error and returning an error code on failure.
std::error_code NVMeMi::tryPost(std::function<void(void)>&& func)
{
    try
    {
        post([self{shared_from_this()}, func{std::move(func)}]() { func(); });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "DEVICE", device->describe(), "ERROR", e.what());
        return std::make_error_code(std::errc::no_such_device);
    }
    return {};
}

void NVMeMi::miConfigureSMBusFrequency(
    uint8_t portId, uint8_t /*maxSupportedFreq*/,
    std::function<void(const std::error_code&)>&& cb)
{
    if (mctpStatus == Status::Reset || mctpStatus == Status::Terminating)
    {
        lg2::error("nvme endpoint is invalid", "DEVICE", device->describe());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device));
        });
        return;
    }
    try
    {
        post([portId, ep{endpoint}, self{shared_from_this()},
              cb{std::move(cb)}]() mutable {
            enum nvme_mi_config_smbus_freq smbusFreq = {};
            auto rc = nvme_mi_mi_config_get_smbus_freq(self->nvmeEP, portId,
                                                       &smbusFreq);
            if (rc != 0)
            {
                lg2::error("failed to get the SMBus frequency", "ENDPOINT",
                           ep->describe());
            }
            else if (smbusFreq == NVME_MI_CONFIG_SMBUS_FREQ_100kHz)
            {
                lg2::info("Setting the SMBus frequency to 400kHz", "ENDPOINT",
                          ep->describe());
                rc = nvme_mi_mi_config_set_smbus_freq(
                    self->nvmeEP, portId, NVME_MI_CONFIG_SMBUS_FREQ_400kHz);
                if (rc != 0)
                {
                    lg2::error("failed to set the SMBus frequency", "ENDPOINT",
                               ep->describe());
                }
            }
            if (rc != 0)
            {
                boost::asio::post(self->io, [cb{std::move(cb)}]() {
                    cb(std::make_error_code(std::errc::bad_message));
                });
                return;
            }
            boost::asio::post(self->io, [cb{std::move(cb)}]() { cb({}); });
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "DEVICE", device->describe(), "ERROR", e.what());
        return;
    }
}

void NVMeMi::miConfigureRemoteMCTP(
    uint8_t port, uint16_t mtu, uint8_t maxSupportedFreq,
    std::function<void(const std::error_code&)>&& cb)
{
    if (mctpStatus == Status::Reset || mctpStatus == Status::Terminating)
    {
        lg2::error("nvme endpoint is invalid", "DEVICE", device->describe());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device));
        });
        return;
    }
    try
    {
        post([port, mtu, maxSupportedFreq, self{shared_from_this()},
              cb{std::move(cb)}]() mutable {
            unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
            nvme_mi_ep_set_timeout(self->nvmeEP, initCmdTimeoutMS);
            auto rc = nvme_mi_mi_config_set_mctp_mtu(self->nvmeEP, port, mtu);
            nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

            if (rc != 0)
            {
                lg2::error("failed to set remote MCTP MTU for port: {PORT}",
                           "DEVICE", self->device->describe(), "PORT", port);
                boost::asio::post(self->io, [cb{std::move(cb)}]() {
                    cb(std::make_error_code(std::errc::bad_message));
                });
                return;
            }
            self->mtu = mtu;
            if (maxSupportedFreq >= 2)
            {
                boost::asio::post(self->io, [self, port, maxSupportedFreq,
                                             cb{std::move(cb)}]() mutable {
                    self->miConfigureSMBusFrequency(port, maxSupportedFreq,
                                                    std::move(cb));
                });
                return;
            }
            boost::asio::post(self->io, [cb{std::move(cb)}]() { cb({}); });
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "DEVICE", device->describe(), "ERROR", e.what());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device));
        });
        return;
    }
}

void NVMeMi::miSetMCTPConfiguration(
    std::function<void(const std::error_code&)>&& cb)
{
    if (mctpStatus == Status::Reset || mctpStatus == Status::Terminating)
    {
        lg2::error("nvme endpoint is invalid", "DEVICE", device->describe());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device));
        });
        return;
    }
    try
    {
        post([cb{std::move(cb)}, self{shared_from_this()}]() mutable {
            unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
            nvme_mi_ep_set_timeout(self->nvmeEP, initCmdTimeoutMS);
            struct nvme_mi_read_nvm_ss_info ssInfo = {};
            auto rc = nvme_mi_mi_read_mi_data_subsys(self->nvmeEP, &ssInfo);
            nvme_mi_ep_set_timeout(self->nvmeEP, timeout);
            if (rc != 0)
            {
                lg2::error("Failed reading subsystem info failing", "DEVICE",
                           self->device->describe());
                boost::asio::post(self->io, [cb{std::move(cb)}]() {
                    cb(std::make_error_code(std::errc::bad_message));
                });
                return;
            }

            for (uint8_t portId = 0; portId <= ssInfo.nump; portId++)
            {
                struct nvme_mi_read_port_info portInfo = {};
                auto rc = nvme_mi_mi_read_mi_data_port(self->nvmeEP, portId,
                                                       &portInfo);
                if (rc != 0)
                {
                    /* PCIe port might not be ready right after AC/DC cycle. */
                    lg2::error("failed reading port info for port_id: {PORT}",
                               "DEVICE", self->device->describe(), "PORT",
                               portId);
                }
                else if (portInfo.portt == 0x2) // SMBus ports = 0x2
                {
                    uint16_t supportedMtu = portInfo.mmctptus;
                    uint8_t supportedFreq = portInfo.smb.mme_freq; // NOLINT
                    boost::asio::post(self->io, [self, portId, supportedMtu,
                                                 supportedFreq,
                                                 cb{std::move(cb)}]() mutable {
                        self->miConfigureRemoteMCTP(
                            portId, supportedMtu, supportedFreq, std::move(cb));
                    });
                    return;
                }
            }
            // Didn't find the SMbus port
            boost::asio::post(self->io, [cb{std::move(cb)}]() {
                cb(std::make_error_code(std::errc::no_such_device));
            });
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "DEVICE", device->describe(), "ERROR", e.what());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device));
        });
        return;
    }
}

void NVMeMi::configureLocalRouteMtu(
    std::function<void(const std::error_code& ec)>&& completed, int retries)
{
    const uint32_t mctpMtu = mtu + 4;
    std::function<void(const std::error_code& ec)> retry =
        [this, cb{std::move(completed)},
         retries](const std::error_code& ec) mutable {
        if (!endpoint)
        {
            lg2::error("failed to set MCTP path MTU: Status::Terminating",
                       "DEVICE", device->describe());
            cb(ec);
            return;
        }

        if (!ec)
        {
            lg2::info("Finished MCTP initialization. MTU: {MTU}", "ENDPOINT",
                      endpoint->describe(), "MTU", mtu);
            cb(ec);
            return;
        }

        retries--;
        if (retries == 0)
        {
            lg2::error("failed to set MCTP path MTU: {ERROR}", "ENDPOINT",
                       endpoint->describe(), "ERROR", ec.message());
            cb(ec);
            return;
        }

        lg2::warning("retry to set MCTP path MTU", "ENDPOINT",
                     endpoint->describe());
        configureLocalRouteMtu(std::move(cb), retries);
    };
    endpoint->setMtu(mctpMtu, std::move(retry));
}

void NVMeMi::miSubsystemHealthStatusPoll(
    std::function<void(const std::error_code&, nvme_mi_nvm_ss_health_status*)>&&
        cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        lg2::error("MCTP connection is not established", "DEVICE",
                   device->describe());

        boost::asio::post(io, [cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(errc, nullptr);
        });
        return;
    }

    try
    {
        post([self{shared_from_this()}, ep{endpoint}, cb{std::move(cb)}]() {
            nvme_mi_nvm_ss_health_status ssHealth = {};
            auto rc = nvme_mi_mi_subsystem_health_status_poll(self->nvmeEP,
                                                              true, &ssHealth);
            if (rc < 0)
            {
                lg2::error("fail to subsystem_health_status_poll: {ERROR}",
                           "ENDPOINT", ep->describe(), "ERROR",
                           strerror(errno));
                boost::asio::post(self->io,
                                  [cb{cb}, lastErrno{errno}]() mutable {
                    cb(std::make_error_code(static_cast<std::errc>(lastErrno)),
                       nullptr);
                });
                return;
            }
            if (rc > 0)
            {
                std::string_view errMsg =
                    statusToString(static_cast<nvme_mi_resp_status>(rc));
                lg2::error("fail to subsystem_health_status_poll: {ERROR}",
                           "ENDPOINT", ep->describe(), "ERROR", errMsg.data());
                boost::asio::post(self->io, [cb{cb}]() mutable {
                    cb(std::make_error_code(std::errc::bad_message), nullptr);
                });
                return;
            }

            boost::asio::post(self->io, [cb{cb}, ssHealth{ssHealth}]() mutable {
                cb({}, &ssHealth);
            });
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "DEVICE", device->describe(), "ERROR", e.what());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device), {});
        });
        return;
    }
}

void NVMeMi::miScanCtrl(std::function<void(const std::error_code&,
                                           const std::vector<nvme_mi_ctrl_t>&)>
                            cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        lg2::error("MCTP connection is not established", "DEVICE",
                   device->describe());

        boost::asio::post(io, [cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(errc, {});
        });
        return;
    }

    try
    {
        post([self{shared_from_this()}, ep{endpoint}, cb{std::move(cb)}]() {
            int rc = nvme_mi_scan_ep(self->nvmeEP, true);
            if (rc < 0)
            {
                lg2::error("fail to scan controllers: {ERROR}", "ENDPOINT",
                           ep->describe(), "ERROR", strerror(errno));
                boost::asio::post(self->io,
                                  [cb{cb}, lastErrno{errno}]() mutable {
                    cb(std::make_error_code(static_cast<std::errc>(lastErrno)),
                       {});
                });
                return;
            }
            if (rc > 0)
            {
                std::string_view errMsg =
                    statusToString(static_cast<nvme_mi_resp_status>(rc));
                lg2::error("fail to scan controllers: {ERROR}", "ENDPOINT",
                           ep->describe(), "ERROR", errMsg.data());
                boost::asio::post(self->io, [cb{cb}]() mutable {
                    cb(std::make_error_code(std::errc::bad_message), {});
                });
                return;
            }

            std::vector<nvme_mi_ctrl_t> list;
            nvme_mi_ctrl_t c = {};
            nvme_mi_for_each_ctrl(self->nvmeEP, c)
            {
                list.push_back(c);
            }
            boost::asio::post(
                self->io,
                [cb{cb}, list{std::move(list)}]() mutable { cb({}, list); });
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "ENDPOINT", endpoint->describe(), "ERROR",
                   e.what());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device), {});
        });
        return;
    }
}

bool NVMeMi::flushOperations(std::function<void()>&& cb)
{
    try
    {
        post([self{shared_from_this()}, cb{std::move(cb)}]() {
            boost::asio::post(self->io, cb);
        });

        return true;
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("Runtime error: {ERROR}", "ERROR", e.what());
        return false;
    }
}

void NVMeMi::adminIdentify(
    nvme_mi_ctrl_t ctrl, nvme_identify_cns cns, uint32_t nsid, uint16_t cntid,
    std::function<void(nvme_ex_ptr, std::span<uint8_t>)>&& cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        lg2::error("MCTP connection is not established", "DEVICE",
                   device->describe());
        boost::asio::post(io, [cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(makeLibNVMeError("nvme endpoint is degraded"), {});
        });
        return;
    }
    try
    {
        post([ctrl, cns, nsid, cntid, self{shared_from_this()}, ep{endpoint},
              cb{std::move(cb)}]() {
            int rc = 0;
            std::vector<uint8_t> data;
            switch (cns)
            {
                case NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST:
                {
                    data.resize(sizeof(nvme_secondary_ctrl_list));
                    nvme_identify_args args{};
                    memset(&args, 0, sizeof(args));
                    args.result = nullptr;
                    args.data = data.data();
                    args.args_size = sizeof(args);
                    args.cns = cns;
                    args.csi = NVME_CSI_NVM;
                    args.nsid = nsid;
                    args.cntid = cntid;
                    args.cns_specific_id = NVME_CNSSPECID_NONE;
                    args.uuidx = NVME_UUID_NONE,

                    rc = nvme_mi_admin_identify_partial(ctrl, &args, 0,
                                                        data.size());

                    break;
                }

                default:
                {
                    data.resize(NVME_IDENTIFY_DATA_SIZE);
                    nvme_identify_args args{};
                    memset(&args, 0, sizeof(args));
                    args.result = nullptr;
                    args.data = data.data();
                    args.args_size = sizeof(args);
                    args.cns = cns;
                    args.csi = NVME_CSI_NVM;
                    args.nsid = nsid;
                    args.cntid = cntid;
                    args.cns_specific_id = NVME_CNSSPECID_NONE;
                    args.uuidx = NVME_UUID_NONE,

                    rc = nvme_mi_admin_identify(ctrl, &args);
                }
            }

            if (rc < 0)
            {
                lg2::error("fail to do nvme identify: {ERROR}", "ENDPOINT",
                           ep->describe(), "ERROR", strerror(errno));
            }
            else if (rc > 0)
            {
                std::string_view errMsg =
                    statusToString(static_cast<nvme_mi_resp_status>(rc));
                lg2::error("fail to do nvme identify: {ERROR}", "ENDPOINT",
                           ep->describe(), "ERROR", errMsg.data());
            }

            auto ex = makeLibNVMeError(errno, rc, "adminIdentify");
            if (ex)
            {
                lg2::error("fail to do nvme identify: {ERROR}", "ERROR",
                           ex->description());
            }

            boost::asio::post(self->io,
                              [cb{cb}, ex, data{std::move(data)}]() mutable {
                std::span<uint8_t> span{data.data(), data.size()};
                cb(ex, span);
            });
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "ENDPOINT", endpoint->describe(), "ERROR",
                   e.what());
        auto msg = std::string("Runtime error: ") + e.what();
        lg2::error("{MSG}", "MSG", msg);
        boost::asio::post(
            io, [cb{std::move(cb)}, msg]() { cb(makeLibNVMeError(msg), {}); });
        return;
    }
}

void NVMeMi::adminGetFeatures(
    nvme_mi_ctrl_t ctrl, const GetFeaturesRequest& req,
    std::function<void(nvme_ex_ptr, uint32_t, std::span<uint8_t>)>&& cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        lg2::error("MCTP connection is not established", "DEVICE",
                   device->describe());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(makeLibNVMeError("nvme endpoint is degraded"), 0, {});
        });
        return;
    }
    try
    {
        post([ctrl, fid{req.fid}, sel{req.sel}, cdw11{req.cdw11},
              nsid{req.nsid}, dataLen{req.data_len}, self{shared_from_this()},
              ep{endpoint}, cb{std::move(cb)}]() mutable {
            nvme_get_features_args getArgs{};
            getArgs.args_size = sizeof(getArgs);
            getArgs.fid = fid;
            getArgs.sel = static_cast<nvme_get_features_sel>(sel);
            getArgs.cdw11 = cdw11;
            getArgs.nsid = nsid;

            std::vector<uint8_t> data;
            if (dataLen > 0)
            {
                data.resize(dataLen);
                getArgs.data = data.data();
                getArgs.data_len = dataLen;
            }

            uint32_t response = 0;
            getArgs.result = &response;

            int rc = nvme_mi_admin_get_features(ctrl, &getArgs);

            if (rc < 0)
            {
                lg2::error("fail to do nvme get features: {ERROR}", "ENDPOINT",
                           ep->describe(), "ERROR", strerror(errno));
            }
            else if (rc > 0)
            {
                std::string_view errMsg =
                    statusToString(static_cast<nvme_mi_resp_status>(rc));
                lg2::error("fail to do nvme get features: {ERROR}", "ENDPOINT",
                           ep->describe(), "ERROR", errMsg.data());
            }

            auto ex = makeLibNVMeError(errno, rc, "adminGetFeatures");

            boost::asio::post(self->io, [cb{cb}, ex, response,
                                         data{std::move(data)}]() mutable {
                std::span<uint8_t> span{data.data(), data.size()};
                cb(ex, response, span);
            });
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "ENDPOINT", endpoint->describe(), "ERROR",
                   e.what());
        auto msg = std::string("Runtime error: ") + e.what();
        boost::asio::post(io, [cb{std::move(cb)}, msg]() {
            cb(makeLibNVMeError(msg), 0, {});
        });
        return;
    }
}

void NVMeMi::adminSetFeatures(nvme_mi_ctrl_t ctrl,
                              const SetFeaturesRequest& req,
                              std::function<void(nvme_ex_ptr, uint32_t)>&& cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        lg2::error("MCTP connection is not established", "DEVICE",
                   device->describe());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(makeLibNVMeError("nvme endpoint is degraded"), 0);
        });
        return;
    }
    try
    {
        std::vector<uint8_t> data(req.data.begin(), req.data.end());

        post([ctrl, fid{req.fid}, cdw11{req.cdw11}, nsid{req.nsid},
              save{req.save}, data{std::move(data)}, self{shared_from_this()},
              ep{endpoint}, cb{std::move(cb)}]() mutable {
            nvme_set_features_args setArgs{};
            setArgs.args_size = sizeof(setArgs);
            setArgs.fid = fid;
            setArgs.cdw11 = cdw11;
            setArgs.nsid = nsid;
            setArgs.save = save;

            if (!data.empty())
            {
                setArgs.data = data.data();
                setArgs.data_len = data.size();
            }

            uint32_t cdw0 = 0;
            setArgs.result = &cdw0;

            int rc = nvme_mi_admin_set_features(ctrl, &setArgs);

            if (rc < 0)
            {
                lg2::error("fail to do nvme set features: {ERROR}", "ENDPOINT",
                           ep->describe(), "ERROR", strerror(errno));
            }
            else if (rc > 0)
            {
                std::string_view errMsg =
                    statusToString(static_cast<nvme_mi_resp_status>(rc));
                lg2::error("fail to do nvme set features: {ERROR}", "ENDPOINT",
                           ep->describe(), "ERROR", errMsg.data());
            }

            auto ex = makeLibNVMeError(errno, rc, "adminSetFeatures");

            boost::asio::post(self->io,
                              [cb{cb}, ex, cdw0]() mutable { cb(ex, cdw0); });
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "ENDPOINT", endpoint->describe(), "ERROR",
                   e.what());
        auto msg = std::string("Runtime error: ") + e.what();
        boost::asio::post(
            io, [cb{std::move(cb)}, msg]() { cb(makeLibNVMeError(msg), 0); });
        return;
    }
}

static int nvmeMiAdminGetLogTelemetryHostRae(nvme_mi_ctrl_t ctrl, bool /*rae*/,
                                             __u64 offset, __u32 len, void* log)
{
    return nvme_mi_admin_get_log_telemetry_host(ctrl, offset, len, log);
}

// Get Temetery Log header and return the size for hdr + data area (Area 1, 2,
// 3, or maybe 4)
int getTelemetryLogSize(nvme_mi_ctrl_t ctrl, bool host, uint32_t& size,
                        uint8_t dataArea = 0)
{
    int rc = 0;
    nvme_telemetry_log log = {};
    auto func = host ? nvmeMiAdminGetLogTelemetryHostRae
                     : nvme_mi_admin_get_log_telemetry_ctrl;

    // Only host telemetry log requires create.
    if (host)
    {
        rc = nvme_mi_admin_get_log_create_telemetry_host(ctrl, &log);
        if (rc != 0)
        {
            lg2::error("failed to create telemetry host log");
            return rc;
        }
    }

    rc = func(ctrl, false, 0, sizeof(log), &log);

    if (rc != 0)
    {
        lg2::error("failed to retain telemetry log for {TYPE}", "TYPE",
                   [host] { return host ? "host" : "ctrl"; }());
        return rc;
    }

    // Dynamically calculate the telemetry log size based on the requested Data
    // Area. The NVMe specification defines boundaries (dalb1, dalb2, etc.) in
    // the Block 0 header. We cast to our enum and calculate the block boundary
    // to prevent over-fetching. If a drive's firmware does not support a
    // requested area (dalbX == 0), the calculation evaluates to 1 block
    // (512 bytes), which safely returns just the telemetry header.
    auto area = static_cast<TelemetryDataArea>(dataArea);
    if (area == TelemetryDataArea::DA2)
    {
        size = static_cast<uint32_t>(
                   (boost::endian::little_to_native(log.dalb2) + 1)) *
               NVME_LOG_TELEM_BLOCK_SIZE;
    }
    else if (area == TelemetryDataArea::DA3)
    {
        size = static_cast<uint32_t>(
                   (boost::endian::little_to_native(log.dalb3) + 1)) *
               NVME_LOG_TELEM_BLOCK_SIZE;
    }
    else if (area == TelemetryDataArea::DA4)
    {
        size = static_cast<uint32_t>(
                   (boost::endian::little_to_native(log.dalb4) + 1)) *
               NVME_LOG_TELEM_BLOCK_SIZE;
    }
    else
    {
        // Default to DA1 or Aggregated
        size = static_cast<uint32_t>(
                   (boost::endian::little_to_native(log.dalb1) + 1)) *
               NVME_LOG_TELEM_BLOCK_SIZE;
    }
    return rc;
}

void NVMeMi::getTelemetryLogChunk(
    nvme_mi_ctrl_t ctrl, bool host, uint64_t offset,
    std::vector<uint8_t>&& data,
    std::function<void(const std::error_code&, std::span<uint8_t>)>&& cb)
{
    if (offset >= data.size())
    {
        lg2::error(
            "get telemetry log: offset exceed the log size. offset: {OFFSET}, size: {SIZE}",
            "DEVICE", device->describe(), "OFFSET", offset, "SIZE",
            data.size());
        cb(std::make_error_code(std::errc::invalid_argument), {});
        return;
    }

    post([self{shared_from_this()}, ctrl, host, offset, data{std::move(data)},
          cb{std::move(cb)}]() mutable {
        int rc = 0;
        bool rae = true;
        auto func = host ? nvmeMiAdminGetLogTelemetryHostRae
                         : nvme_mi_admin_get_log_telemetry_ctrl;
        uint32_t size = 0;

        // final transaction
        if (offset + nvmeMiXferSize >= data.size())
        {
            rae = false;
        }
        size = std::min(static_cast<uint32_t>(nvmeMiXferSize),
                        static_cast<uint32_t>(data.size() - offset));

        rc = func(ctrl, rae, offset, size, data.data() + offset);

        if (rc < 0)
        {
            lg2::error("fail to get chunk for telemetry log: {ERROR}", "DEVICE",
                       self->device->describe(), "ERROR", strerror(errno));
            boost::asio::post(self->io,
                              [cb{std::move(cb)}, lastErrno{errno}]() {
                cb(std::make_error_code(static_cast<std::errc>(lastErrno)), {});
            });
            return;
        }
        if (rc > 0)
        {
            std::string_view errMsg =
                statusToString(static_cast<nvme_mi_resp_status>(rc));
            lg2::error("fail to get chunk for telemetry log: {ERROR}", "DEVICE",
                       self->device->describe(), "ERROR", errMsg.data());
            boost::asio::post(self->io, [cb{std::move(cb)}]() {
                cb(std::make_error_code(std::errc::bad_message), {});
            });
            return;
        }

        if (!rae)
        {
            boost::asio::post(
                self->io, [cb{std::move(cb)}, data{std::move(data)}]() mutable {
                std::span<uint8_t> span{data.data(), data.size()};
                cb({}, span);
            });
            return;
        }

        offset += size;
        boost::asio::post(self->io,
                          [self, ctrl, host, offset, data{std::move(data)},
                           cb{std::move(cb)}]() mutable {
            self->getTelemetryLogChunk(ctrl, host, offset, std::move(data),
                                       std::move(cb));
        });
    });
}

void NVMeMi::getLockdownLogLsp(
    nvme_mi_ctrl_t ctrl, uint8_t lspIndex, std::vector<uint8_t>&& data,
    std::function<void(const std::error_code&, std::span<uint8_t>)>&& cb)
{
    if (lspIndex >= lockdownLogPageLsps.size())
    {
        cb(std::make_error_code(std::errc::invalid_argument), {});
        return;
    }

    this->post([self{shared_from_this()}, ctrl, lspIndex, data{std::move(data)},
                cb{std::move(cb)}]() mutable {
        uint8_t currentLsp = lockdownLogPageLsps[lspIndex];
        size_t offset = lspIndex * sizeof(nvme_lockdown_log);
        nvme_lockdown_log* logPtr =
            // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
            reinterpret_cast<nvme_lockdown_log*>(data.data() + offset);

        int rc = nvme_mi_admin_get_log_lockdown(ctrl, currentLsp, logPtr);
        int lastErrno = errno;

        if (rc < 0)
        {
            lg2::error("fail to get chunk for lockdown log: {ERROR}", "DEVICE",
                       self->device->describe(), "ERROR", strerror(lastErrno));
            boost::asio::post(self->io, [cb{std::move(cb)}, lastErrno]() {
                cb(std::make_error_code(static_cast<std::errc>(lastErrno)), {});
            });
            return;
        }
        if (rc > 0)
        {
            std::string_view errMsg =
                statusToString(static_cast<nvme_mi_resp_status>(rc));
            lg2::error("fail to get chunk for lockdown log: {ERROR}", "DEVICE",
                       self->device->describe(), "ERROR", errMsg.data());
            boost::asio::post(self->io, [cb{std::move(cb)}]() {
                cb(std::make_error_code(std::errc::bad_message), {});
            });
            return;
        }

        uint8_t nextIndex = lspIndex + 1;
        if (nextIndex >= lockdownLogPageLsps.size())
        {
            boost::asio::post(
                self->io, [cb{std::move(cb)}, data{std::move(data)}]() mutable {
                std::span<uint8_t> span{data.data(), data.size()};
                cb({}, span);
            });
            return;
        }
        self->post([self, ctrl, nextIndex, data{std::move(data)},
                    cb{std::move(cb)}]() mutable {
            self->getLockdownLogLsp(ctrl, nextIndex, std::move(data),
                                    std::move(cb));
        });
    });
}

void NVMeMi::processNextLockdownCommand(
    nvme_mi_ctrl_t ctrl, uint8_t prohibit,
    std::deque<std::pair<uint8_t, uint8_t>> lockdownQueue,
    const std::function<void(const std::error_code&, int, uint32_t,
                             const std::string&, uint32_t)>& finalCb,
    int lastNvmeStatus, uint32_t lastCompletionDw0, int attempt,
    const std::string& lastFailureScope, uint32_t lastFailureId)
{
    if (lockdownQueue.empty())
    {
        // Propagates the final success status and the final propagated failure
        // state
        boost::asio::post(this->io, [finalCb, lastNvmeStatus, lastCompletionDw0,
                                     lastFailureScope, lastFailureId]() {
            finalCb(std::error_code(), lastNvmeStatus, lastCompletionDw0,
                    lastFailureScope, lastFailureId);
        });
        return;
    }

    // local variables to hold the result of the synchronous hardware call.
    uint32_t completionDw0 = 0;
    int nvmeStatus = 0;
    int currentErrno = 0;

    const auto& currentCmd = lockdownQueue.front();
    uint8_t itemCode = currentCmd.first;
    uint8_t scope = currentCmd.second;
    uint8_t opcode = 0;
    constexpr uint32_t lockdownTimeoutMs = 5 * 1000;

    if (scope == lockdownScopeLogPage)
    {
        opcode = nvmeAdminOpcSamsungVULockdown;
    }
    else
    {
        opcode = nvmeAdminOpcLockdown;
    }

    // CDW10 Construction is the same for both scopes
    // Bits 15:8 (OFI/PRTID): itemCode
    // Bits 6:5 (IFC): 00b (lockdownIfcAsq)
    // Bit 4 (PRHBT): prohibit
    // Bits 3:0 (SCP): scope
    uint32_t cdw10 =
        (((uint32_t)itemCode) << lockdownOfiShift) |
        (((uint32_t)(lockdownIfcAsq & lockdownIfcMask)) << lockdownIfcShift) |
        (((uint32_t)(prohibit & lockdownPrhbtMask)) << lockdownPrhbtShift) |
        (((uint32_t)(scope & lockdownScopeMask)) << lockdownScopeShift);

    nvmeStatus = nvme_mi_admin_admin_passthru(
        ctrl, opcode, 0, 0, 0, 0, 0, cdw10, 0, 0, 0, 0, 0, 0, nullptr, 0,
        nullptr, lockdownTimeoutMs, &completionDw0);

    if (nvmeStatus < 0)
    {
        currentErrno = errno;
    }
    else
    {
        currentErrno = 0;
    }

    // Success condition
    if (nvmeStatus == 0)
    {
        lockdownQueue.pop_front();

        this->post([self = shared_from_this(), ctrl, prohibit,
                    lockdownQueue = std::move(lockdownQueue), finalCb,
                    nvmeStatus, completionDw0, lastFailureScope,
                    lastFailureId]() mutable {
            self->processNextLockdownCommand(
                ctrl, prohibit, std::move(lockdownQueue), finalCb, nvmeStatus,
                completionDw0, 0, lastFailureScope, lastFailureId);
        });
        return;
    }

    // Failure condition and checking if reattempting is allowed
    if (attempt == 0)
    {
        this->post([self = shared_from_this(), ctrl, prohibit,
                    lockdownQueue = std::move(lockdownQueue), finalCb,
                    nvmeStatus, completionDw0, lastFailureScope,
                    lastFailureId]() mutable {
            self->processNextLockdownCommand(
                ctrl, prohibit, std::move(lockdownQueue), finalCb, nvmeStatus,
                completionDw0, 1, lastFailureScope, lastFailureId);
        });
        return;
    }

    // The device failed this command, so its details become the final error
    // payload.
    std::string failureScope = scopeToString(currentCmd.second);
    uint32_t failureId = currentCmd.first;

    // Call the final D-Bus callback with the specific failure context (current
    // status is the error status).
    boost::asio::post(this->io, [finalCb, currentErrno, nvmeStatus,
                                 completionDw0, failureScope, failureId]() {
        finalCb(std::make_error_code(static_cast<std::errc>(currentErrno)),
                nvmeStatus, completionDw0, failureScope, failureId);
    });
}

void NVMeMi::adminGetLogPage(
    nvme_mi_ctrl_t ctrl, nvme_cmd_get_log_lid lid, uint32_t nsid, uint8_t lsp,
    uint16_t /*lsi*/,
    std::function<void(const std::error_code&, std::span<uint8_t>)>&& cb,
    uint8_t dataArea)
{
    if (auto degraded = isEndpointDegraded())
    {
        lg2::error("MCTP connection is not established", "DEVICE",
                   device->describe());
        boost::asio::post(io, [cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(errc, {});
        });
        return;
    }

    try
    {
        post([ctrl, nsid, lid, lsp, dataArea, self{shared_from_this()},
              ep{endpoint}, cb{std::move(cb)}]() {
            std::vector<uint8_t> data;
            std::function<void(void)> logHandler;
            int rc = 0;
            int logId = lid;
            switch (logId)
            {
                case NVME_LOG_LID_ERROR:
                {
                    data.resize(nvmeMiXferSize);
                    // The number of entries for most recent error logs.
                    // Currently we only do one nvme mi transfer for the
                    // error log to avoid blocking other tasks
                    static constexpr int num = nvmeMiXferSize /
                                               sizeof(nvme_error_log_page);
                    nvme_error_log_page* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_error_log_page*>(data.data());

                    rc = nvme_mi_admin_get_log_error(ctrl, num, false, log);
                    if (rc != 0)
                    {
                        lg2::error("fail to get error log", "ENDPOINT",
                                   ep->describe());
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_SMART:
                {
                    data.resize(sizeof(nvme_smart_log));
                    nvme_smart_log* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_smart_log*>(data.data());
                    rc = nvme_mi_admin_get_log_smart(ctrl, nsid, false, log);
                    if (rc != 0)
                    {
                        lg2::error("fail to get smart log", "ENDPOINT",
                                   ep->describe());
                        break;
                    }
                }
                break;
                    /* Begin of patch context
                     *
                     *
                     *
                     */
                    /*
                     *
                     *
                     * End of patch context
                     */
                case NVME_LOG_LID_FW_SLOT:
                {
                    data.resize(sizeof(nvme_firmware_slot));
                    nvme_firmware_slot* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_firmware_slot*>(data.data());
                    rc = nvme_mi_admin_get_log_fw_slot(ctrl, false, log);
                    if (rc != 0)
                    {
                        lg2::error("fail to get firmware slot", "ENDPOINT",
                                   ep->describe());
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_CMD_EFFECTS:
                {
                    data.resize(sizeof(nvme_cmd_effects_log));
                    nvme_cmd_effects_log* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_cmd_effects_log*>(data.data());

                    // nvme rev 1.3 doesn't support csi,
                    // set to default csi = NVME_CSI_NVM
                    rc = nvme_mi_admin_get_log_cmd_effects(ctrl, NVME_CSI_NVM,
                                                           log);
                    if (rc != 0)
                    {
                        lg2::error("fail to get cmd supported and effects log",
                                   "ENDPOINT", ep->describe());
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_SUPPORTED_LOG_PAGES:
                {
                    data.resize(sizeof(nvme_supported_log_pages));
                    nvme_supported_log_pages* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_supported_log_pages*>(
                            data.data());
                    rc = nvme_mi_admin_get_log_supported_log_pages(ctrl, false,
                                                                   log);
                    if (rc != 0)
                    {
                        lg2::error("fail to get supported log pages log",
                                   "ENDPOINT", ep->describe());
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_FID_SUPPORTED_EFFECTS:
                {
                    data.resize(sizeof(struct nvme_fid_supported_effects_log));
                    struct nvme_get_log_args args = {};
                    args.args_size = sizeof(args);
                    args.lid = NVME_LOG_LID_FID_SUPPORTED_EFFECTS;
                    args.nsid = NVME_NSID_NONE;
                    args.lsp = lsp;
                    args.len = data.size();
                    args.log = data.data();

                    rc = nvme_mi_admin_get_log(ctrl, &args);
                    if (rc != 0)
                    {
                        lg2::error("fail to get FID supported and effects log",
                                   "ENDPOINT", ep->describe());
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_DEVICE_SELF_TEST:
                {
                    data.resize(sizeof(nvme_self_test_log));
                    nvme_self_test_log* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_self_test_log*>(data.data());
                    rc = nvme_mi_admin_get_log_device_self_test(ctrl, log);
                    if (rc != 0)
                    {
                        lg2::error("fail to get device self test log",
                                   "ENDPOINT", ep->describe());
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_CHANGED_NS:
                {
                    data.resize(sizeof(nvme_ns_list));
                    nvme_ns_list* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_ns_list*>(data.data());
                    rc = nvme_mi_admin_get_log_changed_ns_list(ctrl, false,
                                                               log);
                    if (rc != 0)
                    {
                        lg2::error("fail to get changed namespace list",
                                   "ENDPOINT", ep->describe());
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_TELEMETRY_HOST:
                // fall through to NVME_LOG_LID_TELEMETRY_CTRL
                case NVME_LOG_LID_TELEMETRY_CTRL:
                {
                    bool host = lid == NVME_LOG_LID_TELEMETRY_HOST;

                    uint32_t size = 0;
                    rc = getTelemetryLogSize(ctrl, host, size, dataArea);
                    if (rc == 0)
                    {
                        data.resize(size);
                        logHandler = [self, ctrl, host, data{data},
                                      cb{cb}]() mutable {
                            self->getTelemetryLogChunk(
                                ctrl, host, 0, std::move(data), std::move(cb));
                        };
                    }
                }
                break;
                case NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN:
                {
                    if (lsp == 0xFF)
                    {
                        data.resize(sizeof(nvme_lockdown_log) *
                                    lockdownLogPageLsps.size());

                        logHandler = [self, ctrl, data{data},
                                      cb{cb}]() mutable {
                            self->getLockdownLogLsp(ctrl, 0, std::move(data),
                                                    std::move(cb));
                        };
                        break;
                    }

                    data.resize(sizeof(nvme_lockdown_log));
                    nvme_lockdown_log* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_lockdown_log*>(data.data());

                    rc = nvme_mi_admin_get_log_lockdown(ctrl, lsp, log);
                    if (rc != 0)
                    {
                        lg2::error(
                            "fail to get command and feature lockdown log",
                            "ENDPOINT", ep->describe());
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_RESERVATION:
                {
                    data.resize(sizeof(nvme_resv_notification_log));
                    nvme_resv_notification_log* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_resv_notification_log*>(
                            data.data());

                    int rc = nvme_mi_admin_get_log_reservation(ctrl, false,
                                                               log);
                    if (rc != 0)
                    {
                        lg2::error("fail to get reservation notification log",
                                   "ENDPOINT", ep->describe());
                        break;
                    }
                }
                break;
                case NVME_LOG_LID_SANITIZE:
                {
                    data.resize(sizeof(nvme_sanitize_log_page));
                    nvme_sanitize_log_page* log =
                        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                        reinterpret_cast<nvme_sanitize_log_page*>(data.data());

                    int rc = nvme_mi_admin_get_log_sanitize(ctrl, false, log);
                    if (rc != 0)
                    {
                        lg2::error("fail to get sanitize status log",
                                   "ENDPOINT", ep->describe());
                        break;
                    }
                }
                break;
                default:
                {
                    lg2::error("unknown lid for GetLogPage", "ENDPOINT",
                               ep->describe());
                    rc = -1;
                    errno = EINVAL;
                }
            }

            if (rc < 0)
            {
                lg2::error("fail to get log page: {ERROR}", "ENDPOINT",
                           ep->describe(), "ERROR", strerror(errno));
                logHandler = [cb{cb}, lastErrno{errno}]() mutable {
                    cb(std::make_error_code(static_cast<std::errc>(lastErrno)),
                       {});
                };
            }
            else if (rc > 0)
            {
                std::string_view errMsg =
                    statusToString(static_cast<nvme_mi_resp_status>(rc));
                lg2::error("fail to get log page: {ERROR}", "ENDPOINT",
                           ep->describe(), "ERROR", errMsg.data());
                logHandler = [cb{cb}]() mutable {
                    cb(std::make_error_code(std::errc::bad_message), {});
                };
            }

            if (!logHandler)
            {
                logHandler = [cb{cb}, data{std::move(data)}]() mutable {
                    std::span<uint8_t> span{data.data(), data.size()};
                    cb({}, span);
                };
            }
            boost::asio::post(self->io, logHandler);
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("NVMeMi adminGetLogPage throws: {ERROR}", "ENDPOINT",
                   endpoint->describe(), "ERROR", e.what());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device), {});
        });
        return;
    }
}

void NVMeMi::adminLockdownInband(
    nvme_mi_ctrl_t ctrl, uint8_t prohibit,
    const std::vector<uint8_t>& adminCmds, const std::vector<uint8_t>& features,
    const std::vector<uint8_t>& logPages,
    std::function<void(const std::error_code&, int nvmeStatus,
                       uint32_t comptionDw0, const std::string& failureScope,
                       uint32_t failureId)>&& cb)
{
    // Flatten all command sets into a deque of {itemCode, scope} pairs
    std::deque<std::pair<uint8_t, uint8_t>> lockdownQueue;

    for (uint8_t cmd : adminCmds)
    {
        lockdownQueue.emplace_back(cmd, lockdownScopeAdminCmd);
    }
    for (uint8_t feature : features)
    {
        lockdownQueue.emplace_back(feature, lockdownScopeFeatureId);
    }
    for (uint8_t logPage : logPages)
    {
        lockdownQueue.emplace_back(logPage, lockdownScopeLogPage);
    }
    std::error_code postErr =
        tryPost([self{shared_from_this()}, ctrl, prohibit,
                 lockdownQueue = std::move(lockdownQueue), cb{cb}]() mutable {
        self->processNextLockdownCommand(
            ctrl, prohibit, std::move(lockdownQueue), cb, 0, 0, 0, "", 0);
    });

    if (postErr)
    {
        lg2::error("adminLockdownInband post failed: {ERROR}", "DEVICE",
                   device->describe(), "ERROR", postErr.message());

        boost::asio::post(
            io, [cb{std::move(cb)}, postErr]() { cb(postErr, -1, 0, "", 0); });
    }
}

void NVMeMi::adminXfer(
    nvme_mi_ctrl_t ctrl, const nvme_mi_admin_req_hdr& adminReq,
    std::span<uint8_t> data, unsigned int timeoutMs,
    std::function<void(const std::error_code&, const nvme_mi_admin_resp_hdr&,
                       std::span<uint8_t>)>&& cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        lg2::error("MCTP connection is not established", "DEVICE",
                   device->describe());
        boost::asio::post(io, [cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(errc, {}, {});
        });
        return;
    }

    try
    {
        std::vector<uint8_t> req(sizeof(nvme_mi_admin_req_hdr) + data.size());
        memcpy(req.data(), &adminReq, sizeof(nvme_mi_admin_req_hdr));
        memcpy(req.data() + sizeof(nvme_mi_admin_req_hdr), data.data(),
               data.size());
        post([ctrl, req{std::move(req)}, self{shared_from_this()}, ep{endpoint},
              timeoutMs, cb{std::move(cb)}]() mutable {
            int rc = 0;

            nvme_mi_admin_req_hdr* reqHeader =
                // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                reinterpret_cast<nvme_mi_admin_req_hdr*>(req.data());
            // set response data size == req DL. Only if data passed is empty
            size_t respDataSize = 0;
            if (req.size() == sizeof(nvme_mi_admin_req_hdr))
            {
                respDataSize =
                    boost::endian::little_to_native<size_t>(reqHeader->dlen);
            }
            off_t respDataOffset =
                boost::endian::little_to_native<off_t>(reqHeader->doff);
            size_t bufSize = sizeof(nvme_mi_admin_resp_hdr) + respDataSize;
            std::vector<uint8_t> buf(bufSize);
            nvme_mi_admin_resp_hdr* respHeader =
                // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                reinterpret_cast<nvme_mi_admin_resp_hdr*>(buf.data());

            // set timeout
            unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
            nvme_mi_ep_set_timeout(self->nvmeEP, timeoutMs);

            rc = nvme_mi_admin_xfer(ctrl, reqHeader,
                                    req.size() - sizeof(nvme_mi_admin_req_hdr),
                                    respHeader, respDataOffset, &respDataSize);
            // revert to previous timeout
            nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

            if (rc < 0)
            {
                lg2::error("failed to nvme_mi_admin_xfer", "ENDPOINT",
                           ep->describe());
                boost::asio::post(self->io,
                                  [cb{std::move(cb)}, lastErrno{errno}]() {
                    cb(std::make_error_code(static_cast<std::errc>(lastErrno)),
                       {}, {});
                });
                return;
            }
            // the MI interface will only consume protocol/io errors
            // The client will take the reponsibility to deal with nvme-mi
            // status flag and nvme status field(cwd3). cmd specific return
            // value (cdw0) is also client's job.

            buf.resize(sizeof(nvme_mi_admin_resp_hdr) + respDataSize);
            boost::asio::post(
                self->io, [cb{std::move(cb)}, data{std::move(buf)}]() mutable {
                std::span<uint8_t> span(
                    data.begin() + sizeof(nvme_mi_admin_resp_hdr), data.end());
                // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
                cb({}, *reinterpret_cast<nvme_mi_admin_resp_hdr*>(data.data()),
                   span);
            });
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "ENDPOINT", endpoint->describe(), "ERROR",
                   e.what());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device), {}, {});
        });
        return;
    }
}

void NVMeMi::adminFwCommit(
    nvme_mi_ctrl_t ctrl, nvme_fw_commit_ca action, uint8_t slot, bool bpid,
    std::function<void(const std::error_code&, nvme_status_field)>&& cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        lg2::error("MCTP connection is not established", "DEVICE",
                   device->describe());
        boost::asio::post(io, [cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(errc, nvme_status_field::NVME_SC_MASK);
        });
        return;
    }
    try
    {
        nvme_fw_commit_args args{};
        memset(&args, 0, sizeof(args));
        args.args_size = sizeof(args);
        args.action = action;
        args.slot = slot;
        args.bpid = bpid;
        boost::asio::post(io, [ctrl, args, cb{std::move(cb)}, ep{endpoint},
                               self{shared_from_this()}]() mutable {
            int rc = nvme_mi_admin_fw_commit(ctrl, &args);
            if (rc < 0)
            {
                lg2::error("fail to nvme_mi_admin_fw_commit: {ERROR}",
                           "ENDPOINT", ep->describe(), "ERROR",
                           strerror(errno));
                boost::asio::post(self->io,
                                  [cb{std::move(cb)}, lastErrno{errno}]() {
                    cb(std::make_error_code(static_cast<std::errc>(lastErrno)),
                       nvme_status_field::NVME_SC_MASK);
                });
                return;
            }
            if (rc >= 0)
            {
                switch (rc & 0x7ff)
                {
                    case NVME_SC_SUCCESS:
                    case NVME_SC_FW_NEEDS_CONV_RESET:
                    case NVME_SC_FW_NEEDS_SUBSYS_RESET:
                    case NVME_SC_FW_NEEDS_RESET:
                        boost::asio::post(self->io, [rc, cb{std::move(cb)}]() {
                            cb({}, static_cast<nvme_status_field>(rc));
                        });
                        break;
                    default:
                        std::string_view errMsg = statusToString(
                            static_cast<nvme_mi_resp_status>(rc));
                        lg2::error("fail to nvme_mi_admin_fw_commit: {ERROR}",
                                   "ERROR", errMsg.data());
                        boost::asio::post(self->io, [rc, cb{std::move(cb)}]() {
                            cb(std::make_error_code(std::errc::bad_message),
                               static_cast<nvme_status_field>(rc));
                        });
                }
                return;
            }
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "ENDPOINT", endpoint->describe(), "ERROR",
                   e.what());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device),
               nvme_status_field::NVME_SC_MASK);
        });
        return;
    }
}

void NVMeMi::adminFwDownloadChunk(
    nvme_mi_ctrl_t ctrl, const std::string& firmwarefile, size_t size,
    size_t offset, int attemptCount,
    std::function<void(const std::error_code&, nvme_status_field)>&& cb)
{
    if (auto degraded = isEndpointDegraded())
    {
        lg2::error("MCTP connection is not established", "DEVICE",
                   device->describe());
        boost::asio::post(io, [cb{std::move(cb)}, errc{degraded.value()}]() {
            cb(errc, nvme_status_field::NVME_SC_MASK);
        });
        return;
    }
    try
    {
        post([ctrl, firmwarefile, size, offset, attemptCount, cb{std::move(cb)},
              self{shared_from_this()}]() mutable {
            std::array<char, nvmeMiXferSize> data = {};
            std::ifstream fwFile(firmwarefile, std::ios::in | std::ios::binary);
            if (fwFile.fail())
            {
                lg2::error("fail to open fw image file: {FILE}, {ERROR}",
                           "FILE", firmwarefile, "ERROR", strerror(errno));
                boost::asio::post(self->io, [cb{std::move(cb)}]() {
                    cb(std::make_error_code(static_cast<std::errc>(errno)),
                       nvme_status_field::NVME_SC_MASK);
                });
                return;
            }
            fwFile.seekg(static_cast<int64_t>(offset), std::ios::beg);
            nvme_fw_download_args args = {};
            memset(&args, 0, sizeof(args));
            args.args_size = sizeof(args);
            int dataLen =
                static_cast<int>(std::min(size - offset, nvmeMiXferSize));
            fwFile.read((char*)data.data(), dataLen);
            fwFile.close();
            args.offset = offset;
            args.data_len = dataLen;
            args.data = (char*)data.data();
            unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
            nvme_mi_ep_set_timeout(self->nvmeEP, downloadDefaultTimeoutMS);
            int rc = nvme_mi_admin_fw_download(ctrl, &args);
            nvme_mi_ep_set_timeout(self->nvmeEP, timeout);
            if (rc < 0)
            {
                if (attemptCount > 0)
                {
                    lg2::warning(
                        "Retrying the firmware chunk. With Offset: {OFFSET}, Total firmware Size: {SIZE}",
                        "OFFSET", offset, "SIZE", size);
                    attemptCount = attemptCount - 1;
                }
                else
                {
                    lg2::error("fail to nvme_mi_admin_fw_download: {ERROR}",
                               "ERROR", strerror(errno));
                    boost::asio::post(self->io, [cb{std::move(cb)}]() {
                        cb(std::make_error_code(static_cast<std::errc>(errno)),
                           nvme_status_field::NVME_SC_MASK);
                    });
                    return;
                }
            }
            else
            {
                attemptCount = 3; /* Reset the attempt count*/
                offset = offset + args.data_len;
            }
            if (offset >= size)
            {
                lg2::info(
                    "Successfully transferred the firmware. Transfer Size: {XFER}, Total Size: {SIZE}",
                    "XFER", offset, "SIZE", size);
                boost::asio::post(self->io, [rc, cb{std::move(cb)}]() {
                    cb({}, static_cast<nvme_status_field>(rc));
                });
                return;
            }
            boost::asio::post(self->io,
                              [self, ctrl, firmwarefile, size, offset,
                               attemptCount, cb{std::move(cb)}]() mutable {
                self->adminFwDownloadChunk(ctrl, firmwarefile, size, offset,
                                           attemptCount, std::move(cb));
            });
        });
    }
    catch (const std::runtime_error& e)
    {
        lg2::error("{ERROR}", "ERROR", e.what());
        boost::asio::post(io, [cb{std::move(cb)}]() {
            cb(std::make_error_code(std::errc::no_such_device),
               nvme_status_field::NVME_SC_MASK);
        });
        return;
    }
}

void NVMeMi::adminFwDownload(
    nvme_mi_ctrl_t ctrl, std::string firmwarefile,
    std::function<void(const std::error_code&, nvme_status_field)>&& cb)
{
    size_t offset = 0;
    int tryCount = 3;
    std::ifstream imageFile(firmwarefile,
                            std::ios::in | std::ios::binary | std::ios::ate);
    if (imageFile.fail())
    {
        lg2::error("Can't open the firmware file: {ERROR}", "ERROR",
                   strerror(errno));
        boost::asio::post(io, [cb{cb}]() {
            cb(std::make_error_code(std::errc::no_such_device),
               nvme_status_field::NVME_SC_MASK);
        });
    }
    size_t size = imageFile.tellg();
    imageFile.close();
    adminFwDownloadChunk(ctrl, firmwarefile, size, offset, tryCount,
                         std::move(cb));
}

void NVMeMi::adminSecuritySend(
    nvme_mi_ctrl_t ctrl, uint8_t proto, uint16_t protoSpecific,
    std::span<uint8_t> data,
    std::function<void(const std::error_code&, int nvmeStatus)>&& cb)
{
    std::error_code postErr = tryPost(
        [self{shared_from_this()}, ctrl, proto, protoSpecific, data, cb{cb}]() {
        struct nvme_security_send_args args = {};
        memset(&args, 0x0, sizeof(args));
        args.secp = proto;
        args.spsp0 = protoSpecific & 0xff;
        args.spsp1 = protoSpecific >> 8;
        args.nssf = 0;
        args.data = data.data();
        args.data_len = data.size_bytes();
        args.args_size = sizeof(struct nvme_security_send_args);

        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, tcgDefaultTimeoutMS);
        int status = nvme_mi_admin_security_send(ctrl, &args);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

        boost::asio::post(self->io,
                          [cb{cb}, nvmeErrno{errno}, status]() mutable {
            auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
            cb(err, status);
        });
    });
    if (postErr)
    {
        lg2::error("adminSecuritySend post failed: {ERROR}", "DEVICE",
                   device->describe(), "ERROR", postErr.message());
        boost::asio::post(io,
                          [cb{std::move(cb)}, postErr]() { cb(postErr, -1); });
    }
}

void NVMeMi::adminSecurityReceive(
    nvme_mi_ctrl_t ctrl, uint8_t proto, uint16_t protoSpecific,
    uint32_t transferLength,
    std::function<void(const std::error_code&, int nvmeStatus,
                       std::span<uint8_t> data)>&& cb)
{
    if (transferLength > maxNVMeMILength)
    {
        cb(std::make_error_code(std::errc::invalid_argument), -1, {});
        return;
    }

    std::error_code postErr =
        tryPost([self{shared_from_this()}, ctrl, proto, protoSpecific,
                 transferLength, cb{cb}]() {
        std::vector<uint8_t> data(transferLength);

        struct nvme_security_receive_args args = {};
        memset(&args, 0x0, sizeof(args));
        args.secp = proto;
        args.spsp0 = protoSpecific & 0xff;
        args.spsp1 = protoSpecific >> 8;
        args.nssf = 0;
        args.data = data.data();
        args.data_len = data.size();
        args.args_size = sizeof(struct nvme_security_receive_args);

        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, tcgDefaultTimeoutMS);
        int status = nvme_mi_admin_security_recv(ctrl, &args);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

        if (args.data_len > maxNVMeMILength)
        {
            lg2::error(
                "nvme_mi_admin_security_send returned excess data, {LEN}",
                "DEVICE", self->device->describe(), "LEN", args.data_len);
            boost::asio::post(self->io, [cb]() {
                cb(std::make_error_code(std::errc::protocol_error), -1, {});
            });
            return;
        }

        data.resize(args.data_len);
        boost::asio::post(self->io,
                          [cb{cb}, nvmeErrno{errno}, status, data]() mutable {
            std::span<uint8_t> span{data.data(), data.size()};
            auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
            cb(err, status, span);
        });
    });
    if (postErr)
    {
        lg2::error("adminSecurityReceive post failed: {ERROR}", "DEVICE",
                   device->describe(), "ERROR", postErr.message());
        boost::asio::post(
            io, [cb{std::move(cb)}, postErr]() { cb(postErr, -1, {}); });
    }
}

void NVMeMi::adminNonDataCmd(
    nvme_mi_ctrl_t ctrl, uint8_t opcode, uint32_t cdw1, uint32_t cdw2,
    uint32_t cdw3, uint32_t cdw10, uint32_t cdw11, uint32_t cdw12,
    uint32_t cdw13, uint32_t cdw14, uint32_t cdw15,
    std::function<void(const std::error_code&, int nvmeStatus,
                       uint32_t comptionDw0)>&& cb)
{
    std::error_code postErr =
        tryPost([self{shared_from_this()}, ctrl, opcode, cdw1, cdw2, cdw3,
                 cdw10, cdw11, cdw12, cdw13, cdw14, cdw15, cb{cb}]() {
        uint32_t comptionDw0 = 0;
        int nvmeStatus = nvme_mi_admin_admin_passthru(
            ctrl, opcode, 0, 0, cdw1, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13,
            cdw14, cdw15, 0, nullptr, 0, nullptr, 10 * 1000, &comptionDw0);
        boost::asio::post(self->io, [cb{cb}, nvmeErrno{errno}, nvmeStatus,
                                     comptionDw0]() mutable {
            auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
            cb(err, nvmeStatus, comptionDw0);
        });
    });
    if (postErr)
    {
        lg2::error("adminNonDataCmd post failed: {ERROR}", "DEVICE",
                   device->describe(), "ERROR", postErr.message());
        boost::asio::post(
            io, [cb{std::move(cb)}, postErr]() { cb(postErr, -1, 0); });
    }
}

/* throws a nvme_ex_ptr on failure */
size_t NVMeMi::getBlockSize(nvme_mi_ctrl_t ctrl, size_t lbaFormat)
{
    struct nvme_id_ns id = {};
    lg2::debug("getblocksize");
    int status = nvme_mi_admin_identify_ns(ctrl, NVME_NSID_ALL, &id);
    auto e = makeLibNVMeError(errno, status, "getBlockSize");
    if (e)
    {
        // TODO: (b/375054188) Exception handling to be refactored
        // NOLINTNEXTLINE(cert-err09-cpp,cert-err60-cpp,cert-err61-cpp,misc-throw-by-value-catch-by-reference)
        throw e;
    }

    lg2::debug("nlbaf {NLBAF}, lbaf {LBAF}", "NLBAF", (int)id.nlbaf, "LBAF",
               (int)lbaFormat);

    // Sanity check for the value from the drive
    size_t maxLbaf = std::min(63, (int)id.nlbaf);

    // NLBAF is the maximum allowed index (not a count)
    if (lbaFormat > maxLbaf)
    {
        throw makeLibNVMeError("LBA format out of range, maximum is " +
                                   std::to_string(maxLbaf),
                               std::make_shared<common_err::InvalidArgument>());
    }

    return 1 << id.lbaf[lbaFormat].ds;
}

/*
 finished_cb will not be called if submitted_cb is called with a failure.
 */
void NVMeMi::createNamespace(
    nvme_mi_ctrl_t ctrl, uint64_t size, size_t lbaFormat, bool metadataAtEnd,
    std::function<void(nvme_ex_ptr ex)>&& submittedCb,
    std::function<void(nvme_ex_ptr ex, NVMeNSIdentify newid)>&& finishedCb)
{
    lg2::debug("createns {TID}", "TID", (int)gettid());
    std::error_code postErr = tryPost(
        [self{shared_from_this()}, ctrl, size, lbaFormat, metadataAtEnd,
         submittedCb{submittedCb}, finishedCb{std::move(finishedCb)}]() {
        size_t blockSize = 0;

        try
        {
            blockSize = NVMeMi::getBlockSize(ctrl, lbaFormat);
        }
        // TODO: (b/375054188) Exception handling to be refactored
        // NOLINTNEXTLINE(cert-err09-cpp,cert-err60-cpp,cert-err61-cpp,misc-throw-by-value-catch-by-reference)
        catch (nvme_ex_ptr e)
        {
            submittedCb(e);
            return;
        }

        if (size % blockSize != 0)
        {
            auto msg =
                std::string("Size must be a multiple of the block size ") +
                std::to_string(blockSize);
            submittedCb(makeLibNVMeError(
                msg, std::make_shared<common_err::InvalidArgument>()));
            return;
        }

        uint64_t blocks = size / blockSize;

        // TODO: this will become nvme_ns_mgmt_host_sw_specified in a newer
        // libnvme.
        struct nvme_id_ns data = {};
        uint32_t newNsid = 0;

        uint8_t flbas = 0;
        if (metadataAtEnd)
        {
            flbas |= (1 << 4);
        }
        // low 4 bits at 0:3
        flbas |= (lbaFormat & 0xf);
        // high 2 bits at 5:6
        flbas |= ((lbaFormat & 0x30) << 1);

        memset(&data, 0x0, sizeof(data));
        data.nsze = ::htole64(blocks);
        data.ncap = ::htole64(blocks);
        data.flbas = flbas;

        lg2::debug("verified {TID}", "TID", (int)gettid());

        // submission has been verified. Handle the cb in main thread
        // concurrently.
        boost::asio::post(self->io, [submittedCb{submittedCb}]() mutable {
            submittedCb(nvme_ex_ptr());
        });
        lg2::debug("after submitted_cb {TID}", "TID", (int)gettid());

        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, namespaceDefaultTimeoutMS);
        int status = nvme_mi_admin_ns_mgmt_create(ctrl, &data, 0, &newNsid);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

        nvme_ex_ptr e = makeLibNVMeError(errno, status, "createVolume");

        NVMeNSIdentify newns = {
            .namespaceId = newNsid,
            .size = size,
            .capacity = size,
            .blockSize = blockSize,
            .lbaFormat = lbaFormat,
            .metadataAtEnd = metadataAtEnd,
        };

        boost::asio::post(self->io,
                          [finishedCb{finishedCb}, e, newns]() mutable {
            finishedCb(e, newns);
        });
    });

    lg2::debug("submitted cb {TID}", "TID", (int)gettid());

    if (postErr)
    {
        lg2::error("createNamespace post failed: {ERROR}", "ERROR",
                   postErr.message());
        auto e = makeLibNVMeError(postErr, -1, "createVolume");
        boost::asio::post(
            io, [submittedCb{std::move(submittedCb)}, e]() { submittedCb(e); });
    }
}

// Deletes a namespace
void NVMeMi::adminDeleteNamespace(
    nvme_mi_ctrl_t ctrl, uint32_t nsid,
    std::function<void(const std::error_code&, int nvmeStatus)>&& cb)
{
    std::error_code postErr =
        tryPost([self{shared_from_this()}, ctrl, nsid, cb{cb}]() {
        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, namespaceDefaultTimeoutMS);
        int status = nvme_mi_admin_ns_mgmt_delete(ctrl, nsid);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);

        boost::asio::post(self->io,
                          [cb{cb}, nvmeErrno{errno}, status]() mutable {
            auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
            cb(err, status);
        });
    });
    if (postErr)
    {
        lg2::error("deleteNamespace post failed: {ERROR}", "ERROR",
                   postErr.message());
        boost::asio::post(io,
                          [cb{std::move(cb)}, postErr]() { cb(postErr, -1); });
    }
}

void NVMeMi::adminListNamespaces(
    nvme_mi_ctrl_t ctrl,
    std::function<void(nvme_ex_ptr, std::vector<uint32_t> ns)>&& cb)
{
    std::error_code postErr =
        tryPost([self{shared_from_this()}, ctrl, cb{cb}]() {
        int status = 0;
        int nvmeErrno = 0;
        std::vector<uint32_t> ns;
        // sanity in case of bad drives, allows for >1million NSes
        const int maxIter = 1000;

        for (int i = 0; i < maxIter; i++)
        {
            struct nvme_ns_list list = {};
            uint32_t start = NVME_NSID_NONE;
            if (!ns.empty())
            {
                start = ns.back() + 1;
            }
            status = nvme_mi_admin_identify_active_ns_list(ctrl, start, &list);
            nvmeErrno = errno;
            if (status != 0)
            {
                ns.clear();
                break;
            }

            // NOLINTNEXTLINE(modernize-loop-convert)
            for (size_t i = 0; i < NVME_ID_NS_LIST_MAX; i++)
            {
                if (list.ns[i] == 0U)
                {
                    break;
                }
                ns.push_back(list.ns[i]);
            }
            if (list.ns[NVME_ID_NS_LIST_MAX - 1] == 0)
            {
                // all entries read
                break;
            }
        }

        auto ex = makeLibNVMeError(nvmeErrno, status, "adminListNamespaces");
        boost::asio::post(self->io, [cb{cb}, ex, ns]() mutable { cb(ex, ns); });
    });
    if (postErr)
    {
        auto ex = makeLibNVMeError("post failed");
        boost::asio::post(
            io, [cb{std::move(cb)}, ex]() { cb(ex, std::vector<uint32_t>()); });
    }
}

// Attaches or detaches a namespace from a controller
void NVMeMi::adminAttachDetachNamespace(
    nvme_mi_ctrl_t ctrl, uint16_t ctrlid, uint32_t nsid, bool attach,
    std::function<void(const std::error_code&, int nvmeStatus)>&& cb)
{
    std::error_code postErr = tryPost(
        [self{shared_from_this()}, ctrl, nsid, attach, ctrlid, cb{cb}]() {
        struct nvme_ctrl_list ctrlList = {};
        struct nvme_ns_attach_args args = {};
        memset(&args, 0x0, sizeof(args));

        // TODO: add this to a newer libnvme
        // uint16_t ctrl_id = nvme_mi_ctrl_id(ctrl);
        uint16_t ctrlId = ctrlid;
        nvme_init_ctrl_list(&ctrlList, 1, &ctrlId);
        args.ctrlist = &ctrlList;
        args.nsid = nsid;
        if (attach)
        {
            args.sel = NVME_NS_ATTACH_SEL_CTRL_ATTACH;
        }
        else
        {
            args.sel = NVME_NS_ATTACH_SEL_CTRL_DEATTACH;
        }
        args.args_size = sizeof(args);

        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, namespaceDefaultTimeoutMS);
        int status = nvme_mi_admin_ns_attach(ctrl, &args);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);
        boost::asio::post(self->io,
                          [cb{cb}, nvmeErrno{errno}, status]() mutable {
            auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
            cb(err, status);
        });
    });
    if (postErr)
    {
        lg2::error("adminAttachDetachNamespace post failed: {ERROR}", "ERROR",
                   postErr.message());
        boost::asio::post(io,
                          [cb{std::move(cb)}, postErr]() { cb(postErr, -1); });
    }
}

void NVMeMi::adminSanitize(nvme_mi_ctrl_t ctrl,
                           enum nvme_sanitize_sanact sanact, uint8_t passes,
                           uint32_t /*pattern*/, bool invertPattern,
                           std::function<void(nvme_ex_ptr ex)>&& cb)
{
    std::error_code postErr = tryPost([self{shared_from_this()}, ctrl, sanact,
                                       passes, invertPattern, cb{cb}]() {
        struct nvme_sanitize_nvm_args args = {};
        memset(&args, 0x0, sizeof(args));
        args.args_size = sizeof(args);
        args.sanact = sanact;
        args.owpass = passes;
        args.oipbp = invertPattern;

        unsigned timeout = nvme_mi_ep_get_timeout(self->nvmeEP);
        nvme_mi_ep_set_timeout(self->nvmeEP, sanitizeDefaultTimeoutMS);
        int status = nvme_mi_admin_sanitize_nvm(ctrl, &args);
        nvme_mi_ep_set_timeout(self->nvmeEP, timeout);
        lg2::debug("san status {STATUS}, errno {ERRNO}", "STATUS", status,
                   "ERRNO", errno);

        auto ex = makeLibNVMeError(errno, status, "adminSanitize");
        boost::asio::post(self->io, [cb{cb}, ex]() mutable { cb(ex); });
    });
    if (postErr)
    {
        auto ex = makeLibNVMeError("post failed");
        boost::asio::post(io, [cb{std::move(cb)}, ex]() { cb(ex); });
    }
}
