svn commit: r212678 - stable/7/sys/dev/twa

Xin LI delphij at FreeBSD.org
Wed Sep 15 17:25:51 UTC 2010


Author: delphij
Date: Wed Sep 15 17:25:51 2010
New Revision: 212678
URL: http://svn.freebsd.org/changeset/base/212678

Log:
  MFC r212008,212028,212210 the updated twa(4) driver minus maxio change
  which depends on cam(4) revision r195534.
  
  The change have been tested on stable/7 with 3ware 9650SE at iXsystems.

Modified:
  stable/7/sys/dev/twa/tw_cl.h
  stable/7/sys/dev/twa/tw_cl_externs.h
  stable/7/sys/dev/twa/tw_cl_fwif.h
  stable/7/sys/dev/twa/tw_cl_init.c
  stable/7/sys/dev/twa/tw_cl_intr.c
  stable/7/sys/dev/twa/tw_cl_io.c
  stable/7/sys/dev/twa/tw_cl_misc.c
  stable/7/sys/dev/twa/tw_cl_share.h
  stable/7/sys/dev/twa/tw_osl.h
  stable/7/sys/dev/twa/tw_osl_cam.c
  stable/7/sys/dev/twa/tw_osl_freebsd.c
  stable/7/sys/dev/twa/tw_osl_share.h
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/twa/tw_cl.h
==============================================================================
--- stable/7/sys/dev/twa/tw_cl.h	Wed Sep 15 17:25:09 2010	(r212677)
+++ stable/7/sys/dev/twa/tw_cl.h	Wed Sep 15 17:25:51 2010	(r212678)
@@ -88,7 +88,8 @@ struct tw_cli_q_stats {
 #define TW_CLI_BUSY_Q		1	/* q of reqs submitted to fw */
 #define TW_CLI_PENDING_Q	2	/* q of reqs deferred due to 'q full' */
 #define TW_CLI_COMPLETE_Q	3	/* q of reqs completed by fw */
-#define TW_CLI_Q_COUNT		4	/* total number of queues */
+#define TW_CLI_RESET_Q		4	/* q of reqs reset by timeout */
+#define TW_CLI_Q_COUNT		5	/* total number of queues */
 
 
 /* CL's internal request context. */
@@ -133,6 +134,7 @@ struct tw_cli_ctlr_context {
 	TW_UINT8 		interrupts_enabled;	  /* Interrupts on controller enabled. */
 	TW_UINT8 		internal_req_busy;	  /* Data buffer for internal requests in use. */
 	TW_UINT8 		get_more_aens;		  /* More AEN's need to be retrieved. */
+	TW_UINT8 		reset_needed;		  /* Controller needs a soft reset. */
 	TW_UINT8 		reset_in_progress;	  /* Controller is being reset. */
 	TW_UINT8 		reset_phase1_in_progress; /* In 'phase 1' of reset. */
 	TW_UINT32		flags;		/* controller settings */

Modified: stable/7/sys/dev/twa/tw_cl_externs.h
==============================================================================
--- stable/7/sys/dev/twa/tw_cl_externs.h	Wed Sep 15 17:25:09 2010	(r212677)
+++ stable/7/sys/dev/twa/tw_cl_externs.h	Wed Sep 15 17:25:51 2010	(r212678)
@@ -86,6 +86,8 @@ extern TW_INT32	tw_cli_submit_and_poll_r
 
 /* Soft reset the controller. */
 extern TW_INT32	tw_cli_soft_reset(struct tw_cli_ctlr_context *ctlr);
+extern int twa_setup_intr(struct twa_softc *sc);
+extern int twa_teardown_intr(struct twa_softc *sc);
 
 /* Send down a SCSI command to the firmware (usually, an internal Req Sense. */
 extern TW_INT32	tw_cli_send_scsi_cmd(struct tw_cli_req_context *req,

Modified: stable/7/sys/dev/twa/tw_cl_fwif.h
==============================================================================
--- stable/7/sys/dev/twa/tw_cl_fwif.h	Wed Sep 15 17:25:09 2010	(r212677)
+++ stable/7/sys/dev/twa/tw_cl_fwif.h	Wed Sep 15 17:25:51 2010	(r212678)
@@ -89,7 +89,7 @@
 #define TWA_STATUS_MINOR_VERSION_MASK		0x0F000000
 #define TWA_STATUS_MAJOR_VERSION_MASK		0xF0000000
 
-#define TWA_STATUS_UNEXPECTED_BITS		0x00F00000
+#define TWA_STATUS_UNEXPECTED_BITS		0x00D00000
 
 
 /* PCI related defines. */

Modified: stable/7/sys/dev/twa/tw_cl_init.c
==============================================================================
--- stable/7/sys/dev/twa/tw_cl_init.c	Wed Sep 15 17:25:09 2010	(r212677)
+++ stable/7/sys/dev/twa/tw_cl_init.c	Wed Sep 15 17:25:51 2010	(r212678)
@@ -315,6 +315,7 @@ tw_cl_init_ctlr(struct tw_cl_ctlr_handle
 	tw_cli_req_q_init(ctlr, TW_CLI_BUSY_Q);
 	tw_cli_req_q_init(ctlr, TW_CLI_PENDING_Q);
 	tw_cli_req_q_init(ctlr, TW_CLI_COMPLETE_Q);
+	tw_cli_req_q_init(ctlr, TW_CLI_RESET_Q);
 
 	/* Initialize all locks used by CL. */
 	ctlr->gen_lock = &(ctlr->gen_lock_handle);
@@ -675,15 +676,14 @@ tw_cli_init_connection(struct tw_cli_ctl
 	/* Submit the command, and wait for it to complete. */
 	error = tw_cli_submit_and_poll_request(req,
 		TW_CLI_REQUEST_TIMEOUT_PERIOD);
-	if (error == TW_OSL_ETIMEDOUT)
-		/* Clean-up done by tw_cli_submit_and_poll_request. */
-		return(error);
 	if (error)
 		goto out;
 	if ((error = init_connect->status)) {
+#if       0
 		tw_cli_create_ctlr_event(ctlr,
 			TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
 			&(req->cmd_pkt->cmd_hdr));
+#endif // 0
 		goto out;
 	}
 	if (set_features & TWA_EXTENDED_INIT_CONNECT) {

Modified: stable/7/sys/dev/twa/tw_cl_intr.c
==============================================================================
--- stable/7/sys/dev/twa/tw_cl_intr.c	Wed Sep 15 17:25:09 2010	(r212677)
+++ stable/7/sys/dev/twa/tw_cl_intr.c	Wed Sep 15 17:25:51 2010	(r212678)
@@ -248,8 +248,7 @@ tw_cli_process_resp_intr(struct tw_cli_c
 #ifdef TW_OSL_DEBUG
 			tw_cl_print_ctlr_stats(ctlr->ctlr_handle);
 #endif /* TW_OSL_DEBUG */
-			tw_cl_reset_ctlr(ctlr->ctlr_handle);
-			return(TW_OSL_EIO);
+			continue;
 		}
 
 		/*
@@ -402,9 +401,7 @@ tw_cli_complete_io(struct tw_cli_req_con
 #ifdef TW_OSL_DEBUG
 		tw_cl_print_ctlr_stats(ctlr->ctlr_handle);
 #endif /* TW_OSL_DEBUG */
-		tw_cl_reset_ctlr(ctlr->ctlr_handle);
-		req_pkt->status = TW_CL_ERR_REQ_BUS_RESET;
-		goto out;
+		return;
 	}
 
 	if (req->flags & TW_CLI_REQ_FLAGS_PASSTHRU) {
@@ -483,6 +480,7 @@ tw_cli_scsi_complete(struct tw_cli_req_c
 			cdb[8], cdb[9], cdb[10], cdb[11],
 			cdb[12], cdb[13], cdb[14], cdb[15]);
 
+#if       0
 		/* 
 		 * Print the error. Firmware doesn't yet support
 		 * the 'Mode Sense' cmd.  Don't print if the cmd
@@ -493,6 +491,7 @@ tw_cli_scsi_complete(struct tw_cli_req_c
 			tw_cli_create_ctlr_event(req->ctlr,
 				TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
 				cmd_hdr);
+#endif // 0
 	}
 
 	if (scsi_req->sense_data) {
@@ -530,9 +529,11 @@ tw_cli_param_callback(struct tw_cli_req_
 	 */
 	if (! req->error_code)
 		if (cmd->param.status) {
+#if       0
 			tw_cli_create_ctlr_event(ctlr,
 				TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
 				&(req->cmd_pkt->cmd_hdr));
+#endif // 0
 			tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
 				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
 				0x1204, 0x1, TW_CL_SEVERITY_ERROR_STRING,
@@ -590,9 +591,11 @@ tw_cli_aen_callback(struct tw_cli_req_co
 		if ((error = cmd->status)) {
 			cmd_hdr = (struct tw_cl_command_header *)
 				(&(req->cmd_pkt->cmd_hdr));
+#if       0
 			tw_cli_create_ctlr_event(ctlr,
 				TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
 				cmd_hdr);
+#endif // 0
 			tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
 				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
 				0x1206, 0x1, TW_CL_SEVERITY_ERROR_STRING,

Modified: stable/7/sys/dev/twa/tw_cl_io.c
==============================================================================
--- stable/7/sys/dev/twa/tw_cl_io.c	Wed Sep 15 17:25:09 2010	(r212677)
+++ stable/7/sys/dev/twa/tw_cl_io.c	Wed Sep 15 17:25:51 2010	(r212678)
@@ -74,18 +74,12 @@ tw_cl_start_io(struct tw_cl_ctlr_handle 
 	struct tw_cli_req_context		*req;
 	struct tw_cl_command_9k			*cmd;
 	struct tw_cl_scsi_req_packet		*scsi_req;
-	TW_INT32				error;
+	TW_INT32				error = TW_CL_ERR_REQ_SUCCESS;
 
 	tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), "entered");
 
 	ctlr = (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
 
-	if (ctlr->reset_in_progress) {
-		tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
-			"I/O during reset: returning busy.");
-		return(TW_OSL_EBUSY);
-	}
-
 	/*
 	 * If working with a firmware version that does not support multiple
 	 * luns, and this request is directed at a non-zero lun, error it
@@ -145,7 +139,12 @@ tw_cl_start_io(struct tw_cl_ctlr_handle 
 			cmd->sg_list, scsi_req->sgl_entries);
 	}
 
-	if ((error = tw_cli_submit_cmd(req))) {
+	if (((TW_CL_Q_FIRST_ITEM(&(ctlr->req_q_head[TW_CLI_PENDING_Q]))) != TW_CL_NULL) ||
+		(ctlr->reset_in_progress)) {
+		tw_cli_req_q_insert_tail(req, TW_CLI_PENDING_Q);
+		TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
+			TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
+	} else if ((error = tw_cli_submit_cmd(req))) {
 		tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
 			"Could not start request. request = %p, error = %d",
 			req, error);
@@ -171,7 +170,7 @@ tw_cli_submit_cmd(struct tw_cli_req_cont
 	struct tw_cli_ctlr_context	*ctlr = req->ctlr;
 	struct tw_cl_ctlr_handle	*ctlr_handle = ctlr->ctlr_handle;
 	TW_UINT32			status_reg;
-	TW_INT32			error;
+	TW_INT32			error = 0;
 
 	tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), "entered");
 
@@ -185,11 +184,7 @@ tw_cli_submit_cmd(struct tw_cli_req_cont
 				 TWA_COMMAND_QUEUE_OFFSET_LOW,
 				 (TW_UINT32)(req->cmd_pkt_phys + sizeof(struct tw_cl_command_header)), 4);
 
-	/* Check to see if we can post a command. */
 	status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr_handle);
-	if ((error = tw_cli_check_ctlr_state(ctlr, status_reg)))
-		goto out;
-
 	if (status_reg & TWA_STATUS_COMMAND_QUEUE_FULL) {
 		struct tw_cl_req_packet	*req_pkt =
 			(struct tw_cl_req_packet *)(req->orig_req);
@@ -207,14 +202,12 @@ tw_cli_submit_cmd(struct tw_cli_req_cont
 					"pending internal/ioctl request");
 				req->state = TW_CLI_REQ_STATE_PENDING;
 				tw_cli_req_q_insert_tail(req, TW_CLI_PENDING_Q);
-				error = 0;
 				/* Unmask command interrupt. */
 				TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
 					TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
 			} else
 				error = TW_OSL_EBUSY;
 		} else {
-			tw_osl_ctlr_busy(ctlr_handle, req->req_handle);
 			error = TW_OSL_EBUSY;
 		}
 	} else {
@@ -246,7 +239,7 @@ tw_cli_submit_cmd(struct tw_cli_req_cont
 						 (TW_UINT32)(req->cmd_pkt_phys + sizeof(struct tw_cl_command_header)), 4);
 		}
 	}
-out:
+
 	tw_osl_free_lock(ctlr_handle, ctlr->io_lock);
 
 	return(error);
@@ -277,18 +270,12 @@ tw_cl_fw_passthru(struct tw_cl_ctlr_hand
 	TW_UINT8				opcode;
 	TW_UINT8				sgl_offset;
 	TW_VOID					*sgl = TW_CL_NULL;
-	TW_INT32				error;
+	TW_INT32				error = TW_CL_ERR_REQ_SUCCESS;
 
 	tw_cli_dbg_printf(5, ctlr_handle, tw_osl_cur_func(), "entered");
 
 	ctlr = (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
 
-	if (ctlr->reset_in_progress) {
-		tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
-			"Passthru request during reset: returning busy.");
-		return(TW_OSL_EBUSY);
-	}
-
 	if ((req = tw_cli_get_request(ctlr
 		)) == TW_CL_NULL) {
 		tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
@@ -301,7 +288,7 @@ tw_cl_fw_passthru(struct tw_cl_ctlr_hand
 	req->orig_req = req_pkt;
 	req->tw_cli_callback = tw_cli_complete_io;
 
-	req->flags |= (TW_CLI_REQ_FLAGS_EXTERNAL | TW_CLI_REQ_FLAGS_PASSTHRU);
+	req->flags |= TW_CLI_REQ_FLAGS_PASSTHRU;
 
 	pt_req = &(req_pkt->gen_req_pkt.pt_req);
 
@@ -348,7 +335,12 @@ tw_cl_fw_passthru(struct tw_cl_ctlr_hand
 		tw_cli_fill_sg_list(ctlr, pt_req->sg_list,
 			sgl, pt_req->sgl_entries);
 
-	if ((error = tw_cli_submit_cmd(req))) {
+	if (((TW_CL_Q_FIRST_ITEM(&(ctlr->req_q_head[TW_CLI_PENDING_Q]))) != TW_CL_NULL) ||
+		(ctlr->reset_in_progress)) {
+		tw_cli_req_q_insert_tail(req, TW_CLI_PENDING_Q);
+		TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
+			TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
+	} else if ((error = tw_cli_submit_cmd(req))) {
 		tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
 			TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
 			0x1100, 0x1, TW_CL_SEVERITY_ERROR_STRING,
@@ -760,8 +752,7 @@ tw_cli_get_param(struct tw_cli_ctlr_cont
 
 	cmd->param.sgl_off__opcode =
 		BUILD_SGL_OFF__OPCODE(2, TWA_FW_CMD_GET_PARAM);
-	cmd->param.request_id =
-		(TW_UINT8)(TW_CL_SWAP16(req->request_id));
+	cmd->param.request_id = (TW_UINT8)(TW_CL_SWAP16(req->request_id));
 	cmd->param.host_id__unit = BUILD_HOST_ID__UNIT(0, 0);
 	cmd->param.param_count = TW_CL_SWAP16(1);
 
@@ -789,15 +780,14 @@ tw_cli_get_param(struct tw_cli_ctlr_cont
 		/* There's no call back; wait till the command completes. */
 		error = tw_cli_submit_and_poll_request(req,
 				TW_CLI_REQUEST_TIMEOUT_PERIOD);
-		if (error == TW_OSL_ETIMEDOUT)
-			/* Clean-up done by tw_cli_submit_and_poll_request. */
-			return(error);
 		if (error)
 			goto out;
 		if ((error = cmd->param.status)) {
+#if       0
 			tw_cli_create_ctlr_event(ctlr,
 				TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
 				&(req->cmd_pkt->cmd_hdr));
+#endif // 0
 			goto out;
 		}
 		tw_osl_memcpy(param_data, param->data, param_size);
@@ -905,18 +895,17 @@ tw_cli_set_param(struct tw_cli_ctlr_cont
 
 	/* Submit the command. */
 	if (callback == TW_CL_NULL) {
-		/* There's no call back;  wait till the command completes. */
+		/* There's no call back; wait till the command completes. */
 		error = tw_cli_submit_and_poll_request(req,
-			TW_CLI_REQUEST_TIMEOUT_PERIOD);
-		if (error == TW_OSL_ETIMEDOUT)
-			/* Clean-up done by tw_cli_submit_and_poll_request. */
-			return(error);
+				TW_CLI_REQUEST_TIMEOUT_PERIOD);
 		if (error)
 			goto out;
 		if ((error = cmd->param.status)) {
+#if       0
 			tw_cli_create_ctlr_event(ctlr,
 				TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
 				&(req->cmd_pkt->cmd_hdr));
+#endif // 0
 			goto out;
 		}
 		ctlr->internal_req_busy = TW_CL_FALSE;
@@ -1022,9 +1011,7 @@ tw_cli_submit_and_poll_request(struct tw
 	 * tw_cli_submit_pending_queue.  There could be a race in that case.
 	 * Need to revisit.
 	 */
-	if (req->state != TW_CLI_REQ_STATE_PENDING)
-		tw_cl_reset_ctlr(ctlr->ctlr_handle);
-	else {
+	if (req->state == TW_CLI_REQ_STATE_PENDING) {
 		tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(),
 			"Removing request from pending queue");
 		/*
@@ -1053,6 +1040,7 @@ tw_cli_submit_and_poll_request(struct tw
  *			drains any incomplete requests.
  *
  * Input:		ctlr	-- ptr to per ctlr structure
+ * 			req_handle	-- ptr to request handle
  * Output:		None
  * Return value:	0	-- success
  *			non-zero-- failure
@@ -1063,15 +1051,15 @@ tw_cl_reset_ctlr(struct tw_cl_ctlr_handl
 	struct tw_cli_ctlr_context	*ctlr =
 		(struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
 	struct twa_softc		*sc = ctlr_handle->osl_ctlr_ctxt;
+	struct tw_cli_req_context	*req;
 	TW_INT32			reset_attempt = 1;
-	TW_INT32			error;
+	TW_INT32			error = 0;
 
 	tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(), "entered");
 
 	ctlr->reset_in_progress = TW_CL_TRUE;
-	xpt_freeze_simq(sc->sim, 1);
+	twa_teardown_intr(sc);
 
-	tw_cli_disable_interrupts(ctlr);
 
 	/*
 	 * Error back all requests in the complete, busy, and pending queues.
@@ -1080,8 +1068,6 @@ tw_cl_reset_ctlr(struct tw_cl_ctlr_handl
 	 * will continue its course and get submitted to the controller after
 	 * the reset is done (and io_lock is released).
 	 */
-	tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
-		"Draining all queues following reset");
 	tw_cli_drain_complete_queue(ctlr);
 	tw_cli_drain_busy_queue(ctlr);
 	tw_cli_drain_pending_queue(ctlr);
@@ -1089,53 +1075,88 @@ tw_cl_reset_ctlr(struct tw_cl_ctlr_handl
 	ctlr->get_more_aens     = TW_CL_FALSE;
 
 	/* Soft reset the controller. */
-try_reset:
-	if ((error = tw_cli_soft_reset(ctlr))) {
-		tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
-			TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
-			0x1105, 0x1, TW_CL_SEVERITY_ERROR_STRING,
-			"Controller reset failed",
-			"error = %d; attempt %d", error, reset_attempt++);
-		if (reset_attempt <= TW_CLI_MAX_RESET_ATTEMPTS)
-			goto try_reset;
-		else
-			goto out;
-	}
+	while (reset_attempt <= TW_CLI_MAX_RESET_ATTEMPTS) {
+		if ((error = tw_cli_soft_reset(ctlr))) {
+			tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
+				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
+				0x1105, 0x1, TW_CL_SEVERITY_ERROR_STRING,
+				"Controller reset failed",
+				"error = %d; attempt %d", error, reset_attempt++);
+			reset_attempt++;
+			continue;
+		}
 
-	/* Re-establish logical connection with the controller. */
-	if ((error = tw_cli_init_connection(ctlr,
-			(TW_UINT16)(ctlr->max_simult_reqs),
-			0, 0, 0, 0, 0, TW_CL_NULL, TW_CL_NULL, TW_CL_NULL,
-			TW_CL_NULL, TW_CL_NULL))) {
-		tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
+		/* Re-establish logical connection with the controller. */
+		if ((error = tw_cli_init_connection(ctlr,
+				(TW_UINT16)(ctlr->max_simult_reqs),
+				0, 0, 0, 0, 0, TW_CL_NULL, TW_CL_NULL, TW_CL_NULL,
+				TW_CL_NULL, TW_CL_NULL))) {
+			tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
+				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
+				0x1106, 0x1, TW_CL_SEVERITY_ERROR_STRING,
+				"Can't initialize connection after reset",
+				"error = %d", error);
+			reset_attempt++;
+			continue;
+		}
+
+#ifdef    TW_OSL_DEBUG
+		tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
 			TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
-			0x1106, 0x1, TW_CL_SEVERITY_ERROR_STRING,
-			"Can't initialize connection after reset",
-			"error = %d", error);
-		goto out;
-	}
+			0x1107, 0x3, TW_CL_SEVERITY_INFO_STRING,
+			"Controller reset done!", " ");
+#endif /* TW_OSL_DEBUG */
+		break;
+	} /* End of while */
 
-	tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
-		TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
-		0x1107, 0x3, TW_CL_SEVERITY_INFO_STRING,
-		"Controller reset done!",
-		" ");
+	/* Move commands from the reset queue to the pending queue. */
+	while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_RESET_Q)) != TW_CL_NULL) {
+		tw_osl_timeout(req->req_handle);
+		tw_cli_req_q_insert_tail(req, TW_CLI_PENDING_Q);
+	}
 
-out:
+	twa_setup_intr(sc);
+	tw_cli_enable_interrupts(ctlr);
+	if ((TW_CL_Q_FIRST_ITEM(&(ctlr->req_q_head[TW_CLI_PENDING_Q]))) != TW_CL_NULL)
+		TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
+			TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
 	ctlr->reset_in_progress = TW_CL_FALSE;
-	xpt_release_simq(sc->sim, 1);
+	ctlr->reset_needed = TW_CL_FALSE;
 
-	/*
-	 * Enable interrupts, and also clear attention and response interrupts.
-	 */
-	tw_cli_enable_interrupts(ctlr);
-	
 	/* Request for a bus re-scan. */
-	if (!error)
-		tw_osl_scan_bus(ctlr_handle);
+	tw_osl_scan_bus(ctlr_handle);
+
 	return(error);
 }
 
+TW_VOID
+tw_cl_set_reset_needed(struct tw_cl_ctlr_handle *ctlr_handle)
+{
+	struct tw_cli_ctlr_context	*ctlr =
+		(struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
+
+	ctlr->reset_needed = TW_CL_TRUE;
+}
+
+TW_INT32
+tw_cl_is_reset_needed(struct tw_cl_ctlr_handle *ctlr_handle)
+{
+	struct tw_cli_ctlr_context	*ctlr =
+		(struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
+
+	return(ctlr->reset_needed);
+}
+
+TW_INT32
+tw_cl_is_active(struct tw_cl_ctlr_handle *ctlr_handle)
+{
+	struct tw_cli_ctlr_context	*ctlr =
+		(struct tw_cli_ctlr_context *)
+		(ctlr_handle->cl_ctlr_ctxt);
+
+		return(ctlr->active);
+}
+
 
 
 /*
@@ -1151,14 +1172,13 @@ TW_INT32
 tw_cli_soft_reset(struct tw_cli_ctlr_context *ctlr)
 {
 	struct tw_cl_ctlr_handle	*ctlr_handle = ctlr->ctlr_handle;
-	TW_UINT32			status_reg;
 	int				found;
 	int				loop_count;
 	TW_UINT32			error;
 
 	tw_cli_dbg_printf(1, ctlr_handle, tw_osl_cur_func(), "entered");
 
-	tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
+	tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
 		TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
 		0x1108, 0x3, TW_CL_SEVERITY_INFO_STRING,
 		"Resetting controller...",
@@ -1193,7 +1213,7 @@ tw_cli_soft_reset(struct tw_cli_ctlr_con
 		} while (!found && (loop_count < 6000000)); /* Loop for no more than 60 seconds */
 
 		if (!found) {
-			tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
+			tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
 				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
 				0x1109, 0x1, TW_CL_SEVERITY_ERROR_STRING,
 				"Missed firmware handshake after soft-reset",
@@ -1210,7 +1230,7 @@ tw_cli_soft_reset(struct tw_cli_ctlr_con
 			TWA_STATUS_MICROCONTROLLER_READY |
 			TWA_STATUS_ATTENTION_INTERRUPT,
 			TW_CLI_RESET_TIMEOUT_PERIOD))) {
-		tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
+		tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
 			TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
 			0x1109, 0x1, TW_CL_SEVERITY_ERROR_STRING,
 			"Micro-ctlr not ready/No attn intr after reset",
@@ -1244,26 +1264,14 @@ tw_cli_soft_reset(struct tw_cli_ctlr_con
 	}
 	
 	if ((error = tw_cli_find_aen(ctlr, TWA_AEN_SOFT_RESET))) {
-		tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
+		tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
 			TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
 			0x110C, 0x1, TW_CL_SEVERITY_ERROR_STRING,
 			"Reset not reported by controller",
 			"error = %d", error);
 		return(error);
 	}
-	
-	status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr_handle);
-	
-	if ((error = TW_CLI_STATUS_ERRORS(status_reg)) ||
-			(error = tw_cli_check_ctlr_state(ctlr, status_reg))) {
-		tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
-			TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
-			0x110D, 0x1, TW_CL_SEVERITY_ERROR_STRING,
-			"Controller errors detected after reset",
-			"error = %d", error);
-		return(error);
-	}
-	
+
 	return(TW_OSL_ESUCCESS);
 }
 

Modified: stable/7/sys/dev/twa/tw_cl_misc.c
==============================================================================
--- stable/7/sys/dev/twa/tw_cl_misc.c	Wed Sep 15 17:25:09 2010	(r212677)
+++ stable/7/sys/dev/twa/tw_cl_misc.c	Wed Sep 15 17:25:51 2010	(r212678)
@@ -83,7 +83,8 @@ tw_cli_drain_complete_queue(struct tw_cl
 	tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
 
 	/* Walk the busy queue. */
-	while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_COMPLETE_Q))) {
+	while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_COMPLETE_Q)) !=
+		TW_CL_NULL) {
 		if (req->flags & TW_CLI_REQ_FLAGS_INTERNAL) {
 			/*
 			 * It's an internal request.  Set the appropriate
@@ -97,20 +98,21 @@ tw_cli_drain_complete_queue(struct tw_cl
 			req->error_code = TW_CL_ERR_REQ_BUS_RESET;
 			if (req->tw_cli_callback)
 				req->tw_cli_callback(req);
-		} else {
-			if ((req_pkt = req->orig_req)) {
-				/* It's a SCSI request.  Complete it. */
-				tw_cli_dbg_printf(2, ctlr->ctlr_handle,
-					tw_osl_cur_func(),
-					"Completing complete request %p "
-					"on reset",
-					req);
+		} else if (req->flags & TW_CLI_REQ_FLAGS_PASSTHRU) {
+			/* It's a passthru request.  Complete it. */
+			if ((req_pkt = req->orig_req) != TW_CL_NULL) {
 				req_pkt->status = TW_CL_ERR_REQ_BUS_RESET;
-				req_pkt->tw_osl_callback(req->req_handle);
+
+				if (req_pkt->tw_osl_callback)
+					req_pkt->tw_osl_callback(req->req_handle);
 			}
 			tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
+		} else {
+			/* It's an external (SCSI) request.  Add it to the reset queue. */
+			tw_osl_untimeout(req->req_handle);
+			tw_cli_req_q_insert_tail(req, TW_CLI_RESET_Q);
 		}
-	}
+	} /* End of while loop */
 }
 
 
