aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2017-11-17 19:23:08 -0500
committerDan Williams <dan.j.williams@intel.com>2017-12-04 13:19:20 -0500
commitcdd77d3e193031cc67426cd671d8aa370f7dfee4 (patch)
tree593f495eb83145d25e848a4a5c88bfb6f5509440
parentae64f9bd1d3621b5e60d7363bc20afb46aede215 (diff)
nfit, libnvdimm: deprecate the generic SMART ioctl
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>
-rw-r--r--drivers/nvdimm/bus.c3
-rw-r--r--include/uapi/linux/ndctl.h54
-rw-r--r--tools/testing/nvdimm/test/nfit.c39
-rw-r--r--tools/testing/nvdimm/test/nfit_test.h59
4 files changed, 84 insertions, 71 deletions
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index 0a5e6cd758fe..78eabc3a1ab1 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -1142,9 +1142,6 @@ int __init nvdimm_bus_init(void)
1142{ 1142{
1143 int rc; 1143 int rc;
1144 1144
1145 BUILD_BUG_ON(sizeof(struct nd_smart_payload) != 128);
1146 BUILD_BUG_ON(sizeof(struct nd_smart_threshold_payload) != 8);
1147
1148 rc = bus_register(&nvdimm_bus_type); 1145 rc = bus_register(&nvdimm_bus_type);
1149 if (rc) 1146 if (rc)
1150 return rc; 1147 return rc;
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index 3f03567631cb..30ef1236aafa 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -15,54 +15,6 @@
15 15
16#include <linux/types.h> 16#include <linux/types.h>
17 17
18struct nd_cmd_smart {
19 __u32 status;
20 __u8 data[128];
21} __packed;
22
23#define ND_SMART_HEALTH_VALID (1 << 0)
24#define ND_SMART_SPARES_VALID (1 << 1)
25#define ND_SMART_USED_VALID (1 << 2)
26#define ND_SMART_TEMP_VALID (1 << 3)
27#define ND_SMART_CTEMP_VALID (1 << 4)
28#define ND_SMART_ALARM_VALID (1 << 9)
29#define ND_SMART_SHUTDOWN_VALID (1 << 10)
30#define ND_SMART_VENDOR_VALID (1 << 11)
31#define ND_SMART_SPARE_TRIP (1 << 0)
32#define ND_SMART_TEMP_TRIP (1 << 1)
33#define ND_SMART_CTEMP_TRIP (1 << 2)
34#define ND_SMART_NON_CRITICAL_HEALTH (1 << 0)
35#define ND_SMART_CRITICAL_HEALTH (1 << 1)
36#define ND_SMART_FATAL_HEALTH (1 << 2)
37
38struct nd_smart_payload {
39 __u32 flags;
40 __u8 reserved0[4];
41 __u8 health;
42 __u8 spares;
43 __u8 life_used;
44 __u8 alarm_flags;
45 __u16 temperature;
46 __u16 ctrl_temperature;
47 __u8 reserved1[15];
48 __u8 shutdown_state;
49 __u32 vendor_size;
50 __u8 vendor_data[92];
51} __packed;
52
53struct nd_cmd_smart_threshold {
54 __u32 status;
55 __u8 data[8];
56} __packed;
57
58struct nd_smart_threshold_payload {
59 __u8 alarm_control;
60 __u8 reserved0;
61 __u16 temperature;
62 __u8 spares;
63 __u8 reserved[3];
64} __packed;
65
66struct nd_cmd_dimm_flags { 18struct nd_cmd_dimm_flags {
67 __u32 status; 19 __u32 status;
68 __u32 flags; 20 __u32 flags;
@@ -211,12 +163,6 @@ static inline const char *nvdimm_cmd_name(unsigned cmd)
211 163
212#define ND_IOCTL 'N' 164#define ND_IOCTL 'N'
213 165
214#define ND_IOCTL_SMART _IOWR(ND_IOCTL, ND_CMD_SMART,\
215 struct nd_cmd_smart)
216
217#define ND_IOCTL_SMART_THRESHOLD _IOWR(ND_IOCTL, ND_CMD_SMART_THRESHOLD,\
218 struct nd_cmd_smart_threshold)
219
220#define ND_IOCTL_DIMM_FLAGS _IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS,\ 166#define ND_IOCTL_DIMM_FLAGS _IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS,\
221 struct nd_cmd_dimm_flags) 167 struct nd_cmd_dimm_flags)
222 168
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 7217b2b953b5..640c02b08a50 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -440,39 +440,50 @@ static int nfit_test_cmd_translate_spa(struct nvdimm_bus *bus,
440 return 0; 440 return 0;
441} 441}
442 442
443static int nfit_test_cmd_smart(struct nd_cmd_smart *smart, unsigned int buf_len) 443static int nfit_test_cmd_smart(struct nd_intel_smart *smart, unsigned int buf_len)
444{ 444{
445 static const struct nd_smart_payload smart_data = { 445 static const struct nd_intel_smart smart_data = {
446 .flags = ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID 446 .flags = ND_INTEL_SMART_HEALTH_VALID
447 | ND_SMART_SPARES_VALID | ND_SMART_ALARM_VALID 447 | ND_INTEL_SMART_SPARES_VALID
448 | ND_SMART_USED_VALID | ND_SMART_SHUTDOWN_VALID, 448 | ND_INTEL_SMART_ALARM_VALID
449 .health = ND_SMART_NON_CRITICAL_HEALTH, 449 | ND_INTEL_SMART_USED_VALID
450 .temperature = 23 * 16, 450 | ND_INTEL_SMART_SHUTDOWN_VALID
451 | ND_INTEL_SMART_MTEMP_VALID,
452 .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH,
453 .media_temperature = 23 * 16,
454 .ctrl_temperature = 30 * 16,
455 .pmic_temperature = 40 * 16,
451 .spares = 75, 456 .spares = 75,
452 .alarm_flags = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP, 457 .alarm_flags = ND_INTEL_SMART_SPARE_TRIP
458 | ND_INTEL_SMART_TEMP_TRIP,
459 .ait_status = 1,
453 .life_used = 5, 460 .life_used = 5,
454 .shutdown_state = 0, 461 .shutdown_state = 0,
455 .vendor_size = 0, 462 .vendor_size = 0,
463 .shutdown_count = 100,
456 }; 464 };
457 465
458 if (buf_len < sizeof(*smart)) 466 if (buf_len < sizeof(*smart))
459 return -EINVAL; 467 return -EINVAL;
460 memcpy(smart->data, &smart_data, sizeof(smart_data)); 468 memcpy(smart, &smart_data, sizeof(smart_data));
461 return 0; 469 return 0;
462} 470}
463 471
464static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold *smart_t, 472static int nfit_test_cmd_smart_threshold(
473 struct nd_intel_smart_threshold *smart_t,
465 unsigned int buf_len) 474 unsigned int buf_len)
466{ 475{
467 static const struct nd_smart_threshold_payload smart_t_data = { 476 static const struct nd_intel_smart_threshold smart_t_data = {
468 .alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP, 477 .alarm_control = ND_INTEL_SMART_SPARE_TRIP
469 .temperature = 40 * 16, 478 | ND_INTEL_SMART_TEMP_TRIP,
479 .media_temperature = 40 * 16,
480 .ctrl_temperature = 30 * 16,
470 .spares = 5, 481 .spares = 5,
471 }; 482 };
472 483
473 if (buf_len < sizeof(*smart_t)) 484 if (buf_len < sizeof(*smart_t))
474 return -EINVAL; 485 return -EINVAL;
475 memcpy(smart_t->data, &smart_t_data, sizeof(smart_t_data)); 486 memcpy(smart_t, &smart_t_data, sizeof(smart_t_data));
476 return 0; 487 return 0;
477} 488}
478 489
diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h
index 113b44675a71..b85fba2856c7 100644
--- a/tools/testing/nvdimm/test/nfit_test.h
+++ b/tools/testing/nvdimm/test/nfit_test.h
@@ -84,6 +84,65 @@ struct nd_cmd_ars_err_inj_stat {
84 } __packed record[0]; 84 } __packed record[0];
85} __packed; 85} __packed;
86 86
87#define ND_INTEL_SMART 1
88#define ND_INTEL_SMART_THRESHOLD 2
89
90#define ND_INTEL_SMART_HEALTH_VALID (1 << 0)
91#define ND_INTEL_SMART_SPARES_VALID (1 << 1)
92#define ND_INTEL_SMART_USED_VALID (1 << 2)
93#define ND_INTEL_SMART_MTEMP_VALID (1 << 3)
94#define ND_INTEL_SMART_CTEMP_VALID (1 << 4)
95#define ND_INTEL_SMART_SHUTDOWN_COUNT_VALID (1 << 5)
96#define ND_INTEL_SMART_AIT_STATUS_VALID (1 << 6)
97#define ND_INTEL_SMART_PTEMP_VALID (1 << 7)
98#define ND_INTEL_SMART_ALARM_VALID (1 << 9)
99#define ND_INTEL_SMART_SHUTDOWN_VALID (1 << 10)
100#define ND_INTEL_SMART_VENDOR_VALID (1 << 11)
101#define ND_INTEL_SMART_SPARE_TRIP (1 << 0)
102#define ND_INTEL_SMART_TEMP_TRIP (1 << 1)
103#define ND_INTEL_SMART_CTEMP_TRIP (1 << 2)
104#define ND_INTEL_SMART_NON_CRITICAL_HEALTH (1 << 0)
105#define ND_INTEL_SMART_CRITICAL_HEALTH (1 << 1)
106#define ND_INTEL_SMART_FATAL_HEALTH (1 << 2)
107
108struct nd_intel_smart {
109 __u32 status;
110 union {
111 struct {
112 __u32 flags;
113 __u8 reserved0[4];
114 __u8 health;
115 __u8 spares;
116 __u8 life_used;
117 __u8 alarm_flags;
118 __u16 media_temperature;
119 __u16 ctrl_temperature;
120 __u32 shutdown_count;
121 __u8 ait_status;
122 __u16 pmic_temperature;
123 __u8 reserved1[8];
124 __u8 shutdown_state;
125 __u32 vendor_size;
126 __u8 vendor_data[92];
127 } __packed;
128 __u8 data[128];
129 };
130} __packed;
131
132struct nd_intel_smart_threshold {
133 __u32 status;
134 union {
135 struct {
136 __u16 alarm_control;
137 __u8 spares;
138 __u16 media_temperature;
139 __u16 ctrl_temperature;
140 __u8 reserved[1];
141 } __packed;
142 __u8 data[8];
143 };
144} __packed;
145
87union acpi_object; 146union acpi_object;
88typedef void *acpi_handle; 147typedef void *acpi_handle;
89 148