mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-14 12:56:00 +01:00
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>
This commit is contained in:
parent
9895bda2ed
commit
4ca8d95ce1
@ -72,7 +72,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nprps = DIV_ROUND_UP(length, page_size);
|
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) {
|
if (nprps > dev->prp_entry_num) {
|
||||||
free(dev->prp_pool);
|
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");
|
printf("Error: malloc prp_pool fail\n");
|
||||||
return -ENOMEM;
|
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;
|
prp_pool = dev->prp_pool;
|
||||||
i = 0;
|
i = 0;
|
||||||
while (nprps) {
|
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 +
|
*(prp_pool + i) = cpu_to_le64((ulong)prp_pool +
|
||||||
page_size);
|
page_size);
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -104,7 +104,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
|
|||||||
*prp2 = (ulong)dev->prp_pool;
|
*prp2 = (ulong)dev->prp_pool;
|
||||||
|
|
||||||
flush_dcache_range((ulong)dev->prp_pool, (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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user