diff options
author | Dan Williams <dan.j.williams@intel.com> | 2018-12-27 19:54:10 -0800 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2018-12-27 19:54:10 -0800 |
commit | 4b5f747e82b12b6d8ab815fc259827a615c7f2c3 (patch) | |
tree | ec5eb3857bbb776ac521f555978fcb78cc6bd2a8 /drivers/nvdimm/region_devs.c | |
parent | 37379cfc661e51607733f266d9f407b4f8aee16b (diff) | |
parent | 3d9cbe37c16ffd19eeab6b49a0311bbb999627d8 (diff) | |
download | talos-op-linux-4b5f747e82b12b6d8ab815fc259827a615c7f2c3.tar.gz talos-op-linux-4b5f747e82b12b6d8ab815fc259827a615c7f2c3.zip |
Merge miscellaneous libnvdimm updates for 4.21
* Use common helpers, bitmap_zalloc() and kstrndup(), to replace open
coded versions.
* Clarify the comments around hotplug vs initial init case for the nfit
driver.
* Cleanup the libnvdimm init path.
Diffstat (limited to 'drivers/nvdimm/region_devs.c')
-rw-r--r-- | drivers/nvdimm/region_devs.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index b4d8e4ed3020..e2818f94f292 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -1189,6 +1189,47 @@ int nvdimm_has_cache(struct nd_region *nd_region) } EXPORT_SYMBOL_GPL(nvdimm_has_cache); +struct conflict_context { + struct nd_region *nd_region; + resource_size_t start, size; +}; + +static int region_conflict(struct device *dev, void *data) +{ + struct nd_region *nd_region; + struct conflict_context *ctx = data; + resource_size_t res_end, region_end, region_start; + + if (!is_memory(dev)) + return 0; + + nd_region = to_nd_region(dev); + if (nd_region == ctx->nd_region) + return 0; + + res_end = ctx->start + ctx->size; + region_start = nd_region->ndr_start; + region_end = region_start + nd_region->ndr_size; + if (ctx->start >= region_start && ctx->start < region_end) + return -EBUSY; + if (res_end > region_start && res_end <= region_end) + return -EBUSY; + return 0; +} + +int nd_region_conflict(struct nd_region *nd_region, resource_size_t start, + resource_size_t size) +{ + struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev); + struct conflict_context ctx = { + .nd_region = nd_region, + .start = start, + .size = size, + }; + + return device_for_each_child(&nvdimm_bus->dev, &ctx, region_conflict); +} + void __exit nd_region_devs_exit(void) { ida_destroy(®ion_ida); |