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

Shawn Lin shawn.lin at rock-chips.com
Tue Sep 28 02:44:52 CEST 2021


在 2021/9/27 21:22, Jon Lin 写道:
> 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.
> 

Yep, this is indeed a bug that we try to fix, which can be reproduced
with PM981 NVMe when booting kernel.

Reviewed-by: Shawn Lin <shawn.lin at rock-chips.com>

> 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);
> 




More information about the U-Boot mailing list