1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright(c) 2013-2016 Intel Corporation. All rights reserved. 4 */ 5 #include <linux/device.h> 6 #include <linux/sizes.h> 7 #include <linux/slab.h> 8 #include <linux/mm.h> 9 #include "nd-core.h" 10 #include "pfn.h" 11 #include "nd.h" 12 13 static void nd_dax_release(struct device *dev) 14 { 15 struct nd_region *nd_region = to_nd_region(dev->parent); 16 struct nd_dax *nd_dax = to_nd_dax(dev); 17 struct nd_pfn *nd_pfn = &nd_dax->nd_pfn; 18 19 dev_dbg(dev, "trace\n"); 20 nd_detach_ndns(dev, &nd_pfn->ndns); 21 ida_simple_remove(&nd_region->dax_ida, nd_pfn->id); 22 kfree(nd_pfn->uuid); 23 kfree(nd_dax); 24 } 25 26 static struct device_type nd_dax_device_type = { 27 .name = "nd_dax", 28 .release = nd_dax_release, 29 }; 30 31 bool is_nd_dax(struct device *dev) 32 { 33 return dev ? dev->type == &nd_dax_device_type : false; 34 } 35 EXPORT_SYMBOL(is_nd_dax); 36 37 struct nd_dax *to_nd_dax(struct device *dev) 38 { 39 struct nd_dax *nd_dax = container_of(dev, struct nd_dax, nd_pfn.dev); 40 41 WARN_ON(!is_nd_dax(dev)); 42 return nd_dax; 43 } 44 EXPORT_SYMBOL(to_nd_dax); 45 46 static const struct attribute_group *nd_dax_attribute_groups[] = { 47 &nd_pfn_attribute_group, 48 &nd_device_attribute_group, 49 &nd_numa_attribute_group, 50 NULL, 51 }; 52 53 static struct nd_dax *nd_dax_alloc(struct nd_region *nd_region) 54 { 55 struct nd_pfn *nd_pfn; 56 struct nd_dax *nd_dax; 57 struct device *dev; 58 59 nd_dax = kzalloc(sizeof(*nd_dax), GFP_KERNEL); 60 if (!nd_dax) 61 return NULL; 62 63 nd_pfn = &nd_dax->nd_pfn; 64 nd_pfn->id = ida_simple_get(&nd_region->dax_ida, 0, 0, GFP_KERNEL); 65 if (nd_pfn->id < 0) { 66 kfree(nd_dax); 67 return NULL; 68 } 69 70 dev = &nd_pfn->dev; 71 dev_set_name(dev, "dax%d.%d", nd_region->id, nd_pfn->id); 72 dev->groups = nd_dax_attribute_groups; 73 dev->type = &nd_dax_device_type; 74 dev->parent = &nd_region->dev; 75 76 return nd_dax; 77 } 78 79 struct device *nd_dax_create(struct nd_region *nd_region) 80 { 81 struct device *dev = NULL; 82 struct nd_dax *nd_dax; 83 84 if (!is_memory(&nd_region->dev)) 85 return NULL; 86 87 nd_dax = nd_dax_alloc(nd_region); 88 if (nd_dax) 89 dev = nd_pfn_devinit(&nd_dax->nd_pfn, NULL); 90 __nd_device_register(dev); 91 return dev; 92 } 93 94 int nd_dax_probe(struct device *dev, struct nd_namespace_common *ndns) 95 { 96 int rc; 97 struct nd_dax *nd_dax; 98 struct device *dax_dev; 99 struct nd_pfn *nd_pfn; 100 struct nd_pfn_sb *pfn_sb; 101 struct nd_region *nd_region = to_nd_region(ndns->dev.parent); 102 103 if (ndns->force_raw) 104 return -ENODEV; 105 106 switch (ndns->claim_class) { 107 case NVDIMM_CCLASS_NONE: 108 case NVDIMM_CCLASS_DAX: 109 break; 110 default: 111 return -ENODEV; 112 } 113 114 nvdimm_bus_lock(&ndns->dev); 115 nd_dax = nd_dax_alloc(nd_region); 116 nd_pfn = &nd_dax->nd_pfn; 117 dax_dev = nd_pfn_devinit(nd_pfn, ndns); 118 nvdimm_bus_unlock(&ndns->dev); 119 if (!dax_dev) 120 return -ENOMEM; 121 pfn_sb = devm_kmalloc(dev, sizeof(*pfn_sb), GFP_KERNEL); 122 nd_pfn->pfn_sb = pfn_sb; 123 rc = nd_pfn_validate(nd_pfn, DAX_SIG); 124 dev_dbg(dev, "dax: %s\n", rc == 0 ? dev_name(dax_dev) : "<none>"); 125 if (rc < 0) { 126 nd_detach_ndns(dax_dev, &nd_pfn->ndns); 127 put_device(dax_dev); 128 } else 129 __nd_device_register(dax_dev); 130 131 return rc; 132 } 133 EXPORT_SYMBOL(nd_dax_probe); 134