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 ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to