136 lines
3.3 KiB
C++
136 lines
3.3 KiB
C++
#include <sys/endian.h>
|
|
#include "ntr.h"
|
|
#include "spdk/nvme.h"
|
|
#include "spdk/thread.h"
|
|
#include "storage/drivers/nvme.hh"
|
|
|
|
size_t
|
|
birb_nvme_driver::get_capacity()
|
|
{
|
|
return spdk_nvme_ns_get_size(this->ns);
|
|
}
|
|
|
|
birb_driver::birb_driver_status
|
|
birb_nvme_driver::get_status()
|
|
{
|
|
return this->status;
|
|
}
|
|
|
|
void
|
|
birb_nvme_driver::attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
|
|
struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts UNUSED)
|
|
{
|
|
struct spdk_nvme_ns * ns;
|
|
auto ctx = reinterpret_cast<struct attach_context *>(cb_ctx);
|
|
|
|
ntr(NTR_DEP_USER1, NTR_LEVEL_INFO, "birb_nvme_driver: attached to nvme at %s\n", trid->traddr);
|
|
|
|
for (int nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr); nsid != 0;
|
|
nsid = spdk_nvme_ctrlr_get_next_active_ns(ctrlr, nsid)) {
|
|
ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid);
|
|
if (ns == nullptr || !spdk_nvme_ns_is_active(ns)) {
|
|
continue;
|
|
}
|
|
|
|
ntr(NTR_DEP_USER1, NTR_LEVEL_INFO, "birb_nvme_driver: namespace id: %d size: %zu LBA size: %u\n", spdk_nvme_ns_get_id(ns), spdk_nvme_ns_get_size(ns), spdk_nvme_ns_get_sector_size(ns));
|
|
/* XXX: use the first namespace */
|
|
break;
|
|
}
|
|
|
|
*ctx->ns = ns;
|
|
*ctx->ctrlr = ctrlr;
|
|
ctx->valid = 1;
|
|
}
|
|
|
|
bool
|
|
birb_nvme_driver::probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
|
|
struct spdk_nvme_ctrlr_opts *opts UNUSED)
|
|
{
|
|
printf("birb_nvme_driver: found nvme at %s\n", trid->traddr);
|
|
auto ctx = reinterpret_cast<struct attach_context *>(cb_ctx);
|
|
|
|
if (strcmp(trid->traddr, ctx->dev_name) == 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
birb_nvme_driver::birb_nvme_driver(const char * dev_name) : status(BIRB_FAIL),
|
|
ctrlr(nullptr),
|
|
ns(nullptr),
|
|
opts()
|
|
{
|
|
int rc;
|
|
struct spdk_nvme_transport_id trid;
|
|
struct attach_context ctx;
|
|
ctx.ctrlr = &this->ctrlr;
|
|
ctx.ns = &this->ns;
|
|
ctx.dev_name = dev_name;
|
|
ctx.valid = 0;
|
|
|
|
spdk_nvme_trid_populate_transport(&trid, SPDK_NVME_TRANSPORT_PCIE);
|
|
snprintf(trid.subnqn, sizeof(trid.subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN);
|
|
|
|
rc = spdk_nvme_probe(&trid, reinterpret_cast<void *>(&ctx), probe_cb, attach_cb, nullptr);
|
|
if (rc != 0) {
|
|
ntr(NTR_DEP_USER1, NTR_LEVEL_ERROR, "birb_nvme_driver: failed to probe nvme device: %d\n", rc);
|
|
goto end;
|
|
}
|
|
|
|
if (ctx.valid != 1) {
|
|
rc = EINVAL;
|
|
ntr(NTR_DEP_USER1, NTR_LEVEL_ERROR, "birb_nvme_driver: could not find device: %s\n", dev_name);
|
|
goto end;
|
|
}
|
|
|
|
if (spdk_nvme_ns_get_csi(this->ns) == SPDK_NVME_CSI_ZNS) {
|
|
ntr(NTR_DEP_USER1, NTR_LEVEL_ERROR, "birb_nvme_driver: zoned nvme namespace is unsupported\n");
|
|
spdk_nvme_detach(this->ctrlr);
|
|
goto end;
|
|
} else {
|
|
spdk_nvme_ctrlr_get_default_io_qpair_opts(ctrlr, &this->opts, sizeof(this->opts));
|
|
ntr(NTR_DEP_USER1, NTR_LEVEL_INFO, "birb_nvme_driver: io queue depth: %d io queue requests: %d\n", opts.io_queue_size, opts.io_queue_requests);
|
|
this->status = BIRB_SUCCESS;
|
|
}
|
|
|
|
end:
|
|
return;
|
|
}
|
|
|
|
birb_nvme_driver::~birb_nvme_driver()
|
|
{
|
|
if (this->ctrlr != nullptr) {
|
|
spdk_nvme_detach(this->ctrlr);
|
|
}
|
|
}
|
|
|
|
birb_driver::birb_driver_type
|
|
birb_nvme_driver::get_type()
|
|
{
|
|
return BIRB_DRV_NVME;
|
|
}
|
|
|
|
size_t
|
|
birb_nvme_driver::get_align()
|
|
{
|
|
return 0x1000;
|
|
}
|
|
|
|
spdk_nvme_ctrlr *
|
|
birb_nvme_driver::get_ctrlr()
|
|
{
|
|
return this->ctrlr;
|
|
}
|
|
|
|
spdk_nvme_ns *
|
|
birb_nvme_driver::get_ns()
|
|
{
|
|
return this->ns;
|
|
}
|
|
|
|
spdk_nvme_io_qpair_opts *
|
|
birb_nvme_driver::get_io_qpair_opts()
|
|
{
|
|
return &this->opts;
|
|
}
|