summaryrefslogtreecommitdiff
path: root/drivers/nvme/host/core.c
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2016-02-18 16:57:48 (GMT)
committerJens Axboe <axboe@fb.com>2016-03-16 14:46:25 (GMT)
commit118472ab8532e55f48395ef5764b354fe48b1d73 (patch)
treefd16dcee80675a6e96e043a8544696c4129bfefa /drivers/nvme/host/core.c
parent98347a7d8a93ef8a01c8d1946a2059f38f73b239 (diff)
downloadlinux-118472ab8532e55f48395ef5764b354fe48b1d73.tar.xz
NVMe: Expose ns wwid through single sysfs entry
The method to uniquely identify a namespace depends on the controller's specification revision level and implemented capabilities. This patch has the driver figure this out and exports the unique string through a single 'wwid' attribute so the user doesn't have this burden. The longest namespace unique identifier is used if available. If not available, the driver will concat the controller's vendor, serial, and model with the namespace ID. The specification provides this as a unique indentifier. Signed-off-by: Keith Busch <keith.busch@intel.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/nvme/host/core.c')
-rw-r--r--drivers/nvme/host/core.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 4304be0..266918b 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -915,6 +915,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
return -EIO;
}
+ ctrl->vid = le16_to_cpu(id->vid);
ctrl->oncs = le16_to_cpup(&id->oncs);
atomic_set(&ctrl->abort_limit, id->acl + 1);
ctrl->vwc = id->vwc;
@@ -1053,6 +1054,30 @@ static ssize_t nvme_sysfs_reset(struct device *dev,
}
static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset);
+static ssize_t wwid_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct nvme_ns *ns = dev_to_disk(dev)->private_data;
+ struct nvme_ctrl *ctrl = ns->ctrl;
+ int serial_len = sizeof(ctrl->serial);
+ int model_len = sizeof(ctrl->model);
+
+ if (memchr_inv(ns->uuid, 0, sizeof(ns->uuid)))
+ return sprintf(buf, "eui.%16phN\n", ns->uuid);
+
+ if (memchr_inv(ns->eui, 0, sizeof(ns->eui)))
+ return sprintf(buf, "eui.%8phN\n", ns->eui);
+
+ while (ctrl->serial[serial_len - 1] == ' ')
+ serial_len--;
+ while (ctrl->model[model_len - 1] == ' ')
+ model_len--;
+
+ return sprintf(buf, "nvme.%04x-%*phN-%*phN-%08x\n", ctrl->vid,
+ serial_len, ctrl->serial, model_len, ctrl->model, ns->ns_id);
+}
+static DEVICE_ATTR(wwid, S_IRUGO, wwid_show, NULL);
+
static ssize_t uuid_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -1078,6 +1103,7 @@ static ssize_t nsid_show(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(nsid, S_IRUGO, nsid_show, NULL);
static struct attribute *nvme_ns_attrs[] = {
+ &dev_attr_wwid.attr,
&dev_attr_uuid.attr,
&dev_attr_eui.attr,
&dev_attr_nsid.attr,