diff options
Diffstat (limited to 'drivers/nvdimm/namespace_devs.c')
| -rw-r--r-- | drivers/nvdimm/namespace_devs.c | 89 | 
1 files changed, 76 insertions, 13 deletions
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index fef0dd80d4ad..0955b2cb10fe 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -13,6 +13,7 @@  #include <linux/module.h>  #include <linux/device.h>  #include <linux/slab.h> +#include <linux/pmem.h>  #include <linux/nd.h>  #include "nd-core.h"  #include "nd.h" @@ -76,22 +77,54 @@ static bool is_namespace_io(struct device *dev)  	return dev ? dev->type == &namespace_io_device_type : false;  } +bool pmem_should_map_pages(struct device *dev) +{ +	struct nd_region *nd_region = to_nd_region(dev->parent); + +	if (!IS_ENABLED(CONFIG_ZONE_DEVICE)) +		return false; + +	if (!test_bit(ND_REGION_PAGEMAP, &nd_region->flags)) +		return false; + +	if (is_nd_pfn(dev) || is_nd_btt(dev)) +		return false; + +#ifdef ARCH_MEMREMAP_PMEM +	return ARCH_MEMREMAP_PMEM == MEMREMAP_WB; +#else +	return false; +#endif +} +EXPORT_SYMBOL(pmem_should_map_pages); +  const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns,  		char *name)  {  	struct nd_region *nd_region = to_nd_region(ndns->dev.parent); -	const char *suffix = ""; +	const char *suffix = NULL; -	if (ndns->claim && is_nd_btt(ndns->claim)) -		suffix = "s"; +	if (ndns->claim) { +		if (is_nd_btt(ndns->claim)) +			suffix = "s"; +		else if (is_nd_pfn(ndns->claim)) +			suffix = "m"; +		else +			dev_WARN_ONCE(&ndns->dev, 1, +					"unknown claim type by %s\n", +					dev_name(ndns->claim)); +	} -	if (is_namespace_pmem(&ndns->dev) || is_namespace_io(&ndns->dev)) -		sprintf(name, "pmem%d%s", nd_region->id, suffix); -	else if (is_namespace_blk(&ndns->dev)) { +	if (is_namespace_pmem(&ndns->dev) || is_namespace_io(&ndns->dev)) { +		if (!suffix && pmem_should_map_pages(&ndns->dev)) +			suffix = "m"; +		sprintf(name, "pmem%d%s", nd_region->id, suffix ? suffix : ""); +	} else if (is_namespace_blk(&ndns->dev)) {  		struct nd_namespace_blk *nsblk;  		nsblk = to_nd_namespace_blk(&ndns->dev); -		sprintf(name, "ndblk%d.%d%s", nd_region->id, nsblk->id, suffix); +		sprintf(name, "ndblk%d.%d%s", nd_region->id, nsblk->id, +				suffix ? suffix : "");  	} else {  		return NULL;  	} @@ -100,6 +133,26 @@ const char *nvdimm_namespace_disk_name(struct nd_namespace_common *ndns,  }  EXPORT_SYMBOL(nvdimm_namespace_disk_name); +const u8 *nd_dev_to_uuid(struct device *dev) +{ +	static const u8 null_uuid[16]; + +	if (!dev) +		return null_uuid; + +	if (is_namespace_pmem(dev)) { +		struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev); + +		return nspm->uuid; +	} else if (is_namespace_blk(dev)) { +		struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev); + +		return nsblk->uuid; +	} else +		return null_uuid; +} +EXPORT_SYMBOL(nd_dev_to_uuid); +  static ssize_t nstype_show(struct device *dev,  		struct device_attribute *attr, char *buf)  { @@ -1235,12 +1288,22 @@ static const struct attribute_group *nd_namespace_attribute_groups[] = {  struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev)  {  	struct nd_btt *nd_btt = is_nd_btt(dev) ? to_nd_btt(dev) : NULL; +	struct nd_pfn *nd_pfn = is_nd_pfn(dev) ? to_nd_pfn(dev) : NULL;  	struct nd_namespace_common *ndns;  	resource_size_t size; -	if (nd_btt) { -		ndns = nd_btt->ndns; -		if (!ndns) +	if (nd_btt || nd_pfn) { +		struct device *host = NULL; + +		if (nd_btt) { +			host = &nd_btt->dev; +			ndns = nd_btt->ndns; +		} else if (nd_pfn) { +			host = &nd_pfn->dev; +			ndns = nd_pfn->ndns; +		} + +		if (!ndns || !host)  			return ERR_PTR(-ENODEV);  		/* @@ -1251,12 +1314,12 @@ struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev)  		device_unlock(&ndns->dev);  		if (ndns->dev.driver) {  			dev_dbg(&ndns->dev, "is active, can't bind %s\n", -					dev_name(&nd_btt->dev)); +					dev_name(host));  			return ERR_PTR(-EBUSY);  		} -		if (dev_WARN_ONCE(&ndns->dev, ndns->claim != &nd_btt->dev, +		if (dev_WARN_ONCE(&ndns->dev, ndns->claim != host,  					"host (%s) vs claim (%s) mismatch\n", -					dev_name(&nd_btt->dev), +					dev_name(host),  					dev_name(ndns->claim)))  			return ERR_PTR(-ENXIO);  	} else {  |