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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14 #include <linux/vmalloc.h> 15 #include <linux/device.h> 16 #include <linux/ndctl.h> 17 #include <linux/slab.h> 18 #include <linux/io.h> 19 #include <linux/fs.h> 20 #include <linux/mm.h> 21 #include "nd-core.h" 22 #include "nd.h" 23 24 static DEFINE_IDA(dimm_ida); 25 26 /* 27 * Retrieve bus and dimm handle and return if this bus supports 28 * get_config_data commands 29 */ 30 static int __validate_dimm(struct nvdimm_drvdata *ndd) 31 { 32 struct nvdimm *nvdimm; 33 34 if (!ndd) 35 return -EINVAL; 36 37 nvdimm = to_nvdimm(ndd->dev); 38 39 if (!nvdimm->dsm_mask) 40 return -ENXIO; 41 if (!test_bit(ND_CMD_GET_CONFIG_DATA, nvdimm->dsm_mask)) 42 return -ENXIO; 43 44 return 0; 45 } 46 47 static int validate_dimm(struct nvdimm_drvdata *ndd) 48 { 49 int rc = __validate_dimm(ndd); 50 51 if (rc && ndd) 52 dev_dbg(ndd->dev, "%pf: %s error: %d\n", 53 __builtin_return_address(0), __func__, rc); 54 return rc; 55 } 56 57 /** 58 * nvdimm_init_nsarea - determine the geometry of a dimm's namespace area 59 * @nvdimm: dimm to initialize 60 */ 61 int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd) 62 { 63 struct nd_cmd_get_config_size *cmd = &ndd->nsarea; 64 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev); 65 struct nvdimm_bus_descriptor *nd_desc; 66 int rc = validate_dimm(ndd); 67 68 if (rc) 69 return rc; 70 71 if (cmd->config_size) 72 return 0; /* already valid */ 73 74 memset(cmd, 0, sizeof(*cmd)); 75 nd_desc = nvdimm_bus->nd_desc; 76 return nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev), 77 ND_CMD_GET_CONFIG_SIZE, cmd, sizeof(*cmd)); 78 } 79 80 int nvdimm_init_config_data(struct nvdimm_drvdata *ndd) 81 { 82 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev); 83 struct nd_cmd_get_config_data_hdr *cmd; 84 struct nvdimm_bus_descriptor *nd_desc; 85 int rc = validate_dimm(ndd); 86 u32 max_cmd_size, config_size; 87 size_t offset; 88 89 if (rc) 90 return rc; 91 92 if (ndd->data) 93 return 0; 94 95 if (ndd->nsarea.status || ndd->nsarea.max_xfer == 0 96 || ndd->nsarea.config_size < ND_LABEL_MIN_SIZE) { 97 dev_dbg(ndd->dev, "failed to init config data area: (%d:%d)\n", 98 ndd->nsarea.max_xfer, ndd->nsarea.config_size); 99 return -ENXIO; 100 } 101 102 ndd->data = kmalloc(ndd->nsarea.config_size, GFP_KERNEL); 103 if (!ndd->data) 104 ndd->data = vmalloc(ndd->nsarea.config_size); 105 106 if (!ndd->data) 107 return -ENOMEM; 108 109 max_cmd_size = min_t(u32, PAGE_SIZE, ndd->nsarea.max_xfer); 110 cmd = kzalloc(max_cmd_size + sizeof(*cmd), GFP_KERNEL); 111 if (!cmd) 112 return -ENOMEM; 113 114 nd_desc = nvdimm_bus->nd_desc; 115 for (config_size = ndd->nsarea.config_size, offset = 0; 116 config_size; config_size -= cmd->in_length, 117 offset += cmd->in_length) { 118 cmd->in_length = min(config_size, max_cmd_size); 119 cmd->in_offset = offset; 120 rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev), 121 ND_CMD_GET_CONFIG_DATA, cmd, 122 cmd->in_length + sizeof(*cmd)); 123 if (rc || cmd->status) { 124 rc = -ENXIO; 125 break; 126 } 127 memcpy(ndd->data + offset, cmd->out_buf, cmd->in_length); 128 } 129 dev_dbg(ndd->dev, "%s: len: %zu rc: %d\n", __func__, offset, rc); 130 kfree(cmd); 131 132 return rc; 133 } 134 135 int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset, 136 void *buf, size_t len) 137 { 138 int rc = validate_dimm(ndd); 139 size_t max_cmd_size, buf_offset; 140 struct nd_cmd_set_config_hdr *cmd; 141 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev); 142 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc; 143 144 if (rc) 145 return rc; 146 147 if (!ndd->data) 148 return -ENXIO; 149 150 if (offset + len > ndd->nsarea.config_size) 151 return -ENXIO; 152 153 max_cmd_size = min_t(u32, PAGE_SIZE, len); 154 max_cmd_size = min_t(u32, max_cmd_size, ndd->nsarea.max_xfer); 155 cmd = kzalloc(max_cmd_size + sizeof(*cmd) + sizeof(u32), GFP_KERNEL); 156 if (!cmd) 157 return -ENOMEM; 158 159 for (buf_offset = 0; len; len -= cmd->in_length, 160 buf_offset += cmd->in_length) { 161 size_t cmd_size; 162 u32 *status; 163 164 cmd->in_offset = offset + buf_offset; 165 cmd->in_length = min(max_cmd_size, len); 166 memcpy(cmd->in_buf, buf + buf_offset, cmd->in_length); 167 168 /* status is output in the last 4-bytes of the command buffer */ 169 cmd_size = sizeof(*cmd) + cmd->in_length + sizeof(u32); 170 status = ((void *) cmd) + cmd_size - sizeof(u32); 171 172 rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev), 173 ND_CMD_SET_CONFIG_DATA, cmd, cmd_size); 174 if (rc || *status) { 175 rc = rc ? rc : -ENXIO; 176 break; 177 } 178 } 179 kfree(cmd); 180 181 return rc; 182 } 183 184 static void nvdimm_release(struct device *dev) 185 { 186 struct nvdimm *nvdimm = to_nvdimm(dev); 187 188 ida_simple_remove(&dimm_ida, nvdimm->id); 189 kfree(nvdimm); 190 } 191 192 static struct device_type nvdimm_device_type = { 193 .name = "nvdimm", 194 .release = nvdimm_release, 195 }; 196 197 bool is_nvdimm(struct device *dev) 198 { 199 return dev->type == &nvdimm_device_type; 200 } 201 202 struct nvdimm *to_nvdimm(struct device *dev) 203 { 204 struct nvdimm *nvdimm = container_of(dev, struct nvdimm, dev); 205 206 WARN_ON(!is_nvdimm(dev)); 207 return nvdimm; 208 } 209 EXPORT_SYMBOL_GPL(to_nvdimm); 210 211 struct nvdimm_drvdata *to_ndd(struct nd_mapping *nd_mapping) 212 { 213 struct nvdimm *nvdimm = nd_mapping->nvdimm; 214 215 WARN_ON_ONCE(!is_nvdimm_bus_locked(&nvdimm->dev)); 216 217 return dev_get_drvdata(&nvdimm->dev); 218 } 219 EXPORT_SYMBOL(to_ndd); 220 221 void nvdimm_drvdata_release(struct kref *kref) 222 { 223 struct nvdimm_drvdata *ndd = container_of(kref, typeof(*ndd), kref); 224 struct device *dev = ndd->dev; 225 struct resource *res, *_r; 226 227 dev_dbg(dev, "%s\n", __func__); 228 229 nvdimm_bus_lock(dev); 230 for_each_dpa_resource_safe(ndd, res, _r) 231 nvdimm_free_dpa(ndd, res); 232 nvdimm_bus_unlock(dev); 233 234 if (ndd->data && is_vmalloc_addr(ndd->data)) 235 vfree(ndd->data); 236 else 237 kfree(ndd->data); 238 kfree(ndd); 239 put_device(dev); 240 } 241 242 void get_ndd(struct nvdimm_drvdata *ndd) 243 { 244 kref_get(&ndd->kref); 245 } 246 247 void put_ndd(struct nvdimm_drvdata *ndd) 248 { 249 if (ndd) 250 kref_put(&ndd->kref, nvdimm_drvdata_release); 251 } 252 253 const char *nvdimm_name(struct nvdimm *nvdimm) 254 { 255 return dev_name(&nvdimm->dev); 256 } 257 EXPORT_SYMBOL_GPL(nvdimm_name); 258 259 void *nvdimm_provider_data(struct nvdimm *nvdimm) 260 { 261 if (nvdimm) 262 return nvdimm->provider_data; 263 return NULL; 264 } 265 EXPORT_SYMBOL_GPL(nvdimm_provider_data); 266 267 static ssize_t commands_show(struct device *dev, 268 struct device_attribute *attr, char *buf) 269 { 270 struct nvdimm *nvdimm = to_nvdimm(dev); 271 int cmd, len = 0; 272 273 if (!nvdimm->dsm_mask) 274 return sprintf(buf, "\n"); 275 276 for_each_set_bit(cmd, nvdimm->dsm_mask, BITS_PER_LONG) 277 len += sprintf(buf + len, "%s ", nvdimm_cmd_name(cmd)); 278 len += sprintf(buf + len, "\n"); 279 return len; 280 } 281 static DEVICE_ATTR_RO(commands); 282 283 static ssize_t state_show(struct device *dev, struct device_attribute *attr, 284 char *buf) 285 { 286 struct nvdimm *nvdimm = to_nvdimm(dev); 287 288 /* 289 * The state may be in the process of changing, userspace should 290 * quiesce probing if it wants a static answer 291 */ 292 nvdimm_bus_lock(dev); 293 nvdimm_bus_unlock(dev); 294 return sprintf(buf, "%s\n", atomic_read(&nvdimm->busy) 295 ? "active" : "idle"); 296 } 297 static DEVICE_ATTR_RO(state); 298 299 static struct attribute *nvdimm_attributes[] = { 300 &dev_attr_state.attr, 301 &dev_attr_commands.attr, 302 NULL, 303 }; 304 305 struct attribute_group nvdimm_attribute_group = { 306 .attrs = nvdimm_attributes, 307 }; 308 EXPORT_SYMBOL_GPL(nvdimm_attribute_group); 309 310 struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, 311 const struct attribute_group **groups, unsigned long flags, 312 unsigned long *dsm_mask) 313 { 314 struct nvdimm *nvdimm = kzalloc(sizeof(*nvdimm), GFP_KERNEL); 315 struct device *dev; 316 317 if (!nvdimm) 318 return NULL; 319 320 nvdimm->id = ida_simple_get(&dimm_ida, 0, 0, GFP_KERNEL); 321 if (nvdimm->id < 0) { 322 kfree(nvdimm); 323 return NULL; 324 } 325 nvdimm->provider_data = provider_data; 326 nvdimm->flags = flags; 327 nvdimm->dsm_mask = dsm_mask; 328 atomic_set(&nvdimm->busy, 0); 329 dev = &nvdimm->dev; 330 dev_set_name(dev, "nmem%d", nvdimm->id); 331 dev->parent = &nvdimm_bus->dev; 332 dev->type = &nvdimm_device_type; 333 dev->devt = MKDEV(nvdimm_major, nvdimm->id); 334 dev->groups = groups; 335 nd_device_register(dev); 336 337 return nvdimm; 338 } 339 EXPORT_SYMBOL_GPL(nvdimm_create); 340 341 /** 342 * nd_blk_available_dpa - account the unused dpa of BLK region 343 * @nd_mapping: container of dpa-resource-root + labels 344 * 345 * Unlike PMEM, BLK namespaces can occupy discontiguous DPA ranges. 346 */ 347 resource_size_t nd_blk_available_dpa(struct nd_mapping *nd_mapping) 348 { 349 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 350 resource_size_t map_end, busy = 0, available; 351 struct resource *res; 352 353 if (!ndd) 354 return 0; 355 356 map_end = nd_mapping->start + nd_mapping->size - 1; 357 for_each_dpa_resource(ndd, res) 358 if (res->start >= nd_mapping->start && res->start < map_end) { 359 resource_size_t end = min(map_end, res->end); 360 361 busy += end - res->start + 1; 362 } else if (res->end >= nd_mapping->start 363 && res->end <= map_end) { 364 busy += res->end - nd_mapping->start; 365 } else if (nd_mapping->start > res->start 366 && nd_mapping->start < res->end) { 367 /* total eclipse of the BLK region mapping */ 368 busy += nd_mapping->size; 369 } 370 371 available = map_end - nd_mapping->start + 1; 372 if (busy < available) 373 return available - busy; 374 return 0; 375 } 376 377 /** 378 * nd_pmem_available_dpa - for the given dimm+region account unallocated dpa 379 * @nd_mapping: container of dpa-resource-root + labels 380 * @nd_region: constrain available space check to this reference region 381 * @overlap: calculate available space assuming this level of overlap 382 * 383 * Validate that a PMEM label, if present, aligns with the start of an 384 * interleave set and truncate the available size at the lowest BLK 385 * overlap point. 386 * 387 * The expectation is that this routine is called multiple times as it 388 * probes for the largest BLK encroachment for any single member DIMM of 389 * the interleave set. Once that value is determined the PMEM-limit for 390 * the set can be established. 391 */ 392 resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region, 393 struct nd_mapping *nd_mapping, resource_size_t *overlap) 394 { 395 resource_size_t map_start, map_end, busy = 0, available, blk_start; 396 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); 397 struct resource *res; 398 const char *reason; 399 400 if (!ndd) 401 return 0; 402 403 map_start = nd_mapping->start; 404 map_end = map_start + nd_mapping->size - 1; 405 blk_start = max(map_start, map_end + 1 - *overlap); 406 for_each_dpa_resource(ndd, res) 407 if (res->start >= map_start && res->start < map_end) { 408 if (strncmp(res->name, "blk", 3) == 0) 409 blk_start = min(blk_start, res->start); 410 else if (res->start != map_start) { 411 reason = "misaligned to iset"; 412 goto err; 413 } else { 414 if (busy) { 415 reason = "duplicate overlapping PMEM reservations?"; 416 goto err; 417 } 418 busy += resource_size(res); 419 continue; 420 } 421 } else if (res->end >= map_start && res->end <= map_end) { 422 if (strncmp(res->name, "blk", 3) == 0) { 423 /* 424 * If a BLK allocation overlaps the start of 425 * PMEM the entire interleave set may now only 426 * be used for BLK. 427 */ 428 blk_start = map_start; 429 } else { 430 reason = "misaligned to iset"; 431 goto err; 432 } 433 } else if (map_start > res->start && map_start < res->end) { 434 /* total eclipse of the mapping */ 435 busy += nd_mapping->size; 436 blk_start = map_start; 437 } 438 439 *overlap = map_end + 1 - blk_start; 440 available = blk_start - map_start; 441 if (busy < available) 442 return available - busy; 443 return 0; 444 445 err: 446 /* 447 * Something is wrong, PMEM must align with the start of the 448 * interleave set, and there can only be one allocation per set. 449 */ 450 nd_dbg_dpa(nd_region, ndd, res, "%s\n", reason); 451 return 0; 452 } 453 454 void nvdimm_free_dpa(struct nvdimm_drvdata *ndd, struct resource *res) 455 { 456 WARN_ON_ONCE(!is_nvdimm_bus_locked(ndd->dev)); 457 kfree(res->name); 458 __release_region(&ndd->dpa, res->start, resource_size(res)); 459 } 460 461 struct resource *nvdimm_allocate_dpa(struct nvdimm_drvdata *ndd, 462 struct nd_label_id *label_id, resource_size_t start, 463 resource_size_t n) 464 { 465 char *name = kmemdup(label_id, sizeof(*label_id), GFP_KERNEL); 466 struct resource *res; 467 468 if (!name) 469 return NULL; 470 471 WARN_ON_ONCE(!is_nvdimm_bus_locked(ndd->dev)); 472 res = __request_region(&ndd->dpa, start, n, name, 0); 473 if (!res) 474 kfree(name); 475 return res; 476 } 477 478 /** 479 * nvdimm_allocated_dpa - sum up the dpa currently allocated to this label_id 480 * @nvdimm: container of dpa-resource-root + labels 481 * @label_id: dpa resource name of the form {pmem|blk}-<human readable uuid> 482 */ 483 resource_size_t nvdimm_allocated_dpa(struct nvdimm_drvdata *ndd, 484 struct nd_label_id *label_id) 485 { 486 resource_size_t allocated = 0; 487 struct resource *res; 488 489 for_each_dpa_resource(ndd, res) 490 if (strcmp(res->name, label_id->id) == 0) 491 allocated += resource_size(res); 492 493 return allocated; 494 } 495 496 static int count_dimms(struct device *dev, void *c) 497 { 498 int *count = c; 499 500 if (is_nvdimm(dev)) 501 (*count)++; 502 return 0; 503 } 504 505 int nvdimm_bus_check_dimm_count(struct nvdimm_bus *nvdimm_bus, int dimm_count) 506 { 507 int count = 0; 508 /* Flush any possible dimm registration failures */ 509 nd_synchronize(); 510 511 device_for_each_child(&nvdimm_bus->dev, &count, count_dimms); 512 dev_dbg(&nvdimm_bus->dev, "%s: count: %d\n", __func__, count); 513 if (count != dimm_count) 514 return -ENXIO; 515 return 0; 516 } 517 EXPORT_SYMBOL_GPL(nvdimm_bus_check_dimm_count); 518