kern/147694: [PATCH] src/sys/dev/twa update

Tom Couch tom.couch at lsi.com
Tue Jun 8 19:00:18 UTC 2010


>Number:         147694
>Category:       kern
>Synopsis:       [PATCH] src/sys/dev/twa update
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          maintainer-update
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jun 08 19:00:16 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Tom Couch
>Release:        7.2-RELEASE-amd64-all
>Organization:
Tom Couch
>Environment:
FreeBSD MacSolaris4 7.2-RELEASE FreeBSD 7.2-RELEASE #13: Mon May 24 13:34:13 PDT 2010     tcouch at MacSolaris4:/usr/obj/usr/src/sys/MACSOLARIS4  amd64
>Description:
  1) Timeout ioctl command timeouts.
       Do not reset the controller if ioctl command completed successfully.
  2) Remove G66_WORKAROUND code (this bug never shipped).
  3) Remove unnecessary interrupt lock (intr_lock).
  4) Timeout firmware handshake for PChip reset (don't wait forever).
  5) Handle interrupts inline.
  6) Unmask command interrupt ONLY when adding a command to the pending queue.
  7) Mask command interrupt ONLY after removing the last command from the pending queue.
  8) Remove TW_OSLI_DEFERRED_INTR_USED code.
  9) Replace controller "state" with separate data fields to avoid races:
       TW_CLI_CTLR_STATE_ACTIVE                     ctlr->active
       TW_CLI_CTLR_STATE_INTR_ENABLED               ctlr->interrupts_enabled
       TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY          ctlr->internal_req_busy
       TW_CLI_CTLR_STATE_GET_MORE_AENS              ctlr->get_more_aens
       TW_CLI_CTLR_STATE_RESET_IN_PROGRESS          ctlr->reset_in_progress
       TW_CLI_CTLR_STATE_RESET_PHASE1_IN_PROGRESS   ctlr->reset_phase1_in_progress
 10) Fix "req" leak in twa_action() when simq is frozen and req is NOT null.  
 11) Replace softc "state" with separate data fields to avoid races:
       TW_OSLI_CTLR_STATE_OPEN                      sc->open
       TW_OSLI_CTLR_STATE_SIMQ_FROZEN               sc->simq_frozen
 12) Fix reference to TW_OSLI_REQ_FLAGS_IN_PROGRESS in tw_osl_complete_passthru()
 13) Use correct CAM status values.
       Change CAM_REQ_CMP_ERR to CAM_REQ_INVALID.
       Remove use of CAM_RELEASE_SIMQ for physical data addresses.
 14) Do not freeze/ release the simq with non I/O commands.
       When it is appropriate to temporarily freeze the simq with an I/O command use:
         xpt_freeze_simq(sim, 1);
         ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
       otherwise use:
         xpt_freeze_simq(sim, 1);
         xpt_release_simq(sim, 1);

>How-To-Repeat:

>Fix:


Patch attached with submission follows:

diff -u FreeBSD_RELENG_7_twa/tw_cl.h FreeBSD_7_development_twa/tw_cl.h
--- FreeBSD_RELENG_7_twa/tw_cl.h	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_cl.h	2010-06-07 15:07:02.000000000 -0700
@@ -51,22 +51,6 @@
 #define TW_CLI_RESET_TIMEOUT_PERIOD	60 /* seconds */
 #define TW_CLI_MAX_RESET_ATTEMPTS	2
 
-/* Possible values of ctlr->state. */
-/* Initialization done, and controller is active. */
-#define TW_CLI_CTLR_STATE_ACTIVE		(1<<0)
-/* Interrupts on controller enabled. */
-#define TW_CLI_CTLR_STATE_INTR_ENABLED		(1<<1)
-/* Data buffer for internal requests in use. */
-#define TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY	(1<<2)
-/* More AEN's need to be retrieved. */
-#define TW_CLI_CTLR_STATE_GET_MORE_AENS		(1<<3)
-/* Controller is being reset. */
-#define	TW_CLI_CTLR_STATE_RESET_IN_PROGRESS	(1<<4)
-/* G133 controller is in 'phase 1' of being reset. */
-#define TW_CLI_CTLR_STATE_RESET_PHASE1_IN_PROGRESS	(1<<5)
-/* G66 register write access bug needs to be worked around. */
-#define TW_CLI_CTLR_STATE_G66_WORKAROUND_NEEDED	(1<<6)
-
 /* Possible values of ctlr->ioctl_lock.lock. */
 #define TW_CLI_LOCK_FREE		0x0	/* lock is free */
 #define TW_CLI_LOCK_HELD		0x1	/* lock is held */
@@ -146,7 +130,12 @@
 
 	TW_UINT32		device_id;	/* controller device id */
 	TW_UINT32		arch_id;	/* controller architecture id */
-	TW_UINT32		state;		/* controller state */
+	TW_UINT8 		active;			  /* Initialization done, and controller is active. */
+	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_in_progress;	  /* Controller is being reset. */
+	TW_UINT8 		reset_phase1_in_progress; /* In 'phase 1' of reset. */
 	TW_UINT32		flags;		/* controller settings */
 	TW_UINT32		sg_size_factor;	/* SG element size should be a
 							multiple of this */
@@ -199,10 +188,6 @@
 						submission */
 	TW_LOCK_HANDLE		*io_lock;/* ptr to lock held during cmd
 						submission */
-	TW_LOCK_HANDLE		intr_lock_handle;/* lock held during
-						ISR/response intr processing */
-	TW_LOCK_HANDLE		*intr_lock;/* ptr to lock held during ISR/
-						response intr processing */
 
 #ifdef TW_OSL_CAN_SLEEP
 	TW_SLEEP_HANDLE		sleep_handle;	/* handle to co-ordinate sleeps
diff -u FreeBSD_RELENG_7_twa/tw_cl_fwif.h FreeBSD_7_development_twa/tw_cl_fwif.h
--- FreeBSD_RELENG_7_twa/tw_cl_fwif.h	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_cl_fwif.h	2010-06-07 15:07:02.000000000 -0700
@@ -89,7 +89,6 @@
 #define TWA_STATUS_MINOR_VERSION_MASK		0x0F000000
 #define TWA_STATUS_MAJOR_VERSION_MASK		0xF0000000
 
-#define TWA_STATUS_EXPECTED_BITS		0x00002000
 #define TWA_STATUS_UNEXPECTED_BITS		0x00F00000
 
 
@@ -142,7 +141,7 @@
 #define TWA_BASE_FW_SRL			24
 #define TWA_BASE_FW_BRANCH		0
 #define TWA_BASE_FW_BUILD		1
-#define TWA_CURRENT_FW_SRL		30
+#define TWA_CURRENT_FW_SRL		41
 #define TWA_CURRENT_FW_BRANCH_9K	4
 #define TWA_CURRENT_FW_BUILD_9K		8
 #define TWA_CURRENT_FW_BRANCH_9K_X	8
diff -u FreeBSD_RELENG_7_twa/tw_cl_init.c FreeBSD_7_development_twa/tw_cl_init.c
--- FreeBSD_RELENG_7_twa/tw_cl_init.c	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_cl_init.c	2010-06-07 15:07:02.000000000 -0700
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/twa/tw_cl_init.c,v 1.4.2.1 2009/03/30 18:43:41 jhb Exp $
+ *	$FreeBSD: src/sys/dev/twa/tw_cl_init.c,v 1.4 2007/10/09 17:43:57 scottl Exp $
  */
 
 /*
@@ -208,7 +208,7 @@
 	 */
 
 	*non_dma_mem_size = sizeof(struct tw_cli_ctlr_context) +
-		(sizeof(struct tw_cli_req_context) * (max_simult_reqs + 1)) +
+		(sizeof(struct tw_cli_req_context) * max_simult_reqs) +
 		(sizeof(struct tw_cl_event_packet) * max_aens);
 
 
@@ -220,7 +220,7 @@
 	 */
 
 	*dma_mem_size = (sizeof(struct tw_cl_command_packet) *
-		(max_simult_reqs + 1)) + (TW_CLI_SECTOR_SIZE);
+		(max_simult_reqs)) + (TW_CLI_SECTOR_SIZE);
 
 	return(0);
 }
@@ -287,12 +287,12 @@
 	}
 
 	tw_osl_memzero(non_dma_mem, sizeof(struct tw_cli_ctlr_context) +
-		(sizeof(struct tw_cli_req_context) * (max_simult_reqs + 1)) +
+		(sizeof(struct tw_cli_req_context) * max_simult_reqs) +
 		(sizeof(struct tw_cl_event_packet) * max_aens));
 
 	tw_osl_memzero(dma_mem,
 		(sizeof(struct tw_cl_command_packet) *
-		(max_simult_reqs + 1)) +
+		max_simult_reqs) +
 		TW_CLI_SECTOR_SIZE);
 
 	free_non_dma_mem = (TW_UINT8 *)non_dma_mem;
@@ -307,7 +307,7 @@
 	ctlr->arch_id = TWA_ARCH_ID(device_id);
 	ctlr->flags = flags;
 	ctlr->sg_size_factor = TWA_SG_ELEMENT_SIZE_FACTOR(device_id);
