@@ -748,17 +748,28 @@ static enum utp_ocs ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp)
748
748
}
749
749
750
750
/**
751
- * ufshcd_utrl_clear - Clear a bit in UTRLCLR register
751
+ * ufshcd_utrl_clear() - Clear requests from the controller request list.
752
752
* @hba: per adapter instance
753
- * @pos: position of the bit to be cleared
753
+ * @mask: mask with one bit set for each request to be cleared
754
754
*/
755
- static inline void ufshcd_utrl_clear (struct ufs_hba * hba , u32 pos )
755
+ static inline void ufshcd_utrl_clear (struct ufs_hba * hba , u32 mask )
756
756
{
757
757
if (hba -> quirks & UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR )
758
- ufshcd_writel (hba , (1 << pos ), REG_UTP_TRANSFER_REQ_LIST_CLEAR );
759
- else
760
- ufshcd_writel (hba , ~(1 << pos ),
761
- REG_UTP_TRANSFER_REQ_LIST_CLEAR );
758
+ mask = ~mask ;
759
+ /*
760
+ * From the UFSHCI specification: "UTP Transfer Request List CLear
761
+ * Register (UTRLCLR): This field is bit significant. Each bit
762
+ * corresponds to a slot in the UTP Transfer Request List, where bit 0
763
+ * corresponds to request slot 0. A bit in this field is set to ‘0’
764
+ * by host software to indicate to the host controller that a transfer
765
+ * request slot is cleared. The host controller
766
+ * shall free up any resources associated to the request slot
767
+ * immediately, and shall set the associated bit in UTRLDBR to ‘0’. The
768
+ * host software indicates no change to request slots by setting the
769
+ * associated bits in this field to ‘1’. Bits in this field shall only
770
+ * be set ‘1’ or ‘0’ by host software when UTRLRSR is set to ‘1’."
771
+ */
772
+ ufshcd_writel (hba , ~mask , REG_UTP_TRANSFER_REQ_LIST_CLEAR );
762
773
}
763
774
764
775
/**
@@ -2863,15 +2874,18 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba,
2863
2874
return ufshcd_compose_devman_upiu (hba , lrbp );
2864
2875
}
2865
2876
2866
- static int
2867
- ufshcd_clear_cmd (struct ufs_hba * hba , int tag )
2877
+ /*
2878
+ * Clear all the requests from the controller for which a bit has been set in
2879
+ * @mask and wait until the controller confirms that these requests have been
2880
+ * cleared.
2881
+ */
2882
+ static int ufshcd_clear_cmds (struct ufs_hba * hba , u32 mask )
2868
2883
{
2869
2884
unsigned long flags ;
2870
- u32 mask = 1 << tag ;
2871
2885
2872
2886
/* clear outstanding transaction before retry */
2873
2887
spin_lock_irqsave (hba -> host -> host_lock , flags );
2874
- ufshcd_utrl_clear (hba , tag );
2888
+ ufshcd_utrl_clear (hba , mask );
2875
2889
spin_unlock_irqrestore (hba -> host -> host_lock , flags );
2876
2890
2877
2891
/*
@@ -2959,7 +2973,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
2959
2973
err = - ETIMEDOUT ;
2960
2974
dev_dbg (hba -> dev , "%s: dev_cmd request timedout, tag %d\n" ,
2961
2975
__func__ , lrbp -> task_tag );
2962
- if (!ufshcd_clear_cmd (hba , lrbp -> task_tag ))
2976
+ if (!ufshcd_clear_cmds (hba , 1U << lrbp -> task_tag ))
2963
2977
/* successfully cleared the command, retry if needed */
2964
2978
err = - EAGAIN ;
2965
2979
/*
@@ -6982,7 +6996,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd)
6982
6996
/* clear the commands that were pending for corresponding LUN */
6983
6997
for_each_set_bit (pos , & hba -> outstanding_reqs , hba -> nutrs ) {
6984
6998
if (hba -> lrb [pos ].lun == lun ) {
6985
- err = ufshcd_clear_cmd (hba , pos );
6999
+ err = ufshcd_clear_cmds (hba , 1U << pos );
6986
7000
if (err )
6987
7001
break ;
6988
7002
__ufshcd_transfer_req_compl (hba , 1U << pos );
@@ -7084,7 +7098,7 @@ static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag)
7084
7098
goto out ;
7085
7099
}
7086
7100
7087
- err = ufshcd_clear_cmd (hba , tag );
7101
+ err = ufshcd_clear_cmds (hba , 1U << tag );
7088
7102
if (err )
7089
7103
dev_err (hba -> dev , "%s: Failed clearing cmd at tag %d, err %d\n" ,
7090
7104
__func__ , tag , err );
0 commit comments