@@ -748,17 +748,28 @@ static enum utp_ocs ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp)
748748}
749749
750750/**
751- * ufshcd_utrl_clear - Clear a bit in UTRLCLR register
751+ * ufshcd_utrl_clear() - Clear requests from the controller request list.
752752 * @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
754754 */
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 )
756756{
757757 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 );
762773}
763774
764775/**
@@ -2863,15 +2874,18 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba,
28632874 return ufshcd_compose_devman_upiu (hba , lrbp );
28642875}
28652876
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 )
28682883{
28692884 unsigned long flags ;
2870- u32 mask = 1 << tag ;
28712885
28722886 /* clear outstanding transaction before retry */
28732887 spin_lock_irqsave (hba -> host -> host_lock , flags );
2874- ufshcd_utrl_clear (hba , tag );
2888+ ufshcd_utrl_clear (hba , mask );
28752889 spin_unlock_irqrestore (hba -> host -> host_lock , flags );
28762890
28772891 /*
@@ -2959,7 +2973,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
29592973 err = - ETIMEDOUT ;
29602974 dev_dbg (hba -> dev , "%s: dev_cmd request timedout, tag %d\n" ,
29612975 __func__ , lrbp -> task_tag );
2962- if (!ufshcd_clear_cmd (hba , lrbp -> task_tag ))
2976+ if (!ufshcd_clear_cmds (hba , 1U << lrbp -> task_tag ))
29632977 /* successfully cleared the command, retry if needed */
29642978 err = - EAGAIN ;
29652979 /*
@@ -6982,7 +6996,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd)
69826996 /* clear the commands that were pending for corresponding LUN */
69836997 for_each_set_bit (pos , & hba -> outstanding_reqs , hba -> nutrs ) {
69846998 if (hba -> lrb [pos ].lun == lun ) {
6985- err = ufshcd_clear_cmd (hba , pos );
6999+ err = ufshcd_clear_cmds (hba , 1U << pos );
69867000 if (err )
69877001 break ;
69887002 __ufshcd_transfer_req_compl (hba , 1U << pos );
@@ -7084,7 +7098,7 @@ static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag)
70847098 goto out ;
70857099 }
70867100
7087- err = ufshcd_clear_cmd (hba , tag );
7101+ err = ufshcd_clear_cmds (hba , 1U << tag );
70887102 if (err )
70897103 dev_err (hba -> dev , "%s: Failed clearing cmd at tag %d, err %d\n" ,
70907104 __func__ , tag , err );
0 commit comments