0001
0002
0003
0004
0005 #include <linux/device.h>
0006 #include <linux/sizes.h>
0007 #include <linux/slab.h>
0008 #include <linux/mm.h>
0009 #include "nd-core.h"
0010 #include "pfn.h"
0011 #include "nd.h"
0012
0013 static void nd_dax_release(struct device *dev)
0014 {
0015 struct nd_region *nd_region = to_nd_region(dev->parent);
0016 struct nd_dax *nd_dax = to_nd_dax(dev);
0017 struct nd_pfn *nd_pfn = &nd_dax->nd_pfn;
0018
0019 dev_dbg(dev, "trace\n");
0020 nd_detach_ndns(dev, &nd_pfn->ndns);
0021 ida_simple_remove(&nd_region->dax_ida, nd_pfn->id);
0022 kfree(nd_pfn->uuid);
0023 kfree(nd_dax);
0024 }
0025
0026 struct nd_dax *to_nd_dax(struct device *dev)
0027 {
0028 struct nd_dax *nd_dax = container_of(dev, struct nd_dax, nd_pfn.dev);
0029
0030 WARN_ON(!is_nd_dax(dev));
0031 return nd_dax;
0032 }
0033 EXPORT_SYMBOL(to_nd_dax);
0034
0035 static const struct device_type nd_dax_device_type = {
0036 .name = "nd_dax",
0037 .release = nd_dax_release,
0038 .groups = nd_pfn_attribute_groups,
0039 };
0040
0041 bool is_nd_dax(struct device *dev)
0042 {
0043 return dev ? dev->type == &nd_dax_device_type : false;
0044 }
0045 EXPORT_SYMBOL(is_nd_dax);
0046
0047 static struct nd_dax *nd_dax_alloc(struct nd_region *nd_region)
0048 {
0049 struct nd_pfn *nd_pfn;
0050 struct nd_dax *nd_dax;
0051 struct device *dev;
0052
0053 nd_dax = kzalloc(sizeof(*nd_dax), GFP_KERNEL);
0054 if (!nd_dax)
0055 return NULL;
0056
0057 nd_pfn = &nd_dax->nd_pfn;
0058 nd_pfn->id = ida_simple_get(&nd_region->dax_ida, 0, 0, GFP_KERNEL);
0059 if (nd_pfn->id < 0) {
0060 kfree(nd_dax);
0061 return NULL;
0062 }
0063
0064 dev = &nd_pfn->dev;
0065 dev_set_name(dev, "dax%d.%d", nd_region->id, nd_pfn->id);
0066 dev->type = &nd_dax_device_type;
0067 dev->parent = &nd_region->dev;
0068
0069 return nd_dax;
0070 }
0071
0072 struct device *nd_dax_create(struct nd_region *nd_region)
0073 {
0074 struct device *dev = NULL;
0075 struct nd_dax *nd_dax;
0076
0077 if (!is_memory(&nd_region->dev))
0078 return NULL;
0079
0080 nd_dax = nd_dax_alloc(nd_region);
0081 if (nd_dax)
0082 dev = nd_pfn_devinit(&nd_dax->nd_pfn, NULL);
0083 nd_device_register(dev);
0084 return dev;
0085 }
0086
0087 int nd_dax_probe(struct device *dev, struct nd_namespace_common *ndns)
0088 {
0089 int rc;
0090 struct nd_dax *nd_dax;
0091 struct device *dax_dev;
0092 struct nd_pfn *nd_pfn;
0093 struct nd_pfn_sb *pfn_sb;
0094 struct nd_region *nd_region = to_nd_region(ndns->dev.parent);
0095
0096 if (ndns->force_raw)
0097 return -ENODEV;
0098
0099 switch (ndns->claim_class) {
0100 case NVDIMM_CCLASS_NONE:
0101 case NVDIMM_CCLASS_DAX:
0102 break;
0103 default:
0104 return -ENODEV;
0105 }
0106
0107 nvdimm_bus_lock(&ndns->dev);
0108 nd_dax = nd_dax_alloc(nd_region);
0109 nd_pfn = &nd_dax->nd_pfn;
0110 dax_dev = nd_pfn_devinit(nd_pfn, ndns);
0111 nvdimm_bus_unlock(&ndns->dev);
0112 if (!dax_dev)
0113 return -ENOMEM;
0114 pfn_sb = devm_kmalloc(dev, sizeof(*pfn_sb), GFP_KERNEL);
0115 nd_pfn->pfn_sb = pfn_sb;
0116 rc = nd_pfn_validate(nd_pfn, DAX_SIG);
0117 dev_dbg(dev, "dax: %s\n", rc == 0 ? dev_name(dax_dev) : "<none>");
0118 if (rc < 0) {
0119 nd_detach_ndns(dax_dev, &nd_pfn->ndns);
0120 put_device(dax_dev);
0121 } else
0122 nd_device_register(dax_dev);
0123
0124 return rc;
0125 }
0126 EXPORT_SYMBOL(nd_dax_probe);