From dd09232ee51a568fc32a64f515e2f9fce110102b Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Sat, 19 Dec 2020 13:02:34 +0900 Subject: [PATCH] FROMGIT: ufs: introduce a quirk to allow only page-aligned sg entries Some SoCs could require 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, They could behave 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 + +-------+------------ +-------+ In this case, you need to force an alignment with page size for sg entries. Bug: 177399609 Change-Id: I4a930e35efeed233d09ff935431c3db120c13e4d (cherry picked from commit 2b2bfc8aa519f696087475ed8e8c61850c673272 https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git 5.12/scsi-staging) Signed-off-by: Kiwoong Kim --- drivers/scsi/ufs/ufshcd.c | 2 ++ drivers/scsi/ufs/ufshcd.h | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index b7284b2199cd..dc426f3a0ae6 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4791,6 +4791,8 @@ static int ufshcd_slave_configure(struct scsi_device *sdev) struct request_queue *q = sdev->request_queue; blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1); + if (hba->quirks & UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE) + blk_queue_update_dma_alignment(q, PAGE_SIZE - 1); if (ufshcd_is_rpm_autosuspend_allowed(hba)) sdev->rpm_autosuspend = 1; diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index ccd75ae2aae9..cd8b9091e7b9 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -565,6 +565,11 @@ enum ufshcd_quirks { */ UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING = 1 << 13, + /* + * This quirk allows only sg entries aligned with page size. + */ + UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE = 1 << 14, + /* * This quirk needs to be enabled if the host controller supports inline * encryption, but it needs to initialize the crypto capabilities in a