nvmet: allow overriding the NVMe VS via configfs
authorJohannes Thumshirn <jthumshirn@suse.de>
Wed, 7 Jun 2017 09:45:36 +0000 (11:45 +0200)
committerChristoph Hellwig <hch@lst.de>
Thu, 15 Jun 2017 12:30:23 +0000 (14:30 +0200)
Allow overriding the announced NVMe Version of a via configfs.

This is particularly helpful when debugging new features for the host
or target side without bumping the hard coded version (as the target
might not be fully compliant to the announced version yet).

Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Guan Junxiong <guanjunxiong@huawei.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/nvme/target/configfs.c
include/linux/nvme.h

index 83bfe28fe7da66762bd80ff7ccb4d319528c3d41..a358ecd93e110bcbc0331fc77ad22303c0099876 100644 (file)
@@ -650,8 +650,45 @@ out_unlock:
 
 CONFIGFS_ATTR(nvmet_subsys_, attr_allow_any_host);
 
+static ssize_t nvmet_subsys_version_show(struct config_item *item,
+                                             char *page)
+{
+       struct nvmet_subsys *subsys = to_subsys(item);
+
+       if (NVME_TERTIARY(subsys->ver))
+               return snprintf(page, PAGE_SIZE, "%d.%d.%d\n",
+                               (int)NVME_MAJOR(subsys->ver),
+                               (int)NVME_MINOR(subsys->ver),
+                               (int)NVME_TERTIARY(subsys->ver));
+       else
+               return snprintf(page, PAGE_SIZE, "%d.%d\n",
+                               (int)NVME_MAJOR(subsys->ver),
+                               (int)NVME_MINOR(subsys->ver));
+}
+
+static ssize_t nvmet_subsys_version_store(struct config_item *item,
+                                              const char *page, size_t count)
+{
+       struct nvmet_subsys *subsys = to_subsys(item);
+       int major, minor, tertiary = 0;
+       int ret;
+
+
+       ret = sscanf(page, "%d.%d.%d\n", &major, &minor, &tertiary);
+       if (ret != 2 && ret != 3)
+               return -EINVAL;
+
+       down_write(&nvmet_config_sem);
+       subsys->ver = NVME_VS(major, minor, tertiary);
+       up_write(&nvmet_config_sem);
+
+       return count;
+}
+CONFIGFS_ATTR(nvmet_subsys_, version);
+
 static struct configfs_attribute *nvmet_subsys_attrs[] = {
        &nvmet_subsys_attr_attr_allow_any_host,
+       &nvmet_subsys_attr_version,
        NULL,
 };
 
index f2344aa923e867782c4d20e882e3cd21e732a887..acb484935603b1ae3b379cd6f762c843364b6f0b 100644 (file)
@@ -1085,4 +1085,8 @@ struct nvme_completion {
 #define NVME_VS(major, minor, tertiary) \
        (((major) << 16) | ((minor) << 8) | (tertiary))
 
+#define NVME_MAJOR(ver)                ((ver) >> 16)
+#define NVME_MINOR(ver)                (((ver) >> 8) & 0xff)
+#define NVME_TERTIARY(ver)     ((ver) & 0xff)
+
 #endif /* _LINUX_NVME_H */