summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-05-18 10:06:48 -0700
committerDan Williams <dan.j.williams@intel.com>2016-05-18 10:06:48 -0700
commit2159669f581917c4d197d3ea183d3d85b47faf66 (patch)
tree9faa8bbf19fa1ea33e371b02cfa5a5b4507583de /drivers
parent594d6d96ea042366878aa7dc7f5711b8c245db5a (diff)
parent9dec4892ca9afd6aad3c9c9e6c17480ecbd04440 (diff)
downloadlinux-2159669f581917c4d197d3ea183d3d85b47faf66.tar.gz
Merge branch 'for-4.7/libnvdimm' into libnvdimm-for-next
Diffstat (limited to 'drivers')
-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
4 files changed, 79 insertions, 5 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,
 			if (!nfit_mem)
 				return -ENOMEM;
 			INIT_LIST_HEAD(&nfit_mem->list);
+			nfit_mem->acpi_desc = acpi_desc;
 			list_add(&nfit_mem->list, &acpi_desc->dimms);
 		}
 
@@ -841,6 +842,18 @@ static ssize_t device_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(device);
 
+static int num_nvdimm_formats(struct nvdimm *nvdimm)
+{
+	struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
+	int formats = 0;
+
+	if (nfit_mem->memdev_pmem)
+		formats++;
+	if (nfit_mem->memdev_bdw)
+		formats++;
+	return formats;
+}
+
 static ssize_t format_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
@@ -850,6 +863,55 @@ static ssize_t format_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(format);
 
+static ssize_t format1_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	u32 handle;
+	ssize_t rc = -ENXIO;
+	struct nfit_mem *nfit_mem;
+	struct nfit_memdev *nfit_memdev;
+	struct acpi_nfit_desc *acpi_desc;
+	struct nvdimm *nvdimm = to_nvdimm(dev);
+	struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev);
+
+	nfit_mem = nvdimm_provider_data(nvdimm);
+	acpi_desc = nfit_mem->acpi_desc;
+	handle = to_nfit_memdev(dev)->device_handle;
+
+	/* assumes DIMMs have at most 2 published interface codes */
+	mutex_lock(&acpi_desc->init_mutex);
+	list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
+		struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev;
+		struct nfit_dcr *nfit_dcr;
+
+		if (memdev->device_handle != handle)
+			continue;
+
+		list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) {
+			if (nfit_dcr->dcr->region_index != memdev->region_index)
+				continue;
+			if (nfit_dcr->dcr->code == dcr->code)
+				continue;
+			rc = sprintf(buf, "%#x\n", nfit_dcr->dcr->code);
+			break;
+		}
+		if (rc != ENXIO)
+			break;
+	}
+	mutex_unlock(&acpi_desc->init_mutex);
+	return rc;
+}
+static DEVICE_ATTR_RO(format1);
+
+static ssize_t formats_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct nvdimm *nvdimm = to_nvdimm(dev);
+
+	return sprintf(buf, "%d\n", num_nvdimm_formats(nvdimm));
+}
+static DEVICE_ATTR_RO(formats);
+
 static ssize_t serial_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
@@ -879,6 +941,8 @@ static struct attribute *acpi_nfit_dimm_attributes[] = {
 	&dev_attr_vendor.attr,
 	&dev_attr_device.attr,
 	&dev_attr_format.attr,
+	&dev_attr_formats.attr,
+	&dev_attr_format1.attr,
 	&dev_attr_serial.attr,
 	&dev_attr_rev_id.attr,
 	&dev_attr_flags.attr,
@@ -889,11 +953,13 @@ static umode_t acpi_nfit_dimm_attr_visible(struct kobject *kobj,
 		struct attribute *a, int n)
 {
 	struct device *dev = container_of(kobj, struct device, kobj);
+	struct nvdimm *nvdimm = to_nvdimm(dev);
 
-	if (to_nfit_dcr(dev))
-		return a->mode;
-	else
+	if (!to_nfit_dcr(dev))
+		return 0;
+	if (a == &dev_attr_format1.attr && num_nvdimm_formats(nvdimm) <= 1)
 		return 0;
+	return a->mode;
 }
 
 static struct attribute_group acpi_nfit_dimm_attribute_group = {
@@ -2309,7 +2375,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
 	acpi_size sz;
 	int rc;
 
-	status = acpi_get_table_with_size("NFIT", 0, &tbl, &sz);
+	status = acpi_get_table_with_size(ACPI_SIG_NFIT, 0, &tbl, &sz);
 	if (ACPI_FAILURE(status)) {
 		/* This is ok, we could have an nvdimm hotplugged later */
 		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 {
 	struct nfit_flush *nfit_flush;
 	struct list_head list;
 	struct acpi_device *adev;
+	struct acpi_nfit_desc *acpi_desc;
 	unsigned long dsm_mask;
 };
 
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)
 	struct btt *btt;
 	size_t rawsize;
 
-	if (!nd_btt->uuid || !nd_btt->ndns || !nd_btt->lbasize)
+	if (!nd_btt->uuid || !nd_btt->ndns || !nd_btt->lbasize) {
+		dev_dbg(&nd_btt->dev, "incomplete btt configuration\n");
 		return -ENODEV;
+	}
 
 	rawsize = nvdimm_namespace_capacity(ndns) - SZ_4K;
 	if (rawsize < ARENA_MIN_SIZE) {
+		dev_dbg(&nd_btt->dev, "%s must be at least %ld bytes\n",
+				dev_name(&ndns->dev), ARENA_MIN_SIZE + SZ_4K);
 		return -ENXIO;
 	}
 	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)
 {
 	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;