diff options
author | Dan Williams <dan.j.williams@intel.com> | 2017-06-06 14:10:51 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2017-06-15 17:31:40 -0400 |
commit | faec6f8a1cd2c44e439de35ab3328c5cf7bf52d8 (patch) | |
tree | 140523684286a8a5283b54ec1e1d4e1a258fcc04 /drivers/nvdimm/namespace_devs.c | |
parent | f979b13c3cc51584882bffa32965f34e5afa3b9b (diff) |
libnvdimm, label: populate the type_guid property for v1.2 namespaces
The type_guid refers to the "Address Range Type GUID" for the region
backing a namespace as defined the ACPI NFIT (NVDIMM Firmware Interface
Table). This 'type' identifier specifies an access mechanism for the
given namespace. This capability replaces the confusing usage of the
'NSLABEL_FLAG_LOCAL' flag to indicate a block-aperture-mode namespace.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/nvdimm/namespace_devs.c')
-rw-r--r-- | drivers/nvdimm/namespace_devs.c | 57 |
1 files changed, 38 insertions, 19 deletions
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index e034b003a5e2..e101aec186c7 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c | |||
@@ -1639,6 +1639,8 @@ static bool has_uuid_at_pos(struct nd_region *nd_region, u8 *uuid, | |||
1639 | 1639 | ||
1640 | for (i = 0; i < nd_region->ndr_mappings; i++) { | 1640 | for (i = 0; i < nd_region->ndr_mappings; i++) { |
1641 | struct nd_mapping *nd_mapping = &nd_region->mapping[i]; | 1641 | struct nd_mapping *nd_mapping = &nd_region->mapping[i]; |
1642 | struct nd_interleave_set *nd_set = nd_region->nd_set; | ||
1643 | struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); | ||
1642 | struct nd_label_ent *label_ent; | 1644 | struct nd_label_ent *label_ent; |
1643 | bool found_uuid = false; | 1645 | bool found_uuid = false; |
1644 | 1646 | ||
@@ -1659,8 +1661,17 @@ static bool has_uuid_at_pos(struct nd_region *nd_region, u8 *uuid, | |||
1659 | if (memcmp(nd_label->uuid, uuid, NSLABEL_UUID_LEN) != 0) | 1661 | if (memcmp(nd_label->uuid, uuid, NSLABEL_UUID_LEN) != 0) |
1660 | continue; | 1662 | continue; |
1661 | 1663 | ||
1664 | if (namespace_label_has(ndd, type_guid) | ||
1665 | && !guid_equal(&nd_set->type_guid, | ||
1666 | &nd_label->type_guid)) { | ||
1667 | dev_dbg(ndd->dev, "expect type_guid %pUb got %pUb\n", | ||
1668 | nd_set->type_guid.b, | ||
1669 | nd_label->type_guid.b); | ||
1670 | continue; | ||
1671 | } | ||
1672 | |||
1662 | if (found_uuid) { | 1673 | if (found_uuid) { |
1663 | dev_dbg(to_ndd(nd_mapping)->dev, | 1674 | dev_dbg(ndd->dev, |
1664 | "%s duplicate entry for uuid\n", | 1675 | "%s duplicate entry for uuid\n", |
1665 | __func__); | 1676 | __func__); |
1666 | return false; | 1677 | return false; |
@@ -2047,12 +2058,21 @@ struct device *create_namespace_blk(struct nd_region *nd_region, | |||
2047 | { | 2058 | { |
2048 | 2059 | ||
2049 | struct nd_mapping *nd_mapping = &nd_region->mapping[0]; | 2060 | struct nd_mapping *nd_mapping = &nd_region->mapping[0]; |
2061 | struct nd_interleave_set *nd_set = nd_region->nd_set; | ||
2050 | struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); | 2062 | struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); |
2051 | struct nd_namespace_blk *nsblk; | 2063 | struct nd_namespace_blk *nsblk; |
2052 | char name[NSLABEL_NAME_LEN]; | 2064 | char name[NSLABEL_NAME_LEN]; |
2053 | struct device *dev = NULL; | 2065 | struct device *dev = NULL; |
2054 | struct resource *res; | 2066 | struct resource *res; |
2055 | 2067 | ||
2068 | if (namespace_label_has(ndd, type_guid) | ||
2069 | && !guid_equal(&nd_set->type_guid, | ||
2070 | &nd_label->type_guid)) { | ||
2071 | dev_dbg(ndd->dev, "expect type_guid %pUb got %pUb\n", | ||
2072 | nd_set->type_guid.b, nd_label->type_guid.b); | ||
2073 | return ERR_PTR(-EAGAIN); | ||
2074 | } | ||
2075 | |||
2056 | nsblk = kzalloc(sizeof(*nsblk), GFP_KERNEL); | 2076 | nsblk = kzalloc(sizeof(*nsblk), GFP_KERNEL); |
2057 | if (!nsblk) | 2077 | if (!nsblk) |
2058 | return ERR_PTR(-ENOMEM); | 2078 | return ERR_PTR(-ENOMEM); |
@@ -2144,31 +2164,30 @@ static struct device **scan_labels(struct nd_region *nd_region) | |||
2144 | kfree(devs); | 2164 | kfree(devs); |
2145 | devs = __devs; | 2165 | devs = __devs; |
2146 | 2166 | ||
2147 | if (is_nd_blk(&nd_region->dev)) { | 2167 | if (is_nd_blk(&nd_region->dev)) |
2148 | dev = create_namespace_blk(nd_region, nd_label, count); | 2168 | dev = create_namespace_blk(nd_region, nd_label, count); |
2149 | if (IS_ERR(dev)) | 2169 | else { |
2150 | goto err; | ||
2151 | devs[count++] = dev; | ||
2152 | } else { | ||
2153 | struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); | 2170 | struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); |
2154 | struct nd_namespace_index *nsindex; | 2171 | struct nd_namespace_index *nsindex; |
2155 | 2172 | ||
2156 | nsindex = to_namespace_index(ndd, ndd->ns_current); | 2173 | nsindex = to_namespace_index(ndd, ndd->ns_current); |
2157 | dev = create_namespace_pmem(nd_region, nsindex, nd_label); | 2174 | dev = create_namespace_pmem(nd_region, nsindex, nd_label); |
2158 | if (IS_ERR(dev)) { | ||
2159 | switch (PTR_ERR(dev)) { | ||
2160 | case -EAGAIN: | ||
2161 | /* skip invalid labels */ | ||
2162 | continue; | ||
2163 | case -ENODEV: | ||
2164 | /* fallthrough to seed creation */ | ||
2165 | break; | ||
2166 | default: | ||
2167 | goto err; | ||
2168 | } | ||
2169 | } else | ||
2170 | devs[count++] = dev; | ||
2171 | } | 2175 | } |
2176 | |||
2177 | if (IS_ERR(dev)) { | ||
2178 | switch (PTR_ERR(dev)) { | ||
2179 | case -EAGAIN: | ||
2180 | /* skip invalid labels */ | ||
2181 | continue; | ||
2182 | case -ENODEV: | ||
2183 | /* fallthrough to seed creation */ | ||
2184 | break; | ||
2185 | default: | ||
2186 | goto err; | ||
2187 | } | ||
2188 | } else | ||
2189 | devs[count++] = dev; | ||
2190 | |||
2172 | } | 2191 | } |
2173 | 2192 | ||
2174 | dev_dbg(&nd_region->dev, "%s: discovered %d %s namespace%s\n", | 2193 | dev_dbg(&nd_region->dev, "%s: discovered %d %s namespace%s\n", |