@@ -135,7 +137,8 @@ tw_cli_drain_busy_queue(struct tw_cli_ct
 	tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
 
 	/* Walk the busy queue. */
-	while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_BUSY_Q))) {
+	while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_BUSY_Q)) !=
+		TW_CL_NULL) {
 		if (req->flags & TW_CLI_REQ_FLAGS_INTERNAL) {
 			/*
 			 * It's an internal request.  Set the appropriate
@@ -149,19 +152,21 @@ tw_cli_drain_busy_queue(struct tw_cli_ct
 			req->error_code = TW_CL_ERR_REQ_BUS_RESET;
 			if (req->tw_cli_callback)
 				req->tw_cli_callback(req);
-		} else {
-			if ((req_pkt = req->orig_req)) {
-				/* It's a SCSI request.  Complete it. */
-				tw_cli_dbg_printf(2, ctlr->ctlr_handle,
-					tw_osl_cur_func(),
-					"Completing busy request %p on reset",
-					req);
+		} else if (req->flags & TW_CLI_REQ_FLAGS_PASSTHRU) {
+			/* It's a passthru request.  Complete it. */
+			if ((req_pkt = req->orig_req) != TW_CL_NULL) {
 				req_pkt->status = TW_CL_ERR_REQ_BUS_RESET;
-				req_pkt->tw_osl_callback(req->req_handle);
+
+				if (req_pkt->tw_osl_callback)
+					req_pkt->tw_osl_callback(req->req_handle);
 			}
 			tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
+		} else {
+			/* It's an external (SCSI) request.  Add it to the reset queue. */
+			tw_osl_untimeout(req->req_handle);
+			tw_cli_req_q_insert_tail(req, TW_CLI_RESET_Q);
 		}
-	}
+	} /* End of while loop */
 }
 
 
