}
 }
 
+/**
+ * scsih_tm_cmd_map_status - map the target reset & LUN reset TM status
+ * @ioc - per adapter object
+ * @channel - the channel assigned by the OS
+ * @id: the id assigned by the OS
+ * @lun: lun number
+ * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
+ * @smid_task: smid assigned to the task
+ *
+ * Look whether TM has aborted the timed out SCSI command, if
+ * TM has aborted the IO then return SUCCESS else return FAILED.
+ */
+static int
+scsih_tm_cmd_map_status(struct MPT3SAS_ADAPTER *ioc, uint channel,
+       uint id, uint lun, u8 type, u16 smid_task)
+{
+
+       if (smid_task <= ioc->shost->can_queue) {
+               switch (type) {
+               case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
+                       if (!(_scsih_scsi_lookup_find_by_target(ioc,
+                           id, channel)))
+                               return SUCCESS;
+                       break;
+               case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
+               case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
+                       if (!(_scsih_scsi_lookup_find_by_lun(ioc, id,
+                           lun, channel)))
+                               return SUCCESS;
+                       break;
+               default:
+                       return SUCCESS;
+               }
+       } else if (smid_task == ioc->scsih_cmds.smid) {
+               if ((ioc->scsih_cmds.status & MPT3_CMD_COMPLETE) ||
+                   (ioc->scsih_cmds.status & MPT3_CMD_NOT_USED))
+                       return SUCCESS;
+       } else if (smid_task == ioc->ctl_cmds.smid) {
+               if ((ioc->ctl_cmds.status & MPT3_CMD_COMPLETE) ||
+                   (ioc->ctl_cmds.status & MPT3_CMD_NOT_USED))
+                       return SUCCESS;
+       }
+
+       return FAILED;
+}
+
+/**
+ * scsih_tm_post_processing - post processing of target & LUN reset
+ * @ioc - per adapter object
+ * @handle: device handle
+ * @channel - the channel assigned by the OS
+ * @id: the id assigned by the OS
+ * @lun: lun number
+ * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
+ * @smid_task: smid assigned to the task
+ *
+ * Post processing of target & LUN reset. Due to interrupt latency
+ * issue it possible that interrupt for aborted IO might not be
+ * received yet. So before returning failure status, poll the
+ * reply descriptor pools for the reply of timed out SCSI command.
+ * Return FAILED status if reply for timed out is not received
+ * otherwise return SUCCESS.
+ */
+static int
+scsih_tm_post_processing(struct MPT3SAS_ADAPTER *ioc, u16 handle,
+       uint channel, uint id, uint lun, u8 type, u16 smid_task)
+{
+       int rc;
+
+       rc = scsih_tm_cmd_map_status(ioc, channel, id, lun, type, smid_task);
+       if (rc == SUCCESS)
+               return rc;
+
+       ioc_info(ioc,
+           "Poll ReplyDescriptor queues for completion of"
+           " smid(%d), task_type(0x%02x), handle(0x%04x)\n",
+           smid_task, type, handle);
+
+       /*
+        * Due to interrupt latency issues, driver may receive interrupt for
+        * TM first and then for aborted SCSI IO command. So, poll all the
+        * ReplyDescriptor pools before returning the FAILED status to SML.
+        */
+       mpt3sas_base_mask_interrupts(ioc);
+       mpt3sas_base_sync_reply_irqs(ioc, 1);
+       mpt3sas_base_unmask_interrupts(ioc);
+
+       return scsih_tm_cmd_map_status(ioc, channel, id, lun, type, smid_task);
+}
+
 /**
  * mpt3sas_scsih_issue_tm - main routine for sending tm requests
  * @ioc: per adapter struct
 {
        Mpi2SCSITaskManagementRequest_t *mpi_request;
        Mpi2SCSITaskManagementReply_t *mpi_reply;
+       Mpi25SCSIIORequest_t *request;
        u16 smid = 0;
        u32 ioc_state;
        int rc;
        mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
        mpi_request->DevHandle = cpu_to_le16(handle);
        mpi_request->TaskType = type;
-       mpi_request->MsgFlags = tr_method;
+       if (type == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK ||
+           type == MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK)
+               mpi_request->MsgFlags = tr_method;
        mpi_request->TaskMID = cpu_to_le16(smid_task);
        int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
        mpt3sas_scsih_set_tm_flag(ioc, handle);
        }
 
        /* sync IRQs in case those were busy during flush. */
-       mpt3sas_base_sync_reply_irqs(ioc);
+       mpt3sas_base_sync_reply_irqs(ioc, 0);
 
        if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) {
                mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT);
                                    sizeof(Mpi2SCSITaskManagementRequest_t)/4);
                }
        }
-       rc = SUCCESS;
+
+       switch (type) {
+       case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
+               rc = SUCCESS;
+               /*
+                * If DevHandle filed in smid_task's entry of request pool
+                * doesn't match with device handle on which this task abort
+                * TM is received then it means that TM has successfully
+                * aborted the timed out command. Since smid_task's entry in
+                * request pool will be memset to zero once the timed out
+                * command is returned to the SML. If the command is not
+                * aborted then smid_task’s entry won’t be cleared and it
+                * will have same DevHandle value on which this task abort TM
+                * is received and driver will return the TM status as FAILED.
+                */
+               request = mpt3sas_base_get_msg_frame(ioc, smid_task);
+               if (le16_to_cpu(request->DevHandle) != handle)
+                       break;
+
+               ioc_info(ioc, "Task abort tm failed: handle(0x%04x),"
+                   "timeout(%d) tr_method(0x%x) smid(%d) msix_index(%d)\n",
+                   handle, timeout, tr_method, smid_task, msix_task);
+               rc = FAILED;
+               break;
+
+       case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
+       case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
+       case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
+               rc = scsih_tm_post_processing(ioc, handle, channel, id, lun,
+                   type, smid_task);
+               break;
+       case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
+               rc = SUCCESS;
+               break;
+       default:
+               rc = FAILED;
+               break;
+       }
 
 out:
        mpt3sas_scsih_clear_tm_flag(ioc, handle);