aboutsummaryrefslogtreecommitdiff
path: root/drivers/nvme
diff options
context:
space:
mode:
authorAlexander Sowarka2022-08-28 21:30:20 +0200
committerTom Rini2022-09-15 09:55:30 -0400
commit4ca8d95ce1e71995052e81f1854a23803ca48b73 (patch)
tree7e58f52c635ff449dd12eb18f3197cb2d6ccf782 /drivers/nvme
parent9895bda2ed09fe6b38f553022c263d5aa975cf99 (diff)
nvme: Fix multipage prp-list
The nvme driver falsely assumed that the last entry on a page of the prp-list always points to the next page of the prp-list. This potentially can lead to the illegal creation of pages on the prp-list with only a single entry. This change now ensures that splitting the prp-list into multiple pages, behaves now as required by the NVME-Spec. Related to this, also the size of the memory allocation is adjusted accordingly. Signed-off-by: Alexander Sowarka <alexander.sowarka@aerq.com>
Diffstat (limited to 'drivers/nvme')
-rw-r--r--drivers/nvme/nvme.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index a305305885e..31cf7006330 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -72,7 +72,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
}
nprps = DIV_ROUND_UP(length, page_size);
- num_pages = DIV_ROUND_UP(nprps, prps_per_page);
+ num_pages = DIV_ROUND_UP(nprps - 1, prps_per_page - 1);
if (nprps > dev->prp_entry_num) {
free(dev->prp_pool);
@@ -85,13 +85,13 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
printf("Error: malloc prp_pool fail\n");
return -ENOMEM;
}
- dev->prp_entry_num = prps_per_page * num_pages;
+ dev->prp_entry_num = num_pages * (prps_per_page - 1) + 1;
}
prp_pool = dev->prp_pool;
i = 0;
while (nprps) {
- if (i == ((page_size >> 3) - 1)) {
+ if ((i == (prps_per_page - 1)) && nprps > 1) {
*(prp_pool + i) = cpu_to_le64((ulong)prp_pool +
page_size);
i = 0;
@@ -104,7 +104,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
*prp2 = (ulong)dev->prp_pool;
flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool +
- dev->prp_entry_num * sizeof(u64));
+ num_pages * page_size);
return 0;
}