Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 180de007 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

nvme: read the subsystem NQN from Identify Controller



NVMe 1.2.1 or later requires controllers to provide a subsystem NQN in the
Identify controller data structures.  Use this NQN for the subsysnqn
sysfs attribute by storing it in the nvme_ctrl structure after verifying
it.  For older controllers we generate a "fake" NQN per non-normative
text in the NVMe 1.3 spec.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarKeith Busch <keith.busch@intel.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: default avatarSagi Grimberg <sagi@grimberg.me>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 942fbab4
Loading
Loading
Loading
Loading
+28 −3
Original line number Diff line number Diff line
@@ -1705,6 +1705,31 @@ static bool quirk_matches(const struct nvme_id_ctrl *id,
		string_matches(id->fr, q->fr, sizeof(id->fr));
}

static void nvme_init_subnqn(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
{
	size_t nqnlen;
	int off;

	nqnlen = strnlen(id->subnqn, NVMF_NQN_SIZE);
	if (nqnlen > 0 && nqnlen < NVMF_NQN_SIZE) {
		strcpy(ctrl->subnqn, id->subnqn);
		return;
	}

	if (ctrl->vs >= NVME_VS(1, 2, 1))
		dev_warn(ctrl->device, "missing or invalid SUBNQN field.\n");

	/* Generate a "fake" NQN per Figure 254 in NVMe 1.3 + ECN 001 */
	off = snprintf(ctrl->subnqn, NVMF_NQN_SIZE,
			"nqn.2014.08.org.nvmexpress:%4x%4x",
			le16_to_cpu(id->vid), le16_to_cpu(id->ssvid));
	memcpy(ctrl->subnqn + off, id->sn, sizeof(id->sn));
	off += sizeof(id->sn);
	memcpy(ctrl->subnqn + off, id->mn, sizeof(id->mn));
	off += sizeof(id->mn);
	memset(ctrl->subnqn + off, 0, sizeof(ctrl->subnqn) - off);
}

/*
 * Initialize the cached copies of the Identify data and various controller
 * register in our nvme_ctrl structure.  This should be called as soon as
@@ -1740,6 +1765,8 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
		return -EIO;
	}

	nvme_init_subnqn(ctrl, id);

	if (!ctrl->identified) {
		/*
		 * Check for quirks.  Quirk can depend on firmware version,
@@ -2135,8 +2162,7 @@ static ssize_t nvme_sysfs_show_subsysnqn(struct device *dev,
{
	struct nvme_ctrl *ctrl = dev_get_drvdata(dev);

	return snprintf(buf, PAGE_SIZE, "%s\n",
			ctrl->ops->get_subsysnqn(ctrl));
	return snprintf(buf, PAGE_SIZE, "%s\n", ctrl->subnqn);
}
static DEVICE_ATTR(subsysnqn, S_IRUGO, nvme_sysfs_show_subsysnqn, NULL);

@@ -2181,7 +2207,6 @@ static umode_t nvme_dev_attrs_are_visible(struct kobject *kobj,
			return 0;
	}

	CHECK_ATTR(ctrl, a, subsysnqn);
	CHECK_ATTR(ctrl, a, address);

	return a->mode;
+0 −10
Original line number Diff line number Diff line
@@ -125,16 +125,6 @@ int nvmf_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
}
EXPORT_SYMBOL_GPL(nvmf_get_address);

/**
 * nvmf_get_subsysnqn() - Get subsystem NQN
 * @ctrl:	Host NVMe controller instance which we got the NQN
 */
const char *nvmf_get_subsysnqn(struct nvme_ctrl *ctrl)
{
	return ctrl->opts->subsysnqn;
}
EXPORT_SYMBOL_GPL(nvmf_get_subsysnqn);

/**
 * nvmf_reg_read32() -  NVMe Fabrics "Property Get" API function.
 * @ctrl:	Host NVMe controller instance maintaining the admin
+0 −1
Original line number Diff line number Diff line
@@ -139,7 +139,6 @@ int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid);
int nvmf_register_transport(struct nvmf_transport_ops *ops);
void nvmf_unregister_transport(struct nvmf_transport_ops *ops);
void nvmf_free_options(struct nvmf_ctrl_options *opts);
const char *nvmf_get_subsysnqn(struct nvme_ctrl *ctrl);
int nvmf_get_address(struct nvme_ctrl *ctrl, char *buf, int size);
bool nvmf_should_reconnect(struct nvme_ctrl *ctrl);

+0 −1
Original line number Diff line number Diff line
@@ -2631,7 +2631,6 @@ static const struct nvme_ctrl_ops nvme_fc_ctrl_ops = {
	.free_ctrl		= nvme_fc_nvme_ctrl_freed,
	.submit_async_event	= nvme_fc_submit_async_event,
	.delete_ctrl		= nvme_fc_del_nvme_ctrl,
	.get_subsysnqn		= nvmf_get_subsysnqn,
	.get_address		= nvmf_get_address,
};

+1 −1
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ struct nvme_ctrl {
	char serial[20];
	char model[40];
	char firmware_rev[8];
	char subnqn[NVMF_NQN_SIZE];
	u16 cntlid;

	u32 ctrl_config;
@@ -225,7 +226,6 @@ struct nvme_ctrl_ops {
	void (*free_ctrl)(struct nvme_ctrl *ctrl);
	void (*submit_async_event)(struct nvme_ctrl *ctrl, int aer_idx);
	int (*delete_ctrl)(struct nvme_ctrl *ctrl);
	const char *(*get_subsysnqn)(struct nvme_ctrl *ctrl);
	int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
};

Loading