hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/scsi/ufs/ufshcd.c
....@@ -731,16 +731,6 @@
731731 }
732732
733733 /**
734
- * ufshcd_outstanding_req_clear - Clear a bit in outstanding request field
735
- * @hba: per adapter instance
736
- * @tag: position of the bit to be cleared
737
- */
738
-static inline void ufshcd_outstanding_req_clear(struct ufs_hba *hba, int tag)
739
-{
740
- clear_bit(tag, &hba->outstanding_reqs);
741
-}
742
-
743
-/**
744734 * ufshcd_get_lists_status - Check UCRDY, UTRLRDY and UTMRLRDY
745735 * @reg: Register value of host controller status
746736 *
....@@ -2882,37 +2872,76 @@
28822872 static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
28832873 struct ufshcd_lrb *lrbp, int max_timeout)
28842874 {
2885
- int err = 0;
2886
- unsigned long time_left;
2875
+ unsigned long time_left = msecs_to_jiffies(max_timeout);
28872876 unsigned long flags;
2877
+ bool pending;
2878
+ int err;
28882879
2880
+retry:
28892881 time_left = wait_for_completion_timeout(hba->dev_cmd.complete,
2890
- msecs_to_jiffies(max_timeout));
2882
+ time_left);
28912883
28922884 /* Make sure descriptors are ready before ringing the doorbell */
28932885 wmb();
2894
- spin_lock_irqsave(hba->host->host_lock, flags);
2895
- hba->dev_cmd.complete = NULL;
28962886 if (likely(time_left)) {
2887
+ /*
2888
+ * The completion handler called complete() and the caller of
2889
+ * this function still owns the @lrbp tag so the code below does
2890
+ * not trigger any race conditions.
2891
+ */
2892
+ hba->dev_cmd.complete = NULL;
28972893 err = ufshcd_get_tr_ocs(lrbp);
28982894 if (!err)
28992895 err = ufshcd_dev_cmd_completion(hba, lrbp);
2900
- }
2901
- spin_unlock_irqrestore(hba->host->host_lock, flags);
2902
-
2903
- if (!time_left) {
2896
+ } else {
29042897 err = -ETIMEDOUT;
29052898 dev_dbg(hba->dev, "%s: dev_cmd request timedout, tag %d\n",
29062899 __func__, lrbp->task_tag);
2907
- if (!ufshcd_clear_cmd(hba, lrbp->task_tag))
2900
+ if (ufshcd_clear_cmd(hba, lrbp->task_tag) == 0) {
29082901 /* successfully cleared the command, retry if needed */
29092902 err = -EAGAIN;
2910
- /*
2911
- * in case of an error, after clearing the doorbell,
2912
- * we also need to clear the outstanding_request
2913
- * field in hba
2914
- */
2915
- ufshcd_outstanding_req_clear(hba, lrbp->task_tag);
2903
+ /*
2904
+ * Since clearing the command succeeded we also need to
2905
+ * clear the task tag bit from the outstanding_reqs
2906
+ * variable.
2907
+ */
2908
+ spin_lock_irqsave(hba->host->host_lock, flags);
2909
+ pending = test_bit(lrbp->task_tag,
2910
+ &hba->outstanding_reqs);
2911
+ if (pending) {
2912
+ hba->dev_cmd.complete = NULL;
2913
+ __clear_bit(lrbp->task_tag,
2914
+ &hba->outstanding_reqs);
2915
+ }
2916
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
2917
+
2918
+ if (!pending) {
2919
+ /*
2920
+ * The completion handler ran while we tried to
2921
+ * clear the command.
2922
+ */
2923
+ time_left = 1;
2924
+ goto retry;
2925
+ }
2926
+ } else {
2927
+ dev_err(hba->dev, "%s: failed to clear tag %d\n",
2928
+ __func__, lrbp->task_tag);
2929
+ spin_lock_irqsave(hba->host->host_lock, flags);
2930
+ pending = test_bit(lrbp->task_tag,
2931
+ &hba->outstanding_reqs);
2932
+ if (pending)
2933
+ hba->dev_cmd.complete = NULL;
2934
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
2935
+
2936
+ if (!pending) {
2937
+ /*
2938
+ * The completion handler ran while we tried to
2939
+ * clear the command.
2940
+ */
2941
+ time_left = 1;
2942
+ goto retry;
2943
+ }
2944
+ }
29162945 }
29172946
29182947 return err;
....@@ -9485,5 +9514,6 @@
94859514 MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
94869515 MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
94879516 MODULE_DESCRIPTION("Generic UFS host controller driver Core");
9517
+MODULE_SOFTDEP("pre: governor_simpleondemand");
94889518 MODULE_LICENSE("GPL");
94899519 MODULE_VERSION(UFSHCD_DRIVER_VERSION);