aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-05-18 13:06:48 -0400
committerDan Williams <dan.j.williams@intel.com>2016-05-18 13:06:48 -0400
commit2159669f581917c4d197d3ea183d3d85b47faf66 (patch)
tree9faa8bbf19fa1ea33e371b02cfa5a5b4507583de
parent594d6d96ea042366878aa7dc7f5711b8c245db5a (diff)
parent9dec4892ca9afd6aad3c9c9e6c17480ecbd04440 (diff)
Merge branch 'for-4.7/libnvdimm' into libnvdimm-for-next
-rw-r--r--drivers/acpi/nfit.c74
-rw-r--r--drivers/acpi/nfit.h1
-rw-r--r--drivers/nvdimm/btt.c6
-rw-r--r--drivers/nvdimm/bus.c3
-rw-r--r--include/uapi/linux/ndctl.h36
-rw-r--r--tools/testing/nvdimm/test/nfit.c44
6 files changed, 158 insertions, 6 deletions
diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
index 63cc9dbe4f3b..d60f73a63c3c 100644
--- a/drivers/acpi/nfit.c
+++ b/drivers/acpi/nfit.c
@@ -658,6 +658,7 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc,
658 if (!nfit_mem) 658 if (!nfit_mem)
659 return -ENOMEM; 659 return -ENOMEM;
660 INIT_LIST_HEAD(&nfit_mem->list); 660 INIT_LIST_HEAD(&nfit_mem->list);
661 nfit_mem->acpi_desc = acpi_desc;
661 list_add(&nfit_mem->list, &acpi_desc->dimms); 662 list_add(&nfit_mem->list, &acpi_desc->dimms);
662 } 663 }
663 664
@@ -841,6 +842,18 @@ static ssize_t device_show(struct device *dev,
841} 842}
842static DEVICE_ATTR_RO(device); 843static DEVICE_ATTR_RO(device);
843 844
845static int num_nvdimm_formats(struct nvdimm *nvdimm)
846{
847 struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
848 int formats = 0;
849
850 if (nfit_mem->memdev_pmem)
851 formats++;
852 if (nfit_mem->memdev_bdw)
853 formats++;
854 return formats;
855}
856
844static ssize_t format_show(struct device *dev, 857static ssize_t format_show(struct device *dev,
845 struct device_attribute *attr, char *buf) 858 struct device_attribute *attr, char *buf)
846{ 859{
@@ -850,6 +863,55 @@ static ssize_t format_show(struct device *dev,
850} 863}
851static DEVICE_ATTR_RO(format); 864static DEVICE_ATTR_RO(format);
852 865
866static ssize_t format1_show(struct device *dev,
867 struct device_attribute *attr, char *buf)
868{
869 u32 handle;
870 ssize_t rc = -ENXIO;
871 struct nfit_mem *nfit_mem;
872 struct nfit_memdev *nfit_memdev;
873 struct acpi_nfit_desc *acpi_desc;
874 struct nvdimm *nvdimm = to_nvdimm(dev);
875 struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev);
876
877 nfit_mem = nvdimm_provider_data(nvdimm);
878 acpi_desc = nfit_mem->acpi_desc;
879 handle = to_nfit_memdev(dev)->device_handle;
880
881 /* assumes DIMMs have at most 2 published interface codes */
882 mutex_lock(&acpi_desc->init_mutex);
883 list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
884 struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev;
885 struct nfit_dcr *nfit_dcr;
886
887 if (memdev->device_handle != handle)
888 continue;
889
890 list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) {
891 if (nfit_dcr->dcr->region_index != memdev->region_index)
892 continue;
893 if (nfit_dcr->dcr->code == dcr->code)
894 continue;
895 rc = sprintf(buf, "%#x\n", nfit_dcr->dcr->code);
896 break;
897 }
898 if (rc != ENXIO)
899 break;
900 }
901 mutex_unlock(&acpi_desc->init_mutex);
902 return rc;
903}
904static DEVICE_ATTR_RO(format1);
905
906static ssize_t formats_show(struct device *dev,
907 struct device_attribute *attr, char *buf)
908{
909 struct nvdimm *nvdimm = to_nvdimm(dev);
910
911 return sprintf(buf, "%d\n", num_nvdimm_formats(nvdimm));
912}
913static DEVICE_ATTR_RO(formats);
914
853static ssize_t serial_show(struct device *dev, 915static ssize_t serial_show(struct device *dev,
854 struct device_attribute *attr, char *buf) 916 struct device_attribute *attr, char *buf)
855{ 917{
@@ -879,6 +941,8 @@ static struct attribute *acpi_nfit_dimm_attributes[] = {
879 &dev_attr_vendor.attr, 941 &dev_attr_vendor.attr,
880 &dev_attr_device.attr, 942 &dev_attr_device.attr,
881 &dev_attr_format.attr, 943 &dev_attr_format.attr,
944 &dev_attr_formats.attr,
945 &dev_attr_format1.attr,
882 &dev_attr_serial.attr, 946 &dev_attr_serial.attr,
883 &dev_attr_rev_id.attr, 947 &dev_attr_rev_id.attr,
884 &dev_attr_flags.attr, 948 &dev_attr_flags.attr,
@@ -889,11 +953,13 @@ static umode_t acpi_nfit_dimm_attr_visible(struct kobject *kobj,
889 struct attribute *a, int n) 953 struct attribute *a, int n)
890{ 954{
891 struct device *dev = container_of(kobj, struct device, kobj); 955 struct device *dev = container_of(kobj, struct device, kobj);
956 struct nvdimm *nvdimm = to_nvdimm(dev);
892 957
893 if (to_nfit_dcr(dev)) 958 if (!to_nfit_dcr(dev))
894 return a->mode; 959 return 0;
895 else 960 if (a == &dev_attr_format1.attr && num_nvdimm_formats(nvdimm) <= 1)
896 return 0; 961 return 0;
962 return a->mode;
897} 963}
898 964
899static struct attribute_group acpi_nfit_dimm_attribute_group = { 965static struct attribute_group acpi_nfit_dimm_attribute_group = {
@@ -2309,7 +2375,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
2309 acpi_size sz; 2375 acpi_size sz;
2310 int rc; 2376 int rc;
2311 2377
2312 status = acpi_get_table_with_size("NFIT", 0, &tbl, &sz); 2378 status = acpi_get_table_with_size(ACPI_SIG_NFIT, 0, &tbl, &sz);
2313 if (ACPI_FAILURE(status)) { 2379 if (ACPI_FAILURE(status)) {
2314 /* This is ok, we could have an nvdimm hotplugged later */ 2380 /* This is ok, we could have an nvdimm hotplugged later */
2315 dev_dbg(dev, "failed to find NFIT at startup\n"); 2381 dev_dbg(dev, "failed to find NFIT at startup\n");
diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit.h
index c75576b2d50e..5201840c1147 100644
--- a/drivers/acpi/nfit.h
+++ b/drivers/acpi/nfit.h
@@ -109,6 +109,7 @@ struct nfit_mem {
109 struct nfit_flush *nfit_flush; 109 struct nfit_flush *nfit_flush;
110 struct list_head list; 110 struct list_head list;
111 struct acpi_device *adev; 111 struct acpi_device *adev;
112 struct acpi_nfit_desc *acpi_desc;
112 unsigned long dsm_mask; 113 unsigned long dsm_mask;
113}; 114};
114 115
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index cc9fafed9362..68a7c3c1eed9 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -1383,11 +1383,15 @@ int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns)
1383 struct btt *btt; 1383 struct btt *btt;
1384 size_t rawsize; 1384 size_t rawsize;
1385 1385
1386 if (!nd_btt->uuid || !nd_btt->ndns || !nd_btt->lbasize) 1386 if (!nd_btt->uuid || !nd_btt->ndns || !nd_btt->lbasize) {
1387 dev_dbg(&nd_btt->dev, "incomplete btt configuration\n");
1387 return -ENODEV; 1388 return -ENODEV;
1389 }
1388 1390
1389 rawsize = nvdimm_namespace_capacity(ndns) - SZ_4K; 1391 rawsize = nvdimm_namespace_capacity(ndns) - SZ_4K;
1390 if (rawsize < ARENA_MIN_SIZE) { 1392 if (rawsize < ARENA_MIN_SIZE) {
1393 dev_dbg(&nd_btt->dev, "%s must be at least %ld bytes\n",
1394 dev_name(&ndns->dev), ARENA_MIN_SIZE + SZ_4K);
1391 return -ENXIO; 1395 return -ENXIO;
1392 } 1396 }
1393 nd_region = to_nd_region(nd_btt->dev.parent); 1397 nd_region = to_nd_region(nd_btt->dev.parent);
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index 97589e3cb852..dcaefe229887 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -787,6 +787,9 @@ int __init nvdimm_bus_init(void)
787{ 787{
788 int rc; 788 int rc;
789 789
790 BUILD_BUG_ON(sizeof(struct nd_smart_payload) != 128);
791 BUILD_BUG_ON(sizeof(struct nd_smart_threshold_payload) != 8);
792
790 rc = bus_register(&nvdimm_bus_type); 793 rc = bus_register(&nvdimm_bus_type);
791 if (rc) 794 if (rc)
792 return rc; 795 return rc;
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index 4f29d247f709..1eac426aead5 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014-2015, Intel Corporation. 2 * Copyright (c) 2014-2016, Intel Corporation.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU Lesser General Public License, 5 * under the terms and conditions of the GNU Lesser General Public License,
@@ -20,11 +20,45 @@ struct nd_cmd_smart {
20 __u8 data[128]; 20 __u8 data[128];
21} __packed; 21} __packed;
22 22
23#define ND_SMART_HEALTH_VALID (1 << 0)
24#define ND_SMART_TEMP_VALID (1 << 1)
25#define ND_SMART_SPARES_VALID (1 << 2)
26#define ND_SMART_ALARM_VALID (1 << 3)
27#define ND_SMART_USED_VALID (1 << 4)
28#define ND_SMART_SHUTDOWN_VALID (1 << 5)
29#define ND_SMART_VENDOR_VALID (1 << 6)
30#define ND_SMART_TEMP_TRIP (1 << 0)
31#define ND_SMART_SPARE_TRIP (1 << 1)
32#define ND_SMART_NON_CRITICAL_HEALTH (1 << 0)
33#define ND_SMART_CRITICAL_HEALTH (1 << 1)
34#define ND_SMART_FATAL_HEALTH (1 << 2)
35
36struct nd_smart_payload {
37 __u32 flags;
38 __u8 reserved0[4];
39 __u8 health;
40 __u16 temperature;
41 __u8 spares;
42 __u8 alarm_flags;
43 __u8 life_used;
44 __u8 shutdown_state;
45 __u8 reserved1;
46 __u32 vendor_size;
47 __u8 vendor_data[108];
48} __packed;
49
23struct nd_cmd_smart_threshold { 50struct nd_cmd_smart_threshold {
24 __u32 status; 51 __u32 status;
25 __u8 data[8]; 52 __u8 data[8];
26} __packed; 53} __packed;
27 54
55struct nd_smart_threshold_payload {
56 __u16 alarm_control;
57 __u16 temperature;
58 __u8 spares;
59 __u8 reserved[3];
60} __packed;
61
28struct nd_cmd_dimm_flags { 62struct nd_cmd_dimm_flags {
29 __u32 status; 63 __u32 status;
30 __u32 flags; 64 __u32 flags;
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 3187322eeed7..d1c98d4386d4 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -330,6 +330,42 @@ static int nfit_test_cmd_clear_error(struct nd_cmd_clear_error *clear_err,
330 return 0; 330 return 0;
331} 331}
332 332
333static int nfit_test_cmd_smart(struct nd_cmd_smart *smart, unsigned int buf_len)
334{
335 static const struct nd_smart_payload smart_data = {
336 .flags = ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID
337 | ND_SMART_SPARES_VALID | ND_SMART_ALARM_VALID
338 | ND_SMART_USED_VALID | ND_SMART_SHUTDOWN_VALID,
339 .health = ND_SMART_NON_CRITICAL_HEALTH,
340 .temperature = 23 * 16,
341 .spares = 75,
342 .alarm_flags = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
343 .life_used = 5,
344 .shutdown_state = 0,
345 .vendor_size = 0,
346 };
347
348 if (buf_len < sizeof(*smart))
349 return -EINVAL;
350 memcpy(smart->data, &smart_data, sizeof(smart_data));
351 return 0;
352}
353
354static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold *smart_t,
355 unsigned int buf_len)
356{
357 static const struct nd_smart_threshold_payload smart_t_data = {
358 .alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
359 .temperature = 40 * 16,
360 .spares = 5,
361 };
362
363 if (buf_len < sizeof(*smart_t))
364 return -EINVAL;
365 memcpy(smart_t->data, &smart_t_data, sizeof(smart_t_data));
366 return 0;
367}
368
333static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc, 369static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
334 struct nvdimm *nvdimm, unsigned int cmd, void *buf, 370 struct nvdimm *nvdimm, unsigned int cmd, void *buf,
335 unsigned int buf_len, int *cmd_rc) 371 unsigned int buf_len, int *cmd_rc)
@@ -368,6 +404,12 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
368 rc = nfit_test_cmd_set_config_data(buf, buf_len, 404 rc = nfit_test_cmd_set_config_data(buf, buf_len,
369 t->label[i]); 405 t->label[i]);
370 break; 406 break;
407 case ND_CMD_SMART:
408 rc = nfit_test_cmd_smart(buf, buf_len);
409 break;
410 case ND_CMD_SMART_THRESHOLD:
411 rc = nfit_test_cmd_smart_threshold(buf, buf_len);
412 break;
371 default: 413 default:
372 return -ENOTTY; 414 return -ENOTTY;
373 } 415 }
@@ -1254,10 +1296,12 @@ static void nfit_test0_setup(struct nfit_test *t)
1254 set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_dsm_force_en); 1296 set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_dsm_force_en);
1255 set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en); 1297 set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
1256 set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en); 1298 set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_dsm_force_en);
1299 set_bit(ND_CMD_SMART, &acpi_desc->dimm_dsm_force_en);
1257 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en); 1300 set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_dsm_force_en);
1258 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en); 1301 set_bit(ND_CMD_ARS_START, &acpi_desc->bus_dsm_force_en);
1259 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en); 1302 set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_dsm_force_en);
1260 set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_dsm_force_en); 1303 set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_dsm_force_en);
1304 set_bit(ND_CMD_SMART_THRESHOLD, &acpi_desc->dimm_dsm_force_en);
1261} 1305}
1262 1306
1263static void nfit_test1_setup(struct nfit_test *t) 1307static void nfit_test1_setup(struct nfit_test *t)