aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/nvme-core.c19
-rw-r--r--include/linux/nvme.h1
2 files changed, 16 insertions, 4 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index f81280663a4b..4151a3d26e2d 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -519,7 +519,11 @@ static int nvme_map_bio(struct nvme_queue *nvmeq, struct nvme_iod *iod,
519{ 519{
520 struct bio_vec *bvec, *bvprv = NULL; 520 struct bio_vec *bvec, *bvprv = NULL;
521 struct scatterlist *sg = NULL; 521 struct scatterlist *sg = NULL;
522 int i, length = 0, nsegs = 0; 522 int i, length = 0, nsegs = 0, split_len = bio->bi_size;
523
524 if (nvmeq->dev->stripe_size)
525 split_len = nvmeq->dev->stripe_size -
526 ((bio->bi_sector << 9) & (nvmeq->dev->stripe_size - 1));
523 527
524 sg_init_table(iod->sg, psegs); 528 sg_init_table(iod->sg, psegs);
525 bio_for_each_segment(bvec, bio, i) { 529 bio_for_each_segment(bvec, bio, i) {
@@ -535,6 +539,10 @@ static int nvme_map_bio(struct nvme_queue *nvmeq, struct nvme_iod *iod,
535 bvec->bv_offset); 539 bvec->bv_offset);
536 nsegs++; 540 nsegs++;
537 } 541 }
542
543 if (split_len - length < bvec->bv_len)
544 return nvme_split_and_submit(bio, nvmeq, i, split_len,
545 split_len - length);
538 length += bvec->bv_len; 546 length += bvec->bv_len;
539 bvprv = bvec; 547 bvprv = bvec;
540 } 548 }
@@ -543,6 +551,7 @@ static int nvme_map_bio(struct nvme_queue *nvmeq, struct nvme_iod *iod,
543 if (dma_map_sg(nvmeq->q_dmadev, iod->sg, iod->nents, dma_dir) == 0) 551 if (dma_map_sg(nvmeq->q_dmadev, iod->sg, iod->nents, dma_dir) == 0)
544 return -ENOMEM; 552 return -ENOMEM;
545 553
554 BUG_ON(length != bio->bi_size);
546 return length; 555 return length;
547} 556}
548 557
@@ -1612,6 +1621,7 @@ static int nvme_dev_add(struct nvme_dev *dev)
1612 struct nvme_id_ns *id_ns; 1621 struct nvme_id_ns *id_ns;
1613 void *mem; 1622 void *mem;
1614 dma_addr_t dma_addr; 1623 dma_addr_t dma_addr;
1624 int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12;
1615 1625
1616 res = nvme_setup_io_queues(dev); 1626 res = nvme_setup_io_queues(dev);
1617 if (res) 1627 if (res)
@@ -1634,10 +1644,11 @@ static int nvme_dev_add(struct nvme_dev *dev)
1634 memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn)); 1644 memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn));
1635 memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn)); 1645 memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn));
1636 memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr)); 1646 memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr));
1637 if (ctrl->mdts) { 1647 if (ctrl->mdts)
1638 int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12;
1639 dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9); 1648 dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9);
1640 } 1649 if ((dev->pci_dev->vendor == PCI_VENDOR_ID_INTEL) &&
1650 (dev->pci_dev->device == 0x0953) && ctrl->vs[3])
1651 dev->stripe_size = 1 << (ctrl->vs[3] + shift);
1641 1652
1642 id_ns = mem; 1653 id_ns = mem;
1643 for (i = 1; i <= nn; i++) { 1654 for (i = 1; i <= nn; i++) {
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index 9b6fba872f47..af29b0e0b092 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -536,6 +536,7 @@ struct nvme_dev {
536 char model[40]; 536 char model[40];
537 char firmware_rev[8]; 537 char firmware_rev[8];
538 u32 max_hw_sectors; 538 u32 max_hw_sectors;
539 u32 stripe_size;
539 u16 oncs; 540 u16 oncs;
540}; 541};
541 542