-	ctlr->max_simult_reqs = max_simult_reqs + 1;
+	ctlr->max_simult_reqs = max_simult_reqs;
 	ctlr->max_aens_supported = max_aens;
 
 	/* Initialize queues of CL internal request context packets. */
@@ -321,55 +321,23 @@
 	tw_osl_init_lock(ctlr_handle, "tw_cl_gen_lock", ctlr->gen_lock);
 	ctlr->io_lock = &(ctlr->io_lock_handle);
 	tw_osl_init_lock(ctlr_handle, "tw_cl_io_lock", ctlr->io_lock);
-	/*
-	 * If 64 bit cmd pkt addresses are used, we will need to serialize
-	 * writes to the hardware (across registers), since existing (G66)
-	 * hardware will get confused if, for example, we wrote the low 32 bits
-	 * of the cmd pkt address, followed by a response interrupt mask to the
-	 * control register, followed by the high 32 bits of the cmd pkt
-	 * address.  It will then interpret the value written to the control
-	 * register as the low cmd pkt address.  So, for this case, we will
-	 * make a note that we will need to synchronize control register writes
-	 * with command register writes.
-	 */
-	if ((ctlr->flags & TW_CL_64BIT_ADDRESSES) &&
-	    ((ctlr->device_id == TW_CL_DEVICE_ID_9K) ||
-	     (ctlr->device_id == TW_CL_DEVICE_ID_9K_X) ||
-	     (ctlr->device_id == TW_CL_DEVICE_ID_9K_E) ||
-	     (ctlr->device_id == TW_CL_DEVICE_ID_9K_SA))) {
-		ctlr->state |= TW_CLI_CTLR_STATE_G66_WORKAROUND_NEEDED;
-		ctlr->intr_lock = ctlr->io_lock;
-	} else {
-		ctlr->intr_lock = &(ctlr->intr_lock_handle);
-		tw_osl_init_lock(ctlr_handle, "tw_cl_intr_lock",
-			ctlr->intr_lock);
-	}
 
 	/* Initialize CL internal request context packets. */
 	ctlr->req_ctxt_buf = (struct tw_cli_req_context *)free_non_dma_mem;
 	free_non_dma_mem += (sizeof(struct tw_cli_req_context) *
-		(
-		max_simult_reqs +
-		1));
+		max_simult_reqs);
 
 	ctlr->cmd_pkt_buf = (struct tw_cl_command_packet *)dma_mem;
 	ctlr->cmd_pkt_phys = dma_mem_phys;
 
 	ctlr->internal_req_data = (TW_UINT8 *)
 		(ctlr->cmd_pkt_buf +
-		(
-		max_simult_reqs +
-		1));
+		max_simult_reqs);
 	ctlr->internal_req_data_phys = ctlr->cmd_pkt_phys +
 		(sizeof(struct tw_cl_command_packet) *
-		(
-		max_simult_reqs +
-		1));
-
-	for (i = 0;
-		i < (
-		max_simult_reqs +
-		1); i++) {
+		max_simult_reqs);
+
+	for (i = 0; i < max_simult_reqs; i++) {
 		req = &(ctlr->req_ctxt_buf[i]);
 
 		req->cmd_pkt = &(ctlr->cmd_pkt_buf[i]);
@@ -421,8 +389,8 @@
 	/* Notify some info about the controller to the OSL. */
 	tw_cli_notify_ctlr_info(ctlr);
 
-	/* Mark the controller as active. */
-	ctlr->state |= TW_CLI_CTLR_STATE_ACTIVE;
+	/* Mark the controller active. */
+	ctlr->active = TW_CL_TRUE;
 	return(error);
 }
 
@@ -597,7 +565,7 @@
 	 * Mark the controller as inactive, disable any further interrupts,
 	 * and notify the controller that we are going down.
 	 */
-	ctlr->state &= ~TW_CLI_CTLR_STATE_ACTIVE;
+	ctlr->active = TW_CL_FALSE;
 
 	tw_cli_disable_interrupts(ctlr);
 
@@ -617,8 +585,6 @@
 	/* Destroy all locks used by CL. */
 	tw_osl_destroy_lock(ctlr_handle, ctlr->gen_lock);
 	tw_osl_destroy_lock(ctlr_handle, ctlr->io_lock);
-	if (!(ctlr->flags & TW_CL_64BIT_ADDRESSES))
-		tw_osl_destroy_lock(ctlr_handle, ctlr->intr_lock);
 
 ret:
 	return(error);
diff -u FreeBSD_RELENG_7_twa/tw_cl_intr.c FreeBSD_7_development_twa/tw_cl_intr.c
--- FreeBSD_RELENG_7_twa/tw_cl_intr.c	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_cl_intr.c	2010-06-07 15:07:02.000000000 -0700
@@ -75,22 +75,16 @@
 	if (ctlr == NULL)
 		goto out;
 
-	/* If we get an interrupt while resetting, it is a shared
-	   one for another device, so just bail */
-	if (ctlr->state & TW_CLI_CTLR_STATE_RESET_IN_PROGRESS)
-		goto out;
-
 	/*
-	 * Synchronize access between writes to command and control registers
-	 * in 64-bit environments, on G66.
+	 * Bail If we get an interrupt while resetting, or shutting down.
 	 */
-	if (ctlr->state & TW_CLI_CTLR_STATE_G66_WORKAROUND_NEEDED)
-		tw_osl_get_lock(ctlr_handle, ctlr->io_lock);
+	if (ctlr->reset_in_progress || !(ctlr->active))
+		goto out;
 
 	/* Read the status register to determine the type of interrupt. */
 	status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr_handle);
 	if (tw_cli_check_ctlr_state(ctlr, status_reg))
-		goto out_unlock;
+		goto out;
 
 	/* Clear the interrupt. */
 	if (status_reg & TWA_STATUS_HOST_INTERRUPT) {
@@ -98,36 +92,30 @@
 			"Host interrupt");
 		TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
 			TWA_CONTROL_CLEAR_HOST_INTERRUPT);
-		ctlr->host_intr_pending = 0; /* we don't use this */
-		rc |= TW_CL_FALSE; /* don't request for a deferred isr call */
 	}
 	if (status_reg & TWA_STATUS_ATTENTION_INTERRUPT) {
 		tw_cli_dbg_printf(6, ctlr_handle, tw_osl_cur_func(),
 			"Attention interrupt");
+		rc |= TW_CL_TRUE; /* request for a deferred isr call */
+		tw_cli_process_attn_intr(ctlr);
 		TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
 			TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT);
-		ctlr->attn_intr_pending = 1;
-		rc |= TW_CL_TRUE; /* request for a deferred isr call */
 	}
 	if (status_reg & TWA_STATUS_COMMAND_INTERRUPT) {
 		tw_cli_dbg_printf(6, ctlr_handle, tw_osl_cur_func(),
 			"Command interrupt");
-		TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
-			TWA_CONTROL_MASK_COMMAND_INTERRUPT);
-		ctlr->cmd_intr_pending = 1;
 		rc |= TW_CL_TRUE; /* request for a deferred isr call */
+		tw_cli_process_cmd_intr(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_MASK_COMMAND_INTERRUPT);
 	}
 	if (status_reg & TWA_STATUS_RESPONSE_INTERRUPT) {
 		tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(),
 			"Response interrupt");
-		TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
-			TWA_CONTROL_MASK_RESPONSE_INTERRUPT);
-		ctlr->resp_intr_pending = 1;
 		rc |= TW_CL_TRUE; /* request for a deferred isr call */
+		tw_cli_process_resp_intr(ctlr);
 	}
-out_unlock:
-	if (ctlr->state & TW_CLI_CTLR_STATE_G66_WORKAROUND_NEEDED)
-		tw_osl_free_lock(ctlr_handle, ctlr->io_lock);
 out:
 	return(rc);
 }
@@ -135,52 +123,6 @@
 
 
 /*
- * Function name:	tw_cl_deferred_interrupt
- * Description:		Deferred interrupt handler.  Does most of the processing
- *			related to an interrupt.
- *
- * Input:		ctlr_handle	-- controller handle
- * Output:		None
- * Return value:	None
- */
-TW_VOID
-tw_cl_deferred_interrupt(struct tw_cl_ctlr_handle *ctlr_handle)
-{
-	struct tw_cli_ctlr_context	*ctlr =
-		(struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
-
-	tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), "entered");
-
-	/* Dispatch based on the kind of interrupt. */
-	if (ctlr->host_intr_pending) {
-		tw_cli_dbg_printf(6, ctlr_handle, tw_osl_cur_func(),
-			"Processing Host interrupt");
-		ctlr->host_intr_pending = 0;
-		tw_cli_process_host_intr(ctlr);
-	}
-	if (ctlr->attn_intr_pending) {
-		tw_cli_dbg_printf(6, ctlr_handle, tw_osl_cur_func(),
-			"Processing Attention interrupt");
-		ctlr->attn_intr_pending = 0;
-		tw_cli_process_attn_intr(ctlr);
-	}
-	if (ctlr->cmd_intr_pending) {
-		tw_cli_dbg_printf(6, ctlr_handle, tw_osl_cur_func(),
-			"Processing Command interrupt");
-		ctlr->cmd_intr_pending = 0;
-		tw_cli_process_cmd_intr(ctlr);
-	}
-	if (ctlr->resp_intr_pending) {
-		tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(),
-			"Processing Response interrupt");
-		ctlr->resp_intr_pending = 0;
-		tw_cli_process_resp_intr(ctlr);
-	}
-}
-
-
-
-/*
  * Function name:	tw_cli_process_host_intr
  * Description:		This function gets called if we triggered an interrupt.
  *			We don't use it as of now.
@@ -248,12 +190,6 @@
 {
 	tw_cli_dbg_printf(6, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
 
-	/*
-	 * Let the OS Layer submit any requests in its pending queue,
-	 * if it has one.
-	 */
-	tw_osl_ctlr_ready(ctlr->ctlr_handle);
-
 	/* Start any requests that might be in the pending queue. */
 	tw_cli_submit_pending_queue(ctlr);
 
