diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-22 00:11:05 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-22 00:11:05 -0400 |
| commit | 4c50ceae8f3b56e7c13b327f01e973b4127142a2 (patch) | |
| tree | 6e459f79d867c4a798c080951aa0e02de82cee41 /tools | |
| parent | 5e7c7806111ade52f4e198fa0f576c538fbfb0df (diff) | |
| parent | c5794510d7b5f210f05531ff9e82432cf7244367 (diff) | |
Merge branch 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm fixes from Dan Williams:
"A regression fix, new unit test infrastructure and a build fix:
- Regression fix addressing support for the new NVDIMM label storage
area access commands (_LSI, _LSR, and _LSW).
The Intel specific version of these commands communicated the
"Device Locked" status on the label-storage-information command.
However, these new commands (standardized in ACPI 6.2) communicate
the "Device Locked" status on the label-storage-read command, and
the driver was missing the indication.
Reading from locked persistent memory is similar to reading
unmapped PCI memory space, returns all 1's.
- Unit test infrastructure is added to regression test the "Device
Locked" detection failure.
- A build fix is included to allow the "of_pmem" driver to be built
as a module and translate an Open Firmware described device to its
local numa node"
* 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
MAINTAINERS: Add backup maintainers for libnvdimm and DAX
device-dax: allow MAP_SYNC to succeed
Revert "libnvdimm, of_pmem: workaround OF_NUMA=n build error"
libnvdimm, of_pmem: use dev_to_node() instead of of_node_to_nid()
tools/testing/nvdimm: enable labels for nfit_test.1 dimms
tools/testing/nvdimm: fix missing newline in nfit_test_dimm 'handle' attribute
tools/testing/nvdimm: support nfit_test_dimm attributes under nfit_test.1
tools/testing/nvdimm: allow custom error code injection
libnvdimm, dimm: handle EACCES failures from label reads
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/testing/nvdimm/test/nfit.c | 84 |
1 files changed, 65 insertions, 19 deletions
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index cb166be4918d..4ea385be528f 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c | |||
| @@ -138,6 +138,7 @@ static u32 handle[] = { | |||
| 138 | }; | 138 | }; |
| 139 | 139 | ||
| 140 | static unsigned long dimm_fail_cmd_flags[NUM_DCR]; | 140 | static unsigned long dimm_fail_cmd_flags[NUM_DCR]; |
| 141 | static int dimm_fail_cmd_code[NUM_DCR]; | ||
| 141 | 142 | ||
| 142 | struct nfit_test_fw { | 143 | struct nfit_test_fw { |
| 143 | enum intel_fw_update_state state; | 144 | enum intel_fw_update_state state; |
| @@ -892,8 +893,11 @@ static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func) | |||
| 892 | if (i >= ARRAY_SIZE(handle)) | 893 | if (i >= ARRAY_SIZE(handle)) |
| 893 | return -ENXIO; | 894 | return -ENXIO; |
| 894 | 895 | ||
| 895 | if ((1 << func) & dimm_fail_cmd_flags[i]) | 896 | if ((1 << func) & dimm_fail_cmd_flags[i]) { |
| 897 | if (dimm_fail_cmd_code[i]) | ||
| 898 | return dimm_fail_cmd_code[i]; | ||
| 896 | return -EIO; | 899 | return -EIO; |
| 900 | } | ||
| 897 | 901 | ||
| 898 | return i; | 902 | return i; |
| 899 | } | 903 | } |
| @@ -1162,12 +1166,12 @@ static int ars_state_init(struct device *dev, struct ars_state *ars_state) | |||
| 1162 | 1166 | ||
| 1163 | static void put_dimms(void *data) | 1167 | static void put_dimms(void *data) |
| 1164 | { | 1168 | { |
| 1165 | struct device **dimm_dev = data; | 1169 | struct nfit_test *t = data; |
| 1166 | int i; | 1170 | int i; |
| 1167 | 1171 | ||
| 1168 | for (i = 0; i < NUM_DCR; i++) | 1172 | for (i = 0; i < t->num_dcr; i++) |
| 1169 | if (dimm_dev[i]) | 1173 | if (t->dimm_dev[i]) |
| 1170 | device_unregister(dimm_dev[i]); | 1174 | device_unregister(t->dimm_dev[i]); |
| 1171 | } | 1175 | } |
| 1172 | 1176 | ||
| 1173 | static struct class *nfit_test_dimm; | 1177 | static struct class *nfit_test_dimm; |
| @@ -1176,13 +1180,11 @@ static int dimm_name_to_id(struct device *dev) | |||
| 1176 | { | 1180 | { |
| 1177 | int dimm; | 1181 | int dimm; |
| 1178 | 1182 | ||
| 1179 | if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1 | 1183 | if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1) |
| 1180 | || dimm >= NUM_DCR || dimm < 0) | ||
| 1181 | return -ENXIO; | 1184 | return -ENXIO; |
| 1182 | return dimm; | 1185 | return dimm; |
| 1183 | } | 1186 | } |
| 1184 | 1187 | ||
| 1185 | |||
| 1186 | static ssize_t handle_show(struct device *dev, struct device_attribute *attr, | 1188 | static ssize_t handle_show(struct device *dev, struct device_attribute *attr, |
| 1187 | char *buf) | 1189 | char *buf) |
| 1188 | { | 1190 | { |
| @@ -1191,7 +1193,7 @@ static ssize_t handle_show(struct device *dev, struct device_attribute *attr, | |||
| 1191 | if (dimm < 0) | 1193 | if (dimm < 0) |
| 1192 | return dimm; | 1194 | return dimm; |
| 1193 | 1195 | ||
| 1194 | return sprintf(buf, "%#x", handle[dimm]); | 1196 | return sprintf(buf, "%#x\n", handle[dimm]); |
| 1195 | } | 1197 | } |
| 1196 | DEVICE_ATTR_RO(handle); | 1198 | DEVICE_ATTR_RO(handle); |
| 1197 | 1199 | ||
| @@ -1225,8 +1227,39 @@ static ssize_t fail_cmd_store(struct device *dev, struct device_attribute *attr, | |||
| 1225 | } | 1227 | } |
| 1226 | static DEVICE_ATTR_RW(fail_cmd); | 1228 | static DEVICE_ATTR_RW(fail_cmd); |
| 1227 | 1229 | ||
| 1230 | static ssize_t fail_cmd_code_show(struct device *dev, struct device_attribute *attr, | ||
| 1231 | char *buf) | ||
| 1232 | { | ||
| 1233 | int dimm = dimm_name_to_id(dev); | ||
| 1234 | |||
| 1235 | if (dimm < 0) | ||
| 1236 | return dimm; | ||
| 1237 | |||
| 1238 | return sprintf(buf, "%d\n", dimm_fail_cmd_code[dimm]); | ||
| 1239 | } | ||
| 1240 | |||
| 1241 | static ssize_t fail_cmd_code_store(struct device *dev, struct device_attribute *attr, | ||
| 1242 | const char *buf, size_t size) | ||
| 1243 | { | ||
| 1244 | int dimm = dimm_name_to_id(dev); | ||
| 1245 | unsigned long val; | ||
| 1246 | ssize_t rc; | ||
| 1247 | |||
| 1248 | if (dimm < 0) | ||
| 1249 | return dimm; | ||
| 1250 | |||
| 1251 | rc = kstrtol(buf, 0, &val); | ||
| 1252 | if (rc) | ||
| 1253 | return rc; | ||
| 1254 | |||
| 1255 | dimm_fail_cmd_code[dimm] = val; | ||
| 1256 | return size; | ||
| 1257 | } | ||
| 1258 | static DEVICE_ATTR_RW(fail_cmd_code); | ||
| 1259 | |||
| 1228 | static struct attribute *nfit_test_dimm_attributes[] = { | 1260 | static struct attribute *nfit_test_dimm_attributes[] = { |
| 1229 | &dev_attr_fail_cmd.attr, | 1261 | &dev_attr_fail_cmd.attr, |
| 1262 | &dev_attr_fail_cmd_code.attr, | ||
| 1230 | &dev_attr_handle.attr, | 1263 | &dev_attr_handle.attr, |
| 1231 | NULL, | 1264 | NULL, |
| 1232 | }; | 1265 | }; |
| @@ -1240,6 +1273,23 @@ static const struct attribute_group *nfit_test_dimm_attribute_groups[] = { | |||
| 1240 | NULL, | 1273 | NULL, |
| 1241 | }; | 1274 | }; |
| 1242 | 1275 | ||
| 1276 | static int nfit_test_dimm_init(struct nfit_test *t) | ||
| 1277 | { | ||
| 1278 | int i; | ||
| 1279 | |||
| 1280 | if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t)) | ||
| 1281 | return -ENOMEM; | ||
| 1282 | for (i = 0; i < t->num_dcr; i++) { | ||
| 1283 | t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm, | ||
| 1284 | &t->pdev.dev, 0, NULL, | ||
| 1285 | nfit_test_dimm_attribute_groups, | ||
| 1286 | "test_dimm%d", i + t->dcr_idx); | ||
| 1287 | if (!t->dimm_dev[i]) | ||
| 1288 | return -ENOMEM; | ||
| 1289 | } | ||
| 1290 | return 0; | ||
| 1291 | } | ||
| 1292 | |||
| 1243 | static void smart_init(struct nfit_test *t) | 1293 | static void smart_init(struct nfit_test *t) |
| 1244 | { | 1294 | { |
| 1245 | int i; | 1295 | int i; |
| @@ -1335,17 +1385,8 @@ static int nfit_test0_alloc(struct nfit_test *t) | |||
| 1335 | if (!t->_fit) | 1385 | if (!t->_fit) |
| 1336 | return -ENOMEM; | 1386 | return -ENOMEM; |
| 1337 | 1387 | ||
| 1338 | if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t->dimm_dev)) | 1388 | if (nfit_test_dimm_init(t)) |
| 1339 | return -ENOMEM; | 1389 | return -ENOMEM; |
| 1340 | for (i = 0; i < NUM_DCR; i++) { | ||
| 1341 | t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm, | ||
| 1342 | &t->pdev.dev, 0, NULL, | ||
| 1343 | nfit_test_dimm_attribute_groups, | ||
| 1344 | "test_dimm%d", i); | ||
| 1345 | if (!t->dimm_dev[i]) | ||
| 1346 | return -ENOMEM; | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | smart_init(t); | 1390 | smart_init(t); |
| 1350 | return ars_state_init(&t->pdev.dev, &t->ars_state); | 1391 | return ars_state_init(&t->pdev.dev, &t->ars_state); |
| 1351 | } | 1392 | } |
| @@ -1377,6 +1418,8 @@ static int nfit_test1_alloc(struct nfit_test *t) | |||
| 1377 | if (!t->spa_set[1]) | 1418 | if (!t->spa_set[1]) |
| 1378 | return -ENOMEM; | 1419 | return -ENOMEM; |
| 1379 | 1420 | ||
| 1421 | if (nfit_test_dimm_init(t)) | ||
| 1422 | return -ENOMEM; | ||
| 1380 | smart_init(t); | 1423 | smart_init(t); |
| 1381 | return ars_state_init(&t->pdev.dev, &t->ars_state); | 1424 | return ars_state_init(&t->pdev.dev, &t->ars_state); |
| 1382 | } | 1425 | } |
| @@ -2222,6 +2265,9 @@ static void nfit_test1_setup(struct nfit_test *t) | |||
| 2222 | set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en); | 2265 | set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en); |
| 2223 | set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en); | 2266 | set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en); |
| 2224 | set_bit(ND_INTEL_ENABLE_LSS_STATUS, &acpi_desc->dimm_cmd_force_en); | 2267 | set_bit(ND_INTEL_ENABLE_LSS_STATUS, &acpi_desc->dimm_cmd_force_en); |
| 2268 | set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en); | ||
| 2269 | set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en); | ||
| 2270 | set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en); | ||
| 2225 | } | 2271 | } |
| 2226 | 2272 | ||
| 2227 | static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa, | 2273 | static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa, |
