|
@@ -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 = &ndr_desc->mapping[i];
|
|
|
struct nfit_set_info_map *map = &info->mapping[i];
|
|
|
+ struct nfit_set_info_map2 *map2 = &info2->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(&info->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(&info2->mapping[0], nr, sizeof(struct nfit_set_info_map2),
|
|
|
+ cmp_map2, NULL);
|
|
|
+ nd_set->cookie2 = nd_fletcher64(info2, 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(&info->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;
|
|
|
}
|