[PATCH v2 2/2] nvme: Fix error in nvme_setup_prps

Jon Lin jon.lin at rock-chips.com
Mon Sep 27 15:22:30 CEST 2021


Consulting to "NVM Express® Base Specification, revision 2.0".

If more PRP List pages are required, then the last entry of
the PRP List contains the Page Base Address of the next PRP
List page. The next PRP List page shall be memory page aligned.

Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

(no changes since v1)

 drivers/nvme/nvme.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 5d05cb6e9e..07d6bea83c 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -100,7 +100,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);
 
 	if (nprps > dev->prp_entry_num) {
 		free(dev->prp_pool);
@@ -119,10 +119,11 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
 	prp_pool = dev->prp_pool;
 	i = 0;
 	while (nprps) {
-		if (i == ((page_size >> 3) - 1)) {
-			*(prp_pool + i) = cpu_to_le64((ulong)prp_pool +
+		if (i == prps_per_page) {
+			*(prp_pool + i) = *(prp_pool + i - 1);
+			*(prp_pool + i - 1) = cpu_to_le64((ulong)prp_pool +
 					page_size);
-			i = 0;
+			i = 1;
 			prp_pool += page_size;
 		}
 		*(prp_pool + i++) = cpu_to_le64(dma_addr);
-- 
2.17.1





More information about the U-Boot mailing list