Loading drivers/scsi/ufs/ufshcd.c +26 −2 Original line number Diff line number Diff line Loading @@ -2419,6 +2419,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); lrbp->intr_cmd = !ufshcd_is_intr_aggr_allowed(hba) ? true : false; lrbp->command_type = UTP_CMD_TYPE_SCSI; lrbp->req_abort_skip = false; /* form UPIU before issuing the command */ ufshcd_compose_upiu(hba, lrbp); Loading Loading @@ -5645,6 +5646,17 @@ out: return err; } static void ufshcd_set_req_abort_skip(struct ufs_hba *hba, unsigned long bitmap) { struct ufshcd_lrb *lrbp; int tag; for_each_set_bit(tag, &bitmap, hba->nutrs) { lrbp = &hba->lrb[tag]; lrbp->req_abort_skip = true; } } /** * ufshcd_abort - abort a specific command * @cmd: SCSI command pointer Loading Loading @@ -5687,11 +5699,15 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) return ufshcd_eh_host_reset_handler(cmd); ufshcd_hold_all(hba); reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); /* If command is already aborted/completed, return SUCCESS */ if (!(test_bit(tag, &hba->outstanding_reqs))) if (!(test_bit(tag, &hba->outstanding_reqs))) { dev_err(hba->dev, "%s: cmd already completed, outstanding=0x%lx, doorbell=0x%x\n", __func__, hba->outstanding_reqs, reg); goto out; } reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); if (!(reg & (1 << tag))) { dev_err(hba->dev, "%s: cmd was completed, but without a notifying intr, tag = %d", Loading @@ -5705,6 +5721,13 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) ufshcd_print_pwr_info(hba); ufshcd_print_trs(hba, 1 << tag, true); /* Skip task abort in case previous aborts failed and report failure */ if (lrbp->req_abort_skip) { err = -EIO; goto out; } for (poll_cnt = 100; poll_cnt; poll_cnt--) { err = ufshcd_issue_tm_cmd(hba, lrbp->lun, lrbp->task_tag, UFS_QUERY_TASK, &resp); Loading Loading @@ -5778,6 +5801,7 @@ out: err = SUCCESS; } else { dev_err(hba->dev, "%s: failed with err %d\n", __func__, err); ufshcd_set_req_abort_skip(hba, hba->outstanding_reqs); err = FAILED; } Loading include/linux/scsi/ufs/ufshcd.h +3 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,7 @@ struct ufs_pm_lvl_states { * @lun: LUN of the command * @intr_cmd: Interrupt command (doesn't participate in interrupt aggregation) * @issue_time_stamp: time stamp for debug purposes * @req_abort_skip: skip request abort task flag */ struct ufshcd_lrb { struct utp_transfer_req_desc *utr_descriptor_ptr; Loading @@ -206,6 +207,8 @@ struct ufshcd_lrb { u8 lun; /* UPIU LUN id field is only 8-bit wide */ bool intr_cmd; ktime_t issue_time_stamp; bool req_abort_skip; }; /** Loading Loading
drivers/scsi/ufs/ufshcd.c +26 −2 Original line number Diff line number Diff line Loading @@ -2419,6 +2419,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); lrbp->intr_cmd = !ufshcd_is_intr_aggr_allowed(hba) ? true : false; lrbp->command_type = UTP_CMD_TYPE_SCSI; lrbp->req_abort_skip = false; /* form UPIU before issuing the command */ ufshcd_compose_upiu(hba, lrbp); Loading Loading @@ -5645,6 +5646,17 @@ out: return err; } static void ufshcd_set_req_abort_skip(struct ufs_hba *hba, unsigned long bitmap) { struct ufshcd_lrb *lrbp; int tag; for_each_set_bit(tag, &bitmap, hba->nutrs) { lrbp = &hba->lrb[tag]; lrbp->req_abort_skip = true; } } /** * ufshcd_abort - abort a specific command * @cmd: SCSI command pointer Loading Loading @@ -5687,11 +5699,15 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) return ufshcd_eh_host_reset_handler(cmd); ufshcd_hold_all(hba); reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); /* If command is already aborted/completed, return SUCCESS */ if (!(test_bit(tag, &hba->outstanding_reqs))) if (!(test_bit(tag, &hba->outstanding_reqs))) { dev_err(hba->dev, "%s: cmd already completed, outstanding=0x%lx, doorbell=0x%x\n", __func__, hba->outstanding_reqs, reg); goto out; } reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); if (!(reg & (1 << tag))) { dev_err(hba->dev, "%s: cmd was completed, but without a notifying intr, tag = %d", Loading @@ -5705,6 +5721,13 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) ufshcd_print_pwr_info(hba); ufshcd_print_trs(hba, 1 << tag, true); /* Skip task abort in case previous aborts failed and report failure */ if (lrbp->req_abort_skip) { err = -EIO; goto out; } for (poll_cnt = 100; poll_cnt; poll_cnt--) { err = ufshcd_issue_tm_cmd(hba, lrbp->lun, lrbp->task_tag, UFS_QUERY_TASK, &resp); Loading Loading @@ -5778,6 +5801,7 @@ out: err = SUCCESS; } else { dev_err(hba->dev, "%s: failed with err %d\n", __func__, err); ufshcd_set_req_abort_skip(hba, hba->outstanding_reqs); err = FAILED; } Loading
include/linux/scsi/ufs/ufshcd.h +3 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,7 @@ struct ufs_pm_lvl_states { * @lun: LUN of the command * @intr_cmd: Interrupt command (doesn't participate in interrupt aggregation) * @issue_time_stamp: time stamp for debug purposes * @req_abort_skip: skip request abort task flag */ struct ufshcd_lrb { struct utp_transfer_req_desc *utr_descriptor_ptr; Loading @@ -206,6 +207,8 @@ struct ufshcd_lrb { u8 lun; /* UPIU LUN id field is only 8-bit wide */ bool intr_cmd; ktime_t issue_time_stamp; bool req_abort_skip; }; /** Loading