nfit, libnvdimm: deprecate the generic SMART ioctl
authorDan Williams <dan.j.williams@intel.com>
Sat, 18 Nov 2017 00:23:08 +0000 (16:23 -0800)
committerDan Williams <dan.j.williams@intel.com>
Mon, 4 Dec 2017 18:19:20 +0000 (10:19 -0800)
The kernel's ND_IOCTL_SMART_THRESHOLD command is based on a payload
definition that has become broken / out-of-sync with recent versions of
the NVDIMM_FAMILY_INTEL definition. Deprecate the use of the
ND_IOCTL_SMART_THRESHOLD command in favor of the ND_CMD_CALL approach
taken by NVDIMM_FAMILY_{HPE,MSFT}, where we can manage the per-vendor
variance in userspace.

In a couple years, when the new scheme is widely deployed in userspace
packages, the ND_IOCTL_SMART_THRESHOLD support can be removed. For now
we prevent new binaries from compiling against the kernel header
definitions, but kernel still compatible with old binaries. The
libndctl.h [1] header is now the authoritative interface definition for
NVDIMM SMART.

[1]: https://github.com/pmem/ndctl
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/nvdimm/bus.c
include/uapi/linux/ndctl.h
tools/testing/nvdimm/test/nfit.c
tools/testing/nvdimm/test/nfit_test.h

index 0a5e6cd758fe3fcef15aa38332cd5673e4de29d3..78eabc3a1ab1337b68aef7b427c1ee59f570438c 100644 (file)
@@ -1142,9 +1142,6 @@ int __init nvdimm_bus_init(void)
 {
        int rc;
 
-       BUILD_BUG_ON(sizeof(struct nd_smart_payload) != 128);
-       BUILD_BUG_ON(sizeof(struct nd_smart_threshold_payload) != 8);
-
        rc = bus_register(&nvdimm_bus_type);
        if (rc)
                return rc;
index 3f03567631cb092dc8f51aae740dd2a3472730e9..30ef1236aafa6e0345775f9edab56c5c929e06f0 100644 (file)
 
 #include <linux/types.h>
 
-struct nd_cmd_smart {
-       __u32 status;
-       __u8 data[128];
-} __packed;
-
-#define ND_SMART_HEALTH_VALID  (1 << 0)
-#define ND_SMART_SPARES_VALID  (1 << 1)
-#define ND_SMART_USED_VALID    (1 << 2)
-#define ND_SMART_TEMP_VALID    (1 << 3)
-#define ND_SMART_CTEMP_VALID   (1 << 4)
-#define ND_SMART_ALARM_VALID   (1 << 9)
-#define ND_SMART_SHUTDOWN_VALID        (1 << 10)
-#define ND_SMART_VENDOR_VALID  (1 << 11)
-#define ND_SMART_SPARE_TRIP    (1 << 0)
-#define ND_SMART_TEMP_TRIP     (1 << 1)
-#define ND_SMART_CTEMP_TRIP    (1 << 2)
-#define ND_SMART_NON_CRITICAL_HEALTH   (1 << 0)
-#define ND_SMART_CRITICAL_HEALTH       (1 << 1)
-#define ND_SMART_FATAL_HEALTH          (1 << 2)
-
-struct nd_smart_payload {
-       __u32 flags;
-       __u8 reserved0[4];
-       __u8 health;
-       __u8 spares;
-       __u8 life_used;
-       __u8 alarm_flags;
-       __u16 temperature;
-       __u16 ctrl_temperature;
-       __u8 reserved1[15];
-       __u8 shutdown_state;
-       __u32 vendor_size;
-       __u8 vendor_data[92];
-} __packed;
-
-struct nd_cmd_smart_threshold {
-       __u32 status;
-       __u8 data[8];
-} __packed;
-
-struct nd_smart_threshold_payload {
-       __u8 alarm_control;
-       __u8 reserved0;
-       __u16 temperature;
-       __u8 spares;
-       __u8 reserved[3];
-} __packed;
-
 struct nd_cmd_dimm_flags {
        __u32 status;
        __u32 flags;
@@ -211,12 +163,6 @@ static inline const char *nvdimm_cmd_name(unsigned cmd)
 
 #define ND_IOCTL 'N'
 
-#define ND_IOCTL_SMART                 _IOWR(ND_IOCTL, ND_CMD_SMART,\
-                                       struct nd_cmd_smart)
-
-#define ND_IOCTL_SMART_THRESHOLD       _IOWR(ND_IOCTL, ND_CMD_SMART_THRESHOLD,\
-                                       struct nd_cmd_smart_threshold)
-
 #define ND_IOCTL_DIMM_FLAGS            _IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS,\
                                        struct nd_cmd_dimm_flags)
 
index 7217b2b953b588a662d287d83a1e7e8920ebca59..640c02b08a5025712521025a759099cab6bff42c 100644 (file)
@@ -440,39 +440,50 @@ static int nfit_test_cmd_translate_spa(struct nvdimm_bus *bus,
        return 0;
 }
 