@@ -188,7 +193,8 @@ tw_cli_drain_pending_queue(struct tw_cli
 	/*
 	 * Pull requests off the pending queue, and complete them.
 	 */
-	while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_PENDING_Q))) {
+	while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_PENDING_Q)) !=
+		TW_CL_NULL) {
 		if (req->flags & TW_CLI_REQ_FLAGS_INTERNAL) {
 			/*
 			 * It's an internal request.  Set the appropriate
@@ -202,19 +208,21 @@ tw_cli_drain_pending_queue(struct tw_cli
 			req->error_code = TW_CL_ERR_REQ_BUS_RESET;
 			if (req->tw_cli_callback)
 				req->tw_cli_callback(req);
-		} else {
-			if ((req_pkt = req->orig_req)) {
-				/* It's an external request.  Complete it. */
-				tw_cli_dbg_printf(2, ctlr->ctlr_handle,
-					tw_osl_cur_func(),
-					"Completing pending request %p "
-					"on reset", req);
+		} else if (req->flags & TW_CLI_REQ_FLAGS_PASSTHRU) {
+			/* It's a passthru request.  Complete it. */
+			if ((req_pkt = req->orig_req) != TW_CL_NULL) {
 				req_pkt->status = TW_CL_ERR_REQ_BUS_RESET;
-				req_pkt->tw_osl_callback(req->req_handle);
+
+				if (req_pkt->tw_osl_callback)
+					req_pkt->tw_osl_callback(req->req_handle);
 			}
 			tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
+		} else {
+			/* It's an external (SCSI) request.  Add it to the reset queue. */
+			tw_osl_untimeout(req->req_handle);
+			tw_cli_req_q_insert_tail(req, TW_CLI_RESET_Q);
 		}
-	}
+	} /* End of while loop */
 }
 
 
