#include "NVMeMi.hpp"

#include "NVMeError.hpp"
#include "NVMeStorage.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(
                    "[{ENDPOINT}]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("[{ENDPOINT}]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("[{DEVICE}]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("[{DEVICE}]Endpoint optimize timer error: {ERROR}",
                       "DEVICE", device->describe(), "ERROR", ec.what());
            return;
        }
        miSetMCTPConfiguration(
            [self{shared_from_this()}](const std::error_code& ec) {
            self->optimizeTimer = nullptr;
            if (ec)
            {
                lg2::error(
                    "[{DEVICE}]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("[{ENDPOINT}]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("[{DEVICE}]{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("[{DEVICE}]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("[{ENDPOINT}]failed to get the SMBus frequency",
                           "ENDPOINT", ep->describe());
            }
            else if (smbusFreq == NVME_MI_CONFIG_SMBUS_FREQ_100kHz)
            {
                lg2::info("[{ENDPOINT}]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("[{ENDPOINT}]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("[{DEVICE}]{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("[{DEVICE}]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(
                    "[{DEVICE}]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("[{DEVICE}]{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("[{DEVICE}]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("[{DEVICE}]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(
                        "[{DEVICE}]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("[{DEVICE}]{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(
                "[{DEVICE}]failed to set MCTP path MTU: Status::Terminating",
                "DEVICE", device->describe());
            cb(ec);
            return;
        }

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

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

        lg2::warning("[{ENDPOINT}]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("[{DEVICE}]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(
                    "[{ENDPOINT}]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(
                    "[{ENDPOINT}]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("[{DEVICE}]{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("[{DEVICE}]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("[{ENDPOINT}]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("[{ENDPOINT}]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("[{ENDPOINT}]{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("[{ENDPOINT}]Runtime error: {ERROR}", "ENDPOINT",
                   endpoint->describe(), "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("[{DEVICE}]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("[{ENDPOINT}]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("[{ENDPOINT}]fail to do nvme identify: {ERROR}",
                           "ENDPOINT", ep->describe(), "ERROR", errMsg.data());
            }

            auto ex = makeLibNVMeError(errno, rc, "adminIdentify");
            if (ex)
            {
                lg2::error("[{ENDPOINT}]fail to do nvme identify: {ERROR}",
                           "ENDPOINT", ep->describe(), "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("[{ENDPOINT}]{ERROR}", "ENDPOINT", endpoint->describe(),
                   "ERROR", e.what());
        auto msg = std::string("Runtime error: ") + e.what();
        lg2::error("[{ENDPOINT}]{MSG}", "ENDPOINT", endpoint->describe(), "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("[{DEVICE}]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("[{ENDPOINT}]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("[{ENDPOINT}]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("[{ENDPOINT}]{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("[{DEVICE}]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("[{ENDPOINT}]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("[{ENDPOINT}]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("[{ENDPOINT}]{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("[{ENDPOINT}]failed to create telemetry host log",
                       "ENDPOINT", describeCtrl(ctrl));
            return rc;
        }
    }

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

    if (rc != 0)
    {
        lg2::error("[{ENDPOINT}]failed to retain telemetry log for {TYPE}",
                   "ENDPOINT", describeCtrl(ctrl), "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(
            "[{DEVICE}]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("[{DEVICE}]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("[{DEVICE}]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("[{DEVICE}]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("[{ENDPOINT}]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("[{ENDPOINT}]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("[{ENDPOINT}]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(
                            "[{ENDPOINT}]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(
                            "[{ENDPOINT}]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(
                            "[{ENDPOINT}]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(
                            "[{ENDPOINT}]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(
                            "[{ENDPOINT}]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(
                            "[{ENDPOINT}]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(
                            "[{ENDPOINT}]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(
                            "[{ENDPOINT}]fail to get sanitize status log",
                            "ENDPOINT", ep->describe());
                        break;
                    }
                }
                break;
                default:
                {
                    lg2::error("[{ENDPOINT}]unknown lid for GetLogPage",
                               "ENDPOINT", ep->describe());
                    rc = -1;
                    errno = EINVAL;
                }
            }

            if (rc < 0)
            {
                lg2::error("[{ENDPOINT}]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("[{ENDPOINT}]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("[{ENDPOINT}]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("[{DEVICE}]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("[{DEVICE}]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("[{ENDPOINT}]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("[{ENDPOINT}]{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("[{DEVICE}]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(
                    "[{ENDPOINT}]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(
                            "[{ENDPOINT}]fail to nvme_mi_admin_fw_commit: {ERROR}",
                            "ENDPOINT", self->endpoint->describe(), "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("[{ENDPOINT}]{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("[{DEVICE}]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(
                    "[{ENDPOINT}]fail to open fw image file: {FILE}, {ERROR}",
                    "ENDPOINT", self->endpoint->describe(), "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(
                        "[{ENDPOINT}]Retrying the firmware chunk. With Offset: {OFFSET}, Total firmware Size: {SIZE}",
                        "ENDPOINT", self->endpoint->describe(), "OFFSET",
                        offset, "SIZE", size);
                    attemptCount = attemptCount - 1;
                }
                else
                {
                    lg2::error(
                        "[{ENDPOINT}]fail to nvme_mi_admin_fw_download: {ERROR}",
                        "ENDPOINT", self->endpoint->describe(), "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(
                    "[{ENDPOINT}]Successfully transferred the firmware. Transfer Size: {XFER}, Total Size: {SIZE}",
                    "ENDPOINT", self->endpoint->describe(), "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("[{ENDPOINT}]{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::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("[{ENDPOINT}]Can't open the firmware file: {ERROR}",
                   "ENDPOINT", endpoint->describe(), "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("[{DEVICE}]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(
                "[{DEVICE}]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("[{DEVICE}]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("[{DEVICE}]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("[{ENDPOINT}]createns {TID}", "ENDPOINT", endpoint->describe(),
               "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("[{ENDPOINT}]verified {TID}", "ENDPOINT",
                   self->endpoint->describe(), "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("[{ENDPOINT}]after submitted_cb {TID}", "ENDPOINT",
                   self->endpoint->describe(), "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,
            .metadataCapabilities = 0,
        };

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

    lg2::debug("[{ENDPOINT}]submitted cb {TID}", "ENDPOINT",
               endpoint->describe(), "TID", (int)gettid());

    if (postErr)
    {
        lg2::error("[{ENDPOINT}]createNamespace post failed: {ERROR}",
                   "ENDPOINT", endpoint->describe(), "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("[{ENDPOINT}]deleteNamespace post failed: {ERROR}",
                   "ENDPOINT", endpoint->describe(), "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(
            "[{ENDPOINT}]adminAttachDetachNamespace post failed: {ERROR}",
            "ENDPOINT", endpoint->describe(), "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("[{ENDPOINT}]san status {STATUS}, errno {ERRNO}", "ENDPOINT",
                   self->endpoint->describe(), "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); });
    }
}

bool NVMeMi::validateFormatFna(
    nvme_mi_ctrl_t ctrl, uint32_t nsid, uint8_t secureEraseSetting,
    const std::function<void(const std::error_code&, int)>& cb)
{
    constexpr uint8_t sesCryptoErase = 2;

    if (nsid != NVME_NSID_ALL && secureEraseSetting != sesCryptoErase)
    {
        return true;
    }

    std::vector<uint8_t> data(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 = NVME_IDENTIFY_CNS_CTRL;
    args.csi = NVME_CSI_NVM;
    args.nsid = 0;
    args.cntid = 0;
    args.cns_specific_id = NVME_CNSSPECID_NONE;
    args.uuidx = NVME_UUID_NONE;

    int rc = nvme_mi_admin_identify(ctrl, &args);
    if (rc != 0)
    {
        if (rc < 0)
        {
            lg2::error("fail to do nvme identify in adminFormat: {ERROR}",
                       "ERROR", strerror(errno));
            auto err = std::make_error_code(static_cast<std::errc>(errno));
            boost::asio::post(io, [cb{cb}, err]() mutable { cb(err, -1); });
        }
        else
        {
            std::string_view errMsg =
                statusToString(static_cast<nvme_mi_resp_status>(rc));
            lg2::error("fail to do nvme identify in adminFormat: {ERROR}",
                       "ERROR", errMsg.data());
            auto err = std::make_error_code(std::errc::bad_message);
            boost::asio::post(io, [cb{cb}, err, rc]() mutable { cb(err, rc); });
        }
        return false;
    }

    nvme_id_ctrl idCtrl{};
    std::memcpy(&idCtrl, data.data(), std::min(sizeof(idCtrl), data.size()));
    if (nsid == NVME_NSID_ALL &&
        ((idCtrl.fna & nvme::fna::nsidAllRestriction) != 0))
    {
        lg2::error(
            "Format NVM does not support NSID FFFFFFFFh based on FNA bit 3");
        auto err = std::make_error_code(std::errc::invalid_argument);
        boost::asio::post(
            io, [cb{cb}, err]() mutable { cb(err, NVME_SC_INVALID_FIELD); });
        return false;
    }

    if (secureEraseSetting == sesCryptoErase &&
        (idCtrl.fna & nvme::fna::cryptoEraseSupport) == 0)
    {
        lg2::error(
            "Format NVM does not support Cryptographic Erase based on FNA bit 2");
        auto err = std::make_error_code(std::errc::invalid_argument);
        boost::asio::post(
            io, [cb{cb}, err]() mutable { cb(err, NVME_SC_INVALID_FIELD); });
        return false;
    }

    return true;
}

void NVMeMi::adminFormat(
    nvme_mi_ctrl_t ctrl, uint32_t nsid, uint8_t lbaFormat,
    uint8_t secureEraseSetting, uint8_t metadataSettings,
    uint8_t dataProtectionType, uint8_t protectionInformationLocation,
    std::function<void(const std::error_code&, int nvmeStatus)>&& cb)
{
    std::error_code postErr =
        tryPost([self{shared_from_this()}, ctrl, nsid, lbaFormat,
                 secureEraseSetting, metadataSettings, dataProtectionType,
                 protectionInformationLocation, cb{cb}]() {
        // Fast operations (LBA format modification and cryptographic key
        // erasure) typically finish in 1-2s; 10s provides safety margin for
        // MCTP retries.
        constexpr unsigned int formatTimeoutMs = 10 * 1000;

        if (!self->validateFormatFna(ctrl, nsid, secureEraseSetting, cb))
        {
            return;
        }

        constexpr uint8_t lbaFormatLowMask = 0x0F;
        constexpr uint8_t lbaFormatHighMask = 0x03;
        constexpr int lbaFormatHighShift = 4;

        nvme_format_nvm_args args{};
        memset(&args, 0, sizeof(args));
        args.args_size = sizeof(args);
        args.nsid = nsid;
        args.lbaf = lbaFormat & lbaFormatLowMask;
        args.lbafu = (lbaFormat >> lbaFormatHighShift) & lbaFormatHighMask;
        args.mset = static_cast<nvme_cmd_format_mset>(metadataSettings);
        args.pi = static_cast<nvme_cmd_format_pi>(dataProtectionType);
        args.pil =
            static_cast<nvme_cmd_format_pil>(protectionInformationLocation);
        args.ses = static_cast<nvme_cmd_format_ses>(secureEraseSetting);
        args.timeout = formatTimeoutMs;

        int nvmeStatus = nvme_mi_admin_format_nvm(ctrl, &args);

        boost::asio::post(self->io,
                          [cb{cb}, nvmeErrno{errno}, nvmeStatus]() mutable {
            auto err = std::make_error_code(static_cast<std::errc>(nvmeErrno));
            cb(err, nvmeStatus);
        });
    });
    if (postErr)
    {
        boost::asio::post(io,
                          [cb{std::move(cb)}, postErr]() { cb(postErr, -1); });
    }
}
