From ecd2680bd513b85c19c925ebcdbfb0a4476d3280 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim <jaegeuk@google.com> Date: Thu, 24 May 2018 23:06:58 -0700 Subject: [PATCH] scsi: ufs: disallow SECURITY_PROTOCOL_IN without _OUT If we allow this, Hynix will give timeout due to spec violation. The latest Hynix controller gives error instead of timeout. Bug: 79898356 Change-Id: Ie7820a9604e4c7bc4cc530acf41bb5bb72f33d5b Signed-off-by: Jaegeuk Kim <jaegeuk@google.com> --- drivers/scsi/ufs/ufshcd.c | 16 ++++++++++++++-- drivers/scsi/ufs/ufshcd.h | 2 ++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3a2bcaf6b1f4..1e506c4a980e 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2391,7 +2391,19 @@ static void ufshcd_clk_scaling_update_busy(struct ufs_hba *hba) static inline int ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) { - int ret = 0; + if (hba->lrb[task_tag].cmd) { + u8 opcode = (u8)(*hba->lrb[task_tag].cmd->cmnd); + + if (opcode == SECURITY_PROTOCOL_OUT && hba->security_in) { + hba->security_in--; + } else if (opcode == SECURITY_PROTOCOL_IN) { + if (hba->security_in) { + WARN_ON(1); + return -EINVAL; + } + hba->security_in++; + } + } hba->lrb[task_tag].issue_time_stamp = ktime_get(); hba->lrb[task_tag].complete_time_stamp = ktime_set(0, 0); @@ -2404,7 +2416,7 @@ int ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) hba->lrb[task_tag].cmd ? "scsi_send" : "dev_cmd_send"); ufshcd_update_tag_stats(hba, task_tag); update_io_stat(hba, task_tag, 1); - return ret; + return 0; } /** diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 4b72567eff5d..ed9d6a1e0846 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -889,6 +889,8 @@ struct ufs_hba { /* Number of requests aborts */ int req_abort_count; + u32 security_in; + /* Number of lanes available (1 or 2) for Rx/Tx */ u32 lanes_per_direction; -- GitLab