nvme/pcie: register CMB with spdk_mem_register()
Enable address translation for I/O buffers within the controller memory buffer region by registering the CMB using spdk_mem_register(). Change-Id: I44829757ad15fbc3ea96fa494b9fb32dd67a7138 Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com> Signed-off-by: Stephen Bates <sbates@raithlin.com> Reviewed-on: https://review.gerrithub.io/397035 Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
parent
35a331a949
commit
f185e4ecf8
@ -88,6 +88,9 @@ struct nvme_pcie_ctrlr {
|
||||
/* Current offset of controller memory buffer */
|
||||
uint64_t cmb_current_offset;
|
||||
|
||||
void *cmb_mem_register_addr;
|
||||
size_t cmb_mem_register_size;
|
||||
|
||||
/** stride in uint32_t units between doorbell registers (1 = 4 bytes, 2 = 8 bytes, ...) */
|
||||
uint32_t doorbell_stride_u32;
|
||||
|
||||
@ -442,6 +445,7 @@ nvme_pcie_ctrlr_map_cmb(struct nvme_pcie_ctrlr *pctrlr)
|
||||
union spdk_nvme_cmbsz_register cmbsz;
|
||||
union spdk_nvme_cmbloc_register cmbloc;
|
||||
uint64_t size, unit_size, offset, bar_size, bar_phys_addr;
|
||||
uint64_t mem_register_start, mem_register_end;
|
||||
|
||||
if (nvme_pcie_ctrlr_get_cmbsz(pctrlr, &cmbsz) ||
|
||||
nvme_pcie_ctrlr_get_cmbloc(pctrlr, &cmbloc)) {
|
||||
@ -489,6 +493,30 @@ nvme_pcie_ctrlr_map_cmb(struct nvme_pcie_ctrlr *pctrlr)
|
||||
pctrlr->ctrlr.opts.use_cmb_sqs = false;
|
||||
}
|
||||
|
||||
/* If only SQS is supported use legacy mapping */
|
||||
if (cmbsz.bits.sqs && !(cmbsz.bits.wds || cmbsz.bits.rds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If CMB is less than 4MiB in size then abort CMB mapping */
|
||||
if (pctrlr->cmb_size < (1ULL << 22)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mem_register_start = (((uintptr_t)pctrlr->cmb_bar_virt_addr + offset + 0x1fffff) & ~(0x200000 - 1));
|
||||
mem_register_end = ((uintptr_t)pctrlr->cmb_bar_virt_addr + offset + pctrlr->cmb_size);
|
||||
mem_register_end &= ~(uint64_t)(0x200000 - 1);
|
||||
pctrlr->cmb_mem_register_addr = (void *)mem_register_start;
|
||||
pctrlr->cmb_mem_register_size = mem_register_end - mem_register_start;
|
||||
|
||||
rc = spdk_mem_register(pctrlr->cmb_mem_register_addr, pctrlr->cmb_mem_register_size);
|
||||
if (rc) {
|
||||
SPDK_ERRLOG("spdk_mem_register() failed\n");
|
||||
goto exit;
|
||||
}
|
||||
pctrlr->cmb_current_offset = mem_register_start - ((uint64_t)pctrlr->cmb_bar_virt_addr + offset);
|
||||
|
||||
|
||||
return;
|
||||
exit:
|
||||
pctrlr->cmb_bar_virt_addr = NULL;
|
||||
@ -504,6 +532,10 @@ nvme_pcie_ctrlr_unmap_cmb(struct nvme_pcie_ctrlr *pctrlr)
|
||||
void *addr = pctrlr->cmb_bar_virt_addr;
|
||||
|
||||
if (addr) {
|
||||
if (pctrlr->cmb_mem_register_addr) {
|
||||
spdk_mem_unregister(pctrlr->cmb_mem_register_addr, pctrlr->cmb_mem_register_size);
|
||||
}
|
||||
|
||||
if (nvme_pcie_ctrlr_get_cmbloc(pctrlr, &cmbloc)) {
|
||||
SPDK_ERRLOG("get_cmbloc() failed\n");
|
||||
return -EIO;
|
||||
|
@ -39,6 +39,9 @@
|
||||
|
||||
#include "nvme/nvme_pcie.c"
|
||||
|
||||
DEFINE_STUB(spdk_mem_register, int, (void *vaddr, size_t len), 0);
|
||||
DEFINE_STUB(spdk_mem_unregister, int, (void *vaddr, size_t len), 0);
|
||||
|
||||
struct spdk_trace_flag SPDK_LOG_NVME = {
|
||||
.name = "nvme",
|
||||
.enabled = false,
|
||||
|
Loading…
Reference in New Issue
Block a user