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