diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 5f885e0ab930..efaddab8296e 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -596,6 +596,7 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, case NVME_CTRL_NEW: case NVME_CTRL_LIVE: changed = true; + atomic_long_inc(&ctrl->nr_reset); fallthrough; default: break; diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 249f1f8dde40..81f297e995e4 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -416,6 +416,7 @@ struct nvme_ctrl { struct work_struct fw_act_work; unsigned long events; atomic_long_t errors; + atomic_long_t nr_reset; #ifdef CONFIG_NVME_MULTIPATH /* asymmetric namespace access: */ diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c index d2c7d943b23f..ff603a9d7b8c 100644 --- a/drivers/nvme/host/sysfs.c +++ b/drivers/nvme/host/sysfs.c @@ -1151,8 +1151,35 @@ struct device_attribute dev_attr_adm_errors = __ATTR(command_error_count, 0644, nvme_adm_errors_show, nvme_adm_errors_store); +static ssize_t reset_count_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvme_ctrl *ctrl = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%lu\n", atomic_long_read(&ctrl->nr_reset)); +} + +static ssize_t reset_count_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int err; + unsigned long reset_cnt; + struct nvme_ctrl *ctrl = dev_get_drvdata(dev); + + err = kstrtoul(buf, 0, &reset_cnt); + if (err) + return -EINVAL; + + atomic_long_set(&ctrl->nr_reset, reset_cnt); + + return count; +} + +static DEVICE_ATTR_RW(reset_count); + static struct attribute *nvme_dev_diag_attrs[] = { &dev_attr_adm_errors.attr, + &dev_attr_reset_count.attr, NULL, };