scsi: ufs: disallow SECURITY_PROTOCOL_IN without _OUT

This merged the following fix:
6a317b49c98c ("scsi: ufs: revise commit ecd2676bd513 ("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: 113580864
Bug: 79898356
Bug: 109850759
Bug: 117682499
Bug: 112560467
Change-Id: Ie7820a9604e4c7bc4cc530acf41bb5bb72f33d5b
Signed-off-by: Jaegeuk Kim <jaegeuk@google.com>
Signed-off-by: Randall Huang <huangrandall@google.com>
Signed-off-by: Alexander Winkowski <dereference23@outlook.com>
fourteen
Jaegeuk Kim 7 years ago committed by Jenna
parent 72d49e9d8a
commit 01e389737f
  1. 24
      drivers/scsi/ufs/ufshcd.c
  2. 2
      drivers/scsi/ufs/ufshcd.h

@ -3503,7 +3503,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);
@ -3515,7 +3527,7 @@ int ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
ufshcd_cond_add_cmd_trace(hba, task_tag,
hba->lrb[task_tag].cmd ? "scsi_send" : "dev_cmd_send");
ufshcd_update_tag_stats(hba, task_tag);
return ret;
return 0;
}
/**
@ -4407,7 +4419,13 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
ufshcd_vops_pm_qos_req_end(hba, cmd->request, true);
dev_err(hba->dev, "%s: failed sending command, %d\n",
__func__, err);
err = DID_ERROR;
if (err == -EINVAL) {
set_host_byte(cmd, DID_ERROR);
if (has_read_lock)
ufshcd_put_read_lock(hba);
cmd->scsi_done(cmd);
return 0;
}
goto out;
}

@ -1112,6 +1112,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;

Loading…
Cancel
Save