aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-05-18 13:06:59 -0400
committerDan Williams <dan.j.williams@intel.com>2016-05-18 13:06:59 -0400
commit1f716d05f8daee4f393dc568ea7a53c7ecfd0bfc (patch)
tree3ba46ef65cd2fb1766934769c1d4a7fc16c3fe61
parent2159669f581917c4d197d3ea183d3d85b47faf66 (diff)
parenta94e3fbe4d53d4e512c4ea88a475e605b8d8dccb (diff)
Merge branch 'for-4.7/dsm' into libnvdimm-for-next
-rw-r--r--drivers/acpi/nfit.c145
-rw-r--r--drivers/acpi/nfit.h18
-rw-r--r--drivers/acpi/utils.c4
-rw-r--r--drivers/nvdimm/bus.c47
-rw-r--r--drivers/nvdimm/core.c2
-rw-r--r--drivers/nvdimm/dimm_devs.c18
-rw-r--r--drivers/nvdimm/nd-core.h2
-rw-r--r--include/acpi/acpi_bus.h6
-rw-r--r--include/linux/libnvdimm.h7
-rw-r--r--include/uapi/linux/ndctl.h42
-rw-r--r--tools/testing/nvdimm/test/nfit.c50
11 files changed, 283 insertions, 58 deletions
diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
index d60f73a63c3c..2564f330a93e 100644
--- a/drivers/acpi/nfit.c
+++ b/drivers/acpi/nfit.c
@@ -45,6 +45,11 @@ module_param(scrub_overflow_abort, uint, S_IRUGO|S_IWUSR);
45MODULE_PARM_DESC(scrub_overflow_abort, 45MODULE_PARM_DESC(scrub_overflow_abort,
46 "Number of times we overflow ARS results before abort"); 46 "Number of times we overflow ARS results before abort");
47 47
48static bool disable_vendor_specific;
49module_param(disable_vendor_specific, bool, S_IRUGO);
50MODULE_PARM_DESC(disable_vendor_specific,
51 "Limit commands to the publicly specified set\n");
52
48static struct workqueue_struct *nfit_wq; 53static struct workqueue_struct *nfit_wq;
49 54
50struct nfit_table_prev { 55struct nfit_table_prev {
@@ -171,33 +176,46 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
171 unsigned int buf_len, int *cmd_rc) 176 unsigned int buf_len, int *cmd_rc)
172{ 177{
173 struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc); 178 struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc);
174 const struct nd_cmd_desc *desc = NULL;
175 union acpi_object in_obj, in_buf, *out_obj; 179 union acpi_object in_obj, in_buf, *out_obj;
180 const struct nd_cmd_desc *desc = NULL;
176 struct device *dev = acpi_desc->dev; 181 struct device *dev = acpi_desc->dev;
182 struct nd_cmd_pkg *call_pkg = NULL;
177 const char *cmd_name, *dimm_name; 183 const char *cmd_name, *dimm_name;
178 unsigned long dsm_mask; 184 unsigned long cmd_mask, dsm_mask;
179 acpi_handle handle; 185 acpi_handle handle;
186 unsigned int func;
180 const u8 *uuid; 187 const u8 *uuid;
181 u32 offset; 188 u32 offset;
182 int rc, i; 189 int rc, i;
183 190
191 func = cmd;
192 if (cmd == ND_CMD_CALL) {
193 call_pkg = buf;
194 func = call_pkg->nd_command;
195 }
196
184 if (nvdimm) { 197 if (nvdimm) {
185 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); 198 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
186 struct acpi_device *adev = nfit_mem->adev; 199 struct acpi_device *adev = nfit_mem->adev;
187 200
188 if (!adev) 201 if (!adev)
189 return -ENOTTY; 202 return -ENOTTY;
203 if (call_pkg && nfit_mem->family != call_pkg->nd_family)
204 return -ENOTTY;
205
190 dimm_name = nvdimm_name(nvdimm); 206 dimm_name = nvdimm_name(nvdimm);
191 cmd_name = nvdimm_cmd_name(cmd); 207 cmd_name = nvdimm_cmd_name(cmd);
208 cmd_mask = nvdimm_cmd_mask(nvdimm);
192 dsm_mask = nfit_mem->dsm_mask; 209 dsm_mask = nfit_mem->dsm_mask;
193 desc = nd_cmd_dimm_desc(cmd); 210 desc = nd_cmd_dimm_desc(cmd);
194 uuid = to_nfit_uuid(NFIT_DEV_DIMM); 211 uuid = to_nfit_uuid(nfit_mem->family);
195 handle = adev->handle; 212 handle = adev->handle;
196 } else { 213 } else {
197 struct acpi_device *adev = to_acpi_dev(acpi_desc); 214 struct acpi_device *adev = to_acpi_dev(acpi_desc);
198 215
199 cmd_name = nvdimm_bus_cmd_name(cmd); 216 cmd_name = nvdimm_bus_cmd_name(cmd);
200 dsm_mask = nd_desc->dsm_mask; 217 cmd_mask = nd_desc->cmd_mask;
218 dsm_mask = cmd_mask;
201 desc = nd_cmd_bus_desc(cmd); 219 desc = nd_cmd_bus_desc(cmd);
202 uuid = to_nfit_uuid(NFIT_DEV_BUS); 220 uuid = to_nfit_uuid(NFIT_DEV_BUS);
203 handle = adev->handle; 221 handle = adev->handle;
@@ -207,7 +225,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
207 if (!desc || (cmd && (desc->out_num + desc->in_num == 0))) 225 if (!desc || (cmd && (desc->out_num + desc->in_num == 0)))
208 return -ENOTTY; 226 return -ENOTTY;
209 227
210 if (!test_bit(cmd, &dsm_mask)) 228 if (!test_bit(cmd, &cmd_mask) || !test_bit(func, &dsm_mask))
211 return -ENOTTY; 229 return -ENOTTY;
212 230
213 in_obj.type = ACPI_TYPE_PACKAGE; 231 in_obj.type = ACPI_TYPE_PACKAGE;
@@ -222,21 +240,44 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
222 in_buf.buffer.length += nd_cmd_in_size(nvdimm, cmd, desc, 240 in_buf.buffer.length += nd_cmd_in_size(nvdimm, cmd, desc,
223 i, buf); 241 i, buf);
224 242
243 if (call_pkg) {
244 /* skip over package wrapper */
245 in_buf.buffer.pointer = (void *) &call_pkg->nd_payload;
246 in_buf.buffer.length = call_pkg->nd_size_in;
247 }
248
225 if (IS_ENABLED(CONFIG_ACPI_NFIT_DEBUG)) { 249 if (IS_ENABLED(CONFIG_ACPI_NFIT_DEBUG)) {
226 dev_dbg(dev, "%s:%s cmd: %s input length: %d\n", __func__, 250 dev_dbg(dev, "%s:%s cmd: %d: func: %d input length: %d\n",
227 dimm_name, cmd_name, in_buf.buffer.length); 251 __func__, dimm_name, cmd, func,
228 print_hex_dump_debug(cmd_name, DUMP_PREFIX_OFFSET, 4, 252 in_buf.buffer.length);
229 4, in_buf.buffer.pointer, min_t(u32, 128, 253 print_hex_dump_debug("nvdimm in ", DUMP_PREFIX_OFFSET, 4, 4,
230 in_buf.buffer.length), true); 254 in_buf.buffer.pointer,
255 min_t(u32, 256, in_buf.buffer.length), true);
231 } 256 }
232 257
233 out_obj = acpi_evaluate_dsm(handle, uuid, 1, cmd, &in_obj); 258 out_obj = acpi_evaluate_dsm(handle, uuid, 1, func, &in_obj);
234 if (!out_obj) { 259 if (!out_obj) {
235 dev_dbg(dev, "%s:%s _DSM failed cmd: %s\n", __func__, dimm_name, 260 dev_dbg(dev, "%s:%s _DSM failed cmd: %s\n", __func__, dimm_name,
236 cmd_name); 261 cmd_name);
237 return -EINVAL; 262 return -EINVAL;
238 } 263 }
239 264
265 if (call_pkg) {
266 call_pkg->nd_fw_size = out_obj->buffer.length;
267 memcpy(call_pkg->nd_payload + call_pkg->nd_size_in,
268 out_obj->buffer.pointer,
269 min(call_pkg->nd_fw_size, call_pkg->nd_size_out));
270
271 ACPI_FREE(out_obj);
272 /*
273 * Need to support FW function w/o known size in advance.
274 * Caller can determine required size based upon nd_fw_size.
275 * If we return an error (like elsewhere) then caller wouldn't
276 * be able to rely upon data returned to make calculation.
277 */
278 return 0;
279 }
280
240 if (out_obj->package.type != ACPI_TYPE_BUFFER) { 281 if (out_obj->package.type != ACPI_TYPE_BUFFER) {
241 dev_dbg(dev, "%s:%s unexpected output object type cmd: %s type: %d\n", 282 dev_dbg(dev, "%s:%s unexpected output object type cmd: %s type: %d\n",
242 __func__, dimm_name, cmd_name, out_obj->type); 283 __func__, dimm_name, cmd_name, out_obj->type);
@@ -921,6 +962,30 @@ static ssize_t serial_show(struct device *dev,
921} 962}
922static DEVICE_ATTR_RO(serial); 963static DEVICE_ATTR_RO(serial);
923 964
965static ssize_t family_show(struct device *dev,
966 struct device_attribute *attr, char *buf)
967{
968 struct nvdimm *nvdimm = to_nvdimm(dev);
969 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
970
971 if (nfit_mem->family < 0)
972 return -ENXIO;
973 return sprintf(buf, "%d\n", nfit_mem->family);
974}
975static DEVICE_ATTR_RO(family);
976
977static ssize_t dsm_mask_show(struct device *dev,
978 struct device_attribute *attr, char *buf)
979{
980 struct nvdimm *nvdimm = to_nvdimm(dev);
981 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
982
983 if (nfit_mem->family < 0)
984 return -ENXIO;
985 return sprintf(buf, "%#lx\n", nfit_mem->dsm_mask);
986}
987static DEVICE_ATTR_RO(dsm_mask);
988
924static ssize_t flags_show(struct device *dev, 989static ssize_t flags_show(struct device *dev,
925 struct device_attribute *attr, char *buf) 990 struct device_attribute *attr, char *buf)
926{ 991{
@@ -946,6 +1011,8 @@ static struct attribute *acpi_nfit_dimm_attributes[] = {
946 &dev_attr_serial.attr, 1011 &dev_attr_serial.attr,
947 &dev_attr_rev_id.attr, 1012 &dev_attr_rev_id.attr,
948 &dev_attr_flags.attr, 1013 &dev_attr_flags.attr,
1014 &dev_attr_family.attr,
1015 &dev_attr_dsm_mask.attr,
949 NULL, 1016 NULL,
950}; 1017};
951 1018
@@ -992,10 +1059,13 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
992{ 1059{
993 struct acpi_device *adev, *adev_dimm; 1060 struct acpi_device *adev, *adev_dimm;
994 struct device *dev = acpi_desc->dev; 1061 struct device *dev = acpi_desc->dev;
995 const u8 *uuid = to_nfit_uuid(NFIT_DEV_DIMM); 1062 unsigned long dsm_mask;
1063 const u8 *uuid;
996 int i; 1064 int i;
997 1065
998 nfit_mem->dsm_mask = acpi_desc->dimm_dsm_force_en; 1066 /* nfit test assumes 1:1 relationship between commands and dsms */
1067 nfit_mem->dsm_mask = acpi_desc->dimm_cmd_force_en;
1068 nfit_mem->family = NVDIMM_FAMILY_INTEL;
999 adev = to_acpi_dev(acpi_desc); 1069 adev = to_acpi_dev(acpi_desc);
1000 if (!adev) 1070 if (!adev)
1001 return 0; 1071 return 0;
@@ -1008,7 +1078,35 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
1008 return force_enable_dimms ? 0 : -ENODEV; 1078 return force_enable_dimms ? 0 : -ENODEV;
1009 } 1079 }
1010 1080
1011 for (i = ND_CMD_SMART; i <= ND_CMD_VENDOR; i++) 1081 /*
1082 * Until standardization materializes we need to consider up to 3
1083 * different command sets. Note, that checking for function0 (bit0)
1084 * tells us if any commands are reachable through this uuid.
1085 */
1086 for (i = NVDIMM_FAMILY_INTEL; i <= NVDIMM_FAMILY_HPE2; i++)
1087 if (acpi_check_dsm(adev_dimm->handle, to_nfit_uuid(i), 1, 1))
1088 break;
1089
1090 /* limit the supported commands to those that are publicly documented */
1091 nfit_mem->family = i;
1092 if (nfit_mem->family == NVDIMM_FAMILY_INTEL) {
1093 dsm_mask = 0x3fe;
1094 if (disable_vendor_specific)
1095 dsm_mask &= ~(1 << ND_CMD_VENDOR);
1096 } else if (nfit_mem->family == NVDIMM_FAMILY_HPE1)
1097 dsm_mask = 0x1c3c76;
1098 else if (nfit_mem->family == NVDIMM_FAMILY_HPE2) {
1099 dsm_mask = 0x1fe;
1100 if (disable_vendor_specific)
1101 dsm_mask &= ~(1 << 8);
1102 } else {
1103 dev_err(dev, "unknown dimm command family\n");
1104 nfit_mem->family = -1;
1105 return force_enable_dimms ? 0 : -ENODEV;
1106 }
1107
1108 uuid = to_nfit_uuid(nfit_mem->family);
1109 for_each_set_bit(i, &dsm_mask, BITS_PER_LONG)
1012 if (acpi_check_dsm(adev_dimm->handle, uuid, 1, 1ULL << i)) 1110 if (acpi_check_dsm(adev_dimm->handle, uuid, 1, 1ULL << i))
1013 set_bit(i, &nfit_mem->dsm_mask); 1111 set_bit(i, &nfit_mem->dsm_mask);
1014 1112
@@ -1021,8 +1119,8 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
1021 int dimm_count = 0; 1119 int dimm_count = 0;
1022 1120
1023 list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) { 1121 list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) {
1122 unsigned long flags = 0, cmd_mask;
1024 struct nvdimm *nvdimm; 1123 struct nvdimm *nvdimm;
1025 unsigned long flags = 0;
1026 u32 device_handle; 1124 u32 device_handle;
1027 u16 mem_flags; 1125 u16 mem_flags;
1028 int rc; 1126 int rc;
@@ -1045,9 +1143,18 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
1045 if (rc) 1143 if (rc)
1046 continue; 1144 continue;
1047 1145
1146 /*
1147 * TODO: provide translation for non-NVDIMM_FAMILY_INTEL
1148 * devices (i.e. from nd_cmd to acpi_dsm) to standardize the
1149 * userspace interface.
1150 */
1151 cmd_mask = 1UL << ND_CMD_CALL;
1152 if (nfit_mem->family == NVDIMM_FAMILY_INTEL)
1153 cmd_mask |= nfit_mem->dsm_mask;
1154
1048 nvdimm = nvdimm_create(acpi_desc->nvdimm_bus, nfit_mem, 1155 nvdimm = nvdimm_create(acpi_desc->nvdimm_bus, nfit_mem,
1049 acpi_nfit_dimm_attribute_groups, 1156 acpi_nfit_dimm_attribute_groups,
1050 flags, &nfit_mem->dsm_mask); 1157 flags, cmd_mask);
1051 if (!nvdimm) 1158 if (!nvdimm)
1052 return -ENOMEM; 1159 return -ENOMEM;
1053 1160
@@ -1076,14 +1183,14 @@ static void acpi_nfit_init_dsms(struct acpi_nfit_desc *acpi_desc)
1076 struct acpi_device *adev; 1183 struct acpi_device *adev;
1077 int i; 1184 int i;
1078 1185
1079 nd_desc->dsm_mask = acpi_desc->bus_dsm_force_en; 1186 nd_desc->cmd_mask = acpi_desc->bus_cmd_force_en;
1080 adev = to_acpi_dev(acpi_desc); 1187 adev = to_acpi_dev(acpi_desc);
1081 if (!adev) 1188 if (!adev)
1082 return; 1189 return;
1083 1190
1084 for (i = ND_CMD_ARS_CAP; i <= ND_CMD_CLEAR_ERROR; i++) 1191 for (i = ND_CMD_ARS_CAP; i <= ND_CMD_CLEAR_ERROR; i++)
1085 if (acpi_check_dsm(adev->handle, uuid, 1, 1ULL << i)) 1192 if (acpi_check_dsm(adev->handle, uuid, 1, 1ULL << i))
1086 set_bit(i, &nd_desc->dsm_mask); 1193 set_bit(i, &nd_desc->cmd_mask);
1087} 1194}
1088 1195
1089static ssize_t range_index_show(struct device *dev, 1196static ssize_t range_index_show(struct device *dev,
@@ -2532,6 +2639,8 @@ static __init int nfit_init(void)
2532 acpi_str_to_uuid(UUID_PERSISTENT_VIRTUAL_CD, nfit_uuid[NFIT_SPA_PCD]); 2639 acpi_str_to_uuid(UUID_PERSISTENT_VIRTUAL_CD, nfit_uuid[NFIT_SPA_PCD]);
2533 acpi_str_to_uuid(UUID_NFIT_BUS, nfit_uuid[NFIT_DEV_BUS]); 2640 acpi_str_to_uuid(UUID_NFIT_BUS, nfit_uuid[NFIT_DEV_BUS]);
2534 acpi_str_to_uuid(UUID_NFIT_DIMM, nfit_uuid[NFIT_DEV_DIMM]); 2641 acpi_str_to_uuid(UUID_NFIT_DIMM, nfit_uuid[NFIT_DEV_DIMM]);
2642 acpi_str_to_uuid(UUID_NFIT_DIMM_N_HPE1, nfit_uuid[NFIT_DEV_DIMM_N_HPE1]);
2643 acpi_str_to_uuid(UUID_NFIT_DIMM_N_HPE2, nfit_uuid[NFIT_DEV_DIMM_N_HPE2]);
2535 2644
2536 nfit_wq = create_singlethread_workqueue("nfit"); 2645 nfit_wq = create_singlethread_workqueue("nfit");
2537 if (!nfit_wq) 2646 if (!nfit_wq)
diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit.h
index 5201840c1147..46c50148e4b7 100644
--- a/drivers/acpi/nfit.h
+++ b/drivers/acpi/nfit.h
@@ -21,13 +21,25 @@
21#include <linux/acpi.h> 21#include <linux/acpi.h>
22#include <acpi/acuuid.h> 22#include <acpi/acuuid.h>
23 23
24/* ACPI 6.1 */
24#define UUID_NFIT_BUS "2f10e7a4-9e91-11e4-89d3-123b93f75cba" 25#define UUID_NFIT_BUS "2f10e7a4-9e91-11e4-89d3-123b93f75cba"
26
27/* http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf */
25#define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66" 28#define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
29
30/* https://github.com/HewlettPackard/hpe-nvm/blob/master/Documentation/ */
31#define UUID_NFIT_DIMM_N_HPE1 "9002c334-acf3-4c0e-9642-a235f0d53bc6"
32#define UUID_NFIT_DIMM_N_HPE2 "5008664b-b758-41a0-a03c-27c2f2d04f7e"
33
26#define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \ 34#define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
27 | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \ 35 | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
28 | ACPI_NFIT_MEM_NOT_ARMED) 36 | ACPI_NFIT_MEM_NOT_ARMED)
29 37
30enum nfit_uuids { 38enum nfit_uuids {
39 /* for simplicity alias the uuid index with the family id */
40 NFIT_DEV_DIMM = NVDIMM_FAMILY_INTEL,
41 NFIT_DEV_DIMM_N_HPE1 = NVDIMM_FAMILY_HPE1,
42 NFIT_DEV_DIMM_N_HPE2 = NVDIMM_FAMILY_HPE2,
31 NFIT_SPA_VOLATILE, 43 NFIT_SPA_VOLATILE,
32 NFIT_SPA_PM, 44 NFIT_SPA_PM,
33 NFIT_SPA_DCR, 45 NFIT_SPA_DCR,
@@ -37,7 +49,6 @@ enum nfit_uuids {
37 NFIT_SPA_PDISK, 49 NFIT_SPA_PDISK,
38 NFIT_SPA_PCD, 50 NFIT_SPA_PCD,
39 NFIT_DEV_BUS, 51 NFIT_DEV_BUS,
40 NFIT_DEV_DIMM,
41 NFIT_UUID_MAX, 52 NFIT_UUID_MAX,
42}; 53};
43 54
@@ -111,6 +122,7 @@ struct nfit_mem {
111 struct acpi_device *adev; 122 struct acpi_device *adev;
112 struct acpi_nfit_desc *acpi_desc; 123 struct acpi_nfit_desc *acpi_desc;
113 unsigned long dsm_mask; 124 unsigned long dsm_mask;
125 int family;
114}; 126};
115 127
116struct acpi_nfit_desc { 128struct acpi_nfit_desc {
@@ -133,8 +145,8 @@ struct acpi_nfit_desc {
133 size_t ars_status_size; 145 size_t ars_status_size;
134 struct work_struct work; 146 struct work_struct work;
135 unsigned int cancel:1; 147 unsigned int cancel:1;
136 unsigned long dimm_dsm_force_en; 148 unsigned long dimm_cmd_force_en;
137 unsigned long bus_dsm_force_en; 149 unsigned long bus_cmd_force_en;
138 int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa, 150 int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
139 void *iobuf, u64 len, int rw); 151 void *iobuf, u64 len, int rw);
140}; 152};
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 050673f0c0b3..e854dea7d5fe 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -625,7 +625,7 @@ acpi_status acpi_evaluate_lck(acpi_handle handle, int lock)
625 * some old BIOSes do expect a buffer or an integer etc. 625 * some old BIOSes do expect a buffer or an integer etc.
626 */ 626 */
627union acpi_object * 627union acpi_object *
628acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid, int rev, int func, 628acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 func,
629 union acpi_object *argv4) 629 union acpi_object *argv4)
630{ 630{
631 acpi_status ret; 631 acpi_status ret;
@@ -674,7 +674,7 @@ EXPORT_SYMBOL(acpi_evaluate_dsm);
674 * functions. Currently only support 64 functions at maximum, should be 674 * functions. Currently only support 64 functions at maximum, should be
675 * enough for now. 675 * enough for now.
676 */ 676 */
677bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs) 677bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 funcs)
678{ 678{
679 int i; 679 int i;
680 u64 mask = 0; 680 u64 mask = 0;
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index dcaefe229887..04c2c3fda1ab 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -443,6 +443,12 @@ static const struct nd_cmd_desc __nd_cmd_dimm_descs[] = {
443 .out_num = 3, 443 .out_num = 3,
444 .out_sizes = { 4, 4, UINT_MAX, }, 444 .out_sizes = { 4, 4, UINT_MAX, },
445 }, 445 },
446 [ND_CMD_CALL] = {
447 .in_num = 2,
448 .in_sizes = { sizeof(struct nd_cmd_pkg), UINT_MAX, },
449 .out_num = 1,
450 .out_sizes = { UINT_MAX, },
451 },
446}; 452};
447 453
448const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd) 454const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd)
@@ -477,6 +483,12 @@ static const struct nd_cmd_desc __nd_cmd_bus_descs[] = {
477 .out_num = 3, 483 .out_num = 3,
478 .out_sizes = { 4, 4, 8, }, 484 .out_sizes = { 4, 4, 8, },
479 }, 485 },
486 [ND_CMD_CALL] = {
487 .in_num = 2,
488 .in_sizes = { sizeof(struct nd_cmd_pkg), UINT_MAX, },
489 .out_num = 1,
490 .out_sizes = { UINT_MAX, },
491 },
480}; 492};
481 493
482const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd) 494const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd)
@@ -504,6 +516,10 @@ u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd,
504 struct nd_cmd_vendor_hdr *hdr = buf; 516 struct nd_cmd_vendor_hdr *hdr = buf;
505 517
506 return hdr->in_length; 518 return hdr->in_length;
519 } else if (cmd == ND_CMD_CALL) {
520 struct nd_cmd_pkg *pkg = buf;
521
522 return pkg->nd_size_in;
507 } 523 }
508 524
509 return UINT_MAX; 525 return UINT_MAX;
@@ -526,6 +542,12 @@ u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
526 return out_field[1]; 542 return out_field[1];
527 else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 2) 543 else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 2)
528 return out_field[1] - 8; 544 return out_field[1] - 8;
545 else if (cmd == ND_CMD_CALL) {
546 struct nd_cmd_pkg *pkg = (struct nd_cmd_pkg *) in_field;
547
548 return pkg->nd_size_out;
549 }
550
529 551
530 return UINT_MAX; 552 return UINT_MAX;
531} 553}
@@ -592,25 +614,31 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
592 unsigned int cmd = _IOC_NR(ioctl_cmd); 614 unsigned int cmd = _IOC_NR(ioctl_cmd);
593 void __user *p = (void __user *) arg; 615 void __user *p = (void __user *) arg;
594 struct device *dev = &nvdimm_bus->dev; 616 struct device *dev = &nvdimm_bus->dev;
617 struct nd_cmd_pkg pkg;
595 const char *cmd_name, *dimm_name; 618 const char *cmd_name, *dimm_name;
596 unsigned long dsm_mask; 619 unsigned long cmd_mask;
597 void *buf; 620 void *buf;
598 int rc, i; 621 int rc, i;
599 622
600 if (nvdimm) { 623 if (nvdimm) {
601 desc = nd_cmd_dimm_desc(cmd); 624 desc = nd_cmd_dimm_desc(cmd);
602 cmd_name = nvdimm_cmd_name(cmd); 625 cmd_name = nvdimm_cmd_name(cmd);
603 dsm_mask = nvdimm->dsm_mask ? *(nvdimm->dsm_mask) : 0; 626 cmd_mask = nvdimm->cmd_mask;
604 dimm_name = dev_name(&nvdimm->dev); 627 dimm_name = dev_name(&nvdimm->dev);
605 } else { 628 } else {
606 desc = nd_cmd_bus_desc(cmd); 629 desc = nd_cmd_bus_desc(cmd);
607 cmd_name = nvdimm_bus_cmd_name(cmd); 630 cmd_name = nvdimm_bus_cmd_name(cmd);
608 dsm_mask = nd_desc->dsm_mask; 631 cmd_mask = nd_desc->cmd_mask;
609 dimm_name = "bus"; 632 dimm_name = "bus";
610 } 633 }
611 634
635 if (cmd == ND_CMD_CALL) {
636 if (copy_from_user(&pkg, p, sizeof(pkg)))
637 return -EFAULT;
638 }
639
612 if (!desc || (desc->out_num + desc->in_num == 0) || 640 if (!desc || (desc->out_num + desc->in_num == 0) ||
613 !test_bit(cmd, &dsm_mask)) 641 !test_bit(cmd, &cmd_mask))
614 return -ENOTTY; 642 return -ENOTTY;
615 643
616 /* fail write commands (when read-only) */ 644 /* fail write commands (when read-only) */
@@ -620,6 +648,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
620 case ND_CMD_SET_CONFIG_DATA: 648 case ND_CMD_SET_CONFIG_DATA:
621 case ND_CMD_ARS_START: 649 case ND_CMD_ARS_START:
622 case ND_CMD_CLEAR_ERROR: 650 case ND_CMD_CLEAR_ERROR:
651 case ND_CMD_CALL:
623 dev_dbg(&nvdimm_bus->dev, "'%s' command while read-only.\n", 652 dev_dbg(&nvdimm_bus->dev, "'%s' command while read-only.\n",
624 nvdimm ? nvdimm_cmd_name(cmd) 653 nvdimm ? nvdimm_cmd_name(cmd)
625 : nvdimm_bus_cmd_name(cmd)); 654 : nvdimm_bus_cmd_name(cmd));
@@ -647,6 +676,16 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
647 in_len += in_size; 676 in_len += in_size;
648 } 677 }
649 678
679 if (cmd == ND_CMD_CALL) {
680 dev_dbg(dev, "%s:%s, idx: %llu, in: %zu, out: %zu, len %zu\n",
681 __func__, dimm_name, pkg.nd_command,
682 in_len, out_len, buf_len);
683
684 for (i = 0; i < ARRAY_SIZE(pkg.nd_reserved2); i++)
685 if (pkg.nd_reserved2[i])
686 return -EINVAL;
687 }
688
650 /* process an output envelope */ 689 /* process an output envelope */
651 for (i = 0; i < desc->out_num; i++) { 690 for (i = 0; i < desc->out_num; i++) {
652 u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, 691 u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i,
diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c
index 182a93fe3712..e8688a13cf4f 100644
--- a/drivers/nvdimm/core.c
+++ b/drivers/nvdimm/core.c
@@ -251,7 +251,7 @@ static ssize_t commands_show(struct device *dev,
251 struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev); 251 struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev);
252 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc; 252 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
253 253
254 for_each_set_bit(cmd, &nd_desc->dsm_mask, BITS_PER_LONG) 254 for_each_set_bit(cmd, &nd_desc->cmd_mask, BITS_PER_LONG)
255 len += sprintf(buf + len, "%s ", nvdimm_bus_cmd_name(cmd)); 255 len += sprintf(buf + len, "%s ", nvdimm_bus_cmd_name(cmd));
256 len += sprintf(buf + len, "\n"); 256 len += sprintf(buf + len, "\n");
257 return len; 257 return len;
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index c56f88217924..79a35a02053c 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -37,9 +37,9 @@ static int __validate_dimm(struct nvdimm_drvdata *ndd)
37 37
38 nvdimm = to_nvdimm(ndd->dev); 38 nvdimm = to_nvdimm(ndd->dev);
39 39
40 if (!nvdimm->dsm_mask) 40 if (!nvdimm->cmd_mask)
41 return -ENXIO; 41 return -ENXIO;
42 if (!test_bit(ND_CMD_GET_CONFIG_DATA, nvdimm->dsm_mask)) 42 if (!test_bit(ND_CMD_GET_CONFIG_DATA, &nvdimm->cmd_mask))
43 return -ENXIO; 43 return -ENXIO;
44 44
45 return 0; 45 return 0;
@@ -263,6 +263,12 @@ const char *nvdimm_name(struct nvdimm *nvdimm)
263} 263}
264EXPORT_SYMBOL_GPL(nvdimm_name); 264EXPORT_SYMBOL_GPL(nvdimm_name);
265 265
266unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm)
267{
268 return nvdimm->cmd_mask;
269}
270EXPORT_SYMBOL_GPL(nvdimm_cmd_mask);
271
266void *nvdimm_provider_data(struct nvdimm *nvdimm) 272void *nvdimm_provider_data(struct nvdimm *nvdimm)
267{ 273{
268 if (nvdimm) 274 if (nvdimm)
@@ -277,10 +283,10 @@ static ssize_t commands_show(struct device *dev,
277 struct nvdimm *nvdimm = to_nvdimm(dev); 283 struct nvdimm *nvdimm = to_nvdimm(dev);
278 int cmd, len = 0; 284 int cmd, len = 0;
279 285
280 if (!nvdimm->dsm_mask) 286 if (!nvdimm->cmd_mask)
281 return sprintf(buf, "\n"); 287 return sprintf(buf, "\n");
282 288
283 for_each_set_bit(cmd, nvdimm->dsm_mask, BITS_PER_LONG) 289 for_each_set_bit(cmd, &nvdimm->cmd_mask, BITS_PER_LONG)
284 len += sprintf(buf + len, "%s ", nvdimm_cmd_name(cmd)); 290 len += sprintf(buf + len, "%s ", nvdimm_cmd_name(cmd));
285 len += sprintf(buf + len, "\n"); 291 len += sprintf(buf + len, "\n");
286 return len; 292 return len;
@@ -340,7 +346,7 @@ EXPORT_SYMBOL_GPL(nvdimm_attribute_group);
340 346
341struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, 347struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data,
342 const struct attribute_group **groups, unsigned long flags, 348 const struct attribute_group **groups, unsigned long flags,
343 unsigned long *dsm_mask) 349 unsigned long cmd_mask)
344{ 350{
345 struct nvdimm *nvdimm = kzalloc(sizeof(*nvdimm), GFP_KERNEL); 351 struct nvdimm *nvdimm = kzalloc(sizeof(*nvdimm), GFP_KERNEL);
346 struct device *dev; 352 struct device *dev;
@@ -355,7 +361,7 @@ struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data,
355 } 361 }
356 nvdimm->provider_data = provider_data; 362 nvdimm->provider_data = provider_data;
357 nvdimm->flags = flags; 363 nvdimm->flags = flags;
358 nvdimm->dsm_mask = dsm_mask; 364 nvdimm->cmd_mask = cmd_mask;
359 atomic_set(&nvdimm->busy, 0); 365 atomic_set(&nvdimm->busy, 0);
360 dev = &nvdimm->dev; 366 dev = &nvdimm->dev;
361 dev_set_name(dev, "nmem%d", nvdimm->id); 367 dev_set_name(dev, "nmem%d", nvdimm->id);
diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h
index cb65308c0329..86d985ccce82 100644
--- a/drivers/nvdimm/nd-core.h
+++ b/drivers/nvdimm/nd-core.h
@@ -37,7 +37,7 @@ struct nvdimm_bus {
37struct nvdimm { 37struct nvdimm {
38 unsigned long flags; 38 unsigned long flags;
39 void *provider_data; 39 void *provider_data;
40 unsigned long *dsm_mask; 40 unsigned long cmd_mask;
41 struct device dev; 41 struct device dev;
42 atomic_t busy; 42 atomic_t busy;
43 int id; 43 int id;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 14362a84c78e..f092cc6eb1fb 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -61,12 +61,12 @@ bool acpi_ata_match(acpi_handle handle);
61bool acpi_bay_match(acpi_handle handle); 61bool acpi_bay_match(acpi_handle handle);
62bool acpi_dock_match(acpi_handle handle); 62bool acpi_dock_match(acpi_handle handle);
63 63
64bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs); 64bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 funcs);
65union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid, 65union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid,
66 int rev, int func, union acpi_object *argv4); 66 u64 rev, u64 func, union acpi_object *argv4);
67 67
68static inline union acpi_object * 68static inline union acpi_object *
69acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, int rev, int func, 69acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, u64 rev, u64 func,
70 union acpi_object *argv4, acpi_object_type type) 70 union acpi_object *argv4, acpi_object_type type)
71{ 71{
72 union acpi_object *obj; 72 union acpi_object *obj;
diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
index 833867b9ddc2..0c3c30cbbea5 100644
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -27,7 +27,7 @@ enum {
27 /* need to set a limit somewhere, but yes, this is likely overkill */ 27 /* need to set a limit somewhere, but yes, this is likely overkill */
28 ND_IOCTL_MAX_BUFLEN = SZ_4M, 28 ND_IOCTL_MAX_BUFLEN = SZ_4M,
29 ND_CMD_MAX_ELEM = 5, 29 ND_CMD_MAX_ELEM = 5,
30 ND_CMD_MAX_ENVELOPE = 16, 30 ND_CMD_MAX_ENVELOPE = 256,
31 ND_MAX_MAPPINGS = 32, 31 ND_MAX_MAPPINGS = 32,
32 32
33 /* region flag indicating to direct-map persistent memory by default */ 33 /* region flag indicating to direct-map persistent memory by default */
@@ -68,7 +68,7 @@ struct nd_mapping {
68 68
69struct nvdimm_bus_descriptor { 69struct nvdimm_bus_descriptor {
70 const struct attribute_group **attr_groups; 70 const struct attribute_group **attr_groups;
71 unsigned long dsm_mask; 71 unsigned long cmd_mask;
72 char *provider_name; 72 char *provider_name;
73 ndctl_fn ndctl; 73 ndctl_fn ndctl;
74 int (*flush_probe)(struct nvdimm_bus_descriptor *nd_desc); 74 int (*flush_probe)(struct nvdimm_bus_descriptor *nd_desc);
@@ -130,10 +130,11 @@ struct nd_region *to_nd_region(struct device *dev);
130struct nd_blk_region *to_nd_blk_region(struct device *dev); 130struct nd_blk_region *to_nd_blk_region(struct device *dev);
131struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus); 131struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus);
132const char *nvdimm_name(struct nvdimm *nvdimm); 132const char *nvdimm_name(struct nvdimm *nvdimm);
133unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm);
133void *nvdimm_provider_data(struct nvdimm *nvdimm); 134void *nvdimm_provider_data(struct nvdimm *nvdimm);
134struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, 135struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data,
135 const struct attribute_group **groups, unsigned long flags, 136 const struct attribute_group **groups, unsigned long flags,
136 unsigned long *dsm_mask); 137 unsigned long cmd_mask);
137const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd); 138const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd);
138const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd); 139const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd);
139u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd, 140u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd,
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index 1eac426aead5..309915f74492 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -159,6 +159,7 @@ enum {
159 ND_CMD_VENDOR_EFFECT_LOG_SIZE = 7, 159 ND_CMD_VENDOR_EFFECT_LOG_SIZE = 7,
160 ND_CMD_VENDOR_EFFECT_LOG = 8, 160 ND_CMD_VENDOR_EFFECT_LOG = 8,
161 ND_CMD_VENDOR = 9, 161 ND_CMD_VENDOR = 9,
162 ND_CMD_CALL = 10,
162}; 163};
163 164
164enum { 165enum {
@@ -192,6 +193,7 @@ static inline const char *nvdimm_cmd_name(unsigned cmd)
192 [ND_CMD_VENDOR_EFFECT_LOG_SIZE] = "effect_size", 193 [ND_CMD_VENDOR_EFFECT_LOG_SIZE] = "effect_size",
193 [ND_CMD_VENDOR_EFFECT_LOG] = "effect_log", 194 [ND_CMD_VENDOR_EFFECT_LOG] = "effect_log",
194 [ND_CMD_VENDOR] = "vendor", 195 [ND_CMD_VENDOR] = "vendor",
196 [ND_CMD_CALL] = "cmd_call",
195 }; 197 };
196 198
197 if (cmd < ARRAY_SIZE(names) && names[cmd]) 199 if (cmd < ARRAY_SIZE(names) && names[cmd])
@@ -260,4 +262,44 @@ enum ars_masks {
260 ARS_STATUS_MASK = 0x0000FFFF, 262 ARS_STATUS_MASK = 0x0000FFFF,
261 ARS_EXT_STATUS_SHIFT = 16, 263 ARS_EXT_STATUS_SHIFT = 16,
262}; 264};
265
266/*
267 * struct nd_cmd_pkg
268 *
269 * is a wrapper to a quasi pass thru interface for invoking firmware
270 * associated with nvdimms.
271 *
272 * INPUT PARAMETERS
273 *
274 * nd_family corresponds to the firmware (e.g. DSM) interface.
275 *
276 * nd_command are the function index advertised by the firmware.
277 *
278 * nd_size_in is the size of the input parameters being passed to firmware
279 *
280 * OUTPUT PARAMETERS
281 *
282 * nd_fw_size is the size of the data firmware wants to return for
283 * the call. If nd_fw_size is greater than size of nd_size_out, only
284 * the first nd_size_out bytes are returned.
285 */
286
287struct nd_cmd_pkg {
288 __u64 nd_family; /* family of commands */
289 __u64 nd_command;
290 __u32 nd_size_in; /* INPUT: size of input args */
291 __u32 nd_size_out; /* INPUT: size of payload */
292 __u32 nd_reserved2[9]; /* reserved must be zero */
293 __u32 nd_fw_size; /* OUTPUT: size fw wants to return */
294 unsigned char nd_payload[]; /* Contents of call */
295};
296
297/* These NVDIMM families represent pre-standardization command sets */
298#define NVDIMM_FAMILY_INTEL 0
299#define NVDIMM_FAMILY_HPE1 1
300#define NVDIMM_FAMILY_HPE2 2
301
302#define ND_IOCTL_CALL _IOWR(ND_IOCTL, ND_CMD_CALL,\
303 struct nd_cmd_pkg)
304
263#endif /* __NDCTL_H__ */ 305#endif /* __NDCTL_H__ */
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index d1c98d4386d4..c919866853a0 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -372,6 +372,7 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
372{ 372{
373 struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); 373 struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
374 struct nfit_test *t = container_of(acpi_desc, typeof(*t), acpi_desc); 374 struct nfit_test *t = container_of(acpi_desc, typeof(*t), acpi_desc);
375 unsigned int func = cmd;
375 int i, rc = 0, __cmd_rc; 376 int i, rc = 0, __cmd_rc;
376 377
377 if (!cmd_rc) 378 if (!cmd_rc)
@@ -380,8 +381,23 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
380 381
381 if (nvdimm) { 382 if (nvdimm) {
382 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm); 383 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
384 unsigned long cmd_mask = nvdimm_cmd_mask(nvdimm);
383 385
384 if (!nfit_mem || !test_bit(cmd, &nfit_mem->dsm_mask)) 386 if (!nfit_mem)
387 return -ENOTTY;
388
389 if (cmd == ND_CMD_CALL) {
390 struct nd_cmd_pkg *call_pkg = buf;
391
392 buf_len = call_pkg->nd_size_in + call_pkg->nd_size_out;
393 buf = (void *) call_pkg->nd_payload;
394 func = call_pkg->nd_command;
395 if (call_pkg->nd_family != nfit_mem->family)
396 return -ENOTTY;
397 }
398
399 if (!test_bit(cmd, &cmd_mask)
400 || !test_bit(func, &nfit_mem->dsm_mask))
385 return -ENOTTY; 401 return -ENOTTY;
386 402
387 /* lookup label space for the given dimm */ 403 /* lookup label space for the given dimm */
@@ -392,7 +408,7 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
392 if (i >= ARRAY_SIZE(handle)) 408 if (i >= ARRAY_SIZE(handle))
393 return -ENXIO; 409 return -ENXIO;
394 410
395 switch (cmd) { 411 switch (func) {
396 case ND_CMD_GET_CONFIG_SIZE: 412 case ND_CMD_GET_CONFIG_SIZE:
397 rc = nfit_test_cmd_get_config_size(buf, buf_len); 413 rc = nfit_test_cmd_get_config_size(buf, buf_len);
398 break; 414 break;
@@ -416,10 +432,10 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
416 } else { 432 } else {
417 struct ars_state *ars_state = &t->ars_state; 433 struct ars_state *ars_state = &t->ars_state;
418 434
419 if (!nd_desc || !test_bit(cmd, &nd_desc->dsm_mask)) 435 if (!nd_desc || !test_bit(cmd, &nd_desc->cmd_mask))
420 return -ENOTTY; 436 return -ENOTTY;
421 437
422 switch (cmd) { 438 switch (func) {
423 case ND_CMD_ARS_CAP: 439 case ND_CMD_ARS_CAP:
424 rc = nfit_test_cmd_ars_cap(buf, buf_len); 440 rc = nfit_test_cmd_ars_cap(buf, buf_len);
425 break; 441 break;
@@ -1293,15 +1309,15 @@ static void nfit_test0_setup(struct nfit_test *t)
1293 post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA0_SIZE); 1309 post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA0_SIZE);
1294 1310
1295 acpi_desc = &t->acpi_desc; 1311 acpi_desc = &t->acpi_desc;
1296 set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_dsm_force_en); 1312 set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en);
1297 set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en); 1313 set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
1298 set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en); 1314 set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
1299 set_bit(ND_CMD_SMART, &acpi_desc->dimm_dsm_force_en); 1315 set_bit(ND_CMD_SMART, &acpi_desc->dimm_cmd_force_en);
1300 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en); 1316 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_cmd_force_en);
1301 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en); 1317 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
1302 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en); 1318 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
1303 set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_dsm_force_en); 1319 set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
1304 set_bit(ND_CMD_SMART_THRESHOLD, &acpi_desc->dimm_dsm_force_en); 1320 set_bit(ND_CMD_SMART_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
1305} 1321}
1306 1322
1307static void nfit_test1_setup(struct nfit_test *t) 1323static void nfit_test1_setup(struct nfit_test *t)
@@ -1359,10 +1375,10 @@ static void nfit_test1_setup(struct nfit_test *t)
1359 post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA2_SIZE); 1375 post_ars_status(&t->ars_state, t->spa_set_dma[0], SPA2_SIZE);
1360 1376
1361 acpi_desc = &t->acpi_desc; 1377 acpi_desc = &t->acpi_desc;
1362 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en); 1378 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_cmd_force_en);
1363 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en); 1379 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
1364 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en); 1380 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
1365 set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_dsm_force_en); 1381 set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
1366} 1382}
1367 1383
1368static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa, 1384static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,