@@ -286,9 +222,6 @@
     
 	tw_cli_dbg_printf(10, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
 
-	/* Serialize access to the controller response queue. */
-	tw_osl_get_lock(ctlr->ctlr_handle, ctlr->intr_lock);
-
 	for (;;) {
 		status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr->ctlr_handle);
 		if ((error = tw_cli_check_ctlr_state(ctlr, status_reg)))
@@ -315,7 +248,6 @@
 #ifdef TW_OSL_DEBUG
 			tw_cl_print_ctlr_stats(ctlr->ctlr_handle);
 #endif /* TW_OSL_DEBUG */
-			tw_osl_free_lock(ctlr->ctlr_handle, ctlr->intr_lock);
 			tw_cl_reset_ctlr(ctlr->ctlr_handle);
 			return(TW_OSL_EIO);
 		}
@@ -330,12 +262,6 @@
 
 	}
 
-	/* Unmask the response interrupt. */
-	TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
-		TWA_CONTROL_UNMASK_RESPONSE_INTERRUPT);
-
-	tw_osl_free_lock(ctlr->ctlr_handle, ctlr->intr_lock);
-
 	/* Complete this, and other requests in the complete queue. */
 	tw_cli_process_complete_queue(ctlr);
 	
@@ -614,12 +540,11 @@
 				"status = %d", cmd->param.status);
 		}
 
-	ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+	ctlr->internal_req_busy = TW_CL_FALSE;
 	tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 
-	if ((ctlr->state & TW_CLI_CTLR_STATE_GET_MORE_AENS) &&
-		(!(ctlr->state & TW_CLI_CTLR_STATE_RESET_IN_PROGRESS))) {
-		ctlr->state &= ~TW_CLI_CTLR_STATE_GET_MORE_AENS;
+	if ((ctlr->get_more_aens) && (!(ctlr->reset_in_progress))) {
+		ctlr->get_more_aens = TW_CL_FALSE;
 		tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(),
 			"Fetching more AEN's");
 		if ((error = tw_cli_get_aen(ctlr)))
@@ -677,7 +602,7 @@
 		}
 
 	if (error) {
-		ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+		ctlr->internal_req_busy = TW_CL_FALSE;
 		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 		return;
 	}
@@ -688,7 +613,7 @@
 	aen_code = tw_cli_manage_aen(ctlr, req);
 
 	if (aen_code != TWA_AEN_SYNC_TIME_WITH_HOST) {
-		ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+		ctlr->internal_req_busy = TW_CL_FALSE;
 		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 		if (aen_code != TWA_AEN_QUEUE_EMPTY)
 			if ((error = tw_cli_get_aen(ctlr)))
@@ -736,25 +661,25 @@
 		 * Free the internal req pkt right here, since
 		 * tw_cli_set_param will need it.
 		 */
-		ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+		ctlr->internal_req_busy = TW_CL_FALSE;
 		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 
 		/*
 		 * We will use a callback in tw_cli_set_param only when
 		 * interrupts are enabled and we can expect our callback
-		 * to get called.  Setting the TW_CLI_CTLR_STATE_GET_MORE_AENS
+		 * to get called.  Setting the get_more_aens
 		 * flag will make the callback continue to try to retrieve
 		 * more AEN's.
 		 */
-		if (ctlr->state & TW_CLI_CTLR_STATE_INTR_ENABLED)
-			ctlr->state |= TW_CLI_CTLR_STATE_GET_MORE_AENS;
+		if (ctlr->interrupts_enabled)
+			ctlr->get_more_aens = TW_CL_TRUE;
 		/* Calculate time (in seconds) since last Sunday 12.00 AM. */
 		local_time = tw_osl_get_local_time();
 		sync_time = (local_time - (3 * 86400)) % 604800;
 		if ((error = tw_cli_set_param(ctlr, TWA_PARAM_TIME_TABLE,
 				TWA_PARAM_TIME_SCHED_TIME, 4,
 				&sync_time,
-				(ctlr->state & TW_CLI_CTLR_STATE_INTR_ENABLED)
+				(ctlr->interrupts_enabled)
 				? tw_cli_param_callback : TW_CL_NULL)))
 			tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
 				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
@@ -799,7 +724,7 @@
 {
 	tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
 
-	ctlr->state |= TW_CLI_CTLR_STATE_INTR_ENABLED;
+	ctlr->interrupts_enabled = TW_CL_TRUE;
 	TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
 		TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT |
 		TWA_CONTROL_UNMASK_RESPONSE_INTERRUPT |
@@ -823,6 +748,6 @@
 
 	TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
 		TWA_CONTROL_DISABLE_INTERRUPTS);
-	ctlr->state &= ~TW_CLI_CTLR_STATE_INTR_ENABLED;
+	ctlr->interrupts_enabled = TW_CL_FALSE;
 }
 
diff -u FreeBSD_RELENG_7_twa/tw_cl_io.c FreeBSD_7_development_twa/tw_cl_io.c
--- FreeBSD_RELENG_7_twa/tw_cl_io.c	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_cl_io.c	2010-06-07 15:07:02.000000000 -0700
@@ -49,6 +49,13 @@
 #include "tw_cl_externs.h"
 #include "tw_osl_ioctl.h"
 
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+#include <cam/cam_sim.h>
+#include <cam/cam_xpt_sim.h>
+#include <cam/cam_debug.h>
+#include <cam/cam_periph.h>
+
 
 
 /*
@@ -76,11 +83,9 @@
 
 	ctlr = (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
 
-	if (ctlr->state & TW_CLI_CTLR_STATE_RESET_IN_PROGRESS) {
+	if (ctlr->reset_in_progress) {
 		tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
-			"I/O during reset: returning busy. Ctlr state = 0x%x",
-			ctlr->state);
-		tw_osl_ctlr_busy(ctlr_handle, req_handle);
+			"I/O during reset: returning busy.");
 		return(TW_OSL_EBUSY);
 	}
 
@@ -101,7 +106,6 @@
 		)) == TW_CL_NULL) {
 		tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
 			"Out of request context packets: returning busy");
-		tw_osl_ctlr_busy(ctlr_handle, req_handle);
 		return(TW_OSL_EBUSY);
 	}
 
@@ -171,7 +175,6 @@
 	struct tw_cl_ctlr_handle	*ctlr_handle = ctlr->ctlr_handle;
 	TW_UINT32			status_reg;
 	TW_INT32			error;
-	TW_UINT8			notify_osl_of_ctlr_busy = TW_CL_FALSE;
 
 	tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), "entered");
 
@@ -208,10 +211,13 @@
 				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 {
-			notify_osl_of_ctlr_busy = TW_CL_TRUE;
+			tw_osl_ctlr_busy(ctlr_handle, req->req_handle);
 			error = TW_OSL_EBUSY;
 		}
 	} else {
@@ -246,25 +252,6 @@
 out:
 	tw_osl_free_lock(ctlr_handle, ctlr->io_lock);
 
-	if (status_reg & TWA_STATUS_COMMAND_QUEUE_FULL) {
-		if (notify_osl_of_ctlr_busy)
-			tw_osl_ctlr_busy(ctlr_handle, req->req_handle);
-
-		/*
-		 * Synchronize access between writes to command and control
-		 * registers in 64-bit environments, on G66.
-		 */
-		if (ctlr->state & TW_CLI_CTLR_STATE_G66_WORKAROUND_NEEDED)
-			tw_osl_get_lock(ctlr_handle, ctlr->io_lock);
-
-		/* Unmask command interrupt. */
-		TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle,
-			TWA_CONTROL_UNMASK_COMMAND_INTERRUPT);
-
-		if (ctlr->state & TW_CLI_CTLR_STATE_G66_WORKAROUND_NEEDED)
-			tw_osl_free_lock(ctlr_handle, ctlr->io_lock);
-	}
-
 	return(error);
 }
 
