@@ -2997,6 +2997,26 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba,
29972997 return ufshcd_compose_devman_upiu (hba , lrbp );
29982998}
29992999
3000+ /*
3001+ * Check with the block layer if the command is inflight
3002+ * @cmd: command to check.
3003+ *
3004+ * Returns true if command is inflight; false if not.
3005+ */
3006+ bool ufshcd_cmd_inflight (struct scsi_cmnd * cmd )
3007+ {
3008+ struct request * rq ;
3009+
3010+ if (!cmd )
3011+ return false;
3012+
3013+ rq = scsi_cmd_to_rq (cmd );
3014+ if (!blk_mq_request_started (rq ))
3015+ return false;
3016+
3017+ return true;
3018+ }
3019+
30003020/*
30013021 * Clear the pending command in the controller and wait until
30023022 * the controller confirms that the command has been cleared.
@@ -3005,8 +3025,23 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba,
30053025 */
30063026static int ufshcd_clear_cmd (struct ufs_hba * hba , u32 task_tag )
30073027{
3008- unsigned long flags ;
30093028 u32 mask = 1U << task_tag ;
3029+ unsigned long flags ;
3030+ int err ;
3031+
3032+ if (is_mcq_enabled (hba )) {
3033+ /*
3034+ * MCQ mode. Clean up the MCQ resources similar to
3035+ * what the ufshcd_utrl_clear() does for SDB mode.
3036+ */
3037+ err = ufshcd_mcq_sq_cleanup (hba , task_tag );
3038+ if (err ) {
3039+ dev_err (hba -> dev , "%s: failed tag=%d. err=%d\n" ,
3040+ __func__ , task_tag , err );
3041+ return err ;
3042+ }
3043+ return 0 ;
3044+ }
30103045
30113046 /* clear outstanding transaction before retry */
30123047 spin_lock_irqsave (hba -> host -> host_lock , flags );
@@ -7377,6 +7412,20 @@ static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag)
73777412 */
73787413 dev_err (hba -> dev , "%s: cmd at tag %d not pending in the device.\n" ,
73797414 __func__ , tag );
7415+ if (is_mcq_enabled (hba )) {
7416+ /* MCQ mode */
7417+ if (ufshcd_cmd_inflight (lrbp -> cmd )) {
7418+ /* sleep for max. 200us same delay as in SDB mode */
7419+ usleep_range (100 , 200 );
7420+ continue ;
7421+ }
7422+ /* command completed already */
7423+ dev_err (hba -> dev , "%s: cmd at tag=%d is cleared.\n" ,
7424+ __func__ , tag );
7425+ goto out ;
7426+ }
7427+
7428+ /* Single Doorbell Mode */
73807429 reg = ufshcd_readl (hba , REG_UTP_TRANSFER_REQ_DOOR_BELL );
73817430 if (reg & (1 << tag )) {
73827431 /* sleep for max. 200us to stabilize */
@@ -7442,13 +7491,16 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
74427491 WARN_ONCE (tag < 0 , "Invalid tag %d\n" , tag );
74437492
74447493 ufshcd_hold (hba , false);
7445- reg = ufshcd_readl (hba , REG_UTP_TRANSFER_REQ_DOOR_BELL );
7446- /* If command is already aborted/completed, return FAILED. */
7447- if (!(test_bit (tag , & hba -> outstanding_reqs ))) {
7448- dev_err (hba -> dev ,
7449- "%s: cmd at tag %d already completed, outstanding=0x%lx, doorbell=0x%x\n" ,
7450- __func__ , tag , hba -> outstanding_reqs , reg );
7451- goto release ;
7494+
7495+ if (!is_mcq_enabled (hba )) {
7496+ reg = ufshcd_readl (hba , REG_UTP_TRANSFER_REQ_DOOR_BELL );
7497+ if (!test_bit (tag , & hba -> outstanding_reqs )) {
7498+ /* If command is already aborted/completed, return FAILED. */
7499+ dev_err (hba -> dev ,
7500+ "%s: cmd at tag %d already completed, outstanding=0x%lx, doorbell=0x%x\n" ,
7501+ __func__ , tag , hba -> outstanding_reqs , reg );
7502+ goto release ;
7503+ }
74527504 }
74537505
74547506 /* Print Transfer Request of aborted task */
@@ -7473,7 +7525,8 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
74737525 }
74747526 hba -> req_abort_count ++ ;
74757527
7476- if (!(reg & (1 << tag ))) {
7528+ if (!is_mcq_enabled (hba ) && !(reg & (1 << tag ))) {
7529+ /* only execute this code in single doorbell mode */
74777530 dev_err (hba -> dev ,
74787531 "%s: cmd was completed, but without a notifying intr, tag = %d" ,
74797532 __func__ , tag );
@@ -7499,6 +7552,9 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
74997552 goto release ;
75007553 }
75017554
7555+ if (is_mcq_enabled (hba ))
7556+ goto release ;
7557+
75027558 /* Skip task abort in case previous aborts failed and report failure */
75037559 if (lrbp -> req_abort_skip ) {
75047560 dev_err (hba -> dev , "%s: skipping abort\n" , __func__ );
0 commit comments