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 |
> > 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>
Just use quirk instead of all these indirections.
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)
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(+)