@@ -299,12 +286,9 @@
 
 	ctlr = (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
 
-	if (ctlr->state & TW_CLI_CTLR_STATE_RESET_IN_PROGRESS) {
+	if (ctlr->reset_in_progress) {
 		tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
-			"Passthru request during reset: returning busy. "
-			"Ctlr state = 0x%x",
-			ctlr->state);
-		tw_osl_ctlr_busy(ctlr_handle, req_handle);
+			"Passthru request during reset: returning busy.");
 		return(TW_OSL_EBUSY);
 	}
 
@@ -312,7 +296,6 @@
 		)) == TW_CL_NULL) {
 		tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(),
 			"Out of request context packets: returning busy");
-		tw_osl_ctlr_busy(ctlr_handle, req_handle);
 		return(TW_OSL_EBUSY);
 	}
 
@@ -759,11 +742,11 @@
 		goto out;
 
 	/* Make sure this is the only CL internal request at this time. */
-	if (ctlr->state & TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY) {
+	if (ctlr->internal_req_busy) {
 		error = TW_OSL_EBUSY;
 		goto out;
 	}
-	ctlr->state |= TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+	ctlr->internal_req_busy = TW_CL_TRUE;
 	req->data = ctlr->internal_req_data;
 	req->data_phys = ctlr->internal_req_data_phys;
 	req->length = TW_CLI_SECTOR_SIZE;
@@ -821,7 +804,7 @@
 			goto out;
 		}
 		tw_osl_memcpy(param_data, param->data, param_size);
-		ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+		ctlr->internal_req_busy = TW_CL_FALSE;
 		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 	} else {
 		/* There's a call back.  Simply submit the command. */
@@ -838,7 +821,7 @@
 		"get_param failed",
 		"error = %d", error);
 	if (param)
-		ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+		ctlr->internal_req_busy = TW_CL_FALSE;
 	if (req)
 		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 	return(1);
@@ -878,11 +861,11 @@
 		goto out;
 
 	/* Make sure this is the only CL internal request at this time. */
-	if (ctlr->state & TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY) {
+	if (ctlr->internal_req_busy) {
 		error = TW_OSL_EBUSY;
 		goto out;
 	}
-	ctlr->state |= TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+	ctlr->internal_req_busy = TW_CL_TRUE;
 	req->data = ctlr->internal_req_data;
 	req->data_phys = ctlr->internal_req_data_phys;
 	req->length = TW_CLI_SECTOR_SIZE;
@@ -939,7 +922,7 @@
 				&(req->cmd_pkt->cmd_hdr));
 			goto out;
 		}
-		ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+		ctlr->internal_req_busy = TW_CL_FALSE;
 		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 	} else {
 		/* There's a call back.  Simply submit the command. */
@@ -956,7 +939,7 @@
 		"set_param failed",
 		"error = %d", error);
 	if (param)
-		ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+		ctlr->internal_req_busy = TW_CL_FALSE;
 	if (req)
 		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 	return(error);
@@ -1054,8 +1037,11 @@
 		 * taking care of it).
 		 */
 		tw_cli_req_q_remove_item(req, TW_CLI_PENDING_Q);
+		if ((TW_CL_Q_FIRST_ITEM(&(ctlr->req_q_head[TW_CLI_PENDING_Q]))) == TW_CL_NULL)
+			TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
+				TWA_CONTROL_MASK_COMMAND_INTERRUPT);
 		if (req->data)
-			ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+			ctlr->internal_req_busy = TW_CL_FALSE;
 		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 	}
 
@@ -1079,12 +1065,16 @@
 {
 	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;
 	TW_INT32			reset_attempt = 1;
 	TW_INT32			error;
 
 	tw_cli_dbg_printf(2, ctlr_handle, tw_osl_cur_func(), "entered");
 
-	ctlr->state |= TW_CLI_CTLR_STATE_RESET_IN_PROGRESS;
+	ctlr->reset_in_progress = TW_CL_TRUE;
+	xpt_freeze_simq(sc->sim, 1);
+
+	tw_cli_disable_interrupts(ctlr);
 
 	/*
 	 * Error back all requests in the complete, busy, and pending queues.
@@ -1098,8 +1088,8 @@
 	tw_cli_drain_complete_queue(ctlr);
 	tw_cli_drain_busy_queue(ctlr);
 	tw_cli_drain_pending_queue(ctlr);
-
-	tw_cli_disable_interrupts(ctlr);
+	ctlr->internal_req_busy = TW_CL_FALSE;
+	ctlr->get_more_aens     = TW_CL_FALSE;
 
 	/* Soft reset the controller. */
 try_reset:
@@ -1135,7 +1125,9 @@
 		" ");
 
 out:
-	ctlr->state &= ~TW_CLI_CTLR_STATE_RESET_IN_PROGRESS;
+	ctlr->reset_in_progress = TW_CL_FALSE;
+	xpt_release_simq(sc->sim, 1);
+
 	/*
 	 * Enable interrupts, and also clear attention and response interrupts.
 	 */
@@ -1163,6 +1155,8 @@
 {
 	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");
@@ -1192,12 +1186,27 @@
 		 * make sure we don't access any hardware registers (for
 		 * polling) during that window.
 		 */
-		ctlr->state |= TW_CLI_CTLR_STATE_RESET_PHASE1_IN_PROGRESS;
-		while (tw_cli_find_response(ctlr,
-			TWA_RESET_PHASE1_NOTIFICATION_RESPONSE) != TW_OSL_ESUCCESS)
+		ctlr->reset_phase1_in_progress = TW_CL_TRUE;
+                loop_count = 0;
+		do {
+			found = (tw_cli_find_response(ctlr, TWA_RESET_PHASE1_NOTIFICATION_RESPONSE) == TW_OSL_ESUCCESS);
 			tw_osl_delay(10);
+			loop_count++;
+      error = 0x7888;
+		} 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_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
+				0x1109, 0x1, TW_CL_SEVERITY_ERROR_STRING,
+				"Missed firmware handshake after soft-reset",
+				"error = %d", error);
+			tw_osl_free_lock(ctlr_handle, ctlr->io_lock);
+			return(error);
+		}
+
 		tw_osl_delay(TWA_RESET_PHASE1_WAIT_TIME_MS * 1000);
-		ctlr->state &= ~TW_CLI_CTLR_STATE_RESET_PHASE1_IN_PROGRESS;
+		ctlr->reset_phase1_in_progress = TW_CL_FALSE;
 	}
 
 	if ((error = tw_cli_poll_status(ctlr,
@@ -1285,9 +1294,9 @@
 	tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
 
 	/* Make sure this is the only CL internal request at this time. */
-	if (ctlr->state & TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY)
+	if (ctlr->internal_req_busy)
 		return(TW_OSL_EBUSY);
-	ctlr->state |= TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+	ctlr->internal_req_busy = TW_CL_TRUE;
 	req->data = ctlr->internal_req_data;
 	req->data_phys = ctlr->internal_req_data_phys;
 	tw_osl_memzero(req->data, TW_CLI_SECTOR_SIZE);
@@ -1365,7 +1374,7 @@
 			"Could not send SCSI command",
 			"request = %p, error = %d", req, error);
 		if (req->data)
-			ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+			ctlr->internal_req_busy = TW_CL_FALSE;
 		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 	}
 	return(error);
diff -u FreeBSD_RELENG_7_twa/tw_cl_misc.c FreeBSD_7_development_twa/tw_cl_misc.c
--- FreeBSD_RELENG_7_twa/tw_cl_misc.c	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_cl_misc.c	2010-06-07 15:07:02.000000000 -0700
@@ -368,14 +368,14 @@
 		if (aen_code == TWA_AEN_SYNC_TIME_WITH_HOST)
 			continue;
 
-		ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+		ctlr->internal_req_busy = TW_CL_FALSE;
 		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 	}
 
 out:
 	if (req) {
 		if (req->data)
-			ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
+			ctlr->internal_req_busy = TW_CL_FALSE;
 		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
 	}
 	return(error);
@@ -447,34 +447,7 @@
 			/* got the required bit(s) */
 			return(TW_OSL_ESUCCESS);
 
-		/*
-		 * The OSL should not define TW_OSL_CAN_SLEEP if it calls
-		 * tw_cl_deferred_interrupt from within the ISR and not a
-		 * lower interrupt level, since, in that case, we might end
-		 * up here, and try to sleep (within an ISR).
-		 */
-#ifndef TW_OSL_CAN_SLEEP
-		/* OSL doesn't support sleeping; will spin. */
-		tw_osl_delay(1000);
-#else /* TW_OSL_CAN_SLEEP */
-#if 0
-		/* Will spin if initializing, sleep otherwise. */
-		if (!(ctlr->state & TW_CLI_CTLR_STATE_ACTIVE))
-			tw_osl_delay(1000);
-		else
-			tw_osl_sleep(ctlr->ctlr_handle,
-				&(ctlr->sleep_handle), 1 /* ms */);
-#else /* #if 0 */
-		/*
-		 * Will always spin for now (since reset holds a spin lock).
-		 * We could free io_lock after the call to TW_CLI_SOFT_RESET,
-		 * so we could sleep here.  To block new requests (since
-		 * the lock will have been released) we could use the
-		 * ...RESET_IN_PROGRESS flag.  Need to revisit.
-		 */
 		tw_osl_delay(1000);
