Author: kadesai
Date: Mon Dec 19 13:14:39 2016
New Revision: 310264
URL: https://svnweb.freebsd.org/changeset/base/310264

Log:
  MFC r309284-r309294
  
  r309294
  This patch upgrades driver version to 06.712.04.00-fbsd
  
  r309293
  This patch will add code to refire IOCTL commands after OCR.
  
  r309292
  This patch will unblock SYNCHRONIZE_CACHE command to firmware,
  i.e. don't block the SYNCHRONIZE_CACHE command at driver instead of passing 
it to firmware for all Gen3 controllers.
  
  r309291
  Wait for AEN task to be completed(if in queue) before resetting the controller
  and return without processing event in AEN thread, if controller reset is in 
progress.
  
  r309290
  This patch will add task management support in driver. Below is high level 
description:
  If a SCSI IO times out, then before initiating OCR, now the driver will try 
to send a
  target reset to the particular target for which the IO is timed out. If that 
also fails,
  then the driver will initiate OCR.
  
  r309289
  Process outstanding reply descriptors from all the reply descriptor post 
queues before initiating OCR.
  
  r309288
  Clean up reference to AEN command if abort AEN is succesful as the command is 
aborted.
  Did the same by setting sc->aen_cmd = NULL when aborting AEN is successful.
  
  r309287
  Update controller properties(read OCR capability bit) when 
MR_EVT_CTRL_PROP_CHANGED recieved.
  
  r309286
  Add sanity check in IO and IOCTL path not to process command further if 
controller is in
  HW_CRITICAL_ERROR.
  
  r309285
  Use a variable to indicate Gen3 controllers and remove all PCI ids based
  checks used for gen3 controllers.
  
  r309284
  High level description of new solution -
  Free MFI and MPT command from same context.
  Free both the command either from process (from where mfi-mpt pass-through 
was called) or from
  ISR context. Do not split freeing of MFI and MPT, because it creates the race 
condition which
  will do MFI/MPT list.

Modified:
  stable/10/sys/dev/mrsas/mrsas.c
  stable/10/sys/dev/mrsas/mrsas.h
  stable/10/sys/dev/mrsas/mrsas_cam.c
  stable/10/sys/dev/mrsas/mrsas_fp.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/mrsas/mrsas.c
==============================================================================
--- stable/10/sys/dev/mrsas/mrsas.c     Mon Dec 19 12:27:01 2016        
(r310263)
+++ stable/10/sys/dev/mrsas/mrsas.c     Mon Dec 19 13:14:39 2016        
(r310264)
@@ -110,6 +110,7 @@ int mrsas_issue_polled(struct mrsas_soft
 int    mrsas_reset_ctrl(struct mrsas_softc *sc, u_int8_t reset_reason);
 int    mrsas_wait_for_outstanding(struct mrsas_softc *sc, u_int8_t 
check_reason);
 int mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex);
+int mrsas_reset_targets(struct mrsas_softc *sc);
 int
 mrsas_issue_blocked_cmd(struct mrsas_softc *sc,
     struct mrsas_mfi_cmd *cmd);
@@ -153,7 +154,6 @@ extern void mrsas_cam_detach(struct mrsa
 extern void mrsas_cmd_done(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd);
 extern void mrsas_free_frame(struct mrsas_softc *sc, struct mrsas_mfi_cmd 
*cmd);
 extern int mrsas_alloc_mfi_cmds(struct mrsas_softc *sc);
-extern void mrsas_release_mpt_cmd(struct mrsas_mpt_cmd *cmd);
 extern struct mrsas_mpt_cmd *mrsas_get_mpt_cmd(struct mrsas_softc *sc);
 extern int mrsas_passthru(struct mrsas_softc *sc, void *arg, u_long ioctlCmd);
 extern uint8_t MR_ValidateMapInfo(struct mrsas_softc *sc);
@@ -307,28 +307,11 @@ mrsas_enable_intr(struct mrsas_softc *sc
 static int
 mrsas_clear_intr(struct mrsas_softc *sc)
 {
-       u_int32_t status, fw_status, fw_state;
+       u_int32_t status;
 
        /* Read received interrupt */
        status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, 
outbound_intr_status));
 
-       /*
-        * If FW state change interrupt is received, write to it again to
-        * clear
-        */
-       if (status & MRSAS_FW_STATE_CHNG_INTERRUPT) {
-               fw_status = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
-                   outbound_scratch_pad));
-               fw_state = fw_status & MFI_STATE_MASK;
-               if (fw_state == MFI_STATE_FAULT) {
-                       device_printf(sc->mrsas_dev, "FW is in FAULT state!\n");
-                       if (sc->ocr_thread_active)
-                               wakeup(&sc->ocr_chan);
-               }
-               mrsas_write_reg(sc, offsetof(mrsas_reg_set, 
outbound_intr_status), status);
-               mrsas_read_reg(sc, offsetof(mrsas_reg_set, 
outbound_intr_status));
-               return (1);
-       }
        /* Not our interrupt, so just return */
        if (!(status & MFI_FUSION_ENABLE_INTERRUPT_MASK))
                return (0);
@@ -449,6 +432,11 @@ mrsas_setup_sysctl(struct mrsas_softc *s
            OID_AUTO, "reset_in_progress", CTLFLAG_RD,
            &sc->reset_in_progress, 0, "ocr in progress status");
 
