dimm.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
  4. */
  5. #include <linux/vmalloc.h>
  6. #include <linux/module.h>
  7. #include <linux/device.h>
  8. #include <linux/sizes.h>
  9. #include <linux/ndctl.h>
  10. #include <linux/slab.h>
  11. #include <linux/mm.h>
  12. #include <linux/nd.h>
  13. #include "label.h"
  14. #include "nd.h"
  15. static int nvdimm_probe(struct device *dev)
  16. {
  17. struct nvdimm_drvdata *ndd;
  18. int rc;
  19. rc = nvdimm_security_setup_events(dev);
  20. if (rc < 0) {
  21. dev_err(dev, "security event setup failed: %d\n", rc);
  22. return rc;
  23. }
  24. rc = nvdimm_check_config_data(dev);
  25. if (rc) {
  26. /* not required for non-aliased nvdimm, ex. NVDIMM-N */
  27. if (rc == -ENOTTY)
  28. rc = 0;
  29. return rc;
  30. }
  31. /*
  32. * The locked status bit reflects explicit status codes from the
  33. * label reading commands, revalidate it each time the driver is
  34. * activated and re-reads the label area.
  35. */
  36. nvdimm_clear_locked(dev);
  37. ndd = kzalloc(sizeof(*ndd), GFP_KERNEL);
  38. if (!ndd)
  39. return -ENOMEM;
  40. dev_set_drvdata(dev, ndd);
  41. ndd->dpa.name = dev_name(dev);
  42. ndd->ns_current = -1;
  43. ndd->ns_next = -1;
  44. ndd->dpa.start = 0;
  45. ndd->dpa.end = -1;
  46. ndd->dev = dev;
  47. get_device(dev);
  48. kref_init(&ndd->kref);
  49. /*
  50. * Attempt to unlock, if the DIMM supports security commands,
  51. * otherwise the locked indication is determined by explicit
  52. * status codes from the label reading commands.
  53. */
  54. rc = nvdimm_security_unlock(dev);
  55. if (rc < 0)
  56. dev_dbg(dev, "failed to unlock dimm: %d\n", rc);
  57. /*
  58. * EACCES failures reading the namespace label-area-properties
  59. * are interpreted as the DIMM capacity being locked but the
  60. * namespace labels themselves being accessible.
  61. */
  62. rc = nvdimm_init_nsarea(ndd);
  63. if (rc == -EACCES) {
  64. /*
  65. * See nvdimm_namespace_common_probe() where we fail to
  66. * allow namespaces to probe while the DIMM is locked,
  67. * but we do allow for namespace enumeration.
  68. */
  69. nvdimm_set_locked(dev);
  70. rc = 0;
  71. }
  72. if (rc)
  73. goto err;
  74. /*
  75. * EACCES failures reading the namespace label-data are
  76. * interpreted as the label area being locked in addition to the
  77. * DIMM capacity. We fail the dimm probe to prevent regions from
  78. * attempting to parse the label area.
  79. */
  80. rc = nd_label_data_init(ndd);
  81. if (rc == -EACCES)
  82. nvdimm_set_locked(dev);
  83. if (rc)
  84. goto err;
  85. dev_dbg(dev, "config data size: %d\n", ndd->nsarea.config_size);
  86. nvdimm_bus_lock(dev);
  87. if (ndd->ns_current >= 0) {
  88. rc = nd_label_reserve_dpa(ndd);
  89. if (rc == 0)
  90. nvdimm_set_labeling(dev);
  91. }
  92. nvdimm_bus_unlock(dev);
  93. if (rc)
  94. goto err;
  95. return 0;
  96. err:
  97. put_ndd(ndd);
  98. return rc;
  99. }
  100. static int nvdimm_remove(struct device *dev)
  101. {
  102. struct nvdimm_drvdata *ndd = dev_get_drvdata(dev);
  103. if (!ndd)
  104. return 0;
  105. nvdimm_bus_lock(dev);
  106. dev_set_drvdata(dev, NULL);
  107. nvdimm_bus_unlock(dev);
  108. put_ndd(ndd);
  109. return 0;
  110. }
  111. static struct nd_device_driver nvdimm_driver = {
  112. .probe = nvdimm_probe,
  113. .remove = nvdimm_remove,
  114. .drv = {
  115. .name = "nvdimm",
  116. },
  117. .type = ND_DRIVER_DIMM,
  118. };
  119. int __init nvdimm_init(void)
  120. {
  121. return nd_driver_register(&nvdimm_driver);
  122. }
  123. void nvdimm_exit(void)
  124. {
  125. driver_unregister(&nvdimm_driver.drv);
  126. }
  127. MODULE_ALIAS_ND_DEVICE(ND_DEVICE_DIMM);