[PATCH 2/9] libnvdimm, label: add v1.2 interleave-set-cookie algorithm

2017-06-08 Thread Dan Williams
The interleave-set-cookie algorithm is extended to incorporate all the
same components that are used to generate an nvdimm unique-id. For
backwards compatibility we still maintain the old v1.1 definition.

Signed-off-by: Dan Williams 
---
 drivers/acpi/nfit/core.c|   53 ++-
 drivers/nvdimm/label.c  |3 +-
 drivers/nvdimm/namespace_devs.c |9 +--
 drivers/nvdimm/nd.h |3 +-
 drivers/nvdimm/region_devs.c|   43 
 include/linux/libnvdimm.h   |5 +++-
 6 files changed, 104 insertions(+), 12 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 097eff0b963d..db21f5b62562 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -1663,12 +1663,29 @@ struct nfit_set_info {
} mapping[0];
 };
 
+struct nfit_set_info2 {
+   struct nfit_set_info_map2 {
+   u64 region_offset;
+   u32 serial_number;
+   u16 vendor_id;
+   u16 manufacturing_date;
+   u8  manufacturing_location;
+   u8  reserved[31];
+   } mapping[0];
+};
+
 static size_t sizeof_nfit_set_info(int num_mappings)
 {
return sizeof(struct nfit_set_info)
+ num_mappings * sizeof(struct nfit_set_info_map);
 }
 
+static size_t sizeof_nfit_set_info2(int num_mappings)
+{
+   return sizeof(struct nfit_set_info2)
+   + num_mappings * sizeof(struct nfit_set_info_map2);
+}
+
 static int cmp_map_compat(const void *m0, const void *m1)
 {
const struct nfit_set_info_map *map0 = m0;
@@ -1690,6 +1707,18 @@ static int cmp_map(const void *m0, const void *m1)
return 0;
 }
 
+static int cmp_map2(const void *m0, const void *m1)
+{
+   const struct nfit_set_info_map2 *map0 = m0;
+   const struct nfit_set_info_map2 *map1 = m1;
+
+   if (map0->region_offset < map1->region_offset)
+   return -1;
+   else if (map0->region_offset > map1->region_offset)
+   return 1;
+   return 0;
+}
+
 /* Retrieve the nth entry referencing this spa */
 static struct acpi_nfit_memory_map *memdev_from_spa(
struct acpi_nfit_desc *acpi_desc, u16 range_index, int n)
@@ -1711,6 +1740,7 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
struct device *dev = acpi_desc->dev;
struct nd_interleave_set *nd_set;
u16 nr = ndr_desc->num_mappings;
+   struct nfit_set_info2 *info2;
struct nfit_set_info *info;
 
if (spa_type == NFIT_SPA_PM || spa_type == NFIT_SPA_VOLATILE)
@@ -1725,9 +1755,15 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
info = devm_kzalloc(dev, sizeof_nfit_set_info(nr), GFP_KERNEL);
if (!info)
return -ENOMEM;
+
+   info2 = devm_kzalloc(dev, sizeof_nfit_set_info2(nr), GFP_KERNEL);
+   if (!info2)
+   return -ENOMEM;
+
for (i = 0; i < nr; i++) {
struct nd_mapping_desc *mapping = _desc->mapping[i];
struct nfit_set_info_map *map = >mapping[i];
+   struct nfit_set_info_map2 *map2 = >mapping[i];
struct nvdimm *nvdimm = mapping->nvdimm;
struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
struct acpi_nfit_memory_map *memdev = memdev_from_spa(acpi_desc,
@@ -1740,19 +1776,32 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
 
map->region_offset = memdev->region_offset;
map->serial_number = nfit_mem->dcr->serial_number;
+
+   map2->region_offset = memdev->region_offset;
+   map2->serial_number = nfit_mem->dcr->serial_number;
+   map2->vendor_id = nfit_mem->dcr->vendor_id;
+   map2->manufacturing_date = nfit_mem->dcr->manufacturing_date;
+   map2->manufacturing_location = 
nfit_mem->dcr->manufacturing_location;
}
 
+   /* v1.1 namespaces */
sort(>mapping[0], nr, sizeof(struct nfit_set_info_map),
cmp_map, NULL);
-   nd_set->cookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
+   nd_set->cookie1 = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
+
+   /* v1.2 namespaces */
+   sort(>mapping[0], nr, sizeof(struct nfit_set_info_map2),
+   cmp_map2, NULL);
+   nd_set->cookie2 = nd_fletcher64(info, sizeof_nfit_set_info2(nr), 0);
 
-   /* support namespaces created with the wrong sort order */
+   /* support v1.1 namespaces created with the wrong sort order */
sort(>mapping[0], nr, sizeof(struct nfit_set_info_map),
cmp_map_compat, NULL);
nd_set->altcookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
 
ndr_desc->nd_set = nd_set;
devm_kfree(dev, info);
+   devm_kfree(dev, info2);
 

[PATCH 2/9] libnvdimm, label: add v1.2 interleave-set-cookie algorithm

2017-06-08 Thread Dan Williams
The interleave-set-cookie algorithm is extended to incorporate all the
same components that are used to generate an nvdimm unique-id. For
backwards compatibility we still maintain the old v1.1 definition.

Signed-off-by: Dan Williams 
---
 drivers/acpi/nfit/core.c|   53 ++-
 drivers/nvdimm/label.c  |3 +-
 drivers/nvdimm/namespace_devs.c |9 +--
 drivers/nvdimm/nd.h |3 +-
 drivers/nvdimm/region_devs.c|   43 
 include/linux/libnvdimm.h   |5 +++-
 6 files changed, 104 insertions(+), 12 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 097eff0b963d..db21f5b62562 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -1663,12 +1663,29 @@ struct nfit_set_info {
} mapping[0];
 };
 
