Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux-block.git] / drivers / ufs / core / ufshcd.c
index 7c59d7a02243ecc7c92c4fc236caca70e04a1381..029d017fc1b66b5c6695096016b54983e26b3e5f 100644 (file)
@@ -2284,9 +2284,10 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag,
        if (is_mcq_enabled(hba)) {
                int utrd_size = sizeof(struct utp_transfer_req_desc);
                struct utp_transfer_req_desc *src = lrbp->utr_descriptor_ptr;
-               struct utp_transfer_req_desc *dest = hwq->sqe_base_addr + hwq->sq_tail_slot;
+               struct utp_transfer_req_desc *dest;
 
                spin_lock(&hwq->sq_lock);
+               dest = hwq->sqe_base_addr + hwq->sq_tail_slot;
                memcpy(dest, src, utrd_size);
                ufshcd_inc_sq_tail(hwq);
                spin_unlock(&hwq->sq_lock);
@@ -6448,11 +6449,24 @@ static bool ufshcd_abort_one(struct request *rq, void *priv)
        struct scsi_device *sdev = cmd->device;
        struct Scsi_Host *shost = sdev->host;
        struct ufs_hba *hba = shost_priv(shost);
+       struct ufshcd_lrb *lrbp = &hba->lrb[tag];
+       struct ufs_hw_queue *hwq;
+       unsigned long flags;
 
        *ret = ufshcd_try_to_abort_task(hba, tag);
        dev_err(hba->dev, "Aborting tag %d / CDB %#02x %s\n", tag,
                hba->lrb[tag].cmd ? hba->lrb[tag].cmd->cmnd[0] : -1,
                *ret ? "failed" : "succeeded");
+
+       /* Release cmd in MCQ mode if abort succeeds */
+       if (is_mcq_enabled(hba) && (*ret == 0)) {
+               hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(lrbp->cmd));
+               spin_lock_irqsave(&hwq->cq_lock, flags);
+               if (ufshcd_cmd_inflight(lrbp->cmd))
+                       ufshcd_release_scsi_cmd(hba, lrbp);
+               spin_unlock_irqrestore(&hwq->cq_lock, flags);
+       }
+
        return *ret == 0;
 }