-#endif /* #if 0 */
-#endif /* TW_OSL_CAN_SLEEP */
 	} while (tw_osl_get_local_time() <= end_time);
 
 	return(TW_OSL_ETIMEDOUT);
@@ -736,22 +709,20 @@
 	tw_cli_dbg_printf(8, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
 
 	/* Check if the 'micro-controller ready' bit is not set. */
-	if ((status_reg & TWA_STATUS_EXPECTED_BITS) !=
-				TWA_STATUS_EXPECTED_BITS) {
+	if (!(status_reg & TWA_STATUS_MICROCONTROLLER_READY)) {
 		TW_INT8	desc[200];
 
 		tw_osl_memzero(desc, 200);
-		if ((status_reg & TWA_STATUS_MICROCONTROLLER_READY) ||
-			(!(ctlr->state &
-			TW_CLI_CTLR_STATE_RESET_PHASE1_IN_PROGRESS))) {
+		if (!(ctlr->reset_phase1_in_progress)) {
 			tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
 				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
 				0x1301, 0x1, TW_CL_SEVERITY_ERROR_STRING,
 				"Missing expected status bit(s)",
 				"status reg = 0x%x; Missing bits: %s",
 				status_reg,
-				tw_cli_describe_bits (~status_reg &
-					TWA_STATUS_EXPECTED_BITS, desc));
+				tw_cli_describe_bits(
+					TWA_STATUS_MICROCONTROLLER_READY,
+					desc));
 			error = TW_OSL_EGENFAILURE;
 		}
 	}
@@ -765,7 +736,7 @@
 		/* Skip queue error msgs during 9650SE/9690SA reset */
 		if (((ctlr->device_id != TW_CL_DEVICE_ID_9K_E) &&
 		     (ctlr->device_id != TW_CL_DEVICE_ID_9K_SA)) ||
-		    ((ctlr->state & TW_CLI_CTLR_STATE_RESET_IN_PROGRESS) == 0) ||
+		    (!(ctlr->reset_in_progress)) ||
 		    ((status_reg & TWA_STATUS_QUEUE_ERROR_INTERRUPT) == 0))
 		tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
 			TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
@@ -819,7 +790,7 @@
 			/* Skip queue error msgs during 9650SE/9690SA reset */
 			if (((ctlr->device_id != TW_CL_DEVICE_ID_9K_E) &&
 			     (ctlr->device_id != TW_CL_DEVICE_ID_9K_SA)) ||
-			    ((ctlr->state & TW_CLI_CTLR_STATE_RESET_IN_PROGRESS) == 0))
+		            (!(ctlr->reset_in_progress)))
 				tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
 						   TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
 						   0x1305, 0x1, TW_CL_SEVERITY_ERROR_STRING,
diff -u FreeBSD_RELENG_7_twa/tw_cl_share.h FreeBSD_7_development_twa/tw_cl_share.h
--- FreeBSD_RELENG_7_twa/tw_cl_share.h	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_cl_share.h	2010-06-07 15:07:02.000000000 -0700
@@ -76,7 +76,7 @@
  * of supporting only 255, since we want to keep one CL internal request
  * context packet always available for internal requests.
  */
-#define TW_CL_MAX_SIMULTANEOUS_REQUESTS	0xFF	/* max simult reqs supported */
+#define TW_CL_MAX_SIMULTANEOUS_REQUESTS	256	/* max simult reqs supported */
 
 #define TW_CL_MAX_32BIT_SG_ELEMENTS	109	/* max 32-bit sg elements */
 #define TW_CL_MAX_64BIT_SG_ELEMENTS	72	/* max 64-bit sg elements */
@@ -144,6 +144,7 @@
 struct tw_cl_req_handle {
 	TW_VOID	*osl_req_ctxt;	/* OSL's request context */
 	TW_VOID	*cl_req_ctxt;	/* CL's request context */
+	TW_UINT8 is_io;		/* Only freeze/release simq for IOs */
 };
 
 
@@ -353,12 +354,6 @@
 #endif
 
 
-#ifndef tw_osl_ctlr_ready
-/* Called on cmd interrupt.  Allows re-submission of any pending requests. */
-extern TW_VOID	tw_osl_ctlr_ready(struct tw_cl_ctlr_handle *ctlr_handle);
-#endif
-
-
 #ifndef tw_osl_cur_func
 /* Text name of current function. */
 extern TW_INT8	*tw_osl_cur_func(TW_VOID);
@@ -528,10 +523,6 @@
 extern TW_INT32	tw_cl_ctlr_supported(TW_INT32 vendor_id, TW_INT32 device_id);
 
 
-/* Deferred interrupt handler. */
-extern TW_VOID	tw_cl_deferred_interrupt(struct tw_cl_ctlr_handle *ctlr_handle);
-
-
 /* Submit a firmware cmd packet. */
 extern TW_INT32	tw_cl_fw_passthru(struct tw_cl_ctlr_handle *ctlr_handle,
 	struct tw_cl_req_packet *req_pkt, struct tw_cl_req_handle *req_handle);
diff -u FreeBSD_RELENG_7_twa/tw_osl.h FreeBSD_7_development_twa/tw_osl.h
--- FreeBSD_RELENG_7_twa/tw_osl.h	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_osl.h	2010-06-07 15:07:02.000000000 -0700
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/twa/tw_osl.h,v 1.5.2.2 2009/03/30 18:43:41 jhb Exp $
+ *	$FreeBSD: src/sys/dev/twa/tw_osl.h,v 1.5.2.1 2007/10/19 15:21:16 scottl Exp $
  */
 
 /*
@@ -50,13 +50,11 @@
 #define TW_OSLI_DEVICE_NAME		"3ware 9000 series Storage Controller"
 
 #define TW_OSLI_MALLOC_CLASS		M_TWA
-#define TW_OSLI_MAX_NUM_IOS		TW_CL_MAX_SIMULTANEOUS_REQUESTS
+#define TW_OSLI_MAX_NUM_REQUESTS	TW_CL_MAX_SIMULTANEOUS_REQUESTS
+/* Reserve two command packets.  One for ioctls and one for AENs */
+#define TW_OSLI_MAX_NUM_IOS		(TW_OSLI_MAX_NUM_REQUESTS - 2)
 #define TW_OSLI_MAX_NUM_AENS		0x100
 
-/* Disabled, doesn't work yet.
-#define TW_OSLI_DEFERRED_INTR_USED
-*/
-
 #ifdef PAE
 #define	TW_OSLI_DMA_BOUNDARY		(1u << 31)
 #else
@@ -80,10 +78,6 @@
 #define TW_OSLI_REQ_FLAGS_PASSTHRU	(1<<5)	/* pass through request */
 #define TW_OSLI_REQ_FLAGS_SLEEPING	(1<<6)	/* owner sleeping on this cmd */
 
-/* Possible values of sc->state. */
-#define TW_OSLI_CTLR_STATE_OPEN		(1<<0)	/* control device is open */
-#define TW_OSLI_CTLR_STATE_SIMQ_FROZEN	(1<<1)	/* simq frozen */
-
 
 #ifdef TW_OSL_DEBUG
 struct tw_osli_q_stats {
@@ -101,6 +95,8 @@
 /* Driver's request packet. */
 struct tw_osli_req_context {
 	struct tw_cl_req_handle	req_handle;/* tag to track req b/w OSL & CL */
+	struct mtx		ioctl_wake_timeout_lock_handle;/* non-spin lock used to detect ioctl timeout */ 
+	struct mtx		*ioctl_wake_timeout_lock;/* ptr to above lock */
 	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 */
@@ -130,10 +126,10 @@
 /* Per-controller structure. */
 struct twa_softc {
 	struct tw_cl_ctlr_handle	ctlr_handle;
-	struct tw_osli_req_context	*req_ctxt_buf;
+	struct tw_osli_req_context	*req_ctx_buf;
 
 	/* Controller state. */
-	TW_UINT32		state;
+	TW_UINT8		open;
 	TW_UINT32		flags;
 
 	TW_INT32		device_id;
diff -u FreeBSD_RELENG_7_twa/tw_osl_cam.c FreeBSD_7_development_twa/tw_osl_cam.c
--- FreeBSD_RELENG_7_twa/tw_osl_cam.c	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_osl_cam.c	2010-06-07 15:07:02.000000000 -0700
@@ -83,7 +83,7 @@
 	/*
 	 * Create the device queue for our SIM.
 	 */
-	if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_IOS)) == NULL) {
+	if ((devq = cam_simq_alloc(TW_OSLI_MAX_NUM_REQUESTS)) == NULL) {
 		tw_osli_printf(sc, "error = %d",
 			TW_CL_SEVERITY_ERROR_STRING,
 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
@@ -94,15 +94,15 @@
 	}
 
 	/*
-	 * Create a SIM entry.  Though we can support TW_OSLI_MAX_NUM_IOS
+	 * Create a SIM entry.  Though we can support TW_OSLI_MAX_NUM_REQUESTS
 	 * simultaneous requests, we claim to be able to handle only
-	 * (TW_OSLI_MAX_NUM_IOS - 1), so that we always have a request
-	 * packet available to service ioctls.
+	 * TW_OSLI_MAX_NUM_IOS (two less), so that we always have a request
+	 * packet available to service ioctls and AENs.
 	 */
 	tw_osli_dbg_dprintf(3, sc, "Calling cam_sim_alloc");
 	sc->sim = cam_sim_alloc(twa_action, twa_poll, "twa", sc,
 			device_get_unit(sc->bus_dev), sc->sim_lock,
-			TW_OSLI_MAX_NUM_IOS - 1, 1, devq);
+			TW_OSLI_MAX_NUM_IOS, 1, devq);
 	if (sc->sim == NULL) {
 		cam_simq_free(devq);
 		tw_osli_printf(sc, "error = %d",
@@ -185,14 +185,6 @@
 {
 	tw_osli_dbg_dprintf(3, sc, "entered");
 
-#ifdef TW_OSLI_DEFERRED_INTR_USED
-	/*  - drain the taskqueue 
-           Ctrl is already went down so, no more enqueuetask will
-           happen . Don't  hold any locks, that task might need.
- 	*/ 
-
-	taskqueue_drain(taskqueue_fast, &(sc->deferred_intr_callback));
-#endif
 	mtx_lock(sc->sim_lock);
            
 	if (sc->path)
@@ -253,7 +245,7 @@
 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
 			0x2105,
 			"Physical CDB address!");
-		ccb_h->status = CAM_REQ_CMP_ERR;
+		ccb_h->status = CAM_REQ_INVALID;
 		xpt_done(ccb);
 		return(1);
 	}
@@ -314,7 +306,7 @@
 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
 				0x2107,
 				"XPT_SCSI_IO: Got SGList");
-			ccb_h->status = CAM_REQ_CMP_ERR;
+			ccb_h->status = CAM_REQ_INVALID;
 			xpt_done(ccb);
 			return(1);
 		}
