diff mbox series

[v5,2/2] ufs: ufs-exynos: set dma_alignment to 4095

Message ID 689878ebbad3e63a96b431df8d843264f8fe57ba.1610419491.git.kwmad.kim@samsung.com (mailing list archive)
State Changes Requested
Headers show
Series permit to set block parameters per vendor | expand

Commit Message

Kiwoong Kim Jan. 12, 2021, 2:45 a.m. UTC
Exynos requires one scatterlist entry for smaller than
page size, i.e. 4KB. For the cases of dispatching commands
with more than one scatterlist entry and under 4KB size,
Exynos behaves as follows:

Given that a command to read something
from device is dispatched with two scatterlist entries that
are named AAA and BBB. After dispatching, host builds two PRDT
entries and during transmission, device sends just one DATA IN
because device doesn't care on host dma. The host then tranfers
the whole data from start address of the area named AAA.
In consequence, the area that follows AAA would be corrupted.

    |<------------->|
    +-------+------------         +-------+
    +  AAA  + (corrupted)   ...   +  BBB  +
    +-------+------------         +-------+

Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
---
 drivers/scsi/ufs/ufs-exynos.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Avri Altman Jan. 12, 2021, 7:25 a.m. UTC | #1
> 
> Exynos requires one scatterlist entry for smaller than
> page size, i.e. 4KB. For the cases of dispatching commands
> with more than one scatterlist entry and under 4KB size,
> Exynos behaves as follows:
> 
> Given that a command to read something
> from device is dispatched with two scatterlist entries that
> are named AAA and BBB. After dispatching, host builds two PRDT
> entries and during transmission, device sends just one DATA IN
> because device doesn't care on host dma. The host then tranfers
> the whole data from start address of the area named AAA.
> In consequence, the area that follows AAA would be corrupted.
> 
>     |<------------->|
>     +-------+------------         +-------+
>     +  AAA  + (corrupted)   ...   +  BBB  +
>     +-------+------------         +-------+
> 
> Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
Reviewed-by: Avri Altman <avri.altman@wdc.com>
Christoph Hellwig Jan. 12, 2021, 9:03 a.m. UTC | #2
Just use quirk instead of all these indirections.
diff mbox series

Patch

diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
index a8770ff..8635d9d 100644
--- a/drivers/scsi/ufs/ufs-exynos.c
+++ b/drivers/scsi/ufs/ufs-exynos.c
@@ -14,6 +14,7 @@ 
 #include <linux/of_address.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/blkdev.h>
 
 #include "ufshcd.h"
 #include "ufshcd-pltfrm.h"
@@ -1193,6 +1194,13 @@  static int exynos_ufs_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
 	return 0;
 }
 
+static void exynos_ufs_slave_configure(struct scsi_device *sdev)
+{
+	struct request_queue *q = sdev->request_queue;
+
+	blk_queue_update_dma_alignment(q, PAGE_SIZE - 1);
+}
+
 static struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
 	.name				= "exynos_ufs",
 	.init				= exynos_ufs_init,
@@ -1204,6 +1212,7 @@  static struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
 	.hibern8_notify			= exynos_ufs_hibern8_notify,
 	.suspend			= exynos_ufs_suspend,
 	.resume				= exynos_ufs_resume,
+	.slave_configure		= exynos_ufs_slave_configure,
 };
 
 static int exynos_ufs_probe(struct platform_device *pdev)