+struct nfit_set_info2 {
+   struct nfit_set_info_map2 {
+   u64 region_offset;
+   u32 serial_number;
+   u16 vendor_id;
+   u16 manufacturing_date;
+   u8  manufacturing_location;
+   u8  reserved[31];
+   } mapping[0];
+};
+
 static size_t sizeof_nfit_set_info(int num_mappings)
 {
return sizeof(struct nfit_set_info)
+ num_mappings * sizeof(struct nfit_set_info_map);
 }
 
+static size_t sizeof_nfit_set_info2(int num_mappings)
+{
+   return sizeof(struct nfit_set_info2)
+   + num_mappings * sizeof(struct nfit_set_info_map2);
+}
+
 static int cmp_map_compat(const void *m0, const void *m1)
 {
const struct nfit_set_info_map *map0 = m0;
@@ -1690,6 +1707,18 @@ static int cmp_map(const void *m0, const void *m1)
return 0;
 }
 
+static int cmp_map2(const void *m0, const void *m1)
+{
+   const struct nfit_set_info_map2 *map0 = m0;
+   const struct nfit_set_info_map2 *map1 = m1;
+
+   if (map0->region_offset < map1->region_offset)
+   return -1;
+   else if (map0->region_offset > map1->region_offset)
+   return 1;
+   return 0;
+}
+
 /* Retrieve the nth entry referencing this spa */
 static struct acpi_nfit_memory_map *memdev_from_spa(
struct acpi_nfit_desc *acpi_desc, u16 range_index, int n)
@@ -1711,6 +1740,7 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
struct device *dev = acpi_desc->dev;
struct nd_interleave_set *nd_set;
u16 nr = ndr_desc->num_mappings;
+   struct nfit_set_info2 *info2;
struct nfit_set_info *info;
 
if (spa_type == NFIT_SPA_PM || spa_type == NFIT_SPA_VOLATILE)
@@ -1725,9 +1755,15 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
info = devm_kzalloc(dev, sizeof_nfit_set_info(nr), GFP_KERNEL);
if (!info)
return -ENOMEM;
+
+   info2 = devm_kzalloc(dev, sizeof_nfit_set_info2(nr), GFP_KERNEL);
+   if (!info2)
+   return -ENOMEM;
+
for (i = 0; i < nr; i++) {
struct nd_mapping_desc *mapping = _desc->mapping[i];
struct nfit_set_info_map *map = >mapping[i];
+   struct nfit_set_info_map2 *map2 = >mapping[i];
struct nvdimm *nvdimm = mapping->nvdimm;
struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
struct acpi_nfit_memory_map *memdev = memdev_from_spa(acpi_desc,
@@ -1740,19 +1776,32 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
 
map->region_offset = memdev->region_offset;
map->serial_number = nfit_mem->dcr->serial_number;
+
+   map2->region_offset = memdev->region_offset;
+   map2->serial_number = nfit_mem->dcr->serial_number;
+   map2->vendor_id = nfit_mem->dcr->vendor_id;
+   map2->manufacturing_date = nfit_mem->dcr->manufacturing_date;
+   map2->manufacturing_location = 
nfit_mem->dcr->manufacturing_location;
}
 
+   /* v1.1 namespaces */
sort(>mapping[0], nr, sizeof(struct nfit_set_info_map),
cmp_map, NULL);
-   nd_set->cookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
+   nd_set->cookie1 = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
+
+   /* v1.2 namespaces */
+   sort(>mapping[0], nr, sizeof(struct nfit_set_info_map2),
+   cmp_map2, NULL);
+   nd_set->cookie2 = nd_fletcher64(info, sizeof_nfit_set_info2(nr), 0);
 
-   /* support namespaces created with the wrong sort order */
+   /* support v1.1 namespaces created with the wrong sort order */
sort(>mapping[0], nr, sizeof(struct nfit_set_info_map),
cmp_map_compat, NULL);
nd_set->altcookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
 
ndr_desc->nd_set = nd_set;
devm_kfree(dev, info);
+   devm_kfree(dev, info2);
 
return 0;
 }
diff --git