@@ -325,8 +317,7 @@
 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
 			0x2108,
 			"XPT_SCSI_IO: Physical data addresses");
-		ccb_h->status = CAM_REQ_CMP_ERR;
-		ccb_h->status |= CAM_RELEASE_SIMQ;
+		ccb_h->status = CAM_REQ_INVALID;
 		ccb_h->status &= ~CAM_SIM_QUEUED;
 		xpt_done(ccb);
 		return(1);
@@ -364,20 +355,19 @@
 	{
 		struct tw_osli_req_context	*req;
 
-		if ((sc->state & TW_OSLI_CTLR_STATE_SIMQ_FROZEN) ||
-				((req = tw_osli_get_request(sc)) == NULL)) {
-			tw_osli_dbg_dprintf(2, sc,
-				"simq frozen/Cannot get request pkt.");
+		req = tw_osli_get_request(sc);
+		if (req == NULL) {
+			tw_osli_dbg_dprintf(2, sc, "Cannot get request pkt.");
 			/*
 			 * Freeze the simq to maintain ccb ordering.  The next
 			 * ccb that gets completed will unfreeze the simq.
 			 */
-			tw_osli_disallow_new_requests(sc);
 			ccb_h->status |= CAM_REQUEUE_REQ;
 			xpt_done(ccb);
 			break;
 		}
 		req->req_handle.osl_req_ctxt = req;
+		req->req_handle.is_io = TW_CL_TRUE;
 		req->orig_req = ccb;
 		if (tw_osli_execute_scsi(req, ccb))
 			tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
@@ -507,18 +497,7 @@
 	struct twa_softc *sc = (struct twa_softc *)(cam_sim_softc(sim));
 
 	tw_osli_dbg_dprintf(3, sc, "entering; sc = %p", sc);
-	/*
-	 * It's been observed that twa_poll can get called (from
-	 * dashutdown --> xpt_polled_action) even when interrupts are
-	 * active, in which case, the ISR might clear the interrupt,
-	 * leaving the call to tw_cl_interrupt below, no way of determining
-	 * that the response from firmware is ready, resulting in
-	 * tw_cl_deferred_interrupt never getting called.  To cover this case,
-	 * we will make the call to tw_cl_deferred_interrupt not dependent
-	 * on the return value from tw_cl_interrupt.
-	 */
 	tw_cl_interrupt(&(sc->ctlr_handle));
-	tw_cl_deferred_interrupt(&(sc->ctlr_handle));
 	tw_osli_dbg_dprintf(3, sc, "exiting; sc = %p", sc);
 }
 
@@ -580,12 +559,6 @@
 		return(EIO);
 	}
 
-	/* Release simq at the end of a reset */
-	if (sc->state & TW_OSLI_CTLR_STATE_SIMQ_FROZEN) {
-		xpt_release_simq(sc->sim, 1);
-		sc->state &= ~TW_OSLI_CTLR_STATE_SIMQ_FROZEN;
-	}
-
 	xpt_setup_ccb(&ccb->ccb_h, path, 5);
 	ccb->ccb_h.func_code = XPT_SCAN_BUS;
 	ccb->ccb_h.cbfcnp = twa_bus_scan_cb;
@@ -624,44 +597,26 @@
 
 
 /*
- * Function name:	tw_osli_allow_new_requests
- * Description:		Sets the appropriate status bits in a ccb such that,
- *			when the ccb is completed by a call to xpt_done,
- *			CAM knows that it's ok to unfreeze the flow of new
- *			requests to this controller, if the flow is frozen.
- *
- * Input:		sc	-- ptr to OSL internal ctlr context
- *			ccb	-- ptr to CAM request
- * Output:		None
- * Return value:	None
- */
-TW_VOID
-tw_osli_allow_new_requests(struct twa_softc *sc, TW_VOID *ccb)
-{
-	((union ccb *)(ccb))->ccb_h.status |= CAM_RELEASE_SIMQ;
-	sc->state &= ~TW_OSLI_CTLR_STATE_SIMQ_FROZEN;
-}
-
-
-
-/*
  * Function name:	tw_osli_disallow_new_requests
  * Description:		Calls the appropriate CAM function, so as to freeze
  *			the flow of new requests from CAM to this controller.
  *
  * Input:		sc	-- ptr to OSL internal ctlr context
+ *			req_handle -- ptr to request handle sent by OSL.
  * Output:		None
  * Return value:	None
  */
 TW_VOID
-tw_osli_disallow_new_requests(struct twa_softc *sc)
+tw_osli_disallow_new_requests(struct twa_softc *sc,
+	struct tw_cl_req_handle *req_handle)
 {
-	/* Don't double freeze if already frozen */
-	if ((sc->state & TW_OSLI_CTLR_STATE_SIMQ_FROZEN) == 0) {
-		mtx_lock(sc->sim_lock);
+	/* Only freeze/release the simq for IOs */
+	if (req_handle->is_io) {
+		struct tw_osli_req_context	*req = req_handle->osl_req_ctxt;
+		union ccb			*ccb = (union ccb *)(req->orig_req);
+
 		xpt_freeze_simq(sc->sim, 1);
-		mtx_unlock(sc->sim_lock);
-		sc->state |= TW_OSLI_CTLR_STATE_SIMQ_FROZEN;
+		ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
 	}
 }
 
@@ -681,7 +636,7 @@
 tw_osl_ctlr_busy(struct tw_cl_ctlr_handle *ctlr_handle,
 	struct tw_cl_req_handle *req_handle)
 {
-	tw_osli_disallow_new_requests(ctlr_handle->osl_ctlr_ctxt);
+	tw_osli_disallow_new_requests(ctlr_handle->osl_ctlr_ctxt, req_handle);
 }
 
 
@@ -755,10 +710,8 @@
 		if (req->error_code == EBUSY) {
 			/*
 			 * Cmd queue is full, or the Common Layer is out of
-			 * resources.  The simq will already have been frozen
-			 * by CL's call to tw_osl_ctlr_busy, and this will
-			 * maintain ccb ordering.  The next ccb that gets
-			 * completed will unfreeze the simq.
+			 * resources.  The simq will already have been frozen.
+			 * When this ccb gets completed will unfreeze the simq.
 			 */
 			ccb->ccb_h.status |= CAM_REQUEUE_REQ;
 		}
@@ -793,9 +746,6 @@
 		}
 
 		ccb->csio.scsi_status = scsi_req->scsi_status;
-		/* If simq is frozen, unfreeze it. */
-		if (sc->state & TW_OSLI_CTLR_STATE_SIMQ_FROZEN)
-			tw_osli_allow_new_requests(sc, (TW_VOID *)ccb);
 	}
 
 	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
diff -u FreeBSD_RELENG_7_twa/tw_osl_externs.h FreeBSD_7_development_twa/tw_osl_externs.h
--- FreeBSD_RELENG_7_twa/tw_osl_externs.h	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_osl_externs.h	2010-06-07 15:07:02.000000000 -0700
@@ -79,11 +79,9 @@
 /* Request CAM for a bus scan. */
 extern TW_INT32	tw_osli_request_bus_scan(struct twa_softc *sc);
 
-/* Unfreeze ccb flow from CAM. */
-extern TW_VOID	tw_osli_allow_new_requests(struct twa_softc *sc, TW_VOID *ccb);
-
 /* Freeze ccb flow from CAM. */