@@ -239,9 +247,6 @@ tw_cli_drain_response_queue(struct tw_cl
 	for (;;) {
 		status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr->ctlr_handle);
 
-		if (tw_cli_check_ctlr_state(ctlr, status_reg))
-			return(TW_OSL_EGENFAILURE);
-
 		if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY)
 			return(TW_OSL_ESUCCESS); /* no more response queue entries */
 
@@ -273,9 +278,6 @@ tw_cli_find_response(struct tw_cli_ctlr_
 	for (;;) {
 		status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr->ctlr_handle);
 
-		if (tw_cli_check_ctlr_state(ctlr, status_reg))
-			return(TW_OSL_EGENFAILURE);
-
 		if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY)
 			return(TW_OSL_ENOTTY); /* no more response queue entries */
 
@@ -356,9 +358,11 @@ tw_cli_drain_aen_queue(struct tw_cli_ctl
 
 		if ((error = req->cmd_pkt->command.cmd_pkt_9k.status)) {
 			cmd_hdr = &req->cmd_pkt->cmd_hdr;
+#if       0
 			tw_cli_create_ctlr_event(ctlr,
 				TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
 				cmd_hdr);
+#endif // 0
 			break;
 		}
 
@@ -714,7 +718,7 @@ tw_cli_check_ctlr_state(struct tw_cli_ct
 
 		tw_osl_memzero(desc, 200);
 		if (!(ctlr->reset_phase1_in_progress)) {
-			tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
+			tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
 				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
 				0x1301, 0x1, TW_CL_SEVERITY_ERROR_STRING,
 				"Missing expected status bit(s)",
@@ -738,7 +742,7 @@ tw_cli_check_ctlr_state(struct tw_cli_ct
 		     (ctlr->device_id != TW_CL_DEVICE_ID_9K_SA)) ||
 		    (!(ctlr->reset_in_progress)) ||
 		    ((status_reg & TWA_STATUS_QUEUE_ERROR_INTERRUPT) == 0))
-		tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
+		tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
 			TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
 			0x1302, 0x1, TW_CL_SEVERITY_ERROR_STRING,
 			"Unexpected status bit(s)",
@@ -748,7 +752,7 @@ tw_cli_check_ctlr_state(struct tw_cli_ct
 				TWA_STATUS_UNEXPECTED_BITS, desc));
 
 		if (status_reg & TWA_STATUS_PCI_PARITY_ERROR_INTERRUPT) {
-			tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
+			tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
 				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
 				0x1303, 0x1, TW_CL_SEVERITY_ERROR_STRING,
 				"PCI parity error: clearing... "
@@ -768,7 +772,7 @@ tw_cli_check_ctlr_state(struct tw_cli_ct
 		}
 
 		if (status_reg & TWA_STATUS_PCI_ABORT_INTERRUPT) {
-			tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
+			tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
 				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
 				0x1304, 0x1, TW_CL_SEVERITY_ERROR_STRING,
 				"PCI abort: clearing... ",
@@ -791,7 +795,7 @@ tw_cli_check_ctlr_state(struct tw_cli_ct
 			if (((ctlr->device_id != TW_CL_DEVICE_ID_9K_E) &&
 			     (ctlr->device_id != TW_CL_DEVICE_ID_9K_SA)) ||
 			    (!(ctlr->reset_in_progress)))
-				tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
+				tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
 						   TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
 						   0x1305, 0x1, TW_CL_SEVERITY_ERROR_STRING,
 						   "Controller queue error: clearing... ",
@@ -801,17 +805,6 @@ tw_cli_check_ctlr_state(struct tw_cli_ct
 			TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
 				TWA_CONTROL_CLEAR_QUEUE_ERROR);
 		}
-
-		if (status_reg & TWA_STATUS_MICROCONTROLLER_ERROR) {
-			tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
-				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
-				0x1307, 0x1, TW_CL_SEVERITY_ERROR_STRING,
-				"Micro-controller error! ",
-				"status reg = 0x%x %s",
-				status_reg,
-				tw_cli_describe_bits(status_reg, desc));
-			error = TW_OSL_EGENFAILURE;
-		}
 	}
 	return(error);
 }	
