diff --git a/include/spdk/nvme_spec.h b/include/spdk/nvme_spec.h index e88383d9d..391a007f1 100644 --- a/include/spdk/nvme_spec.h +++ b/include/spdk/nvme_spec.h @@ -68,8 +68,8 @@ extern "C" { */ #define SPDK_NVME_DATASET_MANAGEMENT_MAX_RANGES 256 -union spdk_nvme_cap_lo_register { - uint32_t raw; +union spdk_nvme_cap_register { + uint64_t raw; struct { /** maximum queue entries supported */ uint32_t mqes : 16; @@ -84,17 +84,12 @@ union spdk_nvme_cap_lo_register { /** timeout */ uint32_t to : 8; - } bits; -}; -SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cap_lo_register) == 4, "Incorrect size"); -union spdk_nvme_cap_hi_register { - uint32_t raw; - struct { /** doorbell stride */ uint32_t dstrd : 4; - uint32_t reserved3 : 1; + /** NVM subsystem reset supported */ + uint32_t nssrs : 1; /** command sets supported */ uint32_t css_nvm : 1; @@ -108,10 +103,10 @@ union spdk_nvme_cap_hi_register { /** memory page size maximum */ uint32_t mpsmax : 4; - uint32_t reserved1 : 8; + uint32_t reserved3 : 8; } bits; }; -SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cap_hi_register) == 4, "Incorrect size"); +SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cap_register) == 8, "Incorrect size"); union spdk_nvme_cc_register { uint32_t raw; @@ -236,8 +231,7 @@ SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmbsz_register) == 4, "Incorrect size" struct spdk_nvme_registers { /** controller capabilities */ - union spdk_nvme_cap_lo_register cap_lo; - union spdk_nvme_cap_hi_register cap_hi; + union spdk_nvme_cap_register cap; /** version of NVMe specification */ union spdk_nvme_vs_register vs; @@ -269,7 +263,7 @@ struct spdk_nvme_registers { }; /* NVMe controller register space offsets */ -SPDK_STATIC_ASSERT(0x00 == offsetof(struct spdk_nvme_registers, cap_lo), +SPDK_STATIC_ASSERT(0x00 == offsetof(struct spdk_nvme_registers, cap), "Incorrect register offset"); SPDK_STATIC_ASSERT(0x08 == offsetof(struct spdk_nvme_registers, vs), "Incorrect register offset"); SPDK_STATIC_ASSERT(0x0C == offsetof(struct spdk_nvme_registers, intms), diff --git a/include/spdk/nvmf_spec.h b/include/spdk/nvmf_spec.h index 755c76bdf..67d16aa06 100644 --- a/include/spdk/nvmf_spec.h +++ b/include/spdk/nvmf_spec.h @@ -330,8 +330,7 @@ union spdk_nvmf_capsule_attr_hi { SPDK_STATIC_ASSERT(sizeof(union spdk_nvmf_capsule_attr_hi) == 4, "Incorrect size"); struct spdk_nvmf_ctrlr_properties { - union spdk_nvme_cap_lo_register cap_lo; - union spdk_nvme_cap_hi_register cap_hi; + union spdk_nvme_cap_register cap; uint32_t vs; uint32_t intms; @@ -360,7 +359,7 @@ struct spdk_nvmf_ctrlr_properties { uint8_t reserved5[0x2F0]; }; SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_ctrlr_properties) == 4864, "Incorrect size"); -SPDK_STATIC_ASSERT(SPDK_NVMF_PROP_CAP_OFST == offsetof(struct spdk_nvmf_ctrlr_properties, cap_lo), +SPDK_STATIC_ASSERT(SPDK_NVMF_PROP_CAP_OFST == offsetof(struct spdk_nvmf_ctrlr_properties, cap), "Incorrect register offset"); SPDK_STATIC_ASSERT(SPDK_NVMF_PROP_VS_OFST == offsetof(struct spdk_nvmf_ctrlr_properties, vs), "Incorrect register offset"); diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 85512b922..381c46597 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -346,7 +346,7 @@ static int nvme_ctrlr_construct_io_qpairs(struct spdk_nvme_ctrlr *ctrlr) { struct spdk_nvme_qpair *qpair; - union spdk_nvme_cap_lo_register cap_lo; + union spdk_nvme_cap_register cap; uint32_t i, num_entries, num_trackers; int rc; @@ -365,8 +365,8 @@ nvme_ctrlr_construct_io_qpairs(struct spdk_nvme_ctrlr *ctrlr) * devices may specify a smaller limit, so we need to check * the MQES field in the capabilities register. */ - cap_lo.raw = nvme_mmio_read_4(ctrlr, cap_lo.raw); - num_entries = nvme_min(NVME_IO_ENTRIES, cap_lo.bits.mqes + 1); + cap.raw = nvme_mmio_read_8(ctrlr, cap.raw); + num_entries = nvme_min(NVME_IO_ENTRIES, cap.bits.mqes + 1); /* * No need to have more trackers than entries in the submit queue. @@ -450,7 +450,7 @@ nvme_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr) { union spdk_nvme_cc_register cc; union spdk_nvme_aqa_register aqa; - union spdk_nvme_cap_lo_register cap_lo; + union spdk_nvme_cap_register cap; cc.raw = nvme_mmio_read_4(ctrlr, cc.raw); @@ -477,18 +477,18 @@ nvme_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr) /* Page size is 2 ^ (12 + mps). */ cc.bits.mps = nvme_u32log2(PAGE_SIZE) - 12; - cap_lo.raw = nvme_mmio_read_4(ctrlr, cap_lo.raw); + cap.raw = nvme_mmio_read_8(ctrlr, cap.raw); switch (ctrlr->opts.arb_mechanism) { case SPDK_NVME_CC_AMS_RR: break; case SPDK_NVME_CC_AMS_WRR: - if (SPDK_NVME_CAP_AMS_WRR & cap_lo.bits.ams) { + if (SPDK_NVME_CAP_AMS_WRR & cap.bits.ams) { break; } return -EINVAL; case SPDK_NVME_CC_AMS_VS: - if (SPDK_NVME_CAP_AMS_VS & cap_lo.bits.ams) { + if (SPDK_NVME_CAP_AMS_VS & cap.bits.ams) { break; } return -EINVAL; @@ -818,15 +818,15 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr) { union spdk_nvme_cc_register cc; union spdk_nvme_csts_register csts; - union spdk_nvme_cap_lo_register cap_lo; + union spdk_nvme_cap_register cap; uint32_t ready_timeout_in_ms; int rc; cc.raw = nvme_mmio_read_4(ctrlr, cc.raw); csts.raw = nvme_mmio_read_4(ctrlr, csts.raw); - cap_lo.raw = nvme_mmio_read_4(ctrlr, cap_lo.raw); + cap.raw = nvme_mmio_read_8(ctrlr, cap.raw); - ready_timeout_in_ms = 500 * cap_lo.bits.to; + ready_timeout_in_ms = 500 * cap.bits.to; /* * Check if the current initialization step is done or has timed out. @@ -1080,7 +1080,7 @@ nvme_ctrlr_free_bars(struct spdk_nvme_ctrlr *ctrlr) int nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr, void *devhandle) { - union spdk_nvme_cap_hi_register cap_hi; + union spdk_nvme_cap_register cap; uint32_t cmd_reg; int status; int rc; @@ -1099,13 +1099,13 @@ nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr, void *devhandle) cmd_reg |= 0x4; nvme_pcicfg_write32(devhandle, cmd_reg, 4); - cap_hi.raw = nvme_mmio_read_4(ctrlr, cap_hi.raw); + cap.raw = nvme_mmio_read_8(ctrlr, cap.raw); /* Doorbell stride is 2 ^ (dstrd + 2), * but we want multiples of 4, so drop the + 2 */ - ctrlr->doorbell_stride_u32 = 1 << cap_hi.bits.dstrd; + ctrlr->doorbell_stride_u32 = 1 << cap.bits.dstrd; - ctrlr->min_page_size = 1 << (12 + cap_hi.bits.mpsmin); + ctrlr->min_page_size = 1 << (12 + cap.bits.mpsmin); rc = nvme_ctrlr_construct_admin_qpair(ctrlr); if (rc) diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index 572df8d08..d01affd10 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -473,6 +473,9 @@ extern struct nvme_driver g_nvme_driver; #define nvme_mmio_read_4(sc, reg) \ spdk_mmio_read_4(&(sc)->regs->reg) +#define nvme_mmio_read_8(sc, reg) \ + spdk_mmio_read_8(&(sc)->regs->reg) + #define nvme_mmio_write_4(sc, reg, val) \ spdk_mmio_write_4(&(sc)->regs->reg, val) diff --git a/lib/nvmf/conn.c b/lib/nvmf/conn.c index 869d39c28..3e7d005ed 100644 --- a/lib/nvmf/conn.c +++ b/lib/nvmf/conn.c @@ -353,7 +353,7 @@ nvmf_init_conn_properites(struct spdk_nvmf_conn *conn, */ /* reset mdts in vcdata to equal the application default maximum */ mdts = SPDK_NVMF_MAX_RECV_DATA_TRANSFER_SIZE / - (1 << (12 + session->vcprop.cap_hi.bits.mpsmin)); + (1 << (12 + session->vcprop.cap.bits.mpsmin)); if (mdts == 0) { SPDK_ERRLOG("Min page size exceeds max transfer size!\n"); SPDK_ERRLOG("Verify setting of SPDK_NVMF_MAX_RECV_DATA_TRANSFER_SIZE and mpsmin\n"); diff --git a/lib/nvmf/session.c b/lib/nvmf/session.c index 02029a8ee..20ce714bf 100644 --- a/lib/nvmf/session.c +++ b/lib/nvmf/session.c @@ -102,16 +102,14 @@ nvmf_init_discovery_session_properties(struct nvmf_session *session) session->vcdata.sgls.sgl_offset = 1; /* Properties */ - session->vcprop.cap_lo.raw = 0; - session->vcprop.cap_lo.bits.cqr = 1; /* NVMF specification required */ - session->vcprop.cap_lo.bits.mqes = (session->vcdata.maxcmd - 1); /* max queue depth */ - session->vcprop.cap_lo.bits.ams = 0; /* optional arb mechanisms */ - - session->vcprop.cap_hi.raw = 0; - session->vcprop.cap_hi.bits.dstrd = 0; /* fixed to 0 for NVMf */ - session->vcprop.cap_hi.bits.css_nvm = 1; /* NVM command set */ - session->vcprop.cap_hi.bits.mpsmin = 0; /* 2 ^ 12 + mpsmin == 4k */ - session->vcprop.cap_hi.bits.mpsmax = 0; /* 2 ^ 12 + mpsmax == 4k */ + session->vcprop.cap.raw = 0; + session->vcprop.cap.bits.cqr = 1; /* NVMF specification required */ + session->vcprop.cap.bits.mqes = (session->vcdata.maxcmd - 1); /* max queue depth */ + session->vcprop.cap.bits.ams = 0; /* optional arb mechanisms */ + session->vcprop.cap.bits.dstrd = 0; /* fixed to 0 for NVMf */ + session->vcprop.cap.bits.css_nvm = 1; /* NVM command set */ + session->vcprop.cap.bits.mpsmin = 0; /* 2 ^ 12 + mpsmin == 4k */ + session->vcprop.cap.bits.mpsmax = 0; /* 2 ^ 12 + mpsmax == 4k */ session->vcprop.vs = 0x10000; /* Version Supported: Major 1, Minor 0 */ @@ -180,17 +178,15 @@ nvmf_init_nvme_session_properties(struct nvmf_session *session, int aq_depth) /* feature: Number Of Queues. */ session->max_io_queues = MAX_SESSION_IO_QUEUES; - session->vcprop.cap_lo.raw = 0; - session->vcprop.cap_lo.bits.cqr = 0; /* queues not contiguous */ - session->vcprop.cap_lo.bits.mqes = (session->vcdata.maxcmd - 1); /* max queue depth */ - session->vcprop.cap_lo.bits.ams = 0; /* optional arb mechanisms */ - session->vcprop.cap_lo.bits.to = 1; /* ready timeout - 500 msec units */ - - session->vcprop.cap_hi.raw = 0; - session->vcprop.cap_hi.bits.dstrd = 0; /* fixed to 0 for NVMf */ - session->vcprop.cap_hi.bits.css_nvm = 1; /* NVM command set */ - session->vcprop.cap_hi.bits.mpsmin = 0; /* 2 ^ 12 + mpsmin == 4k */ - session->vcprop.cap_hi.bits.mpsmax = 0; /* 2 ^ 12 + mpsmax == 4k */ + session->vcprop.cap.raw = 0; + session->vcprop.cap.bits.cqr = 0; /* queues not contiguous */ + session->vcprop.cap.bits.mqes = (session->vcdata.maxcmd - 1); /* max queue depth */ + session->vcprop.cap.bits.ams = 0; /* optional arb mechanisms */ + session->vcprop.cap.bits.to = 1; /* ready timeout - 500 msec units */ + session->vcprop.cap.bits.dstrd = 0; /* fixed to 0 for NVMf */ + session->vcprop.cap.bits.css_nvm = 1; /* NVM command set */ + session->vcprop.cap.bits.mpsmin = 0; /* 2 ^ 12 + mpsmin == 4k */ + session->vcprop.cap.bits.mpsmax = 0; /* 2 ^ 12 + mpsmax == 4k */ session->vcprop.vs = 0x10000; /* Version Supported: Major 1, Minor 0 */ @@ -213,10 +209,8 @@ nvmf_init_nvme_session_properties(struct nvmf_session *session, int aq_depth) SPDK_TRACELOG(SPDK_TRACE_NVMF, " nvmf_init_session_properties: max io queues %x\n", session->max_io_queues); - SPDK_TRACELOG(SPDK_TRACE_NVMF, " nvmf_init_session_properties: cap_lo %x\n", - session->vcprop.cap_lo.raw); - SPDK_TRACELOG(SPDK_TRACE_NVMF, " nvmf_init_session_properties: cap_hi %x\n", - session->vcprop.cap_hi.raw); + SPDK_TRACELOG(SPDK_TRACE_NVMF, " nvmf_init_session_properties: cap %" PRIx64 "\n", + session->vcprop.cap.raw); SPDK_TRACELOG(SPDK_TRACE_NVMF, " nvmf_init_session_properties: vs %x\n", session->vcprop.vs); SPDK_TRACELOG(SPDK_TRACE_NVMF, " nvmf_init_session_properties: cc %x\n", session->vcprop.cc.raw); SPDK_TRACELOG(SPDK_TRACE_NVMF, " nvmf_init_session_properties: csts %x\n", @@ -406,16 +400,16 @@ nvmf_property_get(struct nvmf_session *session, } switch (cmd->ofst) { - case (offsetof(struct spdk_nvmf_ctrlr_properties, cap_lo)): - response->value.u32.low = session->vcprop.cap_lo.raw; + case (offsetof(struct spdk_nvmf_ctrlr_properties, cap)): + response->value.u32.low = session->vcprop.cap.raw; if (cmd->attrib == 1) - response->value.u32.high = session->vcprop.cap_hi.raw; + response->value.u64 = session->vcprop.cap.raw; break; - case (offsetof(struct spdk_nvmf_ctrlr_properties, cap_hi)): + case (offsetof(struct spdk_nvmf_ctrlr_properties, cap) + 4): if (cmd->attrib == 1) response->status.sc = SPDK_NVMF_FABRIC_SC_INVALID_PARAM; else - response->value.u32.low = session->vcprop.cap_hi.raw; + response->value.u32.low = session->vcprop.cap.raw >> 32; break; case (offsetof(struct spdk_nvmf_ctrlr_properties, vs)): if (cmd->attrib == 1) diff --git a/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c b/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c index 21018ce26..2dcc10a23 100644 --- a/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c +++ b/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c @@ -425,7 +425,7 @@ test_nvme_ctrlr_init_en_0_rdy_0_ams_rr(void) /* * Default round robin enabled */ - g_ut_nvme_regs.cap_lo.bits.ams = 0x0; + g_ut_nvme_regs.cap.bits.ams = 0x0; SPDK_CU_ASSERT_FATAL(nvme_ctrlr_construct(&ctrlr, NULL) == 0); ctrlr.cdata.nn = 1; @@ -543,7 +543,7 @@ test_nvme_ctrlr_init_en_0_rdy_0_ams_wrr(void) /* * Weighted round robin enabled */ - g_ut_nvme_regs.cap_lo.bits.ams = SPDK_NVME_CAP_AMS_WRR; + g_ut_nvme_regs.cap.bits.ams = SPDK_NVME_CAP_AMS_WRR; SPDK_CU_ASSERT_FATAL(nvme_ctrlr_construct(&ctrlr, NULL) == 0); ctrlr.cdata.nn = 1; @@ -662,7 +662,7 @@ test_nvme_ctrlr_init_en_0_rdy_0_ams_vs(void) /* * Default round robin enabled */ - g_ut_nvme_regs.cap_lo.bits.ams = SPDK_NVME_CAP_AMS_VS; + g_ut_nvme_regs.cap.bits.ams = SPDK_NVME_CAP_AMS_VS; SPDK_CU_ASSERT_FATAL(nvme_ctrlr_construct(&ctrlr, NULL) == 0); ctrlr.cdata.nn = 1;