diff mbox series

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

Message ID 750d12f8707189b51d0f1befb5f264a247e05cef.1608602725.git.kwmad.kim@samsung.com (mailing list archive)
State Superseded
Headers show
Series permit to set block parameters per vendor | expand

Commit Message

Kiwoong Kim Dec. 22, 2020, 2:06 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 consequebnce, 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

Kiwoong Kim Dec. 22, 2020, 2:22 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 consequebnce, 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(+)
> 
> diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
> index a8770ff..1fd5265 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_config_request_queue(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,
> +	.config_request_queue		= exynos_ufs_config_request_queue,
>  };
> 
>  static int exynos_ufs_probe(struct platform_device *pdev)
> --
> 2.7.4

Sorry for bothering all of you posting because of a wrong version of this. Will do again.

Thanks.
Kiwoong Kim
diff mbox series

Patch

diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
index a8770ff..1fd5265 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_config_request_queue(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,
+	.config_request_queue		= exynos_ufs_config_request_queue,
 };
 
 static int exynos_ufs_probe(struct platform_device *pdev)