History

libnvdimm, nfit: report multiple interface codes per-dimm

Starting with ACPI 6.1 an NFIT table will report multiple 'NVDIMM Control Region Structure' instances per-dimm, one for each supported format interface. Report that code in the following format in sysfs: nmemX/nfit/formats nmemX/nfit/format nmemX/nfit/format1 nmemX/nfit/format2 ... nmemX/nfit/formatN Where format2 - formatN are theoretical as there are no known DIMMs with support for more than two interface formats. This layout is compatible with existing libndctl binaries that only expect one code per-dimm as they will ignore nmemX/nfit/formats and nmemX/nfit/formatN.

Dan Williams committed 10 years ago

Commit 8cc6ddf1 parent bf162002 files · +70 −3Browse files

Unified · Split

2 files
  1. drivers/acpi/nfit.c +69 −3
  2. drivers/acpi/nfit.h +1 −0
drivers/acpi/nfit.c+69−3
@@ -655,6 +655,7 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc, · 654 unmodified lines
655655 if (!nfit_mem)
656656 return -ENOMEM;
657657 INIT_LIST_HEAD(&nfit_mem->list);
658+ nfit_mem->acpi_desc = acpi_desc;
658659 list_add(&nfit_mem->list, &acpi_desc->dimms);
659660 }
660661
@@ -838,6 +839,18 @@ static ssize_t device_show(struct device *dev, · 177 unmodified lines
838839 }
839840 static DEVICE_ATTR_RO(device);
840841
842+static int num_nvdimm_formats(struct nvdimm *nvdimm)
843+{
844+ struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
845+ int formats = 0;
846+
847+ if (nfit_mem->memdev_pmem)
848+ formats++;
849+ if (nfit_mem->memdev_bdw)
850+ formats++;
851+ return formats;
852+}
853+
841854 static ssize_t format_show(struct device *dev,
842855 struct device_attribute *attr, char *buf)
843856 {
@@ -847,6 +860,55 @@ static ssize_t format_show(struct device *dev, · 3 unmodified lines
847860 }
848861 static DEVICE_ATTR_RO(format);
849862
863+static ssize_t format1_show(struct device *dev,
864+ struct device_attribute *attr, char *buf)
865+{
866+ u32 handle;
867+ ssize_t rc = -ENXIO;
868+ struct nfit_mem *nfit_mem;
869+ struct nfit_memdev *nfit_memdev;
870+ struct acpi_nfit_desc *acpi_desc;
871+ struct nvdimm *nvdimm = to_nvdimm(dev);
872+ struct acpi_nfit_control_region *dcr = to_nfit_dcr(dev);
873+
874+ nfit_mem = nvdimm_provider_data(nvdimm);
875+ acpi_desc = nfit_mem->acpi_desc;
876+ handle = to_nfit_memdev(dev)->device_handle;
877+
878+ /* assumes DIMMs have at most 2 published interface codes */
879+ mutex_lock(&acpi_desc->init_mutex);
880+ list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
881+ struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev;
882+ struct nfit_dcr *nfit_dcr;
883+
884+ if (memdev->device_handle != handle)
885+ continue;
886+
887+ list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) {
888+ if (nfit_dcr->dcr->region_index != memdev->region_index)
889+ continue;
890+ if (nfit_dcr->dcr->code == dcr->code)
891+ continue;
892+ rc = sprintf(buf, "%#x\n", nfit_dcr->dcr->code);
893+ break;
894+ }
895+ if (rc != ENXIO)
896+ break;
897+ }
898+ mutex_unlock(&acpi_desc->init_mutex);
899+ return rc;
900+}
901+static DEVICE_ATTR_RO(format1);
902+
903+static ssize_t formats_show(struct device *dev,
904+ struct device_attribute *attr, char *buf)
905+{
906+ struct nvdimm *nvdimm = to_nvdimm(dev);
907+
908+ return sprintf(buf, "%d\n", num_nvdimm_formats(nvdimm));
909+}
910+static DEVICE_ATTR_RO(formats);
911+
850912 static ssize_t serial_show(struct device *dev,
851913 struct device_attribute *attr, char *buf)
852914 {
@@ -876,6 +938,8 @@ static struct attribute *acpi_nfit_dimm_attributes[] = { · 23 unmodified lines
876938 &dev_attr_vendor.attr,
877939 &dev_attr_device.attr,
878940 &dev_attr_format.attr,
941+ &dev_attr_formats.attr,
942+ &dev_attr_format1.attr,
879943 &dev_attr_serial.attr,
880944 &dev_attr_rev_id.attr,
881945 &dev_attr_flags.attr,
@@ -886,11 +950,13 @@ static umode_t acpi_nfit_dimm_attr_visible(struct kobject *kobj, · 4 unmodified lines
886950 struct attribute *a, int n)
887951 {
888952 struct device *dev = container_of(kobj, struct device, kobj);
953+ struct nvdimm *nvdimm = to_nvdimm(dev);
889954
890− if (to_nfit_dcr(dev))
891− return a->mode;
892− else
955+ if (!to_nfit_dcr(dev))
956+ return 0;
957+ if (a == &dev_attr_format1.attr && num_nvdimm_formats(nvdimm) <= 1)
893958 return 0;
959+ return a->mode;
894960 }
895961
896962 static struct attribute_group acpi_nfit_dimm_attribute_group = {
drivers/acpi/nfit.h+1−0
@@ -109,6 +109,7 @@ struct nfit_mem { · 108 unmodified lines
109109 struct nfit_flush *nfit_flush;
110110 struct list_head list;
111111 struct acpi_device *adev;
112+ struct acpi_nfit_desc *acpi_desc;
112113 unsigned long dsm_mask;
113114 };
114115

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t