nvmet: expose firmware revision to configfs
Allow user to set currently active firmware revision Reviewed-by: Konstantin Shelekhin <k.shelekhin@yadro.com> Reviewed-by: Dmitriy Bogdanov <d.bogdanov@yadro.com> Signed-off-by: Aleksandr Miloserdov <a.miloserdov@yadro.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
23855abdc4
commit
68c5444c31
|
@ -370,7 +370,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
|
|||
memcpy_and_pad(id->mn, sizeof(id->mn), subsys->model_number,
|
||||
strlen(subsys->model_number), ' ');
|
||||
memcpy_and_pad(id->fr, sizeof(id->fr),
|
||||
UTS_RELEASE, strlen(UTS_RELEASE), ' ');
|
||||
subsys->firmware_rev, strlen(subsys->firmware_rev), ' ');
|
||||
|
||||
put_unaligned_le24(subsys->ieee_oui, id->ieee);
|
||||
|
||||
|
|
|
@ -1307,6 +1307,68 @@ static ssize_t nvmet_subsys_attr_ieee_oui_store(struct config_item *item,
|
|||
}
|
||||
CONFIGFS_ATTR(nvmet_subsys_, attr_ieee_oui);
|
||||
|
||||
static ssize_t nvmet_subsys_attr_firmware_show(struct config_item *item,
|
||||
char *page)
|
||||
{
|
||||
struct nvmet_subsys *subsys = to_subsys(item);
|
||||
|
||||
return sysfs_emit(page, "%s\n", subsys->firmware_rev);
|
||||
}
|
||||
|
||||
static ssize_t nvmet_subsys_attr_firmware_store_locked(struct nvmet_subsys *subsys,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
int pos = 0, len;
|
||||
char *val;
|
||||
|
||||
if (subsys->subsys_discovered) {
|
||||
pr_err("Can't set firmware revision. %s is already assigned\n",
|
||||
subsys->firmware_rev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
len = strcspn(page, "\n");
|
||||
if (!len)
|
||||
return -EINVAL;
|
||||
|
||||
if (len > NVMET_FR_MAX_SIZE) {
|
||||
pr_err("Firmware revision size can not exceed %d Bytes\n",
|
||||
NVMET_FR_MAX_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (pos = 0; pos < len; pos++) {
|
||||
if (!nvmet_is_ascii(page[pos]))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
val = kmemdup_nul(page, len, GFP_KERNEL);
|
||||
if (!val)
|
||||
return -ENOMEM;
|
||||
|
||||
kfree(subsys->firmware_rev);
|
||||
|
||||
subsys->firmware_rev = val;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t nvmet_subsys_attr_firmware_store(struct config_item *item,
|
||||
const char *page, size_t count)
|
||||
{
|
||||
struct nvmet_subsys *subsys = to_subsys(item);
|
||||
ssize_t ret;
|
||||
|
||||
down_write(&nvmet_config_sem);
|
||||
mutex_lock(&subsys->lock);
|
||||
ret = nvmet_subsys_attr_firmware_store_locked(subsys, page, count);
|
||||
mutex_unlock(&subsys->lock);
|
||||
up_write(&nvmet_config_sem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
CONFIGFS_ATTR(nvmet_subsys_, attr_firmware);
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INTEGRITY
|
||||
static ssize_t nvmet_subsys_attr_pi_enable_show(struct config_item *item,
|
||||
char *page)
|
||||
|
@ -1369,6 +1431,7 @@ static struct configfs_attribute *nvmet_subsys_attrs[] = {
|
|||
&nvmet_subsys_attr_attr_model,
|
||||
&nvmet_subsys_attr_attr_qid_max,
|
||||
&nvmet_subsys_attr_attr_ieee_oui,
|
||||
&nvmet_subsys_attr_attr_firmware,
|
||||
#ifdef CONFIG_BLK_DEV_INTEGRITY
|
||||
&nvmet_subsys_attr_attr_pi_enable,
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <linux/pci-p2pdma.h>
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
#include <generated/utsrelease.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "trace.h"
|
||||
|
||||
|
@ -1563,6 +1565,12 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn,
|
|||
|
||||
subsys->ieee_oui = 0;
|
||||
|
||||
subsys->firmware_rev = kstrndup(UTS_RELEASE, NVMET_FR_MAX_SIZE, GFP_KERNEL);
|
||||
if (!subsys->firmware_rev) {
|
||||
ret = -ENOMEM;
|
||||
goto free_mn;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case NVME_NQN_NVME:
|
||||
subsys->max_qid = NVMET_NR_QUEUES;
|
||||
|
@ -1574,14 +1582,14 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn,
|
|||
default:
|
||||
pr_err("%s: Unknown Subsystem type - %d\n", __func__, type);
|
||||
ret = -EINVAL;
|
||||
goto free_mn;
|
||||
goto free_fr;
|
||||
}
|
||||
subsys->type = type;
|
||||
subsys->subsysnqn = kstrndup(subsysnqn, NVMF_NQN_SIZE,
|
||||
GFP_KERNEL);
|
||||
if (!subsys->subsysnqn) {
|
||||
ret = -ENOMEM;
|
||||
goto free_mn;
|
||||
goto free_fr;
|
||||
}
|
||||
subsys->cntlid_min = NVME_CNTLID_MIN;
|
||||
subsys->cntlid_max = NVME_CNTLID_MAX;
|
||||
|
@ -1594,6 +1602,8 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn,
|
|||
|
||||
return subsys;
|
||||
|
||||
free_fr:
|
||||
kfree(subsys->firmware_rev);
|
||||
free_mn:
|
||||
kfree(subsys->model_number);
|
||||
free_subsys:
|
||||
|
@ -1613,6 +1623,7 @@ static void nvmet_subsys_free(struct kref *ref)
|
|||
|
||||
kfree(subsys->subsysnqn);
|
||||
kfree(subsys->model_number);
|
||||
kfree(subsys->firmware_rev);
|
||||
kfree(subsys);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#define NVMET_DEFAULT_CTRL_MODEL "Linux"
|
||||
#define NVMET_MN_MAX_SIZE 40
|
||||
#define NVMET_SN_MAX_SIZE 20
|
||||
#define NVMET_FR_MAX_SIZE 8
|
||||
|
||||
/*
|
||||
* Supported optional AENs:
|
||||
|
@ -264,6 +265,7 @@ struct nvmet_subsys {
|
|||
|
||||
char *model_number;
|
||||
u32 ieee_oui;
|
||||
char *firmware_rev;
|
||||
|
||||
#ifdef CONFIG_NVME_TARGET_PASSTHRU
|
||||
struct nvme_ctrl *passthru_ctrl;
|
||||
|
|
Loading…
Reference in New Issue