Message ID | 20240910-topic-ufs-enhancements-v1-2-3ee0bffacc64@linaro.org |
---|---|
State | Accepted |
Delegated to: | Tom Rini |
Headers | show |
Series | ufs: enhancements to support Qualcomm UFS controllers | expand |
On 10/09/24 14:50, Neil Armstrong wrote: > The current calculation will omit doing a flush/invalidate on the last > cacheline if the base address is not aligned with DMA_MINALIGN. > > This causes commands failures and write corruptions on Qualcomm > platforms. > > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> > --- > drivers/ufs/ufs.c | 16 ++++++++-------- > 1 file changed, 8 insertions(+), 8 deletions(-) > > diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c > index e005cc90608..3d9a7d7ee12 100644 > --- a/drivers/ufs/ufs.c > +++ b/drivers/ufs/ufs.c > @@ -703,11 +703,11 @@ static inline u8 ufshcd_get_upmcrs(struct ufs_hba *hba) > */ > static void ufshcd_cache_flush_and_invalidate(void *addr, unsigned long size) > { > - uintptr_t aaddr = (uintptr_t)addr & ~(ARCH_DMA_MINALIGN - 1); > - unsigned long asize = ALIGN(size, ARCH_DMA_MINALIGN); > + uintptr_t start_addr = (uintptr_t)addr & ~(ARCH_DMA_MINALIGN - 1); > + uintptr_t end_addr = ALIGN((uintptr_t)addr + size, ARCH_DMA_MINALIGN); > > - flush_dcache_range(aaddr, aaddr + asize); > - invalidate_dcache_range(aaddr, aaddr + asize); > + flush_dcache_range(start_addr, end_addr); > + invalidate_dcache_range(start_addr, end_addr); > } > > /** > @@ -1466,13 +1466,13 @@ static void prepare_prdt_table(struct ufs_hba *hba, struct scsi_cmd *pccb) > } > > if (pccb->dma_dir == DMA_TO_DEVICE) { /* Write to device */ > - flush_dcache_range(aaddr, aaddr + > - ALIGN(datalen, ARCH_DMA_MINALIGN)); > + flush_dcache_range(aaddr, > + ALIGN((uintptr_t)pccb->pdata + datalen, ARCH_DMA_MINALIGN)); > } > > /* In any case, invalidate cache to avoid stale data in it. */ > - invalidate_dcache_range(aaddr, aaddr + > - ALIGN(datalen, ARCH_DMA_MINALIGN)); > + invalidate_dcache_range(aaddr, > + ALIGN((uintptr_t)pccb->pdata + datalen, ARCH_DMA_MINALIGN)); > > table_length = DIV_ROUND_UP(pccb->datalen, MAX_PRDT_ENTRY); > buf = pccb->pdata; > Reviewed-by: Neha Malcom Francis <n-francis@ti.com>
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index e005cc90608..3d9a7d7ee12 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -703,11 +703,11 @@ static inline u8 ufshcd_get_upmcrs(struct ufs_hba *hba) */ static void ufshcd_cache_flush_and_invalidate(void *addr, unsigned long size) { - uintptr_t aaddr = (uintptr_t)addr & ~(ARCH_DMA_MINALIGN - 1); - unsigned long asize = ALIGN(size, ARCH_DMA_MINALIGN); + uintptr_t start_addr = (uintptr_t)addr & ~(ARCH_DMA_MINALIGN - 1); + uintptr_t end_addr = ALIGN((uintptr_t)addr + size, ARCH_DMA_MINALIGN); - flush_dcache_range(aaddr, aaddr + asize); - invalidate_dcache_range(aaddr, aaddr + asize); + flush_dcache_range(start_addr, end_addr); + invalidate_dcache_range(start_addr, end_addr); } /** @@ -1466,13 +1466,13 @@ static void prepare_prdt_table(struct ufs_hba *hba, struct scsi_cmd *pccb) } if (pccb->dma_dir == DMA_TO_DEVICE) { /* Write to device */ - flush_dcache_range(aaddr, aaddr + - ALIGN(datalen, ARCH_DMA_MINALIGN)); + flush_dcache_range(aaddr, + ALIGN((uintptr_t)pccb->pdata + datalen, ARCH_DMA_MINALIGN)); } /* In any case, invalidate cache to avoid stale data in it. */ - invalidate_dcache_range(aaddr, aaddr + - ALIGN(datalen, ARCH_DMA_MINALIGN)); + invalidate_dcache_range(aaddr, + ALIGN((uintptr_t)pccb->pdata + datalen, ARCH_DMA_MINALIGN)); table_length = DIV_ROUND_UP(pccb->datalen, MAX_PRDT_ENTRY); buf = pccb->pdata;
The current calculation will omit doing a flush/invalidate on the last cacheline if the base address is not aligned with DMA_MINALIGN. This causes commands failures and write corruptions on Qualcomm platforms. Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> --- drivers/ufs/ufs.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)