Merge branch '5.9/scsi-fixes' into 5.10/scsi-ufs
authorMartin K. Petersen <martin.petersen@oracle.com>
Tue, 15 Sep 2020 15:24:32 +0000 (11:24 -0400)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 15 Sep 2020 15:36:40 +0000 (11:36 -0400)
Resolve UFS discrepancies between fixes and queue.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
13 files changed:
1  2 
drivers/scsi/cxgbi/libcxgbi.c
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/scsi/qedf/qedf_main.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_nvme.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_target.c
drivers/scsi/scsi_debug.c
drivers/scsi/ufs/ufs-mediatek.c
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -6739,22 -6459,87 +6736,25 @@@ static int ufshcd_abort(struct scsi_cmn
        }
        hba->req_abort_count++;
  
-       /* Skip task abort in case previous aborts failed and report failure */
-       if (lrbp->req_abort_skip) {
-               err = -EIO;
-               goto out;
+       if (!(reg & (1 << tag))) {
+               dev_err(hba->dev,
+               "%s: cmd was completed, but without a notifying intr, tag = %d",
+               __func__, tag);
+               goto cleanup;
        }
  
-       err = ufshcd_try_to_abort_task(hba, tag);
-       if (err)
-               goto out;
-       spin_lock_irqsave(host->host_lock, flags);
-       __ufshcd_transfer_req_compl(hba, (1UL << tag));
-       spin_unlock_irqrestore(host->host_lock, flags);
+       /* Skip task abort in case previous aborts failed and report failure */
 -      if (lrbp->req_abort_skip) {
++      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);
 -              if (!err && resp == UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED) {
 -                      /* cmd pending in the device */
 -                      dev_err(hba->dev, "%s: cmd pending in the device. tag = %d\n",
 -                              __func__, tag);
 -                      break;
 -              } else if (!err && resp == UPIU_TASK_MANAGEMENT_FUNC_COMPL) {
 -                      /*
 -                       * cmd not pending in the device, check if it is
 -                       * in transition.
 -                       */
 -                      dev_err(hba->dev, "%s: cmd at tag %d not pending in the device.\n",
 -                              __func__, tag);
 -                      reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
 -                      if (reg & (1 << tag)) {
 -                              /* sleep for max. 200us to stabilize */
 -                              usleep_range(100, 200);
 -                              continue;
 -                      }
 -                      /* command completed already */
 -                      dev_err(hba->dev, "%s: cmd at tag %d successfully cleared from DB.\n",
 -                              __func__, tag);
 -                      goto cleanup;
 -              } else {
 -                      dev_err(hba->dev,
 -                              "%s: no response from device. tag = %d, err %d\n",
 -                              __func__, tag, err);
 -                      if (!err)
 -                              err = resp; /* service response error */
 -                      goto out;
 -              }
 -      }
 -
 -      if (!poll_cnt) {
 -              err = -EBUSY;
 -              goto out;
 -      }
 -
 -      err = ufshcd_issue_tm_cmd(hba, lrbp->lun, lrbp->task_tag,
 -                      UFS_ABORT_TASK, &resp);
 -      if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) {
 -              if (!err) {
 -                      err = resp; /* service response error */
 -                      dev_err(hba->dev, "%s: issued. tag = %d, err %d\n",
 -                              __func__, tag, err);
 -              }
 -              goto out;
 -      }
 -
 -      err = ufshcd_clear_cmd(hba, tag);
 -      if (err) {
 -              dev_err(hba->dev, "%s: Failed clearing cmd at tag %d, err %d\n",
 -                      __func__, tag, err);
 -              goto out;
 -      }
++      else
++              err = ufshcd_try_to_abort_task(hba, tag);
  
- out:
 +      if (!err) {
+ cleanup:
 -      scsi_dma_unmap(cmd);
 -
 -      spin_lock_irqsave(host->host_lock, flags);
 -      ufshcd_outstanding_req_clear(hba, tag);
 -      hba->lrb[tag].cmd = NULL;
 -      spin_unlock_irqrestore(host->host_lock, flags);
 -
++              spin_lock_irqsave(host->host_lock, flags);
++              __ufshcd_transfer_req_compl(hba, (1UL << tag));
++              spin_unlock_irqrestore(host->host_lock, flags);
+ out:
 -      if (!err) {
                err = SUCCESS;
        } else {
                dev_err(hba->dev, "%s: failed with err %d\n", __func__, err);
@@@ -532,9 -522,10 +532,16 @@@ enum ufshcd_quirks 
        UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR             = 1 << 10,
  
        /*
-       UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL          = 1 << 11,
+        * This quirk needs to be enabled if the host controller has
+        * auto-hibernate capability but it doesn't work.
+        */
+       UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8                = 1 << 11,
++
++      /*
 +       * This quirk needs to disable manual flush for write booster
 +       */
++      UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL          = 1 << 12,
++
  };
  
  enum ufshcd_caps {