diff options
author | Bao D. Nguyen <quic_nguyenb@quicinc.com> | 2023-05-29 15:12:26 -0700 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2023-05-31 20:17:08 -0400 |
commit | ab248643d3d68b30f95ee9c238a5a20a06891204 (patch) | |
tree | f4bd3e39c29a2c5d18537db83a39f81864173727 /drivers/ufs/core/ufs-mcq.c | |
parent | 57d6ef4601c0b7975aab5144c7c3760846362e1c (diff) |
scsi: ufs: core: Add error handling for MCQ mode
Add support for error handling for MCQ mode.
Suggested-by: Can Guo <quic_cang@quicinc.com>
Co-developed-by: Stanley Chu <stanley.chu@mediatek.com>
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Signed-off-by: Bao D. Nguyen <quic_nguyenb@quicinc.com>
Link: https://lore.kernel.org/r/f0d923ee1f009f171a55c258d044e814ec0917ab.1685396241.git.quic_nguyenb@quicinc.com
Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
Tested-by: Stanley Chu <stanley.chu@mediatek.com>
Reviewed-by: Can Guo <quic_cang@quicinc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/ufs/core/ufs-mcq.c')
-rw-r--r-- | drivers/ufs/core/ufs-mcq.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c index 2efa0129b2c4..66ac02e0a859 100644 --- a/drivers/ufs/core/ufs-mcq.c +++ b/drivers/ufs/core/ufs-mcq.c @@ -276,12 +276,34 @@ static int ufshcd_mcq_get_tag(struct ufs_hba *hba, } static void ufshcd_mcq_process_cqe(struct ufs_hba *hba, - struct ufs_hw_queue *hwq) + struct ufs_hw_queue *hwq) { struct cq_entry *cqe = ufshcd_mcq_cur_cqe(hwq); int tag = ufshcd_mcq_get_tag(hba, hwq, cqe); - ufshcd_compl_one_cqe(hba, tag, cqe); + if (cqe->command_desc_base_addr) { + ufshcd_compl_one_cqe(hba, tag, cqe); + /* After processed the cqe, mark it empty (invalid) entry */ + cqe->command_desc_base_addr = 0; + } +} + +void ufshcd_mcq_compl_all_cqes_lock(struct ufs_hba *hba, + struct ufs_hw_queue *hwq) +{ + unsigned long flags; + u32 entries = hwq->max_entries; + + spin_lock_irqsave(&hwq->cq_lock, flags); + while (entries > 0) { + ufshcd_mcq_process_cqe(hba, hwq); + ufshcd_mcq_inc_cq_head_slot(hwq); + entries--; + } + + ufshcd_mcq_update_cq_tail_slot(hwq); + hwq->cq_head_slot = hwq->cq_tail_slot; + spin_unlock_irqrestore(&hwq->cq_lock, flags); } static unsigned long ufshcd_mcq_poll_cqe_nolock(struct ufs_hba *hba, |