-extern TW_VOID	tw_osli_disallow_new_requests(struct twa_softc *sc);
+extern TW_VOID	tw_osli_disallow_new_requests(struct twa_softc *sc,
+	struct tw_cl_req_handle *req_handle);
 
 /* OSL's completion routine for SCSI I/O's. */
 extern TW_VOID	tw_osl_complete_io(struct tw_cl_req_handle *req_handle);
diff -u FreeBSD_RELENG_7_twa/tw_osl_freebsd.c FreeBSD_7_development_twa/tw_osl_freebsd.c
--- FreeBSD_RELENG_7_twa/tw_osl_freebsd.c	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_osl_freebsd.c	2010-06-07 15:07:02.000000000 -0700
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/twa/tw_osl_freebsd.c,v 1.9.2.2 2009/03/30 18:43:41 jhb Exp $
+ *	$FreeBSD: src/sys/dev/twa/tw_osl_freebsd.c,v 1.9.2.1 2008/10/14 19:02:47 delphij Exp $
  */
 
 /*
@@ -88,11 +88,11 @@
 static TW_INT32
 twa_open(struct cdev *dev, TW_INT32 flags, TW_INT32 fmt, d_thread_t *proc)
 {
-	TW_INT32		unit = minor(dev);
+	TW_INT32		unit = dev2unit(dev);
 	struct twa_softc	*sc = devclass_get_softc(twa_devclass, unit);
 
 	tw_osli_dbg_dprintf(5, sc, "entered");
-	sc->state |= TW_OSLI_CTLR_STATE_OPEN;
+	sc->open = TW_CL_TRUE;
 	return(0);
 }
 
@@ -114,11 +114,11 @@
 static TW_INT32
 twa_close(struct cdev *dev, TW_INT32 flags, TW_INT32 fmt, d_thread_t *proc)
 {
-	TW_INT32		unit = minor(dev);
+	TW_INT32		unit = dev2unit(dev);
 	struct twa_softc	*sc = devclass_get_softc(twa_devclass, unit);
 
 	tw_osli_dbg_dprintf(5, sc, "entered");
-	sc->state &= ~TW_OSLI_CTLR_STATE_OPEN;
+	sc->open = TW_CL_FALSE;
 	return(0);
 }
 
@@ -176,12 +176,7 @@
 static TW_INT32	twa_detach(device_t dev);
 static TW_INT32	twa_shutdown(device_t dev);
 static TW_VOID	twa_busdma_lock(TW_VOID *lock_arg, bus_dma_lock_op_t op);
-#ifdef TW_OSLI_DEFERRED_INTR_USED
-static int	twa_pci_intr_fast(TW_VOID *arg);
-static TW_VOID	twa_deferred_intr(TW_VOID *context, TW_INT32 pending);
-#else
 static TW_VOID	twa_pci_intr(TW_VOID *arg);
-#endif /* TW_OSLI_DEFERRED_INTR_USED */
 
 static TW_INT32	tw_osli_alloc_mem(struct twa_softc *sc);
 static TW_VOID	tw_osli_free_resources(struct twa_softc *sc);
