Commit 0e93df5c authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

nvme: combine CAP register into one 64-bit union



Previously, we used cap_lo and cap_hi to represent the 32-bit halves of
the full CAP register.  However, it is simpler to keep them in a single
64-bit structure, and is no less efficient on 64-bit platforms.

Also name the NSSRS field from NVMe 1.2, which was previously reserved.

Change-Id: I1d5d9b0dccbb12373b4aed3db29c883881d43223
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 80c350ed
Loading
Loading
Loading
Loading
+8 −14
Original line number Diff line number Diff line
@@ -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),
+2 −3
Original line number Diff line number Diff line
@@ -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");
+14 −14
Original line number Diff line number Diff line
@@ -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)
+3 −0
Original line number Diff line number Diff line
@@ -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)

+1 −1
Original line number Diff line number Diff line
@@ -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");
Loading