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