svn commit: r212490 - stable/8/sys/dev/twa
Xin LI
delphij at FreeBSD.org
Sun Sep 12 06:19:36 UTC 2010
Author: delphij
Date: Sun Sep 12 06:19:35 2010
New Revision: 212490
URL: http://svn.freebsd.org/changeset/base/212490
Log:
MFC r212008, 212028, 212210: Vendor update to version 3.80.06.003 to
fix panic with ZFS under heavy I/O load.
PR: kern/149968
Submitted by: LSI (Tom Couch)
Reported by: Kai Kockro <kkockro web de>
Tested by: Kai Kockro, jpaetzel
Modified:
stable/8/sys/dev/twa/tw_cl.h
stable/8/sys/dev/twa/tw_cl_externs.h
stable/8/sys/dev/twa/tw_cl_fwif.h
stable/8/sys/dev/twa/tw_cl_init.c
stable/8/sys/dev/twa/tw_cl_intr.c
stable/8/sys/dev/twa/tw_cl_io.c
stable/8/sys/dev/twa/tw_cl_misc.c
stable/8/sys/dev/twa/tw_cl_share.h
stable/8/sys/dev/twa/tw_osl.h
stable/8/sys/dev/twa/tw_osl_cam.c
stable/8/sys/dev/twa/tw_osl_freebsd.c
stable/8/sys/dev/twa/tw_osl_share.h
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/dev/twa/tw_cl.h
==============================================================================
--- stable/8/sys/dev/twa/tw_cl.h Sun Sep 12 00:53:10 2010 (r212489)
+++ stable/8/sys/dev/twa/tw_cl.h Sun Sep 12 06:19:35 2010 (r212490)
@@ -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/8/sys/dev/twa/tw_cl_externs.h
==============================================================================
--- stable/8/sys/dev/twa/tw_cl_externs.h Sun Sep 12 00:53:10 2010 (r212489)
+++ stable/8/sys/dev/twa/tw_cl_externs.h Sun Sep 12 06:19:35 2010 (r212490)
@@ -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/8/sys/dev/twa/tw_cl_fwif.h
==============================================================================
--- stable/8/sys/dev/twa/tw_cl_fwif.h Sun Sep 12 00:53:10 2010 (r212489)
+++ stable/8/sys/dev/twa/tw_cl_fwif.h Sun Sep 12 06:19:35 2010 (r212490)
@@ -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/8/sys/dev/twa/tw_cl_init.c
==============================================================================
--- stable/8/sys/dev/twa/tw_cl_init.c Sun Sep 12 00:53:10 2010 (r212489)
+++ stable/8/sys/dev/twa/tw_cl_init.c Sun Sep 12 06:19:35 2010 (r212490)
@@ -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/8/sys/dev/twa/tw_cl_intr.c
==============================================================================
--- stable/8/sys/dev/twa/tw_cl_intr.c Sun Sep 12 00:53:10 2010 (r212489)
+++ stable/8/sys/dev/twa/tw_cl_intr.c Sun Sep 12 06:19:35 2010 (r212490)
@@ -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/8/sys/dev/twa/tw_cl_io.c
==============================================================================
--- stable/8/sys/dev/twa/tw_cl_io.c Sun Sep 12 00:53:10 2010 (r212489)
+++ stable/8/sys/dev/twa/tw_cl_io.c Sun Sep 12 06:19:35 2010 (r212490)
@@ -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/8/sys/dev/twa/tw_cl_misc.c
==============================================================================
--- stable/8/sys/dev/twa/tw_cl_misc.c Sun Sep 12 00:53:10 2010 (r212489)
+++ stable/8/sys/dev/twa/tw_cl_misc.c Sun Sep 12 06:19:35 2010 (r212490)
@@ -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/8/sys/dev/twa/tw_cl_share.h
==============================================================================
--- stable/8/sys/dev/twa/tw_cl_share.h Sun Sep 12 00:53:10 2010 (r212489)
+++ stable/8/sys/dev/twa/tw_cl_share.h Sun Sep 12 06:19:35 2010 (r212490)
@@ -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/8/sys/dev/twa/tw_osl.h
==============================================================================
--- stable/8/sys/dev/twa/tw_osl.h Sun Sep 12 00:53:10 2010 (r212489)
+++ stable/8/sys/dev/twa/tw_osl.h Sun Sep 12 06:19:35 2010 (r212490)
@@ -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/8/sys/dev/twa/tw_osl_cam.c
==============================================================================
--- stable/8/sys/dev/twa/tw_osl_cam.c Sun Sep 12 00:53:10 2010 (r212489)
+++ stable/8/sys/dev/twa/tw_osl_cam.c Sun Sep 12 06:19:35 2010 (r212490)
@@ -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_INT32 tw_osli_execute_scsi(struct tw_osli_req_context *req,
union ccb *ccb);
@@ -81,7 +80,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,
@@ -275,6 +274,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);
}
@@ -290,6 +290,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);
}
@@ -306,13 +307,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);
}
@@ -345,10 +353,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;
@@ -364,25 +382,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;
@@ -450,6 +457,7 @@ twa_action(struct cam_sim *sim, union cc
path_inq->transport_version = 2;
path_inq->protocol = PROTO_SCSI;
path_inq->protocol_version = SCSI_REV_2;
+ path_inq->maxio = TW_CL_MAX_IO_SIZE;
ccb_h->status = CAM_REQ_CMP;
xpt_done(ccb);
break;
@@ -487,31 +495,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.
*
@@ -574,20 +557,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,
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list