+       SYSCTL_ADD_UINT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+           OID_AUTO, "block_sync_cache", CTLFLAG_RW,
+           &sc->block_sync_cache, 0,
+           "Block SYNC CACHE at driver. <default: 0, send it to FW>");
+
 }
 
 /*
@@ -468,6 +456,7 @@ mrsas_get_tunables(struct mrsas_softc *s
        sc->mrsas_fw_fault_check_delay = 1;
        sc->reset_count = 0;
        sc->reset_in_progress = 0;
+       sc->block_sync_cache = 0;
 
        /*
         * Grab the global variables.
@@ -674,16 +663,15 @@ mrsas_register_aen(struct mrsas_softc *s
                            sc->aen_cmd);
 
                        if (ret_val) {
-                               printf("mrsas: Failed to abort "
-                                   "previous AEN command\n");
+                               printf("mrsas: Failed to abort previous AEN 
command\n");
                                return ret_val;
-                       }
+                       } else
+                               sc->aen_cmd = NULL;
                }
        }
        cmd = mrsas_get_mfi_cmd(sc);
-
        if (!cmd)
-               return -ENOMEM;
+               return ENOMEM;
 
        dcmd = &cmd->frame->dcmd;
 
@@ -835,6 +823,15 @@ mrsas_attach(device_t dev)
        sc->mrsas_dev = dev;
        sc->device_id = pci_get_device(dev);
 
+       if ((sc->device_id == MRSAS_INVADER) ||
+           (sc->device_id == MRSAS_FURY) ||
+           (sc->device_id == MRSAS_INTRUDER) ||
+           (sc->device_id == MRSAS_INTRUDER_24) ||
+           (sc->device_id == MRSAS_CUTLASS_52) ||
+           (sc->device_id == MRSAS_CUTLASS_53)) {
+               sc->mrsas_gen3_ctrl = 1;
+    }
+
        mrsas_get_tunables(sc);
 
        /*
@@ -875,6 +872,7 @@ mrsas_attach(device_t dev)
        TAILQ_INIT(&sc->mrsas_mfi_cmd_list_head);
 
        mrsas_atomic_set(&sc->fw_outstanding, 0);
+       mrsas_atomic_set(&sc->target_reset_outstanding, 0);
 
        sc->io_cmds_highwater = 0;
 
@@ -953,8 +951,7 @@ mrsas_ich_startup(void *arg)
        /*
         * Intialize a counting Semaphore to take care no. of concurrent IOCTLs
         */
