aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvdimm/pmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/nvdimm/pmem.c')
-rw-r--r--drivers/nvdimm/pmem.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index cc31c6f1f88e..ca304342af33 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -244,7 +244,9 @@ static void pmem_detach_disk(struct pmem_device *pmem)
244static int pmem_attach_disk(struct device *dev, 244static int pmem_attach_disk(struct device *dev,
245 struct nd_namespace_common *ndns, struct pmem_device *pmem) 245 struct nd_namespace_common *ndns, struct pmem_device *pmem)
246{ 246{
247 struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
247 int nid = dev_to_node(dev); 248 int nid = dev_to_node(dev);
249 struct resource bb_res;
248 struct gendisk *disk; 250 struct gendisk *disk;
249 251
250 blk_queue_make_request(pmem->pmem_queue, pmem_make_request); 252 blk_queue_make_request(pmem->pmem_queue, pmem_make_request);
@@ -271,8 +273,17 @@ static int pmem_attach_disk(struct device *dev,
271 devm_exit_badblocks(dev, &pmem->bb); 273 devm_exit_badblocks(dev, &pmem->bb);
272 if (devm_init_badblocks(dev, &pmem->bb)) 274 if (devm_init_badblocks(dev, &pmem->bb))
273 return -ENOMEM; 275 return -ENOMEM;
274 nvdimm_namespace_add_poison(ndns, &pmem->bb, pmem->data_offset); 276 bb_res.start = nsio->res.start + pmem->data_offset;
275 277 bb_res.end = nsio->res.end;
278 if (is_nd_pfn(dev)) {
279 struct nd_pfn *nd_pfn = to_nd_pfn(dev);
280 struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
281
282 bb_res.start += __le32_to_cpu(pfn_sb->start_pad);
283 bb_res.end -= __le32_to_cpu(pfn_sb->end_trunc);
284 }
285 nvdimm_badblocks_populate(to_nd_region(dev->parent), &pmem->bb,
286 &bb_res);
276 disk->bb = &pmem->bb; 287 disk->bb = &pmem->bb;
277 add_disk(disk); 288 add_disk(disk);
278 revalidate_disk(disk); 289 revalidate_disk(disk);
@@ -553,7 +564,7 @@ static int nd_pmem_probe(struct device *dev)
553 ndns->rw_bytes = pmem_rw_bytes; 564 ndns->rw_bytes = pmem_rw_bytes;
554 if (devm_init_badblocks(dev, &pmem->bb)) 565 if (devm_init_badblocks(dev, &pmem->bb))
555 return -ENOMEM; 566 return -ENOMEM;
556 nvdimm_namespace_add_poison(ndns, &pmem->bb, 0); 567 nvdimm_badblocks_populate(nd_region, &pmem->bb, &nsio->res);
557 568
558 if (is_nd_btt(dev)) { 569 if (is_nd_btt(dev)) {
559 /* btt allocates its own request_queue */ 570 /* btt allocates its own request_queue */
@@ -595,14 +606,25 @@ static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
595{ 606{
596 struct pmem_device *pmem = dev_get_drvdata(dev); 607 struct pmem_device *pmem = dev_get_drvdata(dev);
597 struct nd_namespace_common *ndns = pmem->ndns; 608 struct nd_namespace_common *ndns = pmem->ndns;
609 struct nd_region *nd_region = to_nd_region(dev->parent);
610 struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
611 struct resource res = {
612 .start = nsio->res.start + pmem->data_offset,
613 .end = nsio->res.end,
614 };
598 615
599 if (event != NVDIMM_REVALIDATE_POISON) 616 if (event != NVDIMM_REVALIDATE_POISON)
600 return; 617 return;
601 618
602 if (is_nd_btt(dev)) 619 if (is_nd_pfn(dev)) {
603 nvdimm_namespace_add_poison(ndns, &pmem->bb, 0); 620 struct nd_pfn *nd_pfn = to_nd_pfn(dev);
604 else 621 struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
605 nvdimm_namespace_add_poison(ndns, &pmem->bb, pmem->data_offset); 622
623 res.start += __le32_to_cpu(pfn_sb->start_pad);
624 res.end -= __le32_to_cpu(pfn_sb->end_trunc);
625 }
626
627 nvdimm_badblocks_populate(nd_region, &pmem->bb, &res);
606} 628}
607 629
608MODULE_ALIAS("pmem"); 630MODULE_ALIAS("pmem");