diff options
author | Dan Williams <dan.j.williams@intel.com> | 2018-04-09 20:50:08 +0300 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2018-04-09 20:50:08 +0300 |
commit | 1ed41b5696ccc3ff40a1dee39fe14eff273faf82 (patch) | |
tree | 1202df08129d350a65cf220406eb7ce87185d813 /drivers/nvdimm | |
parent | 3eb2ce825ea1ad89d20f7a3b5780df850e4be274 (diff) | |
parent | 291717b6fbdb175da88ae2144fc58d63a490128d (diff) | |
download | linux-1ed41b5696ccc3ff40a1dee39fe14eff273faf82.tar.xz |
Merge branch 'for-4.17/libnvdimm' into libnvdimm-for-next
Diffstat (limited to 'drivers/nvdimm')
-rw-r--r-- | drivers/nvdimm/Kconfig | 11 | ||||
-rw-r--r-- | drivers/nvdimm/Makefile | 1 | ||||
-rw-r--r-- | drivers/nvdimm/btt_devs.c | 21 | ||||
-rw-r--r-- | drivers/nvdimm/bus.c | 14 | ||||
-rw-r--r-- | drivers/nvdimm/claim.c | 2 | ||||
-rw-r--r-- | drivers/nvdimm/core.c | 6 | ||||
-rw-r--r-- | drivers/nvdimm/dax_devs.c | 5 | ||||
-rw-r--r-- | drivers/nvdimm/dimm.c | 8 | ||||
-rw-r--r-- | drivers/nvdimm/dimm_devs.c | 7 | ||||
-rw-r--r-- | drivers/nvdimm/label.c | 85 | ||||
-rw-r--r-- | drivers/nvdimm/label.h | 2 | ||||
-rw-r--r-- | drivers/nvdimm/namespace_devs.c | 42 | ||||
-rw-r--r-- | drivers/nvdimm/nd.h | 1 | ||||
-rw-r--r-- | drivers/nvdimm/of_pmem.c | 119 | ||||
-rw-r--r-- | drivers/nvdimm/pfn_devs.c | 25 | ||||
-rw-r--r-- | drivers/nvdimm/pmem.c | 14 | ||||
-rw-r--r-- | drivers/nvdimm/region.c | 4 | ||||
-rw-r--r-- | drivers/nvdimm/region_devs.c | 9 |
18 files changed, 253 insertions, 123 deletions
diff --git a/drivers/nvdimm/Kconfig b/drivers/nvdimm/Kconfig index a65f2e1d9f53..f6c533c4d09b 100644 --- a/drivers/nvdimm/Kconfig +++ b/drivers/nvdimm/Kconfig @@ -102,4 +102,15 @@ config NVDIMM_DAX Select Y if unsure +config OF_PMEM + # FIXME: make tristate once OF_NUMA dependency removed + bool "Device-tree support for persistent memory regions" + depends on OF + default LIBNVDIMM + help + Allows regions of persistent memory to be described in the + device-tree. + + Select Y if unsure. + endif diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile index 70d5f3ad9909..e8847045dac0 100644 --- a/drivers/nvdimm/Makefile +++ b/drivers/nvdimm/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o obj-$(CONFIG_ND_BTT) += nd_btt.o obj-$(CONFIG_ND_BLK) += nd_blk.o obj-$(CONFIG_X86_PMEM_LEGACY) += nd_e820.o +obj-$(CONFIG_OF_PMEM) += of_pmem.o nd_pmem-y := pmem.o diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c index d58925295aa7..795ad4ff35ca 100644 --- a/drivers/nvdimm/btt_devs.c +++ b/drivers/nvdimm/btt_devs.c @@ -26,7 +26,7 @@ static void nd_btt_release(struct device *dev) struct nd_region *nd_region = to_nd_region(dev->parent); struct nd_btt *nd_btt = to_nd_btt(dev); - dev_dbg(dev, "%s\n", __func__); + dev_dbg(dev, "trace\n"); nd_detach_ndns(&nd_btt->dev, &nd_btt->ndns); ida_simple_remove(&nd_region->btt_ida, nd_btt->id); kfree(nd_btt->uuid); @@ -74,8 +74,8 @@ static ssize_t sector_size_store(struct device *dev, nvdimm_bus_lock(dev); rc = nd_size_select_store(dev, buf, &nd_btt->lbasize, btt_lbasize_supported); - dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, - rc, buf, buf[len - 1] == '\n' ? "" : "\n"); + dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, + buf[len - 1] == '\n' ? "" : "\n"); nvdimm_bus_unlock(dev); device_unlock(dev); @@ -101,8 +101,8 @@ static ssize_t uuid_store(struct device *dev, device_lock(dev); rc = nd_uuid_store(dev, &nd_btt->uuid, buf, len); - dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, - rc, buf, buf[len - 1] == '\n' ? "" : "\n"); + dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, + buf[len - 1] == '\n' ? "" : "\n"); device_unlock(dev); return rc ? rc : len; @@ -131,8 +131,8 @@ static ssize_t namespace_store(struct device *dev, device_lock(dev); nvdimm_bus_lock(dev); rc = nd_namespace_store(dev, &nd_btt->ndns, buf, len); - dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, - rc, buf, buf[len - 1] == '\n' ? "" : "\n"); + dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, + buf[len - 1] == '\n' ? "" : "\n"); nvdimm_bus_unlock(dev); device_unlock(dev); @@ -206,8 +206,8 @@ static struct device *__nd_btt_create(struct nd_region *nd_region, dev->groups = nd_btt_attribute_groups; device_initialize(&nd_btt->dev); if (ndns && !__nd_attach_ndns(&nd_btt->dev, ndns, &nd_btt->ndns)) { - dev_dbg(&ndns->dev, "%s failed, already claimed by %s\n", - __func__, dev_name(ndns->claim)); + dev_dbg(&ndns->dev, "failed, already claimed by %s\n", + dev_name(ndns->claim)); put_device(dev); return NULL; } @@ -346,8 +346,7 @@ int nd_btt_probe(struct device *dev, struct nd_namespace_common *ndns) return -ENOMEM; btt_sb = devm_kzalloc(dev, sizeof(*btt_sb), GFP_KERNEL); rc = __nd_btt_probe(to_nd_btt(btt_dev), ndns, btt_sb); - dev_dbg(dev, "%s: btt: %s\n", __func__, - rc == 0 ? dev_name(btt_dev) : "<none>"); + dev_dbg(dev, "btt: %s\n", rc == 0 ? dev_name(btt_dev) : "<none>"); if (rc < 0) { struct nd_btt *nd_btt = to_nd_btt(btt_dev); diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 78eabc3a1ab1..a64023690cad 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -358,6 +358,7 @@ struct nvdimm_bus *nvdimm_bus_register(struct device *parent, nvdimm_bus->dev.release = nvdimm_bus_release; nvdimm_bus->dev.groups = nd_desc->attr_groups; nvdimm_bus->dev.bus = &nvdimm_bus_type; + nvdimm_bus->dev.of_node = nd_desc->of_node; dev_set_name(&nvdimm_bus->dev, "ndbus%d", nvdimm_bus->id); rc = device_register(&nvdimm_bus->dev); if (rc) { @@ -984,8 +985,8 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, if (cmd == ND_CMD_CALL) { func = pkg.nd_command; - dev_dbg(dev, "%s:%s, idx: %llu, in: %u, out: %u, len %llu\n", - __func__, dimm_name, pkg.nd_command, + dev_dbg(dev, "%s, idx: %llu, in: %u, out: %u, len %llu\n", + dimm_name, pkg.nd_command, in_len, out_len, buf_len); } @@ -996,8 +997,8 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, u32 copy; if (out_size == UINT_MAX) { - dev_dbg(dev, "%s:%s unknown output size cmd: %s field: %d\n", - __func__, dimm_name, cmd_name, i); + dev_dbg(dev, "%s unknown output size cmd: %s field: %d\n", + dimm_name, cmd_name, i); return -EFAULT; } if (out_len < sizeof(out_env)) @@ -1012,9 +1013,8 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, buf_len = (u64) out_len + (u64) in_len; if (buf_len > ND_IOCTL_MAX_BUFLEN) { - dev_dbg(dev, "%s:%s cmd: %s buf_len: %llu > %d\n", __func__, - dimm_name, cmd_name, buf_len, - ND_IOCTL_MAX_BUFLEN); + dev_dbg(dev, "%s cmd: %s buf_len: %llu > %d\n", dimm_name, + cmd_name, buf_len, ND_IOCTL_MAX_BUFLEN); return -EINVAL; } diff --git a/drivers/nvdimm/claim.c b/drivers/nvdimm/claim.c index b2fc29b8279b..30852270484f 100644 --- a/drivers/nvdimm/claim.c +++ b/drivers/nvdimm/claim.c @@ -148,7 +148,7 @@ ssize_t nd_namespace_store(struct device *dev, char *name; if (dev->driver) { - dev_dbg(dev, "%s: -EBUSY\n", __func__); + dev_dbg(dev, "namespace already active\n"); return -EBUSY; } diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c index 1dc527660637..acce050856a8 100644 --- a/drivers/nvdimm/core.c +++ b/drivers/nvdimm/core.c @@ -134,7 +134,7 @@ static void nvdimm_map_release(struct kref *kref) nvdimm_map = container_of(kref, struct nvdimm_map, kref); nvdimm_bus = nvdimm_map->nvdimm_bus; - dev_dbg(&nvdimm_bus->dev, "%s: %pa\n", __func__, &nvdimm_map->offset); + dev_dbg(&nvdimm_bus->dev, "%pa\n", &nvdimm_map->offset); list_del(&nvdimm_map->list); if (nvdimm_map->flags) memunmap(nvdimm_map->mem); @@ -230,8 +230,8 @@ static int nd_uuid_parse(struct device *dev, u8 *uuid_out, const char *buf, for (i = 0; i < 16; i++) { if (!isxdigit(str[0]) || !isxdigit(str[1])) { - dev_dbg(dev, "%s: pos: %d buf[%zd]: %c buf[%zd]: %c\n", - __func__, i, str - buf, str[0], + dev_dbg(dev, "pos: %d buf[%zd]: %c buf[%zd]: %c\n", + i, str - buf, str[0], str + 1 - buf, str[1]); return -EINVAL; } diff --git a/drivers/nvdimm/dax_devs.c b/drivers/nvdimm/dax_devs.c index 1bf2bd318371..0453f49dc708 100644 --- a/drivers/nvdimm/dax_devs.c +++ b/drivers/nvdimm/dax_devs.c @@ -24,7 +24,7 @@ static void nd_dax_release(struct device *dev) struct nd_dax *nd_dax = to_nd_dax(dev); struct nd_pfn *nd_pfn = &nd_dax->nd_pfn; - dev_dbg(dev, "%s\n", __func__); + dev_dbg(dev, "trace\n"); nd_detach_ndns(dev, &nd_pfn->ndns); ida_simple_remove(&nd_region->dax_ida, nd_pfn->id); kfree(nd_pfn->uuid); @@ -129,8 +129,7 @@ int nd_dax_probe(struct device *dev, struct nd_namespace_common *ndns) pfn_sb = devm_kzalloc(dev, sizeof(*pfn_sb), GFP_KERNEL); nd_pfn->pfn_sb = pfn_sb; rc = nd_pfn_validate(nd_pfn, DAX_SIG); - dev_dbg(dev, "%s: dax: %s\n", __func__, - rc == 0 ? dev_name(dax_dev) : "<none>"); + dev_dbg(dev, "dax: %s\n", rc == 0 ? dev_name(dax_dev) : "<none>"); if (rc < 0) { nd_detach_ndns(dax_dev, &nd_pfn->ndns); put_device(dax_dev); diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c index f8913b8124b6..233907889f96 100644 --- a/drivers/nvdimm/dimm.c +++ b/drivers/nvdimm/dimm.c @@ -67,9 +67,11 @@ static int nvdimm_probe(struct device *dev) ndd->ns_next = nd_label_next_nsindex(ndd->ns_current); nd_label_copy(ndd, to_next_namespace_index(ndd), to_current_namespace_index(ndd)); - rc = nd_label_reserve_dpa(ndd); - if (ndd->ns_current >= 0) - nvdimm_set_aliasing(dev); + if (ndd->ns_current >= 0) { + rc = nd_label_reserve_dpa(ndd); + if (rc == 0) + nvdimm_set_aliasing(dev); + } nvdimm_clear_locked(dev); nvdimm_bus_unlock(dev); diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index 097794d9f786..e00d45522b80 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -131,7 +131,7 @@ int nvdimm_init_config_data(struct nvdimm_drvdata *ndd) } memcpy(ndd->data + offset, cmd->out_buf, cmd->in_length); } - dev_dbg(ndd->dev, "%s: len: %zu rc: %d\n", __func__, offset, rc); + dev_dbg(ndd->dev, "len: %zu rc: %d\n", offset, rc); kfree(cmd); return rc; @@ -266,8 +266,7 @@ void nvdimm_drvdata_release(struct kref *kref) struct device *dev = ndd->dev; struct resource *res, *_r; - dev_dbg(dev, "%s\n", __func__); - + dev_dbg(dev, "trace\n"); nvdimm_bus_lock(dev); for_each_dpa_resource_safe(ndd, res, _r) nvdimm_free_dpa(ndd, res); @@ -660,7 +659,7 @@ int nvdimm_bus_check_dimm_count(struct nvdimm_bus *nvdimm_bus, int dimm_count) nd_synchronize(); device_for_each_child(&nvdimm_bus->dev, &count, count_dimms); - dev_dbg(&nvdimm_bus->dev, "%s: count: %d\n", __func__, count); + dev_dbg(&nvdimm_bus->dev, "count: %d\n", count); if (count != dimm_count) return -ENXIO; return 0; diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c index de66c02f6140..1d28cd656536 100644 --- a/drivers/nvdimm/label.c +++ b/drivers/nvdimm/label.c @@ -45,9 +45,27 @@ unsigned sizeof_namespace_label(struct nvdimm_drvdata *ndd) return ndd->nslabel_size; } +static size_t __sizeof_namespace_index(u32 nslot) +{ + return ALIGN(sizeof(struct nd_namespace_index) + DIV_ROUND_UP(nslot, 8), + NSINDEX_ALIGN); +} + +static int __nvdimm_num_label_slots(struct nvdimm_drvdata *ndd, + size_t index_size) +{ + return (ndd->nsarea.config_size - index_size * 2) / + sizeof_namespace_label(ndd); +} + int nvdimm_num_label_slots(struct nvdimm_drvdata *ndd) { - return ndd->nsarea.config_size / (sizeof_namespace_label(ndd) + 1); + u32 tmp_nslot, n; + + tmp_nslot = ndd->nsarea.config_size / sizeof_namespace_label(ndd); + n = __sizeof_namespace_index(tmp_nslot) / NSINDEX_ALIGN; + + return __nvdimm_num_label_slots(ndd, NSINDEX_ALIGN * n); } size_t sizeof_namespace_index(struct nvdimm_drvdata *ndd) @@ -55,18 +73,14 @@ size_t sizeof_namespace_index(struct nvdimm_drvdata *ndd) u32 nslot, space, size; /* - * The minimum index space is 512 bytes, with that amount of - * index we can describe ~1400 labels which is less than a byte - * of overhead per label. Round up to a byte of overhead per - * label and determine the size of the index region. Yes, this - * starts to waste space at larger config_sizes, but it's - * unlikely we'll ever see anything but 128K. + * Per UEFI 2.7, the minimum size of the Label Storage Area is large + * enough to hold 2 index blocks and 2 labels. The minimum index + * block size is 256 bytes, and the minimum label size is 256 bytes. */ nslot = nvdimm_num_label_slots(ndd); space = ndd->nsarea.config_size - nslot * sizeof_namespace_label(ndd); - size = ALIGN(sizeof(struct nd_namespace_index) + DIV_ROUND_UP(nslot, 8), - NSINDEX_ALIGN) * 2; - if (size <= space) + size = __sizeof_namespace_index(nslot) * 2; + if (size <= space && nslot >= 2) return size / 2; dev_err(ndd->dev, "label area (%d) too small to host (%d byte) labels\n", @@ -121,8 +135,7 @@ static int __nd_label_validate(struct nvdimm_drvdata *ndd) memcpy(sig, nsindex[i]->sig, NSINDEX_SIG_LEN); if (memcmp(sig, NSINDEX_SIGNATURE, NSINDEX_SIG_LEN) != 0) { - dev_dbg(dev, "%s: nsindex%d signature invalid\n", - __func__, i); + dev_dbg(dev, "nsindex%d signature invalid\n", i); continue; } @@ -135,8 +148,8 @@ static int __nd_label_validate(struct nvdimm_drvdata *ndd) labelsize = 128; if (labelsize != sizeof_namespace_label(ndd)) { - dev_dbg(dev, "%s: nsindex%d labelsize %d invalid\n", - __func__, i, nsindex[i]->labelsize); + dev_dbg(dev, "nsindex%d labelsize %d invalid\n", + i, nsindex[i]->labelsize); continue; } @@ -145,30 +158,28 @@ static int __nd_label_validate(struct nvdimm_drvdata *ndd) sum = nd_fletcher64(nsindex[i], sizeof_namespace_index(ndd), 1); nsindex[i]->checksum = __cpu_to_le64(sum_save); if (sum != sum_save) { - dev_dbg(dev, "%s: nsindex%d checksum invalid\n", - __func__, i); + dev_dbg(dev, "nsindex%d checksum invalid\n", i); continue; } seq = __le32_to_cpu(nsindex[i]->seq); if ((seq & NSINDEX_SEQ_MASK) == 0) { - dev_dbg(dev, "%s: nsindex%d sequence: %#x invalid\n", - __func__, i, seq); + dev_dbg(dev, "nsindex%d sequence: %#x invalid\n", i, seq); continue; } /* sanity check the index against expected values */ if (__le64_to_cpu(nsindex[i]->myoff) != i * sizeof_namespace_index(ndd)) { - dev_dbg(dev, "%s: nsindex%d myoff: %#llx invalid\n", - __func__, i, (unsigned long long) + dev_dbg(dev, "nsindex%d myoff: %#llx invalid\n", + i, (unsigned long long) __le64_to_cpu(nsindex[i]->myoff)); continue; } if (__le64_to_cpu(nsindex[i]->otheroff) != (!i) * sizeof_namespace_index(ndd)) { - dev_dbg(dev, "%s: nsindex%d otheroff: %#llx invalid\n", - __func__, i, (unsigned long long) + dev_dbg(dev, "nsindex%d otheroff: %#llx invalid\n", + i, (unsigned long long) __le64_to_cpu(nsindex[i]->otheroff)); continue; } @@ -176,8 +187,7 @@ static int __nd_label_validate(struct nvdimm_drvdata *ndd) size = __le64_to_cpu(nsindex[i]->mysize); if (size > sizeof_namespace_index(ndd) || size < sizeof(struct nd_namespace_index)) { - dev_dbg(dev, "%s: nsindex%d mysize: %#llx invalid\n", - __func__, i, size); + dev_dbg(dev, "nsindex%d mysize: %#llx invalid\n", i, size); continue; } @@ -185,9 +195,8 @@ static int __nd_label_validate(struct nvdimm_drvdata *ndd) if (nslot * sizeof_namespace_label(ndd) + 2 * sizeof_namespace_index(ndd) > ndd->nsarea.config_size) { - dev_dbg(dev, "%s: nsindex%d nslot: %u invalid, config_size: %#x\n", - __func__, i, nslot, - ndd->nsarea.config_size); + dev_dbg(dev, "nsindex%d nslot: %u invalid, config_size: %#x\n", + i, nslot, ndd->nsarea.config_size); continue; } valid[i] = true; @@ -356,8 +365,8 @@ static bool slot_valid(struct nvdimm_drvdata *ndd, sum = nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1); nd_label->checksum = __cpu_to_le64(sum_save); if (sum != sum_save) { - dev_dbg(ndd->dev, "%s fail checksum. slot: %d expect: %#llx\n", - __func__, slot, sum); + dev_dbg(ndd->dev, "fail checksum. slot: %d expect: %#llx\n", + slot, sum); return false; } } @@ -422,8 +431,8 @@ int nd_label_active_count(struct nvdimm_drvdata *ndd) u64 dpa = __le64_to_cpu(nd_label->dpa); dev_dbg(ndd->dev, - "%s: slot%d invalid slot: %d dpa: %llx size: %llx\n", - __func__, slot, label_slot, dpa, size); + "slot%d invalid slot: %d dpa: %llx size: %llx\n", + slot, label_slot, dpa, size); continue; } count++; @@ -650,7 +659,7 @@ static int __pmem_label_update(struct nd_region *nd_region, slot = nd_label_alloc_slot(ndd); if (slot == UINT_MAX) return -ENXIO; - dev_dbg(ndd->dev, "%s: allocated: %d\n", __func__, slot); + dev_dbg(ndd->dev, "allocated: %d\n", slot); nd_label = to_label(ndd, slot); memset(nd_label, 0, sizeof_namespace_label(ndd)); @@ -678,7 +687,7 @@ static int __pmem_label_update(struct nd_region *nd_region, sum = nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1); nd_label->checksum = __cpu_to_le64(sum); } - nd_dbg_dpa(nd_region, ndd, res, "%s\n", __func__); + nd_dbg_dpa(nd_region, ndd, res, "\n"); /* update label */ offset = nd_label_offset(ndd, nd_label); @@ -700,7 +709,7 @@ static int __pmem_label_update(struct nd_region *nd_region, break; } if (victim) { - dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot); + dev_dbg(ndd->dev, "free: %d\n", slot); slot = to_slot(ndd, victim->label); nd_label_free_slot(ndd, slot); victim->label = NULL; @@ -868,7 +877,7 @@ static int __blk_label_update(struct nd_region *nd_region, slot = nd_label_alloc_slot(ndd); if (slot == UINT_MAX) goto abort; - dev_dbg(ndd->dev, "%s: allocated: %d\n", __func__, slot); + dev_dbg(ndd->dev, "allocated: %d\n", slot); nd_label = to_label(ndd, slot); memset(nd_label, 0, sizeof_namespace_label(ndd)); @@ -928,7 +937,7 @@ static int __blk_label_update(struct nd_region *nd_region, /* free up now unused slots in the new index */ for_each_set_bit(slot, victim_map, victim_map ? nslot : 0) { - dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot); + dev_dbg(ndd->dev, "free: %d\n", slot); nd_label_free_slot(ndd, slot); } @@ -1092,7 +1101,7 @@ static int del_labels(struct nd_mapping *nd_mapping, u8 *uuid) active--; slot = to_slot(ndd, nd_label); nd_label_free_slot(ndd, slot); - dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot); + dev_dbg(ndd->dev, "free: %d\n", slot); list_move_tail(&label_ent->list, &list); label_ent->label = NULL; } @@ -1100,7 +1109,7 @@ static int del_labels(struct nd_mapping *nd_mapping, u8 *uuid) if (active == 0) { nd_mapping_free_labels(nd_mapping); - dev_dbg(ndd->dev, "%s: no more active labels\n", __func__); + dev_dbg(ndd->dev, "no more active labels\n"); } mutex_unlock(&nd_mapping->lock); diff --git a/drivers/nvdimm/label.h b/drivers/nvdimm/label.h index 1ebf4d3d01ba..18bbe183b3a9 100644 --- a/drivers/nvdimm/label.h +++ b/drivers/nvdimm/label.h @@ -33,7 +33,7 @@ enum { BTTINFO_UUID_LEN = 16, BTTINFO_FLAG_ERROR = 0x1, /* error state (read-only) */ BTTINFO_MAJOR_VERSION = 1, - ND_LABEL_MIN_SIZE = 512 * 129, /* see sizeof_namespace_index() */ + ND_LABEL_MIN_SIZE = 256 * 4, /* see sizeof_namespace_index() */ ND_LABEL_ID_SIZE = 50, ND_NSINDEX_INIT = 0x1, }; diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index 658ada497be0..28afdd668905 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -421,7 +421,7 @@ static ssize_t alt_name_store(struct device *dev, rc = __alt_name_store(dev, buf, len); if (rc >= 0) rc = nd_namespace_label_update(nd_region, dev); - dev_dbg(dev, "%s: %s(%zd)\n", __func__, rc < 0 ? "fail " : "", rc); + dev_dbg(dev, "%s(%zd)\n", rc < 0 ? "fail " : "", rc); nvdimm_bus_unlock(dev); device_unlock(dev); @@ -1007,7 +1007,7 @@ static ssize_t __size_store(struct device *dev, unsigned long long val) if (uuid_not_set(uuid, dev, __func__)) return -ENXIO; if (nd_region->ndr_mappings == 0) { - dev_dbg(dev, "%s: not associated with dimm(s)\n", __func__); + dev_dbg(dev, "not associated with dimm(s)\n"); return -ENXIO; } @@ -1105,8 +1105,7 @@ static ssize_t size_store(struct device *dev, *uuid = NULL; } - dev_dbg(dev, "%s: %llx %s (%d)\n", __func__, val, rc < 0 - ? "fail" : "success", rc); + dev_dbg(dev, "%llx %s (%d)\n", val, rc < 0 ? "fail" : "success", rc); nvdimm_bus_unlock(dev); device_unlock(dev); @@ -1270,8 +1269,8 @@ static ssize_t uuid_store(struct device *dev, rc = nd_namespace_label_update(nd_region, dev); else kfree(uuid); - dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, - rc, buf, buf[len - 1] == '\n' ? "" : "\n"); + dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, + buf[len - 1] == '\n' ? "" : "\n"); nvdimm_bus_unlock(dev); device_unlock(dev); @@ -1355,9 +1354,8 @@ static ssize_t sector_size_store(struct device *dev, rc = nd_size_select_store(dev, buf, lbasize, supported); if (rc >= 0) rc = nd_namespace_label_update(nd_region, dev); - dev_dbg(dev, "%s: result: %zd %s: %s%s", __func__, - rc, rc < 0 ? "tried" : "wrote", buf, - buf[len - 1] == '\n' ? "" : "\n"); + dev_dbg(dev, "result: %zd %s: %s%s", rc, rc < 0 ? "tried" : "wrote", + buf, buf[len - 1] == '\n' ? "" : "\n"); nvdimm_bus_unlock(dev); device_unlock(dev); @@ -1519,7 +1517,7 @@ static ssize_t holder_class_store(struct device *dev, rc = __holder_class_store(dev, buf); if (rc >= 0) rc = nd_namespace_label_update(nd_region, dev); - dev_dbg(dev, "%s: %s(%zd)\n", __func__, rc < 0 ? "fail " : "", rc); + dev_dbg(dev, "%s(%zd)\n", rc < 0 ? "fail " : "", rc); nvdimm_bus_unlock(dev); device_unlock(dev); @@ -1717,8 +1715,7 @@ struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev) if (uuid_not_set(nsblk->uuid, &ndns->dev, __func__)) return ERR_PTR(-ENODEV); if (!nsblk->lbasize) { - dev_dbg(&ndns->dev, "%s: sector size not set\n", - __func__); + dev_dbg(&ndns->dev, "sector size not set\n"); return ERR_PTR(-ENODEV); } if (!nd_namespace_blk_validate(nsblk)) @@ -1798,9 +1795,7 @@ static bool has_uuid_at_pos(struct nd_region *nd_region, u8 *uuid, } if (found_uuid) { - dev_dbg(ndd->dev, - "%s duplicate entry for uuid\n", - __func__); + dev_dbg(ndd->dev, "duplicate entry for uuid\n"); return false; } found_uuid = true; @@ -1926,7 +1921,7 @@ static struct device *create_namespace_pmem(struct nd_region *nd_region, } if (i < nd_region->ndr_mappings) { - struct nvdimm_drvdata *ndd = to_ndd(&nd_region->mapping[i]); + struct nvdimm *nvdimm = nd_region->mapping[i].nvdimm; /* * Give up if we don't find an instance of a uuid at each @@ -1934,7 +1929,7 @@ static struct device *create_namespace_pmem(struct nd_region *nd_region, * find a dimm with two instances of the same uuid. */ dev_err(&nd_region->dev, "%s missing label for %pUb\n", - dev_name(ndd->dev), nd_label->uuid); + nvdimm_name(nvdimm), nd_label->uuid); rc = -EINVAL; goto err; } @@ -1994,14 +1989,13 @@ static struct device *create_namespace_pmem(struct nd_region *nd_region, namespace_pmem_release(dev); switch (rc) { case -EINVAL: - dev_dbg(&nd_region->dev, "%s: invalid label(s)\n", __func__); + dev_dbg(&nd_region->dev, "invalid label(s)\n"); break; case -ENODEV: - dev_dbg(&nd_region->dev, "%s: label not found\n", __func__); + dev_dbg(&nd_region->dev, "label not found\n"); break; default: - dev_dbg(&nd_region->dev, "%s: unexpected err: %d\n", - __func__, rc); + dev_dbg(&nd_region->dev, "unexpected err: %d\n", rc); break; } return ERR_PTR(rc); @@ -2334,8 +2328,8 @@ static struct device **scan_labels(struct nd_region *nd_region) } - dev_dbg(&nd_region->dev, "%s: discovered %d %s namespace%s\n", - __func__, count, is_nd_blk(&nd_region->dev) + dev_dbg(&nd_region->dev, "discovered %d %s namespace%s\n", + count, is_nd_blk(&nd_region->dev) ? "blk" : "pmem", count == 1 ? "" : "s"); if (count == 0) { @@ -2467,7 +2461,7 @@ static int init_active_labels(struct nd_region *nd_region) get_ndd(ndd); count = nd_label_active_count(ndd); - dev_dbg(ndd->dev, "%s: %d\n", __func__, count); + dev_dbg(ndd->dev, "count: %d\n", count); if (!count) continue; for (j = 0; j < count; j++) { diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index 8d6375ee0fda..9dad5d737309 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -341,7 +341,6 @@ static inline struct device *nd_dax_create(struct nd_region *nd_region) } #endif -struct nd_region *to_nd_region(struct device *dev); int nd_region_to_nstype(struct nd_region *nd_region); int nd_region_register_namespaces(struct nd_region *nd_region, int *err); u64 nd_region_interleave_set_cookie(struct nd_region *nd_region, diff --git a/drivers/nvdimm/of_pmem.c b/drivers/nvdimm/of_pmem.c new file mode 100644 index 000000000000..85013bad35de --- /dev/null +++ b/drivers/nvdimm/of_pmem.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#define pr_fmt(fmt) "of_pmem: " fmt + +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/libnvdimm.h> +#include <linux/module.h> +#include <linux/ioport.h> +#include <linux/slab.h> + +static const struct attribute_group *region_attr_groups[] = { + &nd_region_attribute_group, + &nd_device_attribute_group, + NULL, +}; + +static const struct attribute_group *bus_attr_groups[] = { + &nvdimm_bus_attribute_group, + NULL, +}; + +struct of_pmem_private { + struct nvdimm_bus_descriptor bus_desc; + struct nvdimm_bus *bus; +}; + +static int of_pmem_region_probe(struct platform_device *pdev) +{ + struct of_pmem_private *priv; + struct device_node *np; + struct nvdimm_bus *bus; + bool is_volatile; + int i; + + np = dev_of_node(&pdev->dev); + if (!np) + return -ENXIO; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->bus_desc.attr_groups = bus_attr_groups; + priv->bus_desc.provider_name = "of_pmem"; + priv->bus_desc.module = THIS_MODULE; + priv->bus_desc.of_node = np; + + priv->bus = bus = nvdimm_bus_register(&pdev->dev, &priv->bus_desc); + if (!bus) { + kfree(priv); + return -ENODEV; + } + platform_set_drvdata(pdev, priv); + + is_volatile = !!of_find_property(np, "volatile", NULL); + dev_dbg(&pdev->dev, "Registering %s regions from %pOF\n", + is_volatile ? "volatile" : "non-volatile", np); + + for (i = 0; i < pdev->num_resources; i++) { + struct nd_region_desc ndr_desc; + struct nd_region *region; + + /* + * NB: libnvdimm copies the data from ndr_desc into it's own + * structures so passing a stack pointer is fine. + */ + memset(&ndr_desc, 0, sizeof(ndr_desc)); + ndr_desc.attr_groups = region_attr_groups; + ndr_desc.numa_node = of_node_to_nid(np); + ndr_desc.res = &pdev->resource[i]; + ndr_desc.of_node = np; + set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags); + + if (is_volatile) + region = nvdimm_volatile_region_create(bus, &ndr_desc); + else + region = nvdimm_pmem_region_create(bus, &ndr_desc); + + if (!region) + dev_warn(&pdev->dev, "Unable to register region %pR from %pOF\n", + ndr_desc.res, np); + else + dev_dbg(&pdev->dev, "Registered region %pR from %pOF\n", + ndr_desc.res, np); + } + + return 0; +} + +static int of_pmem_region_remove(struct platform_device *pdev) +{ + struct of_pmem_private *priv = platform_get_drvdata(pdev); + + nvdimm_bus_unregister(priv->bus); + kfree(priv); + + return 0; +} + +static const struct of_device_id of_pmem_region_match[] = { + { .compatible = "pmem-region" }, + { }, +}; + +static struct platform_driver of_pmem_region_driver = { + .probe = of_pmem_region_probe, + .remove = of_pmem_region_remove, + .driver = { + .name = "of_pmem", + .owner = THIS_MODULE, + .of_match_table = of_pmem_region_match, + }, +}; + +module_platform_driver(of_pmem_region_driver); +MODULE_DEVICE_TABLE(of, of_pmem_region_match); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("IBM Corporation"); diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 2f4d18752c97..30b08791597d 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -27,7 +27,7 @@ static void nd_pfn_release(struct device *dev) struct nd_region *nd_region = to_nd_region(dev->parent); struct nd_pfn *nd_pfn = to_nd_pfn(dev); - dev_dbg(dev, "%s\n", __func__); + dev_dbg(dev, "trace\n"); nd_detach_ndns(&nd_pfn->dev, &nd_pfn->ndns); ida_simple_remove(&nd_region->pfn_ida, nd_pfn->id); kfree(nd_pfn->uuid); @@ -94,8 +94,8 @@ static ssize_t mode_store(struct device *dev, else rc = -EINVAL; } - dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, - rc, buf, buf[len - 1] == '\n' ? "" : "\n"); + dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, + buf[len - 1] == '\n' ? "" : "\n"); nvdimm_bus_unlock(dev); device_unlock(dev); @@ -144,8 +144,8 @@ static ssize_t align_store(struct device *dev, nvdimm_bus_lock(dev); rc = nd_size_select_store(dev, buf, &nd_pfn->align, nd_pfn_supported_alignments()); - dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, - rc, buf, buf[len - 1] == '\n' ? "" : "\n"); + dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, + buf[len - 1] == '\n' ? "" : "\n"); nvdimm_bus_unlock(dev); device_unlock(dev); @@ -171,8 +171,8 @@ static ssize_t uuid_store(struct device *dev, device_lock(dev); rc = nd_uuid_store(dev, &nd_pfn->uuid, buf, len); - dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, - rc, buf, buf[len - 1] == '\n' ? "" : "\n"); + dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, + buf[len - 1] == '\n' ? "" : "\n"); device_unlock(dev); return rc ? rc : len; @@ -201,8 +201,8 @@ static ssize_t namespace_store(struct device *dev, device_lock(dev); nvdimm_bus_lock(dev); rc = nd_namespace_store(dev, &nd_pfn->ndns, buf, len); - dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__, - rc, buf, buf[len - 1] == '\n' ? "" : "\n"); + dev_dbg(dev, "result: %zd wrote: %s%s", rc, buf, + buf[len - 1] == '\n' ? "" : "\n"); nvdimm_bus_unlock(dev); device_unlock(dev); @@ -314,8 +314,8 @@ struct device *nd_pfn_devinit(struct nd_pfn *nd_pfn, dev = &nd_pfn->dev; device_initialize(&nd_pfn->dev); if (ndns && !__nd_attach_ndns(&nd_pfn->dev, ndns, &nd_pfn->ndns)) { - dev_dbg(&ndns->dev, "%s failed, already claimed by %s\n", - __func__, dev_name(ndns->claim)); + dev_dbg(&ndns->dev, "failed, already claimed by %s\n", + dev_name(ndns->claim)); put_device(dev); return NULL; } @@ -510,8 +510,7 @@ int nd_pfn_probe(struct device *dev, struct nd_namespace_common *ndns) nd_pfn = to_nd_pfn(pfn_dev); nd_pfn->pfn_sb = pfn_sb; rc = nd_pfn_validate(nd_pfn, PFN_SIG); - dev_dbg(dev, "%s: pfn: %s\n", __func__, - rc == 0 ? dev_name(pfn_dev) : "<none>"); + dev_dbg(dev, "pfn: %s\n", rc == 0 ? dev_name(pfn_dev) : "<none>"); if (rc < 0) { nd_detach_ndns(pfn_dev, &nd_pfn->ndns); put_device(pfn_dev); diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 06f8dcc52ca6..85dfb3dc3981 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -66,7 +66,7 @@ static blk_status_t pmem_clear_poison(struct pmem_device *pmem, rc = BLK_STS_IOERR; if (cleared > 0 && cleared / 512) { cleared /= 512; - dev_dbg(dev, "%s: %#llx clear %ld sector%s\n", __func__, + dev_dbg(dev, "%#llx clear %ld sector%s\n", (unsigned long long) sector, cleared, cleared > 1 ? "s" : ""); badblocks_clear(&pmem->bb, sector, cleared); @@ -547,17 +547,7 @@ static struct nd_device_driver nd_pmem_driver = { .type = ND_DRIVER_NAMESPACE_IO | ND_DRIVER_NAMESPACE_PMEM, }; -static int __init pmem_init(void) -{ - return nd_driver_register(&nd_pmem_driver); -} -module_init(pmem_init); - -static void pmem_exit(void) -{ - driver_unregister(&nd_pmem_driver.drv); -} -module_exit(pmem_exit); +module_nd_driver(nd_pmem_driver); MODULE_AUTHOR("Ross Zwisler <ross.zwisler@linux.intel.com>"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/nvdimm/region.c b/drivers/nvdimm/region.c index 034f0a07d627..b9ca0033cc99 100644 --- a/drivers/nvdimm/region.c +++ b/drivers/nvdimm/region.c @@ -27,10 +27,10 @@ static int nd_region_probe(struct device *dev) if (nd_region->num_lanes > num_online_cpus() && nd_region->num_lanes < num_possible_cpus() && !test_and_set_bit(0, &once)) { - dev_info(dev, "online cpus (%d) < concurrent i/o lanes (%d) < possible cpus (%d)\n", + dev_dbg(dev, "online cpus (%d) < concurrent i/o lanes (%d) < possible cpus (%d)\n", num_online_cpus(), nd_region->num_lanes, num_possible_cpus()); - dev_info(dev, "setting nr_cpus=%d may yield better libnvdimm device performance\n", + dev_dbg(dev, "setting nr_cpus=%d may yield better libnvdimm device performance\n", nd_region->num_lanes); } diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index 1593e1806b16..a612be6f019d 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -182,6 +182,14 @@ struct nd_region *to_nd_region(struct device *dev) } EXPORT_SYMBOL_GPL(to_nd_region); +struct device *nd_region_dev(struct nd_region *nd_region) +{ + if (!nd_region) + return NULL; + return &nd_region->dev; +} +EXPORT_SYMBOL_GPL(nd_region_dev); + struct nd_blk_region *to_nd_blk_region(struct device *dev) { struct nd_region *nd_region = to_nd_region(dev); @@ -1014,6 +1022,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, dev->parent = &nvdimm_bus->dev; dev->type = dev_type; dev->groups = ndr_desc->attr_groups; + dev->of_node = ndr_desc->of_node; nd_region->ndr_size = resource_size(ndr_desc->res); nd_region->ndr_start = ndr_desc->res->start; nd_device_register(dev); |