-       sema_init(&sc->ioctl_count_sema,
-           MRSAS_MAX_MFI_CMDS - 5,
+       sema_init(&sc->ioctl_count_sema, MRSAS_MAX_IOCTL_CMDS,
            IOCTL_SEMA_DESCRIPTION);
 
        /* Create a /dev entry for mrsas controller. */
@@ -1070,7 +1067,7 @@ mrsas_detach(device_t dev)
        mtx_destroy(&sc->raidmap_lock);
 
        /* Wait for all the semaphores to be released */
-       while (sema_value(&sc->ioctl_count_sema) != (MRSAS_MAX_MFI_CMDS - 5))
+       while (sema_value(&sc->ioctl_count_sema) != MRSAS_MAX_IOCTL_CMDS)
                pause("mr_shutdown", hz);
 
        /* Destroy the counting semaphore created for Ioctl */
@@ -1353,9 +1350,11 @@ mrsas_ioctl(struct cdev *dev, u_long cmd
        if (!sc)
                return ENOENT;
 
-       if (sc->remove_in_progress) {
+       if (sc->remove_in_progress ||
+               (sc->adprecovery == MRSAS_HW_CRITICAL_ERROR)) {
                mrsas_dprint(sc, MRSAS_INFO,
-                   "Driver remove or shutdown called.\n");
+                   "Either driver remove or shutdown called or "
+                       "HW is in unrecoverable critical error state.\n");
                return ENOENT;
        }
        mtx_lock_spin(&sc->ioctl_lock);
@@ -1547,7 +1546,10 @@ mrsas_complete_cmd(struct mrsas_softc *s
        PLD_LOAD_BALANCE_INFO lbinfo;
        u_int32_t device_id;
        int threshold_reply_count = 0;
-
+#if TM_DEBUG
+       MR_TASK_MANAGE_REQUEST *mr_tm_req;
+       MPI2_SCSI_TASK_MANAGE_REQUEST *mpi_tm_req;
+#endif
 
        /* If we have a hardware error, not need to continue */
        if (sc->adprecovery == MRSAS_HW_CRITICAL_ERROR)
@@ -1574,6 +1576,16 @@ mrsas_complete_cmd(struct mrsas_softc *s
                extStatus = scsi_io_req->RaidContext.exStatus;
 
                switch (scsi_io_req->Function) {
+               case MPI2_FUNCTION_SCSI_TASK_MGMT:
+#if TM_DEBUG
+                       mr_tm_req = (MR_TASK_MANAGE_REQUEST *) 
cmd_mpt->io_request;
+                       mpi_tm_req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)
+                           &mr_tm_req->TmRequest;
+                       device_printf(sc->mrsas_dev, "TM completion type 0x%X, "
+                           "TaskMID: 0x%X", mpi_tm_req->TaskType, 
mpi_tm_req->TaskMID);
+#endif
+            wakeup_one((void *)&sc->ocr_chan);
+            break;
                case MPI2_FUNCTION_SCSI_IO_REQUEST:     /* Fast Path IO. */
                        device_id = cmd_mpt->ccb_ptr->ccb_h.target_id;
                        lbinfo = &sc->load_balance_info[device_id];
@@ -1591,9 +1603,16 @@ mrsas_complete_cmd(struct mrsas_softc *s
                        break;
                case MRSAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST:   /* MFI command 
*/
                        cmd_mfi = sc->mfi_cmd_list[cmd_mpt->sync_cmd_idx];
-                       mrsas_complete_mptmfi_passthru(sc, cmd_mfi, status);
-                       cmd_mpt->flags = 0;
-                       mrsas_release_mpt_cmd(cmd_mpt);
+                       /*
+                        * Make sure NOT TO release the mfi command from the 
called
+                        * function's context if it is fired with issue_polled 
call.
+                        * And also make sure that the issue_polled call should 
only be
+                        * used if INTERRUPT IS DISABLED.
+                        */
+                       if (cmd_mfi->frame->hdr.flags & 
MFI_FRAME_DONT_POST_IN_REPLY_QUEUE)
+                               mrsas_release_mfi_cmd(cmd_mfi);
+                       else
+                               mrsas_complete_mptmfi_passthru(sc, cmd_mfi, 
status);
                        break;
                }
 
@@ -1628,12 +1647,7 @@ mrsas_complete_cmd(struct mrsas_softc *s
                 */
                if (threshold_reply_count >= THRESHOLD_REPLY_COUNT) {
                        if (sc->msix_enable) {
-                               if ((sc->device_id == MRSAS_INVADER) ||
-                                   (sc->device_id == MRSAS_FURY) ||
-                                   (sc->device_id == MRSAS_INTRUDER) ||
-                                   (sc->device_id == MRSAS_INTRUDER_24) ||
-                                   (sc->device_id == MRSAS_CUTLASS_52) ||
-                                   (sc->device_id == MRSAS_CUTLASS_53))
+                               if (sc->mrsas_gen3_ctrl)
                                        mrsas_write_reg(sc, 
sc->msix_reg_offset[MSIxIndex / 8],
                                            ((MSIxIndex & 0x7) << 24) |
                                            sc->last_reply_idx[MSIxIndex]);
@@ -1654,12 +1668,7 @@ mrsas_complete_cmd(struct mrsas_softc *s
 
        /* Clear response interrupt */
        if (sc->msix_enable) {
-               if ((sc->device_id == MRSAS_INVADER) ||
-                   (sc->device_id == MRSAS_FURY) ||
-                   (sc->device_id == MRSAS_INTRUDER) ||
-                   (sc->device_id == MRSAS_INTRUDER_24) ||
-                   (sc->device_id == MRSAS_CUTLASS_52) ||
-                   (sc->device_id == MRSAS_CUTLASS_53)) {
+                       if (sc->mrsas_gen3_ctrl) {
                        mrsas_write_reg(sc, sc->msix_reg_offset[MSIxIndex / 8],
                            ((MSIxIndex & 0x7) << 24) |
                            sc->last_reply_idx[MSIxIndex]);
@@ -2434,12 +2443,21 @@ mrsas_ioc_init(struct mrsas_softc *sc)
        u_int8_t max_wait = MRSAS_IOC_INIT_WAIT_TIME;
        bus_addr_t phys_addr;
        int i, retcode = 0;
+       u_int32_t scratch_pad_2;
 
        /* Allocate memory for the IOC INIT command */
        if (mrsas_alloc_ioc_cmd(sc)) {
                device_printf(sc->mrsas_dev, "Cannot allocate IOC command.\n");
                return (1);
        }
+
+       if (!sc->block_sync_cache) {
+               scratch_pad_2 = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+                   outbound_scratch_pad_2));
+               sc->fw_sync_cache_support = (scratch_pad_2 &
+                   MR_CAN_HANDLE_SYNC_CACHE_OFFSET) ? 1 : 0;
+       }
+
        IOCInitMsg = (pMpi2IOCInitRequest_t)(((char *)sc->ioc_init_mem) + 1024);
        IOCInitMsg->Function = MPI2_FUNCTION_IOC_INIT;
        IOCInitMsg->WhoInit = MPI2_WHOINIT_HOST_DRIVER;
@@ -2457,12 +2475,7 @@ mrsas_ioc_init(struct mrsas_softc *sc)
        init_frame->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
 
        /* driver support Extended MSIX */
-       if ((sc->device_id == MRSAS_INVADER) ||
-           (sc->device_id == MRSAS_FURY) ||
-           (sc->device_id == MRSAS_INTRUDER) ||
-           (sc->device_id == MRSAS_INTRUDER_24) ||
-           (sc->device_id == MRSAS_CUTLASS_52) ||
-           (sc->device_id == MRSAS_CUTLASS_53)) {
+               if (sc->mrsas_gen3_ctrl) {
                init_frame->driver_operations.
                    mfi_capabilities.support_additional_msix = 1;
        }
@@ -2584,7 +2597,7 @@ mrsas_alloc_mpt_cmds(struct mrsas_softc 
                memset(cmd, 0, sizeof(struct mrsas_mpt_cmd));
                cmd->index = i + 1;
                cmd->ccb_ptr = NULL;
-               callout_init(&cmd->cm_callout, 0);
+               callout_init_mtx(&cmd->cm_callout, &sc->sim_lock, 0);
                cmd->sync_cmd_idx = (u_int32_t)MRSAS_ULONG_MAX;
                cmd->sc = sc;
                cmd->io_request = (MRSAS_RAID_SCSI_IO_REQUEST *) (io_req_base + 
offset);
@@ -2779,6 +2792,7 @@ mrsas_ocr_thread(void *arg)
 {
        struct mrsas_softc *sc;
        u_int32_t fw_status, fw_state;
+       u_int8_t tm_target_reset_failed = 0;
 
        sc = (struct mrsas_softc *)arg;
 
@@ -2801,20 +2815,66 @@ mrsas_ocr_thread(void *arg)
                fw_status = mrsas_read_reg(sc,
                    offsetof(mrsas_reg_set, outbound_scratch_pad));
                fw_state = fw_status & MFI_STATE_MASK;
-               if (fw_state == MFI_STATE_FAULT || sc->do_timedout_reset) {
-                       device_printf(sc->mrsas_dev, "%s started due to %s!\n",
-                           sc->disableOnlineCtrlReset ? "Kill Adapter" : "OCR",
-                           sc->do_timedout_reset ? "IO Timeout" :
-                           "FW fault detected");
-                       mtx_lock_spin(&sc->ioctl_lock);
-                       sc->reset_in_progress = 1;
-                       sc->reset_count++;
-                       mtx_unlock_spin(&sc->ioctl_lock);
+               if (fw_state == MFI_STATE_FAULT || sc->do_timedout_reset ||
+                       mrsas_atomic_read(&sc->target_reset_outstanding)) {
+
+                       /* First, freeze further IOs to come to the SIM */
                        mrsas_xpt_freeze(sc);
-                       mrsas_reset_ctrl(sc, sc->do_timedout_reset);
-                       mrsas_xpt_release(sc);
-                       sc->reset_in_progress = 0;
-                       sc->do_timedout_reset = 0;
+
+                       /* If this is an IO timeout then go for target reset */
+                       if (mrsas_atomic_read(&sc->target_reset_outstanding)) {
+                               device_printf(sc->mrsas_dev, "Initiating Target 
RESET "
+                                   "because of SCSI IO timeout!\n");
+
+                               /* Let the remaining IOs to complete */
+                               msleep(&sc->ocr_chan, &sc->sim_lock, PRIBIO,
+                                     "mrsas_reset_targets", 5 * hz);
+
+                               /* Try to reset the target device */
+                               if (mrsas_reset_targets(sc) == FAIL)
+                                       tm_target_reset_failed = 1;
+                       }
+
+                       /* If this is a DCMD timeout or FW fault,
+                        * then go for controller reset
+                        */
+                       if (fw_state == MFI_STATE_FAULT || 
tm_target_reset_failed ||
+                           (sc->do_timedout_reset == MFI_DCMD_TIMEOUT_OCR)) {
+                               if (tm_target_reset_failed)
+                                       device_printf(sc->mrsas_dev, 
"Initiaiting OCR because of "
+                                           "TM FAILURE!\n");
+                               else
+                                       device_printf(sc->mrsas_dev, 
"Initiaiting OCR "
+                                               "because of %s!\n", 
sc->do_timedout_reset ?
+                                               "DCMD IO Timeout" : "FW fault");
+
+                               mtx_lock_spin(&sc->ioctl_lock);
+                               sc->reset_in_progress = 1;
+                               mtx_unlock_spin(&sc->ioctl_lock);
+                               sc->reset_count++;
+                               
+                               /*
+                                * Wait for the AEN task to be completed if it 
is running.
+                                */
+                               mtx_unlock(&sc->sim_lock);
+                               taskqueue_drain(sc->ev_tq, &sc->ev_task);
+                               mtx_lock(&sc->sim_lock);
+
+                               taskqueue_block(sc->ev_tq);
+                               /* Try to reset the controller */
+                               mrsas_reset_ctrl(sc, sc->do_timedout_reset);
+
+                               sc->do_timedout_reset = 0;
+                               sc->reset_in_progress = 0;
+                               tm_target_reset_failed = 0;
+                               mrsas_atomic_set(&sc->target_reset_outstanding, 
0);
+                               memset(sc->target_reset_pool, 0,
+                                   sizeof(sc->target_reset_pool));
+                               taskqueue_unblock(sc->ev_tq);
+                       }
+
+                       /* Now allow IOs to come to the SIM */
+                        mrsas_xpt_release(sc);
                }
        }
        mtx_unlock(&sc->sim_lock);
@@ -2866,6 +2926,7 @@ mrsas_reset_ctrl(struct mrsas_softc *sc,
        struct mrsas_mfi_cmd *mfi_cmd;
        struct mrsas_mpt_cmd *mpt_cmd;
        union mrsas_evt_class_locale class_locale;
+       MRSAS_REQUEST_DESCRIPTOR_UNION *req_desc;
 
        if (sc->adprecovery == MRSAS_HW_CRITICAL_ERROR) {
                device_printf(sc->mrsas_dev,
@@ -2993,13 +3054,25 @@ mrsas_reset_ctrl(struct mrsas_softc *sc,
                                mpt_cmd = sc->mpt_cmd_list[j];
                                if (mpt_cmd->sync_cmd_idx != 
(u_int32_t)MRSAS_ULONG_MAX) {
                                        mfi_cmd = 
sc->mfi_cmd_list[mpt_cmd->sync_cmd_idx];
-                                       mrsas_release_mfi_cmd(mfi_cmd);
-                                       mrsas_release_mpt_cmd(mpt_cmd);
+                                       /* If not an IOCTL then release the 
command else re-fire */
+                                       if (!mfi_cmd->sync_cmd) {
+                                               mrsas_release_mfi_cmd(mfi_cmd);
+                                       } else {
+                                               req_desc = 
mrsas_get_request_desc(sc,
+                                                   
mfi_cmd->cmd_id.context.smid - 1);
+                                               mrsas_dprint(sc, MRSAS_OCR,
+                                                   "Re-fire command DCMD 
opcode 0x%x index %d\n ",
+                                                   
mfi_cmd->frame->dcmd.opcode, j);
+                                               if (!req_desc)
+                                                       
device_printf(sc->mrsas_dev, 
+                                                           "Cannot build MPT 
cmd.\n");
+                                               else
+                                                       mrsas_fire_cmd(sc, 
req_desc->addr.u.low,
+                                                           
req_desc->addr.u.high);
+                                       }
                                }
                        }
 
-                       sc->aen_cmd = NULL;
-
                        /* Reset load balance info */
                        memset(sc->load_balance_info, 0,
                            sizeof(LD_LOAD_BALANCE_INFO) * 
MAX_LOGICAL_DRIVES_EXT);
@@ -3014,17 +3087,6 @@ mrsas_reset_ctrl(struct mrsas_softc *sc,
 
                        megasas_setup_jbod_map(sc);
 
-                       memset(sc->pd_list, 0,
-                           MRSAS_MAX_PD * sizeof(struct mrsas_pd_list));
-                       if (mrsas_get_pd_list(sc) != SUCCESS) {
-                               device_printf(sc->mrsas_dev, "Get PD list 
failed from OCR.\n"
-                                   "Will get the latest PD LIST after OCR on 
event.\n");
-                       }
-                       memset(sc->ld_ids, 0xff, MRSAS_MAX_LD_IDS);
-                       if (mrsas_get_ld_list(sc) != SUCCESS) {
-                               device_printf(sc->mrsas_dev, "Get LD lsit 
failed from OCR.\n"
-                                   "Will get the latest LD LIST after OCR on 
event.\n");
-                       }
                        mrsas_clear_bit(MRSAS_FUSION_IN_RESET, 
&sc->reset_flags);
                        mrsas_enable_intr(sc);
                        sc->adprecovery = MRSAS_HBA_OPERATIONAL;
@@ -3034,6 +3096,7 @@ mrsas_reset_ctrl(struct mrsas_softc *sc,
                        class_locale.members.locale = MR_EVT_LOCALE_ALL;
                        class_locale.members.class = MR_EVT_CLASS_DEBUG;
 
+                       mtx_unlock(&sc->sim_lock);
                        if (mrsas_register_aen(sc, sc->last_seq_num,
                            class_locale.word)) {
                                device_printf(sc->mrsas_dev,
@@ -3043,6 +3106,8 @@ mrsas_reset_ctrl(struct mrsas_softc *sc,
                                    "or the controller does not support AEN.\n"
                                    "Please contact to the SUPPORT TEAM if the 
problem persists\n");
                        }
+                       mtx_lock(&sc->sim_lock);
+
                        /* Adapter reset completed successfully */
                        device_printf(sc->mrsas_dev, "Reset successful\n");
                        retval = SUCCESS;
@@ -3139,6 +3204,11 @@ mrsas_wait_for_outstanding(struct mrsas_
                if (fw_state == MFI_STATE_FAULT) {
                        mrsas_dprint(sc, MRSAS_OCR,
                            "Found FW in FAULT state, will reset adapter.\n");
+                       count = sc->msix_vectors > 0 ? sc->msix_vectors : 1;
+                       mtx_unlock(&sc->sim_lock);
+                       for (MSIxIndex = 0; MSIxIndex < count; MSIxIndex++)
+                               mrsas_complete_cmd(sc, MSIxIndex);
+                       mtx_lock(&sc->sim_lock);
                        retval = 1;
                        goto out;
                }
@@ -3156,8 +3226,10 @@ mrsas_wait_for_outstanding(struct mrsas_
                        mrsas_dprint(sc, MRSAS_OCR, "[%2d]waiting for %d "
                            "commands to complete\n", i, outstanding);
                        count = sc->msix_vectors > 0 ? sc->msix_vectors : 1;
+                       mtx_unlock(&sc->sim_lock);
                        for (MSIxIndex = 0; MSIxIndex < count; MSIxIndex++)
                                mrsas_complete_cmd(sc, MSIxIndex);
+                       mtx_lock(&sc->sim_lock);
                }
                DELAY(1000 * 1000);
        }
@@ -3176,17 +3248,33 @@ out:
  * mrsas_release_mfi_cmd:      Return a cmd to free command pool
  * input:                                      Command packet for return to 
free cmd pool
  *
- * This function returns the MFI command to the command list.
+ * This function returns the MFI & MPT command to the command list.
  */
 void
-mrsas_release_mfi_cmd(struct mrsas_mfi_cmd *cmd)
+mrsas_release_mfi_cmd(struct mrsas_mfi_cmd *cmd_mfi)
 {
-       struct mrsas_softc *sc = cmd->sc;
+       struct mrsas_softc *sc = cmd_mfi->sc;
+       struct mrsas_mpt_cmd *cmd_mpt;
+
 
        mtx_lock(&sc->mfi_cmd_pool_lock);
-       cmd->ccb_ptr = NULL;
-       cmd->cmd_id.frame_count = 0;
-       TAILQ_INSERT_TAIL(&(sc->mrsas_mfi_cmd_list_head), cmd, next);
+       /*
+        * Release the mpt command (if at all it is allocated
+        * associated with the mfi command
+        */
+       if (cmd_mfi->cmd_id.context.smid) {
+               mtx_lock(&sc->mpt_cmd_pool_lock);
+               /* Get the mpt cmd from mfi cmd frame's smid value */
+               cmd_mpt = sc->mpt_cmd_list[cmd_mfi->cmd_id.context.smid-1];
+               cmd_mpt->flags = 0;
+               cmd_mpt->sync_cmd_idx = (u_int32_t)MRSAS_ULONG_MAX;
+               TAILQ_INSERT_HEAD(&(sc->mrsas_mpt_cmd_list_head), cmd_mpt, 
next);
+               mtx_unlock(&sc->mpt_cmd_pool_lock);
+       }
+       /* Release the mfi command */
+       cmd_mfi->ccb_ptr = NULL;
+       cmd_mfi->cmd_id.frame_count = 0;
+       TAILQ_INSERT_HEAD(&(sc->mrsas_mfi_cmd_list_head), cmd_mfi, next);
        mtx_unlock(&sc->mfi_cmd_pool_lock);
 
        return;
@@ -3235,7 +3323,11 @@ mrsas_get_ctrl_info(struct mrsas_softc *
        dcmd->sgl.sge32[0].phys_addr = sc->ctlr_info_phys_addr;
        dcmd->sgl.sge32[0].length = sizeof(struct mrsas_ctrl_info);
 
-       retcode = mrsas_issue_polled(sc, cmd);
+       if (!sc->mask_interrupts)
+               retcode = mrsas_issue_blocked_cmd(sc, cmd);
+       else
+               retcode = mrsas_issue_polled(sc, cmd);
+
        if (retcode == ETIMEDOUT)
                goto dcmd_timeout;
        else
@@ -3246,13 +3338,16 @@ mrsas_get_ctrl_info(struct mrsas_softc *
 
        sc->use_seqnum_jbod_fp =
            sc->ctrl_info->adapterOperations3.useSeqNumJbodFP;
+       sc->disableOnlineCtrlReset =
+           sc->ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
 
 dcmd_timeout:
        mrsas_free_ctlr_info_cmd(sc);
 
        if (do_ocr)
                sc->do_timedout_reset = MFI_DCMD_TIMEOUT_OCR;
-       else
+
+       if (!sc->mask_interrupts)
                mrsas_release_mfi_cmd(cmd);
 
        return (retcode);
@@ -3495,12 +3590,7 @@ mrsas_build_mptmfi_passthru(struct mrsas
 
        io_req = mpt_cmd->io_request;
 
-       if ((sc->device_id == MRSAS_INVADER) ||
-           (sc->device_id == MRSAS_FURY) ||
-           (sc->device_id == MRSAS_INTRUDER) ||
-           (sc->device_id == MRSAS_INTRUDER_24) ||
-           (sc->device_id == MRSAS_CUTLASS_52) ||
-           (sc->device_id == MRSAS_CUTLASS_53)) {
+               if (sc->mrsas_gen3_ctrl) {
                pMpi25IeeeSgeChain64_t sgl_ptr_end = 
(pMpi25IeeeSgeChain64_t)&io_req->SGL;
 
                sgl_ptr_end += sc->max_sge_in_main_msg - 1;
@@ -3868,8 +3958,6 @@ megasas_sync_pd_seq_num(struct mrsas_sof
 dcmd_timeout:
        if (do_ocr)
                sc->do_timedout_reset = MFI_DCMD_TIMEOUT_OCR;
-       else
-               mrsas_release_mfi_cmd(cmd);
 
        return (retcode);
 }
@@ -3946,8 +4034,6 @@ mrsas_get_ld_map_info(struct mrsas_softc
        retcode = mrsas_issue_polled(sc, cmd);
        if (retcode == ETIMEDOUT)
                sc->do_timedout_reset = MFI_DCMD_TIMEOUT_OCR;
-       else
-               mrsas_release_mfi_cmd(cmd);
 
        return (retcode);
 }
@@ -3974,9 +4060,8 @@ mrsas_sync_map_info(struct mrsas_softc *
 
        cmd = mrsas_get_mfi_cmd(sc);
        if (!cmd) {
-               device_printf(sc->mrsas_dev,
-                   "Cannot alloc for sync map info cmd\n");
-               return 1;
+               device_printf(sc->mrsas_dev, "Cannot alloc for sync map info 
cmd\n");
+               return ENOMEM;
        }
        map = sc->ld_drv_map[sc->map_id & 1];
        num_lds = map->raidMap.ldCount;
@@ -4076,7 +4161,11 @@ mrsas_get_pd_list(struct mrsas_softc *sc
        dcmd->sgl.sge32[0].phys_addr = pd_list_phys_addr;
        dcmd->sgl.sge32[0].length = MRSAS_MAX_PD * sizeof(struct MR_PD_LIST);
 
-       retcode = mrsas_issue_polled(sc, cmd);
+       if (!sc->mask_interrupts)
+               retcode = mrsas_issue_blocked_cmd(sc, cmd);
+       else
+               retcode = mrsas_issue_polled(sc, cmd);
+
        if (retcode == ETIMEDOUT)
                goto dcmd_timeout;
 
@@ -4107,7 +4196,8 @@ dcmd_timeout:
 
        if (do_ocr)
                sc->do_timedout_reset = MFI_DCMD_TIMEOUT_OCR;
-       else
+
+       if (!sc->mask_interrupts)
                mrsas_release_mfi_cmd(cmd);
 
        return (retcode);
@@ -4169,7 +4259,11 @@ mrsas_get_ld_list(struct mrsas_softc *sc
        dcmd->sgl.sge32[0].length = sizeof(struct MR_LD_LIST);
        dcmd->pad_0 = 0;
 
-       retcode = mrsas_issue_polled(sc, cmd);
+       if (!sc->mask_interrupts)
+               retcode = mrsas_issue_blocked_cmd(sc, cmd);
+       else
+               retcode = mrsas_issue_polled(sc, cmd);
+
        if (retcode == ETIMEDOUT)
                goto dcmd_timeout;
 
@@ -4195,7 +4289,7 @@ dcmd_timeout:
 
        if (do_ocr)
                sc->do_timedout_reset = MFI_DCMD_TIMEOUT_OCR;
-       else
+       if (!sc->mask_interrupts)
                mrsas_release_mfi_cmd(cmd);
 
        return (retcode);
@@ -4359,6 +4453,11 @@ mrsas_aen_handler(struct mrsas_softc *sc
                printf("invalid instance!\n");
                return;
        }
+       if (sc->remove_in_progress || sc->reset_in_progress) {
+               device_printf(sc->mrsas_dev, "Returning from %s, line no %d\n",
+                       __func__, __LINE__);
+               return;
+       }
        if (sc->evt_detail_mem) {
                switch (sc->evt_detail_mem->code) {
                case MR_EVT_PD_INSERTED:
@@ -4367,7 +4466,6 @@ mrsas_aen_handler(struct mrsas_softc *sc
                                mrsas_bus_scan_sim(sc, sc->sim_1);
                        else
                                goto skip_register_aen;
-                       doscan = 0;
                        break;
                case MR_EVT_PD_REMOVED:
                        fail_aen = mrsas_get_pd_list(sc);
@@ -4375,13 +4473,11 @@ mrsas_aen_handler(struct mrsas_softc *sc
                                mrsas_bus_scan_sim(sc, sc->sim_1);
                        else
                                goto skip_register_aen;
-                       doscan = 0;
                        break;
                case MR_EVT_LD_OFFLINE:
                case MR_EVT_CFG_CLEARED:
                case MR_EVT_LD_DELETED:
                        mrsas_bus_scan_sim(sc, sc->sim_0);
-                       doscan = 0;
                        break;
                case MR_EVT_LD_CREATED:
                        fail_aen = mrsas_get_ld_list(sc);
@@ -4389,15 +4485,18 @@ mrsas_aen_handler(struct mrsas_softc *sc
                                mrsas_bus_scan_sim(sc, sc->sim_0);
                        else
                                goto skip_register_aen;
-                       doscan = 0;
                        break;
                case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
                case MR_EVT_FOREIGN_CFG_IMPORTED:
                case MR_EVT_LD_STATE_CHANGE:
                        doscan = 1;
                        break;
+               case MR_EVT_CTRL_PROP_CHANGED:
+                       fail_aen = mrsas_get_ctrl_info(sc);
+                       if (fail_aen)
+                               goto skip_register_aen;
+                       break;
                default:
-                       doscan = 0;
                        break;
                }
        } else {
@@ -4473,8 +4572,7 @@ mrsas_complete_aen(struct mrsas_softc *s
        sc->aen_cmd = NULL;
        mrsas_release_mfi_cmd(cmd);
 
-       if (!sc->remove_in_progress)
-               taskqueue_enqueue(sc->ev_tq, &sc->ev_task);
+       taskqueue_enqueue(sc->ev_tq, &sc->ev_task);
 
        return;
 }

Modified: stable/10/sys/dev/mrsas/mrsas.h
==============================================================================
--- stable/10/sys/dev/mrsas/mrsas.h     Mon Dec 19 12:27:01 2016        
(r310263)
+++ stable/10/sys/dev/mrsas/mrsas.h     Mon Dec 19 13:14:39 2016        
(r310264)
@@ -106,7 +106,7 @@ __FBSDID("$FreeBSD$");
  */
 #define        BYTE_ALIGNMENT                                  1
 #define        MRSAS_MAX_NAME_LENGTH                   32
-#define        MRSAS_VERSION                                   
"06.709.07.00-fbsd"
+#define        MRSAS_VERSION                                   
"06.712.04.00-fbsd"
 #define        MRSAS_ULONG_MAX                                 
0xFFFFFFFFFFFFFFFF
 #define        MRSAS_DEFAULT_TIMEOUT                   0x14    /* Temporarily 
set */
 #define        DONE                                                    0
@@ -205,7 +205,9 @@ typedef struct _RAID_CONTEXT {
 #define        MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD               (0x0100)
 #define        MPI2_SCSIIO_EEDPFLAGS_INSERT_OP                 (0x0004)
 #define        MPI2_FUNCTION_SCSI_IO_REQUEST                   (0x00)  /* SCSI 
IO */
-#define        MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY   (0x06)
+#define        MPI2_FUNCTION_SCSI_TASK_MGMT                    (0x01)
+#define        MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY   (0x03)
+#define        MPI2_REQ_DESCRIPT_FLAGS_FP_IO                   (0x06)
 #define        MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO                 (0x00)
 #define        MPI2_SGE_FLAGS_64_BIT_ADDRESSING                (0x02)
 #define        MPI2_SCSIIO_CONTROL_WRITE                               
(0x01000000)
@@ -314,6 +316,91 @@ typedef union {
 }      MPI2_SCSI_IO_CDB_UNION, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_UNION,
 Mpi2ScsiIoCdb_t, MPI2_POINTER pMpi2ScsiIoCdb_t;
 
+/****************************************************************************
+ *  *  SCSI Task Management messages
+ *   
****************************************************************************/
+
+/*SCSI Task Management Request Message */
+typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST {
+       u_int16_t DevHandle;        /*0x00 */
+       u_int8_t ChainOffset;       /*0x02 */
+       u_int8_t Function;      /*0x03 */
+       u_int8_t Reserved1;     /*0x04 */
+       u_int8_t TaskType;      /*0x05 */
+       u_int8_t Reserved2;     /*0x06 */
+       u_int8_t MsgFlags;      /*0x07 */
+       u_int8_t VP_ID;     /*0x08 */
+       u_int8_t VF_ID;     /*0x09 */
+       u_int16_t Reserved3;        /*0x0A */
+       u_int8_t LUN[8];        /*0x0C */
+       u_int32_t Reserved4[7]; /*0x14 */
+       u_int16_t TaskMID;      /*0x30 */
+       u_int16_t Reserved5;        /*0x32 */
+} MPI2_SCSI_TASK_MANAGE_REQUEST;
+
+/*SCSI Task Management Reply Message */
+typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY {
+       u_int16_t DevHandle;        /*0x00 */
+       u_int8_t MsgLength;     /*0x02 */
+       u_int8_t Function;      /*0x03 */
+       u_int8_t ResponseCode;  /*0x04 */
+       u_int8_t TaskType;      /*0x05 */
+       u_int8_t Reserved1;     /*0x06 */
+       u_int8_t MsgFlags;      /*0x07 */
+       u_int8_t VP_ID;     /*0x08 */
+       u_int8_t VF_ID;     /*0x09 */
+       u_int16_t Reserved2;        /*0x0A */
+       u_int16_t Reserved3;        /*0x0C */
+       u_int16_t IOCStatus;        /*0x0E */
+       u_int32_t IOCLogInfo;       /*0x10 */
+       u_int32_t TerminationCount; /*0x14 */
+       u_int32_t ResponseInfo; /*0x18 */
+} MPI2_SCSI_TASK_MANAGE_REPLY;
+
+typedef struct _MR_TM_REQUEST {
+       char request[128];
+} MR_TM_REQUEST;
+
+typedef struct _MR_TM_REPLY {
+       char reply[128];
+} MR_TM_REPLY;
+
+/* SCSI Task Management Request Message */
+typedef struct _MR_TASK_MANAGE_REQUEST {
+       /*To be type casted to struct MPI2_SCSI_TASK_MANAGE_REQUEST */
+       MR_TM_REQUEST        TmRequest;
+       union {
+               struct {
+                       u_int32_t isTMForLD:1;
+                       u_int32_t isTMForPD:1;
+                       u_int32_t reserved1:30;
+                       u_int32_t reserved2;
+               } tmReqFlags;
+               MR_TM_REPLY   TMReply;
+       } uTmReqReply;
+} MR_TASK_MANAGE_REQUEST;
+
+/* TaskType values */
+#define MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK           (0x01)
+#define MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET        (0x02)
+#define MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET         (0x03)
+#define MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET   (0x05)
+#define MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET       (0x06)
+#define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK           (0x07)
+#define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA              (0x08)
+#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET         (0x09)
+#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT      (0x0A)
+
+/* ResponseCode values */
+#define MPI2_SCSITASKMGMT_RSP_TM_COMPLETE               (0x00)
+#define MPI2_SCSITASKMGMT_RSP_INVALID_FRAME             (0x02)
+#define MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED          (0x04)
+#define MPI2_SCSITASKMGMT_RSP_TM_FAILED                 (0x05)
+#define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED              (0x08)
+#define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN            (0x09)
+#define MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG         (0x0A)
+#define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC          (0x80)
+
 /*
  * RAID SCSI IO Request Message Total SGE count will be one less than
  * _MPI2_SCSI_IO_REQUEST
@@ -584,7 +671,7 @@ Mpi2IOCInitRequest_t, MPI2_POINTER pMpi2
 #define        MAX_RAIDMAP_PHYSICAL_DEVICES    (MAX_PHYSICAL_DEVICES)
 #define        MR_DCMD_LD_MAP_GET_INFO 0x0300e101
 #define        MR_DCMD_SYSTEM_PD_MAP_GET_INFO  0x0200e102
-
+#define MR_DCMD_PD_MFI_TASK_MGMT       0x0200e100
 
 #define        MRSAS_MAX_PD_CHANNELS           1
 #define        MRSAS_MAX_LD_CHANNELS           1
@@ -599,7 +686,7 @@ Mpi2IOCInitRequest_t, MPI2_POINTER pMpi2
 
 
 #define        VD_EXT_DEBUG    0
-
+#define TM_DEBUG               1
 
 /*******************************************************************
  * RAID map related structures
@@ -659,7 +746,8 @@ typedef struct _MR_LD_RAID {
                u_int32_t fpWriteAcrossStripe:1;
                u_int32_t fpReadAcrossStripe:1;
                u_int32_t fpNonRWCapable:1;
-               u_int32_t reserved4:7;
+               u_int32_t tmCapable:1;
+               u_int32_t reserved4:6;
        }       capability;
        u_int32_t reserved6;
        u_int64_t size;
@@ -876,7 +964,11 @@ struct IO_REQUEST_INFO {
 struct MR_PD_CFG_SEQ {
        u_int16_t seqNum;
        u_int16_t devHandle;
-       u_int8_t reserved[4];
+       struct {
+               u_int8_t tmCapable:1;
+               u_int8_t reserved:7;
+       } capability;
+       u_int8_t reserved[3];
 } __packed;
 
 struct MR_PD_CFG_SEQ_NUM_SYNC {
@@ -1242,7 +1334,6 @@ enum MR_EVT_ARGS {
        MR_EVT_ARGS_GENERIC,
 };
 
-
 /*
  * Thunderbolt (and later) Defines
  */
@@ -1256,7 +1347,8 @@ enum MR_EVT_ARGS {
 #define        HOST_DIAG_WRITE_ENABLE                                          
0x80
 #define        HOST_DIAG_RESET_ADAPTER                                         
0x4
 #define        MRSAS_TBOLT_MAX_RESET_TRIES                                     
3
-#define        MRSAS_MAX_MFI_CMDS                                              
        32
+#define MRSAS_MAX_MFI_CMDS                          16
+#define MRSAS_MAX_IOCTL_CMDS                        3
 
 /*
  * Invader Defines
@@ -1395,6 +1487,7 @@ struct mrsas_mpt_cmd {
        union ccb *ccb_ptr;
        struct callout cm_callout;
        struct mrsas_softc *sc;
+       boolean_t tmCapable;
        TAILQ_ENTRY(mrsas_mpt_cmd) next;
 };
 
@@ -1448,6 +1541,7 @@ enum MR_PD_QUERY_TYPE {
 #define        MR_EVT_LD_DELETED                                               
0x008b
 #define        MR_EVT_FOREIGN_CFG_IMPORTED                             0x00db
 #define        MR_EVT_LD_OFFLINE                                               
0x00fc
+#define        MR_EVT_CTRL_PROP_CHANGED                                0x012f
 #define        MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED             0x0152
 
 enum MR_PD_STATE {
@@ -1990,6 +2084,11 @@ struct mrsas_ctrl_info {
 #define        MR_MAX_MSIX_REG_ARRAY                                   16
 
 /*
+ * SYNC CACHE offset define
+ */
+#define MR_CAN_HANDLE_SYNC_CACHE_OFFSET     0X01000000
+
+/*
  * FW reports the maximum of number of commands that it can accept (maximum
  * commands that can be outstanding) at any time. The driver must report a
  * lower number to the mid layer because it can issue a few internal commands
@@ -2470,8 +2569,7 @@ struct mrsas_irq_context {
 
 enum MEGASAS_OCR_REASON {
        FW_FAULT_OCR = 0,
-       SCSIIO_TIMEOUT_OCR = 1,
-       MFI_DCMD_TIMEOUT_OCR = 2,
+       MFI_DCMD_TIMEOUT_OCR = 1,
 };
 
 /* Controller management info added to support Linux Emulator */
@@ -2746,6 +2844,11 @@ struct mrsas_softc {
        u_int8_t do_timedout_reset;
        u_int32_t reset_in_progress;
        u_int32_t reset_count;
+       u_int32_t block_sync_cache;
+       u_int8_t fw_sync_cache_support;
+       mrsas_atomic_t target_reset_outstanding;
+#define MRSAS_MAX_TM_TARGETS (MRSAS_MAX_PD + MRSAS_MAX_LD_IDS)
+    struct mrsas_mpt_cmd *target_reset_pool[MRSAS_MAX_TM_TARGETS];
 
        bus_dma_tag_t jbodmap_tag[2];
        bus_dmamap_t jbodmap_dmamap[2];
@@ -2794,6 +2897,7 @@ struct mrsas_softc {
        LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES_EXT];
        LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT];
 
+       u_int8_t mrsas_gen3_ctrl;
        u_int8_t secure_jbod_support;
        u_int8_t use_seqnum_jbod_fp;
        u_int8_t max256vdSupport;

Modified: stable/10/sys/dev/mrsas/mrsas_cam.c
==============================================================================
--- stable/10/sys/dev/mrsas/mrsas_cam.c Mon Dec 19 12:27:01 2016        
(r310263)
+++ stable/10/sys/dev/mrsas/mrsas_cam.c Mon Dec 19 13:14:39 2016        
(r310264)
@@ -95,6 +95,11 @@ static void mrsas_freeze_simq(struct mrs
 static void mrsas_cam_poll(struct cam_sim *sim);
 static void mrsas_action(struct cam_sim *sim, union ccb *ccb);
 static void mrsas_scsiio_timeout(void *data);
+static int mrsas_track_scsiio(struct mrsas_softc *sc, target_id_t id, 
u_int32_t bus_id);
+static void mrsas_tm_response_code(struct mrsas_softc *sc,
+    MPI2_SCSI_TASK_MANAGE_REPLY *mpi_reply);
+static int mrsas_issue_tm(struct mrsas_softc *sc,
+    MRSAS_REQUEST_DESCRIPTOR_UNION *req_desc);
 static void
 mrsas_data_load_cb(void *arg, bus_dma_segment_t *segs,
     int nseg, int error);
@@ -105,6 +110,10 @@ struct mrsas_mpt_cmd *mrsas_get_mpt_cmd(
 MRSAS_REQUEST_DESCRIPTOR_UNION *
        mrsas_get_request_desc(struct mrsas_softc *sc, u_int16_t index);
 
+extern void
+mrsas_map_mpt_cmd_status(struct mrsas_mpt_cmd *cmd, u_int8_t status,
+    u_int8_t extStatus);
+extern int mrsas_reset_targets(struct mrsas_softc *sc);
 extern u_int16_t MR_TargetIdToLdGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * 
map);
 extern u_int32_t
 MR_LdBlockSizeGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * map,
@@ -125,6 +134,9 @@ extern u_int8_t
 megasas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm,
     u_int64_t block, u_int32_t count);
 extern int mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex);
+extern MR_LD_RAID *MR_LdRaidGet(u_int32_t ld, MR_DRV_RAID_MAP_ALL * map);
+extern void mrsas_disable_intr(struct mrsas_softc *sc);
+extern void mrsas_enable_intr(struct mrsas_softc *sc);
 
 
 /*
@@ -260,6 +272,17 @@ mrsas_action(struct cam_sim *sim, union 
        struct ccb_hdr *ccb_h = &(ccb->ccb_h);
        u_int32_t device_id;
 
+       /*
+     * Check if the system going down
+     * or the adapter is in unrecoverable critical error
+     */
+    if (sc->remove_in_progress ||
+        (sc->adprecovery == MRSAS_HW_CRITICAL_ERROR)) {
+        ccb->ccb_h.status |= CAM_DEV_NOT_THERE;
+        xpt_done(ccb);
+        return;
+    }
+
        switch (ccb->ccb_h.func_code) {
        case XPT_SCSI_IO:
                {
@@ -375,6 +398,10 @@ mrsas_scsiio_timeout(void *data)
 {
        struct mrsas_mpt_cmd *cmd;
        struct mrsas_softc *sc;
+       u_int32_t target_id;
+
+       if (!data)
+               return;
 
        cmd = (struct mrsas_mpt_cmd *)data;
        sc = cmd->sc;
@@ -383,6 +410,7 @@ mrsas_scsiio_timeout(void *data)
                printf("command timeout with NULL ccb\n");
                return;
        }
+
        /*
         * Below callout is dummy entry so that it will be cancelled from
         * mrsas_cmd_done(). Now Controller will go to OCR/Kill Adapter based
@@ -390,15 +418,25 @@ mrsas_scsiio_timeout(void *data)
         * context.
         */
 #if (__FreeBSD_version >= 1000510)
-       callout_reset_sbt(&cmd->cm_callout, SBT_1S * 600, 0,
+       callout_reset_sbt(&cmd->cm_callout, SBT_1S * 180, 0,
            mrsas_scsiio_timeout, cmd, 0);
 #else
-       callout_reset(&cmd->cm_callout, (600000 * hz) / 1000,
+       callout_reset(&cmd->cm_callout, (180000 * hz) / 1000,
            mrsas_scsiio_timeout, cmd);
 #endif
-       sc->do_timedout_reset = SCSIIO_TIMEOUT_OCR;
-       if (sc->ocr_thread_active)
-               wakeup(&sc->ocr_chan);
+
+       if (cmd->ccb_ptr->cpi.bus_id == 0)
+               target_id = cmd->ccb_ptr->ccb_h.target_id;
+       else
+               target_id = (cmd->ccb_ptr->ccb_h.target_id + (MRSAS_MAX_PD - 
1));

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to