dax_devs.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright(c) 2013-2016 Intel Corporation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of version 2 of the GNU General Public License as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * General Public License for more details.
  12. */
  13. #include <linux/device.h>
  14. #include <linux/sizes.h>
  15. #include <linux/slab.h>
  16. #include <linux/mm.h>
  17. #include "nd-core.h"
  18. #include "pfn.h"
  19. #include "nd.h"
  20. static void nd_dax_release(struct device *dev)
  21. {
  22. struct nd_region *nd_region = to_nd_region(dev->parent);
  23. struct nd_dax *nd_dax = to_nd_dax(dev);
  24. struct nd_pfn *nd_pfn = &nd_dax->nd_pfn;
  25. dev_dbg(dev, "trace\n");
  26. nd_detach_ndns(dev, &nd_pfn->ndns);
  27. ida_simple_remove(&nd_region->dax_ida, nd_pfn->id);
  28. kfree(nd_pfn->uuid);
  29. kfree(nd_dax);
  30. }
  31. static struct device_type nd_dax_device_type = {
  32. .name = "nd_dax",
  33. .release = nd_dax_release,
  34. };
  35. bool is_nd_dax(struct device *dev)
  36. {
  37. return dev ? dev->type == &nd_dax_device_type : false;
  38. }
  39. EXPORT_SYMBOL(is_nd_dax);
  40. struct nd_dax *to_nd_dax(struct device *dev)
  41. {
  42. struct nd_dax *nd_dax = container_of(dev, struct nd_dax, nd_pfn.dev);
  43. WARN_ON(!is_nd_dax(dev));
  44. return nd_dax;
  45. }
  46. EXPORT_SYMBOL(to_nd_dax);
  47. static const struct attribute_group *nd_dax_attribute_groups[] = {
  48. &nd_pfn_attribute_group,
  49. &nd_device_attribute_group,
  50. &nd_numa_attribute_group,
  51. NULL,
  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. nd_dax = kzalloc(sizeof(*nd_dax), GFP_KERNEL);
  59. if (!nd_dax)
  60. return NULL;
  61. nd_pfn = &nd_dax->nd_pfn;
  62. nd_pfn->id = ida_simple_get(&nd_region->dax_ida, 0, 0, GFP_KERNEL);
  63. if (nd_pfn->id < 0) {
  64. kfree(nd_dax);
  65. return NULL;
  66. }
  67. dev = &nd_pfn->dev;
  68. dev_set_name(dev, "dax%d.%d", nd_region->id, nd_pfn->id);
  69. dev->groups = nd_dax_attribute_groups;
  70. dev->type = &nd_dax_device_type;
  71. dev->parent = &nd_region->dev;
  72. return nd_dax;
  73. }
  74. struct device *nd_dax_create(struct nd_region *nd_region)
  75. {
  76. struct device *dev = NULL;
  77. struct nd_dax *nd_dax;
  78. if (!is_memory(&nd_region->dev))
  79. return NULL;
  80. nd_dax = nd_dax_alloc(nd_region);
  81. if (nd_dax)
  82. dev = nd_pfn_devinit(&nd_dax->nd_pfn, NULL);
  83. __nd_device_register(dev);
  84. return dev;
  85. }
  86. int nd_dax_probe(struct device *dev, struct nd_namespace_common *ndns)
  87. {
  88. int rc;
  89. struct nd_dax *nd_dax;
  90. struct device *dax_dev;
  91. struct nd_pfn *nd_pfn;
  92. struct nd_pfn_sb *pfn_sb;
  93. struct nd_region *nd_region = to_nd_region(ndns->dev.parent);
  94. if (ndns->force_raw)
  95. return -ENODEV;
  96. switch (ndns->claim_class) {
  97. case NVDIMM_CCLASS_NONE:
  98. case NVDIMM_CCLASS_DAX:
  99. break;
  100. default:
  101. return -ENODEV;
  102. }
  103. nvdimm_bus_lock(&ndns->dev);
  104. nd_dax = nd_dax_alloc(nd_region);
  105. nd_pfn = &nd_dax->nd_pfn;
  106. dax_dev = nd_pfn_devinit(nd_pfn, ndns);
  107. nvdimm_bus_unlock(&ndns->dev);
  108. if (!dax_dev)
  109. return -ENOMEM;
  110. pfn_sb = devm_kmalloc(dev, sizeof(*pfn_sb), GFP_KERNEL);
  111. nd_pfn->pfn_sb = pfn_sb;
  112. rc = nd_pfn_validate(nd_pfn, DAX_SIG);
  113. dev_dbg(dev, "dax: %s\n", rc == 0 ? dev_name(dax_dev) : "<none>");
  114. if (rc < 0) {
  115. nd_detach_ndns(dax_dev, &nd_pfn->ndns);
  116. put_device(dax_dev);
  117. } else
  118. __nd_device_register(dax_dev);
  119. return rc;
  120. }
  121. EXPORT_SYMBOL(nd_dax_probe);