-static int nfit_test_cmd_smart(struct nd_cmd_smart *smart, unsigned int buf_len)
+static int nfit_test_cmd_smart(struct nd_intel_smart *smart, unsigned int buf_len)
 {
-       static const struct nd_smart_payload smart_data = {
-               .flags = ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID
-                       | ND_SMART_SPARES_VALID | ND_SMART_ALARM_VALID
-                       | ND_SMART_USED_VALID | ND_SMART_SHUTDOWN_VALID,
-               .health = ND_SMART_NON_CRITICAL_HEALTH,
-               .temperature = 23 * 16,
+       static const struct nd_intel_smart smart_data = {
+               .flags = ND_INTEL_SMART_HEALTH_VALID
+                       | ND_INTEL_SMART_SPARES_VALID
+                       | ND_INTEL_SMART_ALARM_VALID
+                       | ND_INTEL_SMART_USED_VALID
+                       | ND_INTEL_SMART_SHUTDOWN_VALID
+                       | ND_INTEL_SMART_MTEMP_VALID,
+               .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH,
+               .media_temperature = 23 * 16,
+               .ctrl_temperature = 30 * 16,
+               .pmic_temperature = 40 * 16,
                .spares = 75,
-               .alarm_flags = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
+               .alarm_flags = ND_INTEL_SMART_SPARE_TRIP
+                       | ND_INTEL_SMART_TEMP_TRIP,
+               .ait_status = 1,
                .life_used = 5,
                .shutdown_state = 0,
                .vendor_size = 0,
+               .shutdown_count = 100,
        };
 
        if (buf_len < sizeof(*smart))
                return -EINVAL;
-       memcpy(smart->data, &smart_data, sizeof(smart_data));
+       memcpy(smart, &smart_data, sizeof(smart_data));
        return 0;
 }
 
-static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold *smart_t,
+static int nfit_test_cmd_smart_threshold(
+               struct nd_intel_smart_threshold *smart_t,
                unsigned int buf_len)
 {
-       static const struct nd_smart_threshold_payload smart_t_data = {
-               .alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
-               .temperature = 40 * 16,
+       static const struct nd_intel_smart_threshold smart_t_data = {
+               .alarm_control = ND_INTEL_SMART_SPARE_TRIP
+                       | ND_INTEL_SMART_TEMP_TRIP,
+               .media_temperature = 40 * 16,
+               .ctrl_temperature = 30 * 16,
                .spares = 5,
        };
 
        if (buf_len < sizeof(*smart_t))
                return -EINVAL;
-       memcpy(smart_t->data, &smart_t_data, sizeof(smart_t_data));
+       memcpy(smart_t, &smart_t_data, sizeof(smart_t_data));
        return 0;
 }
 
index 113b44675a71860548e21cd77148f4a5dea03f32..b85fba2856c7cff550d1c76a05d46830c7036d08 100644 (file)
@@ -84,6 +84,65 @@ struct nd_cmd_ars_err_inj_stat {
        } __packed record[0];
 } __packed;
 
+#define ND_INTEL_SMART 1
+#define ND_INTEL_SMART_THRESHOLD 2
+
+#define ND_INTEL_SMART_HEALTH_VALID             (1 << 0)
+#define ND_INTEL_SMART_SPARES_VALID             (1 << 1)
+#define ND_INTEL_SMART_USED_VALID               (1 << 2)
+#define ND_INTEL_SMART_MTEMP_VALID              (1 << 3)
+#define ND_INTEL_SMART_CTEMP_VALID              (1 << 4)
+#define ND_INTEL_SMART_SHUTDOWN_COUNT_VALID     (1 << 5)
+#define ND_INTEL_SMART_AIT_STATUS_VALID         (1 << 6)
+#define ND_INTEL_SMART_PTEMP_VALID              (1 << 7)
+#define ND_INTEL_SMART_ALARM_VALID              (1 << 9)
+#define ND_INTEL_SMART_SHUTDOWN_VALID           (1 << 10)
+#define ND_INTEL_SMART_VENDOR_VALID             (1 << 11)
+#define ND_INTEL_SMART_SPARE_TRIP               (1 << 0)
+#define ND_INTEL_SMART_TEMP_TRIP                (1 << 1)
+#define ND_INTEL_SMART_CTEMP_TRIP               (1 << 2)
+#define ND_INTEL_SMART_NON_CRITICAL_HEALTH      (1 << 0)
+#define ND_INTEL_SMART_CRITICAL_HEALTH          (1 << 1)
+#define ND_INTEL_SMART_FATAL_HEALTH             (1 << 2)
+
+struct nd_intel_smart {
+       __u32 status;
+       union {
+               struct {
+                       __u32 flags;
+                       __u8 reserved0[4];
+                       __u8 health;
+                       __u8 spares;
+                       __u8 life_used;
+                       __u8 alarm_flags;
+                       __u16 media_temperature;
+                       __u16 ctrl_temperature;
+                       __u32 shutdown_count;
+                       __u8 ait_status;
+                       __u16 pmic_temperature;
+                       __u8 reserved1[8];
+                       __u8 shutdown_state;
+                       __u32 vendor_size;
+                       __u8 vendor_data[92];
+               } __packed;
+               __u8 data[128];
+       };
+} __packed;
+
+struct nd_intel_smart_threshold {
+       __u32 status;
+       union {
+               struct {
+                       __u16 alarm_control;
+                       __u8 spares;
+                       __u16 media_temperature;
+                       __u16 ctrl_temperature;
+                       __u8 reserved[1];
+               } __packed;
+               __u8 data[8];
+       };
+} __packed;
+
 union acpi_object;
 typedef void *acpi_handle;