@@ -850,8 +843,6 @@ tw_cli_describe_bits(TW_UINT32 reg, TW_I
 		tw_osl_strcpy(&str[tw_osl_strlen(str)], "HOST_INTR,");
 	if (reg & TWA_STATUS_PCI_ABORT_INTERRUPT)
 		tw_osl_strcpy(&str[tw_osl_strlen(str)], "PCI_ABRT,");
-	if (reg & TWA_STATUS_MICROCONTROLLER_ERROR)
-		tw_osl_strcpy(&str[tw_osl_strlen(str)], "MC_ERR,");
 	if (reg & TWA_STATUS_QUEUE_ERROR_INTERRUPT)
 		tw_osl_strcpy(&str[tw_osl_strlen(str)], "Q_ERR,");
 	if (reg & TWA_STATUS_PCI_PARITY_ERROR_INTERRUPT)

Modified: stable/7/sys/dev/twa/tw_cl_share.h
==============================================================================
--- stable/7/sys/dev/twa/tw_cl_share.h	Wed Sep 15 17:25:09 2010	(r212677)
+++ stable/7/sys/dev/twa/tw_cl_share.h	Wed Sep 15 17:25:51 2010	(r212678)
@@ -349,10 +349,14 @@ extern TW_VOID	tw_osl_breakpoint(TW_VOID
 #endif
 
 
-#ifndef tw_osl_ctlr_busy
-/* Called when CL is too busy to accept new requests. */
-extern TW_VOID	tw_osl_ctlr_busy(struct tw_cl_ctlr_handle *ctlr_handle,
-	struct tw_cl_req_handle *req_handle);
+#ifndef tw_osl_timeout
+/* Start OS timeout() routine after controller reset sequence */
+extern TW_VOID	tw_osl_timeout(struct tw_cl_req_handle *req_handle);
+#endif
+
+#ifndef tw_osl_untimeout
+/* Stop OS timeout() routine during controller reset sequence */
+extern TW_VOID	tw_osl_untimeout(struct tw_cl_req_handle *req_handle);
 #endif
 
 
@@ -552,6 +556,10 @@ extern TW_INT32	tw_cl_init_ctlr(struct t
 	);
 
 
+extern TW_VOID  tw_cl_set_reset_needed(struct tw_cl_ctlr_handle *ctlr_handle);
+extern TW_INT32 tw_cl_is_reset_needed(struct tw_cl_ctlr_handle *ctlr_handle);
+extern TW_INT32 tw_cl_is_active(struct tw_cl_ctlr_handle *ctlr_handle);
+
 /* CL's interrupt handler. */
 extern TW_INT32	tw_cl_interrupt(struct tw_cl_ctlr_handle *ctlr_handle);
 

Modified: stable/7/sys/dev/twa/tw_osl.h
==============================================================================
--- stable/7/sys/dev/twa/tw_osl.h	Wed Sep 15 17:25:09 2010	(r212677)
+++ stable/7/sys/dev/twa/tw_osl.h	Wed Sep 15 17:25:51 2010	(r212678)
@@ -77,6 +77,7 @@
 						EINPROGRESS */
 #define TW_OSLI_REQ_FLAGS_PASSTHRU	(1<<5)	/* pass through request */
 #define TW_OSLI_REQ_FLAGS_SLEEPING	(1<<6)	/* owner sleeping on this cmd */
+#define TW_OSLI_REQ_FLAGS_FAILED	(1<<7)	/* bus_dmamap_load() failed */
 
 
 #ifdef TW_OSL_DEBUG
@@ -100,6 +101,7 @@ struct tw_osli_req_context {
 	struct twa_softc	*ctlr;	/* ptr to OSL's controller context */
 	TW_VOID			*data;	/* ptr to data being passed to CL */
 	TW_UINT32		length;	/* length of buf being passed to CL */
+	TW_UINT64		deadline;/* request timeout (in absolute time) */
 
 	/*
 	 * ptr to, and length of data passed to us from above, in case a buffer
@@ -151,6 +153,9 @@ struct twa_softc {
 	struct mtx		sim_lock_handle;/* sim lock shared with cam */
 	struct mtx		*sim_lock;/* ptr to sim lock */
 
+	struct callout		watchdog_callout[2]; /* For command timout */
+	TW_UINT32		watchdog_index;
+
 #ifdef TW_OSL_DEBUG
 	struct tw_osli_q_stats	q_stats[TW_OSLI_Q_COUNT];/* queue statistics */
 #endif /* TW_OSL_DEBUG */

Modified: stable/7/sys/dev/twa/tw_osl_cam.c
==============================================================================
--- stable/7/sys/dev/twa/tw_osl_cam.c	Wed Sep 15 17:25:09 2010	(r212677)
+++ stable/7/sys/dev/twa/tw_osl_cam.c	Wed Sep 15 17:25:51 2010	(r212678)
@@ -55,7 +55,6 @@
 
 static TW_VOID	twa_action(struct cam_sim *sim, union ccb *ccb);
 static TW_VOID	twa_poll(struct cam_sim *sim);
-static TW_VOID	twa_timeout(TW_VOID *arg);
 static TW_VOID	twa_bus_scan_cb(struct cam_periph *periph, union ccb *ccb);
 
 static TW_INT32	tw_osli_execute_scsi(struct tw_osli_req_context *req,
@@ -83,7 +82,7 @@ tw_osli_cam_attach(struct twa_softc *sc)
 	/*
 	 * Create the device queue for our SIM.
 	 */
-	if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_REQUESTS)) == NULL) {
+	if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_IOS)) == NULL) {
 		tw_osli_printf(sc, "error = %d",
 			TW_CL_SEVERITY_ERROR_STRING,
 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
@@ -292,6 +291,7 @@ tw_osli_execute_scsi(struct tw_osli_req_
 					"I/O size too big",
 					csio->dxfer_len);
 				ccb_h->status = CAM_REQ_TOO_BIG;
+				ccb_h->status &= ~CAM_SIM_QUEUED;
 				xpt_done(ccb);
 				return(1);
 			}
@@ -307,6 +307,7 @@ tw_osli_execute_scsi(struct tw_osli_req_
 				0x2107,
 				"XPT_SCSI_IO: Got SGList");
 			ccb_h->status = CAM_REQ_INVALID;
+			ccb_h->status &= ~CAM_SIM_QUEUED;
 			xpt_done(ccb);
 			return(1);
 		}
