Merge branch 'for-4.16/nfit' into libnvdimm-for-next
[sfrench/cifs-2.6.git] / drivers / nvdimm / pmem.c
index 7fbc5c5dc8e176b7fda861f9929ea879bad0406e..10041ac4032c038db09109b8f757a8719d26f902 100644 (file)
@@ -35,6 +35,7 @@
 #include "pmem.h"
 #include "pfn.h"
 #include "nd.h"
+#include "nd-core.h"
 
 static struct device *to_dev(struct pmem_device *pmem)
 {
@@ -298,34 +299,34 @@ static int pmem_attach_disk(struct device *dev,
 {
        struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
        struct nd_region *nd_region = to_nd_region(dev->parent);
-       struct vmem_altmap __altmap, *altmap = NULL;
        int nid = dev_to_node(dev), fua, wbc;
        struct resource *res = &nsio->res;
+       struct resource bb_res;
        struct nd_pfn *nd_pfn = NULL;
        struct dax_device *dax_dev;
        struct nd_pfn_sb *pfn_sb;
        struct pmem_device *pmem;
-       struct resource pfn_res;
        struct request_queue *q;
        struct device *gendev;
        struct gendisk *disk;
        void *addr;
+       int rc;
+
+       pmem = devm_kzalloc(dev, sizeof(*pmem), GFP_KERNEL);
+       if (!pmem)
+               return -ENOMEM;
 
        /* while nsio_rw_bytes is active, parse a pfn info block if present */
        if (is_nd_pfn(dev)) {
                nd_pfn = to_nd_pfn(dev);
-               altmap = nvdimm_setup_pfn(nd_pfn, &pfn_res, &__altmap);
-               if (IS_ERR(altmap))
-                       return PTR_ERR(altmap);
+               rc = nvdimm_setup_pfn(nd_pfn, &pmem->pgmap);
+               if (rc)
+                       return rc;
        }
 
        /* we're attaching a block device, disable raw namespace access */
        devm_nsio_disable(dev, nsio);
 
-       pmem = devm_kzalloc(dev, sizeof(*pmem), GFP_KERNEL);
-       if (!pmem)
-               return -ENOMEM;
-
        dev_set_drvdata(dev, pmem);
        pmem->phys_addr = res->start;
        pmem->size = resource_size(res);
@@ -334,7 +335,8 @@ static int pmem_attach_disk(struct device *dev,
                dev_warn(dev, "unable to guarantee persistence of writes\n");
                fua = 0;
        }
-       wbc = nvdimm_has_cache(nd_region);
+       wbc = nvdimm_has_cache(nd_region) &&
+               !test_bit(ND_REGION_PERSIST_CACHE, &nd_region->flags);
 
        if (!devm_request_mem_region(dev, res->start, resource_size(res),
                                dev_name(&ndns->dev))) {
@@ -350,19 +352,22 @@ static int pmem_attach_disk(struct device *dev,
                return -ENOMEM;
 
        pmem->pfn_flags = PFN_DEV;
+       pmem->pgmap.ref = &q->q_usage_counter;
        if (is_nd_pfn(dev)) {
-               addr = devm_memremap_pages(dev, &pfn_res, &q->q_usage_counter,
-                               altmap);
+               addr = devm_memremap_pages(dev, &pmem->pgmap);
                pfn_sb = nd_pfn->pfn_sb;
                pmem->data_offset = le64_to_cpu(pfn_sb->dataoff);
-               pmem->pfn_pad = resource_size(res) - resource_size(&pfn_res);
+               pmem->pfn_pad = resource_size(res) -
+                       resource_size(&pmem->pgmap.res);
                pmem->pfn_flags |= PFN_MAP;
-               res = &pfn_res; /* for badblocks populate */
-               res->start += pmem->data_offset;
+               memcpy(&bb_res, &pmem->pgmap.res, sizeof(bb_res));
+               bb_res.start += pmem->data_offset;
        } else if (pmem_should_map_pages(dev)) {
-               addr = devm_memremap_pages(dev, &nsio->res,
-                               &q->q_usage_counter, NULL);
+               memcpy(&pmem->pgmap.res, &nsio->res, sizeof(pmem->pgmap.res));
+               pmem->pgmap.altmap_valid = false;
+               addr = devm_memremap_pages(dev, &pmem->pgmap);
                pmem->pfn_flags |= PFN_MAP;
+               memcpy(&bb_res, &pmem->pgmap.res, sizeof(bb_res));
        } else
                addr = devm_memremap(dev, pmem->phys_addr,
                                pmem->size, ARCH_MEMREMAP_PMEM);
@@ -401,7 +406,7 @@ static int pmem_attach_disk(struct device *dev,
                        / 512);
        if (devm_init_badblocks(dev, &pmem->bb))
                return -ENOMEM;
-       nvdimm_badblocks_populate(nd_region, &pmem->bb, res);
+       nvdimm_badblocks_populate(nd_region, &pmem->bb, &bb_res);
        disk->bb = &pmem->bb;
 
        dax_dev = alloc_dax(pmem, disk->disk_name, &pmem_dax_ops);