|
@@ -33,10 +33,24 @@
|
|
|
#include "pfn.h"
|
|
|
#include "nd.h"
|
|
|
|
|
|
+static struct device *to_dev(struct pmem_device *pmem)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * nvdimm bus services need a 'dev' parameter, and we record the device
|
|
|
+ * at init in bb.dev.
|
|
|
+ */
|
|
|
+ return pmem->bb.dev;
|
|
|
+}
|
|
|
+
|
|
|
+static struct nd_region *to_region(struct pmem_device *pmem)
|
|
|
+{
|
|
|
+ return to_nd_region(to_dev(pmem)->parent);
|
|
|
+}
|
|
|
+
|
|
|
static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset,
|
|
|
unsigned int len)
|
|
|
{
|
|
|
- struct device *dev = pmem->bb.dev;
|
|
|
+ struct device *dev = to_dev(pmem);
|
|
|
sector_t sector;
|
|
|
long cleared;
|
|
|
|
|
@@ -122,7 +136,7 @@ static blk_qc_t pmem_make_request(struct request_queue *q, struct bio *bio)
|
|
|
nd_iostat_end(bio, start);
|
|
|
|
|
|
if (bio_data_dir(bio))
|
|
|
- wmb_pmem();
|
|
|
+ nvdimm_flush(to_region(pmem));
|
|
|
|
|
|
bio_endio(bio);
|
|
|
return BLK_QC_T_NONE;
|
|
@@ -136,7 +150,7 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector,
|
|
|
|
|
|
rc = pmem_do_bvec(pmem, page, PAGE_SIZE, 0, rw, sector);
|
|
|
if (rw & WRITE)
|
|
|
- wmb_pmem();
|
|
|
+ nvdimm_flush(to_region(pmem));
|
|
|
|
|
|
/*
|
|
|
* The ->rw_page interface is subtle and tricky. The core
|
|
@@ -193,6 +207,7 @@ static int pmem_attach_disk(struct device *dev,
|
|
|
struct nd_namespace_common *ndns)
|
|
|
{
|
|
|
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;
|
|
|
struct resource *res = &nsio->res;
|
|
|
struct nd_pfn *nd_pfn = NULL;
|
|
@@ -222,7 +237,7 @@ static int pmem_attach_disk(struct device *dev,
|
|
|
dev_set_drvdata(dev, pmem);
|
|
|
pmem->phys_addr = res->start;
|
|
|
pmem->size = resource_size(res);
|
|
|
- if (!arch_has_wmb_pmem())
|
|
|
+ if (nvdimm_has_flush(nd_region) < 0)
|
|
|
dev_warn(dev, "unable to guarantee persistence of writes\n");
|
|
|
|
|
|
if (!devm_request_mem_region(dev, res->start, resource_size(res),
|
|
@@ -284,7 +299,7 @@ static int pmem_attach_disk(struct device *dev,
|
|
|
/ 512);
|
|
|
if (devm_init_badblocks(dev, &pmem->bb))
|
|
|
return -ENOMEM;
|
|
|
- nvdimm_badblocks_populate(to_nd_region(dev->parent), &pmem->bb, res);
|
|
|
+ nvdimm_badblocks_populate(nd_region, &pmem->bb, res);
|
|
|
disk->bb = &pmem->bb;
|
|
|
add_disk(disk);
|
|
|
|
|
@@ -331,8 +346,8 @@ static int nd_pmem_remove(struct device *dev)
|
|
|
|
|
|
static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
|
|
|
{
|
|
|
- struct nd_region *nd_region = to_nd_region(dev->parent);
|
|
|
struct pmem_device *pmem = dev_get_drvdata(dev);
|
|
|
+ struct nd_region *nd_region = to_region(pmem);
|
|
|
resource_size_t offset = 0, end_trunc = 0;
|
|
|
struct nd_namespace_common *ndns;
|
|
|
struct nd_namespace_io *nsio;
|