diff options
| -rw-r--r-- | drivers/scsi/ufs/ufshcd.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 40ebaf2e25e9..7d1e575fc8d7 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -703,6 +703,16 @@ static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos) } /** + * ufshcd_outstanding_req_clear - Clear a bit in outstanding request field + * @hba: per adapter instance + * @tag: position of the bit to be cleared + */ +static inline void ufshcd_outstanding_req_clear(struct ufs_hba *hba, int tag) +{ + __clear_bit(tag, &hba->outstanding_reqs); +} + +/** * ufshcd_get_lists_status - Check UCRDY, UTRLRDY and UTMRLRDY * @reg: Register value of host controller status * @@ -2588,8 +2598,14 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, dev_dbg(hba->dev, "%s: dev_cmd request timedout, tag %d\n", __func__, lrbp->task_tag); if (!ufshcd_clear_cmd(hba, lrbp->task_tag)) - /* sucessfully cleared the command, retry if needed */ + /* successfully cleared the command, retry if needed */ err = -EAGAIN; + /* + * in case of an error, after clearing the doorbell, + * we also need to clear the outstanding_request + * field in hba + */ + ufshcd_outstanding_req_clear(hba, lrbp->task_tag); } return err; @@ -4668,7 +4684,7 @@ void ufshcd_abort_outstanding_transfer_requests(struct ufs_hba *hba, int result) lrbp->cmd = NULL; /* Clear pending transfer requests */ ufshcd_clear_cmd(hba, index); - __clear_bit(index, &hba->outstanding_reqs); + ufshcd_outstanding_req_clear(hba, index); clear_bit_unlock(index, &hba->lrb_in_use); /* Do not touch lrbp after scsi done */ cmd->scsi_done(cmd); @@ -4677,7 +4693,7 @@ void ufshcd_abort_outstanding_transfer_requests(struct ufs_hba *hba, int result) if (hba->dev_cmd.complete) { ufshcd_cond_add_cmd_trace(hba, index, "dev_failed"); - __clear_bit(index, &hba->outstanding_reqs); + ufshcd_outstanding_req_clear(hba, index); complete(hba->dev_cmd.complete); } } @@ -5794,7 +5810,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) scsi_dma_unmap(cmd); spin_lock_irqsave(host->host_lock, flags); - __clear_bit(tag, &hba->outstanding_reqs); + ufshcd_outstanding_req_clear(hba, tag); hba->lrb[tag].cmd = NULL; spin_unlock_irqrestore(host->host_lock, flags); |
