diff --git a/test/external_code/nvme/nvme.c b/test/external_code/nvme/nvme.c index 9ce61cb75..0540f3bf3 100644 --- a/test/external_code/nvme/nvme.c +++ b/test/external_code/nvme/nvme.c @@ -103,6 +103,8 @@ struct nvme_ctrlr { uint32_t page_size; /* Admin queue pair */ struct nvme_qpair *admin_qpair; + /* Controller's identify data */ + struct spdk_nvme_ctrlr_data *cdata; /* State of the controller */ enum nvme_ctrlr_state state; TAILQ_ENTRY(nvme_ctrlr) tailq; @@ -332,11 +334,21 @@ pcie_enum_cb(void *ctx, struct spdk_pci_device *pci_dev) ctrlr->page_size = 1 << (12 + cap.bits.mpsmin); ctrlr->doorbell_stride_u32 = 1 << cap.bits.dstrd; + ctrlr->cdata = spdk_zmalloc(sizeof(*ctrlr->cdata), ctrlr->page_size, NULL, + SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA); + if (!ctrlr->cdata) { + SPDK_ERRLOG("Failed to allocate identify data for NVMe controller: %s\n", addr); + spdk_pci_device_unclaim(pci_dev); + free(ctrlr); + return -1; + } + /* Initialize admin queue pair with minimum number of entries (2) */ ctrlr->admin_qpair = init_qpair(ctrlr, 0, SPDK_NVME_ADMIN_QUEUE_MIN_ENTRIES); if (!ctrlr->admin_qpair) { SPDK_ERRLOG("Failed to initialize admin queue pair for controller: %s\n", addr); spdk_pci_device_unclaim(pci_dev); + spdk_free(ctrlr->cdata); free(ctrlr); return -1; } @@ -418,6 +430,7 @@ free_ctrlr(struct nvme_ctrlr *ctrlr) spdk_pci_device_unclaim(ctrlr->pci_device); spdk_pci_device_detach(ctrlr->pci_device); free_qpair(ctrlr->admin_qpair); + spdk_free(ctrlr->cdata); free(ctrlr); } @@ -497,4 +510,10 @@ nvme_detach(struct nvme_ctrlr *ctrlr) free_ctrlr(ctrlr); } +const struct spdk_nvme_ctrlr_data * +nvme_ctrlr_get_data(struct nvme_ctrlr *ctrlr) +{ + return ctrlr->cdata; +} + SPDK_LOG_REGISTER_COMPONENT(nvme_external) diff --git a/test/external_code/nvme/nvme.h b/test/external_code/nvme/nvme.h index ddce395ff..1d709ac04 100644 --- a/test/external_code/nvme/nvme.h +++ b/test/external_code/nvme/nvme.h @@ -35,6 +35,7 @@ #define EXTERNAL_NVME_H #include "spdk/env.h" +#include "spdk/nvme_spec.h" struct nvme_ctrlr; @@ -86,4 +87,16 @@ struct nvme_ctrlr *nvme_connect(struct spdk_pci_addr *addr); */ void nvme_detach(struct nvme_ctrlr *ctrlr); +/** + * Get the identify controller data as defined by the NVMe specification. + * + * This function is thread safe and can be called at any point while the controller + * is attached to the SPDK NVMe driver. + * + * \param ctrlr Opaque handle to NVMe controller. + * + * \return pointer to the identify controller data. + */ +const struct spdk_nvme_ctrlr_data *nvme_ctrlr_get_data(struct nvme_ctrlr *ctrlr); + #endif /* EXTERNAL_NVME_H */