1 /* 2 * Copyright(c) 2013-2015 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/vmalloc.h> 14 #include <linux/module.h> 15 #include <linux/device.h> 16 #include <linux/sizes.h> 17 #include <linux/ndctl.h> 18 #include <linux/slab.h> 19 #include <linux/mm.h> 20 #include <linux/nd.h> 21 #include "label.h" 22 #include "nd.h" 23 24 static int nvdimm_probe(struct device *dev) 25 { 26 struct nvdimm_drvdata *ndd; 27 int rc; 28 29 rc = nvdimm_check_config_data(dev); 30 if (rc) { 31 /* not required for non-aliased nvdimm, ex. NVDIMM-N */ 32 if (rc == -ENOTTY) 33 rc = 0; 34 return rc; 35 } 36 37 /* reset locked, to be validated below... */ 38 nvdimm_clear_locked(dev); 39 40 ndd = kzalloc(sizeof(*ndd), GFP_KERNEL); 41 if (!ndd) 42 return -ENOMEM; 43 44 dev_set_drvdata(dev, ndd); 45 ndd->dpa.name = dev_name(dev); 46 ndd->ns_current = -1; 47 ndd->ns_next = -1; 48 ndd->dpa.start = 0; 49 ndd->dpa.end = -1; 50 ndd->dev = dev; 51 get_device(dev); 52 kref_init(&ndd->kref); 53 54 /* 55 * EACCES failures reading the namespace label-area-properties 56 * are interpreted as the DIMM capacity being locked but the 57 * namespace labels themselves being accessible. 58 */ 59 rc = nvdimm_init_nsarea(ndd); 60 if (rc == -EACCES) { 61 /* 62 * See nvdimm_namespace_common_probe() where we fail to 63 * allow namespaces to probe while the DIMM is locked, 64 * but we do allow for namespace enumeration. 65 */ 66 nvdimm_set_locked(dev); 67 rc = 0; 68 } 69 if (rc) 70 goto err; 71 72 /* 73 * EACCES failures reading the namespace label-data are 74 * interpreted as the label area being locked in addition to the 75 * DIMM capacity. We fail the dimm probe to prevent regions from 76 * attempting to parse the label area. 77 */ 78 rc = nd_label_data_init(ndd); 79 if (rc == -EACCES) 80 nvdimm_set_locked(dev); 81 if (rc) 82 goto err; 83 84 dev_dbg(dev, "config data size: %d\n", ndd->nsarea.config_size); 85 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_aliasing(dev); 91 } 92 nvdimm_bus_unlock(dev); 93 94 if (rc) 95 goto err; 96 97 return 0; 98 99 err: 100 put_ndd(ndd); 101 return rc; 102 } 103 104 static int nvdimm_remove(struct device *dev) 105 { 106 struct nvdimm_drvdata *ndd = dev_get_drvdata(dev); 107 108 if (!ndd) 109 return 0; 110 111 nvdimm_bus_lock(dev); 112 dev_set_drvdata(dev, NULL); 113 nvdimm_bus_unlock(dev); 114 put_ndd(ndd); 115 116 return 0; 117 } 118 119 static struct nd_device_driver nvdimm_driver = { 120 .probe = nvdimm_probe, 121 .remove = nvdimm_remove, 122 .drv = { 123 .name = "nvdimm", 124 }, 125 .type = ND_DRIVER_DIMM, 126 }; 127 128 int __init nvdimm_init(void) 129 { 130 return nd_driver_register(&nvdimm_driver); 131 } 132 133 void nvdimm_exit(void) 134 { 135 driver_unregister(&nvdimm_driver.drv); 136 } 137 138 MODULE_ALIAS_ND_DEVICE(ND_DEVICE_DIMM); 139