@@ -323,13 +324,20 @@ tw_osli_execute_scsi(struct tw_osli_req_
 		return(1);
 	}
 
-	ccb_h->timeout_ch = timeout(twa_timeout, req,
-		(ccb_h->timeout * hz) / 1000);
+	req->deadline = tw_osl_get_local_time() + (ccb_h->timeout / 1000);
+
+
 	/*
 	 * twa_map_load_data_callback will fill in the SGL,
 	 * and submit the I/O.
 	 */
 	error = tw_osli_map_request(req);
+	if ((error) && (req->flags & TW_OSLI_REQ_FLAGS_FAILED)) {
+		req->deadline = 0;
+		ccb_h->status = CAM_REQ_CMP_ERR;
+		ccb_h->status &= ~CAM_SIM_QUEUED;
+		xpt_done(ccb);
+	}
 	return(error);
 }
 
@@ -362,10 +370,20 @@ twa_action(struct cam_sim *sim, union cc
 			 * Freeze the simq to maintain ccb ordering.  The next
 			 * ccb that gets completed will unfreeze the simq.
 			 */
+			ccb_h->status &= ~CAM_SIM_QUEUED;
 			ccb_h->status |= CAM_REQUEUE_REQ;
 			xpt_done(ccb);
 			break;
 		}
