diff mbox series

mmc: rpmb: realign frames before passing to MMC driver

Message ID 20230511150717.1790324-1-pavel@loebl.cz
State New
Delegated to: Jaehoon Chung
Headers show
Series mmc: rpmb: realign frames before passing to MMC driver | expand

Commit Message

Pavel Löbl May 11, 2023, 3:07 p.m. UTC
MMC driver requires request and response frame buffers to be properly
aligned for DMA transfers.

Fix already implemented reallocation for request frame and also add
realigment for response frame if needed.

Signed-off-by: Pavel Löbl <pavel@loebl.cz>
---
 drivers/mmc/rpmb.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

Comments

Peng Fan (OSS) June 14, 2023, 11:59 a.m. UTC | #1
On 5/11/2023 11:07 PM, Pavel Löbl wrote:
> MMC driver requires request and response frame buffers to be properly
> aligned for DMA transfers.
> 
> Fix already implemented reallocation for request frame and also add
> realigment for response frame if needed.

Have you met any issues without your patch?

> 
> Signed-off-by: Pavel Löbl <pavel@loebl.cz>
> ---
>   drivers/mmc/rpmb.c | 17 +++++++++++++++--
>   1 file changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/rpmb.c b/drivers/mmc/rpmb.c
> index b68d98573c..e951f4e9bd 100644
> --- a/drivers/mmc/rpmb.c
> +++ b/drivers/mmc/rpmb.c
> @@ -482,13 +482,14 @@ int mmc_rpmb_route_frames(struct mmc *mmc, void *req, unsigned long reqlen,
>   	 */
>   	void *rpmb_data = NULL;
>   	int ret;
> +	void *rsp_aligned = rsp;
>   
>   	if (reqlen % sizeof(struct s_rpmb) || rsplen % sizeof(struct s_rpmb))
>   		return -EINVAL;
>   
>   	if (!IS_ALIGNED((uintptr_t)req, ARCH_DMA_MINALIGN)) {
>   		/* Memory alignment is required by MMC driver */
> -		rpmb_data = malloc(reqlen);
> +		rpmb_data = memalign(ARCH_DMA_MINALIGN, reqlen);

The mmc driver use ALLOC_CACHE_ALIGN_BUFFER, so better align.

Regards,
Peng.

>   		if (!rpmb_data)
>   			return -ENOMEM;
>   
> @@ -496,8 +497,20 @@ int mmc_rpmb_route_frames(struct mmc *mmc, void *req, unsigned long reqlen,
>   		req = rpmb_data;
>   	}
>   
> +	if (!IS_ALIGNED((uintptr_t)rsp_aligned, ARCH_DMA_MINALIGN)) {
> +		rsp_aligned = memalign(ARCH_DMA_MINALIGN, rsplen);
> +		if (!rsp_aligned)
> +			return -ENOMEM;
> +	}
> +
>   	ret = rpmb_route_frames(mmc, req, reqlen / sizeof(struct s_rpmb),
> -				rsp, rsplen / sizeof(struct s_rpmb));
> +				rsp_aligned, rsplen / sizeof(struct s_rpmb));
> +
> +	if (rsp_aligned != rsp) {
> +		memcpy(rsp, rsp_aligned, rsplen);
> +		free(rsp_aligned);
> +	}
> +
>   	free(rpmb_data);
>   	return ret;
>   }
diff mbox series

Patch

diff --git a/drivers/mmc/rpmb.c b/drivers/mmc/rpmb.c
index b68d98573c..e951f4e9bd 100644
--- a/drivers/mmc/rpmb.c
+++ b/drivers/mmc/rpmb.c
@@ -482,13 +482,14 @@  int mmc_rpmb_route_frames(struct mmc *mmc, void *req, unsigned long reqlen,
 	 */
 	void *rpmb_data = NULL;
 	int ret;
+	void *rsp_aligned = rsp;
 
 	if (reqlen % sizeof(struct s_rpmb) || rsplen % sizeof(struct s_rpmb))
 		return -EINVAL;
 
 	if (!IS_ALIGNED((uintptr_t)req, ARCH_DMA_MINALIGN)) {
 		/* Memory alignment is required by MMC driver */
-		rpmb_data = malloc(reqlen);
+		rpmb_data = memalign(ARCH_DMA_MINALIGN, reqlen);
 		if (!rpmb_data)
 			return -ENOMEM;
 
@@ -496,8 +497,20 @@  int mmc_rpmb_route_frames(struct mmc *mmc, void *req, unsigned long reqlen,
 		req = rpmb_data;
 	}
 
+	if (!IS_ALIGNED((uintptr_t)rsp_aligned, ARCH_DMA_MINALIGN)) {
+		rsp_aligned = memalign(ARCH_DMA_MINALIGN, rsplen);
+		if (!rsp_aligned)
+			return -ENOMEM;
+	}
+
 	ret = rpmb_route_frames(mmc, req, reqlen / sizeof(struct s_rpmb),
-				rsp, rsplen / sizeof(struct s_rpmb));
+				rsp_aligned, rsplen / sizeof(struct s_rpmb));
+
+	if (rsp_aligned != rsp) {
+		memcpy(rsp, rsp_aligned, rsplen);
+		free(rsp_aligned);
+	}
+
 	free(rpmb_data);
 	return ret;
 }