Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Sep 2017 17:49:57 +0000 (UTC)
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r323819 - stable/11/sys/dev/mrsas
Message-ID:  <201709201749.v8KHnvZ3066965@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jkim
Date: Wed Sep 20 17:49:57 2017
New Revision: 323819
URL: https://svnweb.freebsd.org/changeset/base/323819

Log:
  MFC:	r309284-r309294 (kadesai)
  
  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/11/sys/dev/mrsas/mrsas.c
  stable/11/sys/dev/mrsas/mrsas.h
  stable/11/sys/dev/mrsas/mrsas_cam.c
  stable/11/sys/dev/mrsas/mrsas_fp.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/mrsas/mrsas.c
==============================================================================
--- stable/11/sys/dev/mrsas/mrsas.c	Wed Sep 20 17:30:01 2017	(r323818)
+++ stable/11/sys/dev/mrsas/mrsas.c	Wed Sep 20 17:49:57 2017	(r323819)
@@ -110,6 +110,7 @@ int	mrsas_issue_polled(struct mrsas_softc *sc, struct 
 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 mrsas_softc *sc);
 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 *sc)
 	    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 *sc)
 	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 *sc, u_int32_t 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 */
@@ -1354,9 +1351,11 @@ mrsas_ioctl(struct cdev *dev, u_long cmd, caddr_t arg,
 	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);
@@ -1548,8 +1547,11 @@ mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t M
 	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)
 		return (DONE);
@@ -1575,6 +1577,16 @@ mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t M
 		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];
@@ -1592,9 +1604,16 @@ mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t M
 			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;
 		}
 
@@ -1629,12 +1648,7 @@ mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t M
 		 */
 		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]);
@@ -1655,12 +1669,7 @@ mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t M
 
 	/* 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]);
@@ -2435,12 +2444,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;
@@ -2458,12 +2476,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;
 	}
@@ -2585,7 +2598,7 @@ mrsas_alloc_mpt_cmds(struct mrsas_softc *sc)
 		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);
@@ -2780,6 +2793,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;
 
@@ -2802,20 +2816,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);
@@ -2867,6 +2927,7 @@ mrsas_reset_ctrl(struct mrsas_softc *sc, u_int8_t rese
 	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,
@@ -2994,13 +3055,25 @@ mrsas_reset_ctrl(struct mrsas_softc *sc, u_int8_t rese
 				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);
@@ -3015,17 +3088,6 @@ mrsas_reset_ctrl(struct mrsas_softc *sc, u_int8_t rese
 
 			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;
@@ -3035,6 +3097,7 @@ mrsas_reset_ctrl(struct mrsas_softc *sc, u_int8_t rese
 			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,
@@ -3044,6 +3107,8 @@ mrsas_reset_ctrl(struct mrsas_softc *sc, u_int8_t rese
 				    "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;
@@ -3140,6 +3205,11 @@ mrsas_wait_for_outstanding(struct mrsas_softc *sc, u_i
 		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;
 		}
@@ -3157,8 +3227,10 @@ mrsas_wait_for_outstanding(struct mrsas_softc *sc, u_i
 			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);
 	}
@@ -3177,17 +3249,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;
@@ -3236,7 +3324,11 @@ mrsas_get_ctrl_info(struct mrsas_softc *sc)
 	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
@@ -3247,13 +3339,16 @@ mrsas_get_ctrl_info(struct mrsas_softc *sc)
 
 	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);
@@ -3496,12 +3591,7 @@ mrsas_build_mptmfi_passthru(struct mrsas_softc *sc, st
 
 	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;
@@ -3869,8 +3959,6 @@ megasas_sync_pd_seq_num(struct mrsas_softc *sc, boolea
 dcmd_timeout:
 	if (do_ocr)
 		sc->do_timedout_reset = MFI_DCMD_TIMEOUT_OCR;
-	else
-		mrsas_release_mfi_cmd(cmd);
 
 	return (retcode);
 }
@@ -3947,8 +4035,6 @@ mrsas_get_ld_map_info(struct mrsas_softc *sc)
 	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);
 }
@@ -3975,9 +4061,8 @@ mrsas_sync_map_info(struct mrsas_softc *sc)
 
 	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;
@@ -4077,7 +4162,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;
 
@@ -4108,7 +4197,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);
@@ -4170,7 +4260,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;
 
@@ -4196,7 +4290,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);
@@ -4360,6 +4454,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:
@@ -4368,7 +4467,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);
@@ -4376,13 +4474,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);
@@ -4390,15 +4486,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 {
@@ -4474,8 +4573,7 @@ mrsas_complete_aen(struct mrsas_softc *sc, struct mrsa
 	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/11/sys/dev/mrsas/mrsas.h
==============================================================================
--- stable/11/sys/dev/mrsas/mrsas.h	Wed Sep 20 17:30:01 2017	(r323818)
+++ stable/11/sys/dev/mrsas/mrsas.h	Wed Sep 20 17:49:57 2017	(r323819)
@@ -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,8 +671,8 @@ Mpi2IOCInitRequest_t, MPI2_POINTER pMpi2IOCInitRequest
 #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
 #define	MRSAS_MAX_DEV_PER_CHANNEL	256
@@ -599,8 +686,8 @@ Mpi2IOCInitRequest_t, MPI2_POINTER pMpi2IOCInitRequest
 
 
 #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/11/sys/dev/mrsas/mrsas_cam.c
==============================================================================
--- stable/11/sys/dev/mrsas/mrsas_cam.c	Wed Sep 20 17:30:01 2017	(r323818)
+++ stable/11/sys/dev/mrsas/mrsas_cam.c	Wed Sep 20 17:49:57 2017	(r323819)
@@ -95,6 +95,11 @@ static void mrsas_freeze_simq(struct mrsas_mpt_cmd *cm
 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(struct mrsas_s
 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 ccb *ccb)
 	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,7 +398,11 @@ 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);
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201709201749.v8KHnvZ3066965>