+
+		if ((tw_cl_is_reset_needed(&(req->ctlr->ctlr_handle)))) {
+			ccb_h->status &= ~CAM_SIM_QUEUED;
+			ccb_h->status |= CAM_REQUEUE_REQ;
+			xpt_done(ccb);
+			tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
+			break;
+		}
+
 		req->req_handle.osl_req_ctxt = req;
 		req->req_handle.is_io = TW_CL_TRUE;
 		req->orig_req = ccb;
@@ -381,25 +399,14 @@ twa_action(struct cam_sim *sim, union cc
 		break;
 
 	case XPT_RESET_BUS:
-		tw_cl_create_event(&(sc->ctlr_handle), TW_CL_TRUE,
+		tw_cl_create_event(&(sc->ctlr_handle), TW_CL_FALSE,
 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
 			0x2108, 0x3, TW_CL_SEVERITY_INFO_STRING,
 			"Received Reset Bus request from CAM",
 			" ");
 
-		mtx_unlock(sc->sim_lock);
-		if (tw_cl_reset_ctlr(&sc->ctlr_handle)) {
-			tw_cl_create_event(&(sc->ctlr_handle), TW_CL_TRUE,
-				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
-				0x2109, 0x1, TW_CL_SEVERITY_ERROR_STRING,
-				"Failed to reset bus",
-				" ");
-			ccb_h->status = CAM_REQ_CMP_ERR;
-		}
-		else
-			ccb_h->status = CAM_REQ_CMP;
-
-		mtx_lock(sc->sim_lock);
+		tw_cl_set_reset_needed(&(sc->ctlr_handle));
+		ccb_h->status = CAM_REQ_CMP;
 		xpt_done(ccb);
 		break;
 
@@ -504,31 +511,6 @@ twa_poll(struct cam_sim *sim)
 
 
 /*
- * Function name:	twa_timeout
- * Description:		Driver entry point for being alerted on a request
- *			timing out.
- *
- * Input:		arg	-- ptr to timed out request
- * Output:		None
- * Return value:	None
- */
-static TW_VOID
-twa_timeout(TW_VOID *arg)
-{
-	struct tw_osli_req_context	*req =
-		(struct tw_osli_req_context *)arg;
-
-	tw_cl_create_event(&(req->ctlr->ctlr_handle), TW_CL_TRUE,
-		TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
-		0x210B, 0x1, TW_CL_SEVERITY_ERROR_STRING,
-		"Request timed out!",
-		"request = %p", req);
-	tw_cl_reset_ctlr(&(req->ctlr->ctlr_handle));
-}
-
-
-
-/*
  * Function name:	tw_osli_request_bus_scan
  * Description:		Requests CAM for a scan of the bus.
  *
@@ -623,20 +605,39 @@ tw_osli_disallow_new_requests(struct twa
 
 
 /*
- * Function name:	tw_osl_ctlr_busy
- * Description:		CL calls this function on cmd queue full or otherwise,
- *			when it is too busy to accept new requests.
+ * Function name:	tw_osl_timeout
+ * Description:		Call to timeout().
  *
- * Input:		ctlr_handle	-- ptr to controller handle
- *			req_handle	-- ptr to request handle sent by OSL.
+ * Input:		req_handle -- ptr to request handle sent by OSL.
  * Output:		None
  * Return value:	None
  */
 TW_VOID
-tw_osl_ctlr_busy(struct tw_cl_ctlr_handle *ctlr_handle,
-	struct tw_cl_req_handle *req_handle)
+tw_osl_timeout(struct tw_cl_req_handle *req_handle)
+{
+	struct tw_osli_req_context	*req = req_handle->osl_req_ctxt;
+	union ccb			*ccb = (union ccb *)(req->orig_req);
+	struct ccb_hdr			*ccb_h = &(ccb->ccb_h);
+
+	req->deadline = tw_osl_get_local_time() + (ccb_h->timeout / 1000);

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


More information about the svn-src-stable-7 mailing list