@@ -362,13 +357,8 @@
 		return(ENXIO);
 	}
 	if ((error = bus_setup_intr(sc->bus_dev, sc->irq_res,
-#ifdef TW_OSLI_DEFERRED_INTR_USED
-			INTR_TYPE_CAM | INTR_FAST,
-			twa_pci_intr_fast, NULL,
-#else
 			INTR_TYPE_CAM | INTR_MPSAFE,
 			NULL, twa_pci_intr,	    
-#endif 
 			sc, &sc->intr_handle))) {
 		tw_osli_printf(sc, "error = %d",
 			TW_CL_SEVERITY_ERROR_STRING,
@@ -380,10 +370,6 @@
 		return(error);
 	}
 
-#ifdef TW_OSLI_DEFERRED_INTR_USED
-	TASK_INIT(&sc->deferred_intr_callback, 0, twa_deferred_intr, sc);
-#endif /* TW_OSLI_DEFERRED_INTR_USED */
-
 	if ((error = tw_osli_alloc_mem(sc))) {
 		tw_osli_printf(sc, "error = %d",
 			TW_CL_SEVERITY_ERROR_STRING,
@@ -397,7 +383,7 @@
 
 	/* Initialize the Common Layer for this controller. */
 	if ((error = tw_cl_init_ctlr(&sc->ctlr_handle, sc->flags, sc->device_id,
-			TW_OSLI_MAX_NUM_IOS, TW_OSLI_MAX_NUM_AENS,
+			TW_OSLI_MAX_NUM_REQUESTS, TW_OSLI_MAX_NUM_AENS,
 			sc->non_dma_mem, sc->dma_mem,
 			sc->dma_mem_phys
 			))) {
@@ -456,15 +442,12 @@
 
 	sc->flags |= (sizeof(bus_addr_t) == 8) ? TW_CL_64BIT_ADDRESSES : 0;
 	sc->flags |= (sizeof(bus_size_t) == 8) ? TW_CL_64BIT_SG_LENGTH : 0;
-#ifdef TW_OSLI_DEFERRED_INTR_USED
-	sc->flags |= TW_CL_DEFERRED_INTR_USED; 
-#endif /* TW_OSLI_DEFERRED_INTR_USED */
 
 	max_sg_elements = (sizeof(bus_addr_t) == 8) ?
 		TW_CL_MAX_64BIT_SG_ELEMENTS : TW_CL_MAX_32BIT_SG_ELEMENTS;
 
 	if ((error = tw_cl_get_mem_requirements(&sc->ctlr_handle, sc->flags,
-			sc->device_id, TW_OSLI_MAX_NUM_IOS,  TW_OSLI_MAX_NUM_AENS,
+			sc->device_id, TW_OSLI_MAX_NUM_REQUESTS,  TW_OSLI_MAX_NUM_AENS,
 			&(sc->alignment), &(sc->sg_size_factor),
 			&non_dma_mem_size, &dma_mem_size
 			))) {
@@ -623,9 +606,9 @@
 	tw_osli_req_q_init(sc, TW_OSLI_FREE_Q);
 	tw_osli_req_q_init(sc, TW_OSLI_BUSY_Q);
 
-	if ((sc->req_ctxt_buf = (struct tw_osli_req_context *)
+	if ((sc->req_ctx_buf = (struct tw_osli_req_context *)
 			malloc((sizeof(struct tw_osli_req_context) *
-				TW_OSLI_MAX_NUM_IOS),
+				TW_OSLI_MAX_NUM_REQUESTS),
 				TW_OSLI_MALLOC_CLASS, M_WAITOK)) == NULL) {
 		tw_osli_printf(sc, "error = %d",
 			TW_CL_SEVERITY_ERROR_STRING,
@@ -635,11 +618,11 @@
 			ENOMEM);
 		return(ENOMEM);
 	}
-	bzero(sc->req_ctxt_buf,
-		sizeof(struct tw_osli_req_context) * TW_OSLI_MAX_NUM_IOS);
+	bzero(sc->req_ctx_buf,
+		sizeof(struct tw_osli_req_context) * TW_OSLI_MAX_NUM_REQUESTS);
 
-	for (i = 0; i < TW_OSLI_MAX_NUM_IOS; i++) {
-		req = &(sc->req_ctxt_buf[i]);
+	for (i = 0; i < TW_OSLI_MAX_NUM_REQUESTS; i++) {
+		req = &(sc->req_ctx_buf[i]);
 		req->ctlr = sc;
 		if (bus_dmamap_create(sc->dma_tag, 0, &req->dma_map)) {
 			tw_osli_printf(sc, "request # = %d, error = %d",
@@ -651,6 +634,10 @@
 			return(ENOMEM);
 		}
 
+		/* Initialize the ioctl wakeup/ timeout mutex */
+		req->ioctl_wake_timeout_lock = &(req->ioctl_wake_timeout_lock_handle);
+		mtx_init(req->ioctl_wake_timeout_lock, "tw_ioctl_wake_timeout_lock", NULL, MTX_DEF);
+
 		/* Insert request into the free queue. */
 		tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
 	}
@@ -679,14 +666,17 @@
 	/* Detach from CAM */
 	tw_osli_cam_detach(sc);
 
-	if (sc->req_ctxt_buf)
+	if (sc->req_ctx_buf)
 		while ((req = tw_osli_req_q_remove_head(sc, TW_OSLI_FREE_Q)) !=
-			NULL)
+			NULL) {
+			mtx_destroy(req->ioctl_wake_timeout_lock);
+
 			if ((error = bus_dmamap_destroy(sc->dma_tag,
 					req->dma_map)))
 				tw_osli_dbg_dprintf(1, sc,
 					"dmamap_destroy(dma) returned %d",
 					error);
+		}
 
 	if ((sc->ioctl_tag) && (sc->ioctl_map))
 		if ((error = bus_dmamap_destroy(sc->ioctl_tag, sc->ioctl_map)))
@@ -694,8 +684,8 @@
 				"dmamap_destroy(ioctl) returned %d", error);
 
 	/* Free all memory allocated so far. */
-	if (sc->req_ctxt_buf)
-		free(sc->req_ctxt_buf, TW_OSLI_MALLOC_CLASS);
+	if (sc->req_ctx_buf)
+		free(sc->req_ctx_buf, TW_OSLI_MALLOC_CLASS);
 
 	if (sc->non_dma_mem)
 		free(sc->non_dma_mem, TW_OSLI_MALLOC_CLASS);
@@ -779,7 +769,7 @@
 	tw_osli_dbg_dprintf(3, sc, "entered");
 
 	error = EBUSY;
-	if (sc->state & TW_OSLI_CTLR_STATE_OPEN) {
+	if (sc->open) {
 		tw_osli_printf(sc, "error = %d",
 			TW_CL_SEVERITY_ERROR_STRING,
 			TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
@@ -865,29 +855,6 @@
 }
 
 
-#ifdef TW_OSLI_DEFERRED_INTR_USED
-/*
- * Function name:	twa_pci_intr_fast
- * Description:		Interrupt handler.  Wrapper for twa_interrupt.
- *
- * Input:		arg	-- ptr to OSL internal ctlr context
- * Output:		FILTER_HANDLED or FILTER_STRAY
- * Return value:	None
- */
-static int
-twa_pci_intr_fast(TW_VOID *arg)
-{
-	struct twa_softc	*sc = (struct twa_softc *)arg;
-
-	tw_osli_dbg_dprintf(10, sc, "entered");
-	if (tw_cl_interrupt(&(sc->ctlr_handle))) {
-		taskqueue_enqueue_fast(taskqueue_fast,
-			&(sc->deferred_intr_callback));
-		return(FILTER_HANDLED);
-	}
-	return(FILTER_STRAY);
-}
-#else
 /*
  * Function name:	twa_pci_intr
  * Description:		Interrupt handler.  Wrapper for twa_interrupt.
@@ -902,35 +869,9 @@
 	struct twa_softc	*sc = (struct twa_softc *)arg;
 
 	tw_osli_dbg_dprintf(10, sc, "entered");
-	if (tw_cl_interrupt(&(sc->ctlr_handle)))
-		tw_cl_deferred_interrupt(&(sc->ctlr_handle));
-}
-#endif
-
-#ifdef TW_OSLI_DEFERRED_INTR_USED
-
-/*
- * Function name:	twa_deferred_intr
- * Description:		Deferred interrupt handler.
- *
- * Input:		context	-- ptr to OSL internal ctlr context
- *			pending	-- not used
- * Output:		None
- * Return value:	None
- */
-static TW_VOID
-twa_deferred_intr(TW_VOID *context, TW_INT32 pending)
-{
-	struct twa_softc	*sc = (struct twa_softc *)context;
-
-	tw_osli_dbg_dprintf(10, sc, "entered");
-
-	tw_cl_deferred_interrupt(&(sc->ctlr_handle));
+	tw_cl_interrupt(&(sc->ctlr_handle));
 }
 
-#endif /* TW_OSLI_DEFERRED_INTR_USED */
-
-
 
 /*
  * Function name:	tw_osli_fw_passthru
@@ -1017,10 +958,13 @@
 
 	end_time = tw_osl_get_local_time() + timeout;
 	while (req->state != TW_OSLI_REQ_STATE_COMPLETE) {
+		mtx_lock(req->ioctl_wake_timeout_lock);
 		req->flags |= TW_OSLI_REQ_FLAGS_SLEEPING;
-		
-		error = tsleep(req, PRIBIO, "twa_passthru", timeout * hz);
-
+	
+		error = mtx_sleep(req, req->ioctl_wake_timeout_lock, 0,
+                         	    "twa_passthru", timeout*hz);
+		mtx_unlock(req->ioctl_wake_timeout_lock);
+	
 		if (!(req->flags & TW_OSLI_REQ_FLAGS_SLEEPING))
 			error = 0;
 		req->flags &= ~TW_OSLI_REQ_FLAGS_SLEEPING;
@@ -1041,6 +985,20 @@
 
 		if (error == EWOULDBLOCK) {
 			/* Time out! */
+			if ((!(req->error_code))                       &&
+			    (req->state == TW_OSLI_REQ_STATE_COMPLETE) &&
+			    (!(req_pkt->status))			  ) {
+#ifdef    TW_OSL_DEBUG
+				tw_osli_printf(sc, "request = %p",
+					TW_CL_SEVERITY_ERROR_STRING,
+					TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
+					0x7777,
+					"FALSE Passthru timeout!",
+					req);
+#endif /* TW_OSL_DEBUG */
+				error = 0; /* False error */
+				break;
+			}
 			tw_osli_printf(sc, "request = %p",
 				TW_CL_SEVERITY_ERROR_STRING,
 				TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER,
@@ -1146,8 +1104,7 @@
 	 * EINPROGRESS.  The request originator will then be returned an
 	 * error, and he can do the clean-up.
 	 */
-	if ((req->error_code) &&
-		(!(req->state & TW_OSLI_REQ_FLAGS_IN_PROGRESS)))
+	if ((req->error_code) && (!(req->flags & TW_OSLI_REQ_FLAGS_IN_PROGRESS)))
 		return;
 
 	if (req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU) {
@@ -1159,7 +1116,7 @@
 			wakeup_one(req);
 		} else {
 			/*
-			 * If the request completed even before tsleep
+			 * If the request completed even before mtx_sleep
 			 * was called, simply return.
 			 */
 			if (req->flags & TW_OSLI_REQ_FLAGS_MAPPED)
@@ -1208,6 +1165,7 @@
 	if (req) {
 		req->req_handle.osl_req_ctxt = NULL;
 		req->req_handle.cl_req_ctxt = NULL;
+		req->req_handle.is_io = 0;
 		req->data = NULL;
 		req->length = 0;
 		req->real_data = NULL;
@@ -1257,8 +1215,6 @@
 	tw_osli_req_q_insert_tail(req, TW_OSLI_BUSY_Q);
 
 	req->flags |= TW_OSLI_REQ_FLAGS_MAPPED;
-	if (req->flags & TW_OSLI_REQ_FLAGS_IN_PROGRESS)
-		tw_osli_allow_new_requests(sc, (TW_VOID *)(req->orig_req));
 
 	if (error == EFBIG) {
 		req->error_code = error;
@@ -1347,7 +1303,7 @@
 twa_map_load_callback(TW_VOID *arg, bus_dma_segment_t *segs,
 	TW_INT32 nsegments, TW_INT32 error)
 {
-	*((TW_UINT64 *)arg) = segs[0].ds_addr;
+	*((bus_addr_t *)arg) = segs[0].ds_addr;
 }
 
 
@@ -1440,11 +1396,9 @@
 				 * of ...FLAGS_MAPPED from the callback.
 				 */
 				mtx_lock_spin(sc->io_lock);
-				if (!(req->flags & TW_OSLI_REQ_FLAGS_MAPPED)) {
-					req->flags |=
-						TW_OSLI_REQ_FLAGS_IN_PROGRESS;
-					tw_osli_disallow_new_requests(sc);
-				}
+				if (!(req->flags & TW_OSLI_REQ_FLAGS_MAPPED))
+					req->flags |= TW_OSLI_REQ_FLAGS_IN_PROGRESS;
+				tw_osli_disallow_new_requests(sc, &(req->req_handle));
 				mtx_unlock_spin(sc->io_lock);
 				error = 0;
 			} else {
diff -u FreeBSD_RELENG_7_twa/tw_osl_inline.h FreeBSD_7_development_twa/tw_osl_inline.h
--- FreeBSD_RELENG_7_twa/tw_osl_inline.h	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_osl_inline.h	2010-06-07 15:07:02.000000000 -0700
@@ -108,21 +108,6 @@
 
 
 
-/*
- * Function name:	tw_osl_ctlr_ready
- * Description:		CL calls this function to notify the OS Layer that it
- *			is ready to accept new requests.  This function is
- *			called only if a call to tw_osl_ctlr_busy has been
- *			made previously.  We don't use this function as of now.
- *
- * Input:		ctlr_handle	-- ptr to controller handle
- * Output:		None
- * Return value:	None
- */
-#define tw_osl_ctlr_ready(ctlr_handle)
-
-
-
 #ifdef TW_OSL_DEBUG
 
 /*
diff -u FreeBSD_RELENG_7_twa/tw_osl_share.h FreeBSD_7_development_twa/tw_osl_share.h
--- FreeBSD_RELENG_7_twa/tw_osl_share.h	2010-06-07 15:32:12.000000000 -0700
+++ FreeBSD_7_development_twa/tw_osl_share.h	2010-06-07 15:07:02.000000000 -0700
@@ -75,7 +75,7 @@
 #define TW_OSL_ENCLOSURE_SUPPORT
 #endif
 
-#define TW_OSL_DRIVER_VERSION_STRING	"3.70.05.001"
+#define TW_OSL_DRIVER_VERSION_STRING	"3.70.05.008"
 
 #define	TW_OSL_CAN_SLEEP
 


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list