diff options
Diffstat (limited to 'sys/dev/twa/tw_cl_intr.c')
-rw-r--r-- | sys/dev/twa/tw_cl_intr.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/sys/dev/twa/tw_cl_intr.c b/sys/dev/twa/tw_cl_intr.c index 3271d59..818e4ee 100644 --- a/sys/dev/twa/tw_cl_intr.c +++ b/sys/dev/twa/tw_cl_intr.c @@ -70,10 +70,11 @@ tw_cl_interrupt(struct tw_cl_ctlr_handle *ctlr_handle) tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), "entered"); /* - * Serialize access to this function so multiple threads don't try to - * do the same thing (such as clearing interrupt bits). + * Synchronize access between writes to command and control registers + * in 64-bit environments, on G66. */ - tw_osl_get_lock(ctlr_handle, ctlr->intr_lock); + if (ctlr->state & TW_CLI_CTLR_STATE_G66_WORKAROUND_NEEDED) + tw_osl_get_lock(ctlr_handle, ctlr->io_lock); /* Read the status register to determine the type of interrupt. */ status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr_handle); @@ -114,7 +115,8 @@ tw_cl_interrupt(struct tw_cl_ctlr_handle *ctlr_handle) rc |= TW_CL_TRUE; /* request for a deferred isr call */ } out: - tw_osl_free_lock(ctlr_handle, ctlr->intr_lock); + if (ctlr->state & TW_CLI_CTLR_STATE_G66_WORKAROUND_NEEDED) + tw_osl_free_lock(ctlr_handle, ctlr->io_lock); return(rc); } @@ -319,10 +321,13 @@ tw_cli_process_resp_intr(struct tw_cli_ctlr_context *ctlr) tw_cli_req_q_remove_item(req, TW_CLI_BUSY_Q); req->state = TW_CLI_REQ_STATE_COMPLETE; tw_cli_req_q_insert_tail(req, TW_CLI_COMPLETE_Q); + #ifdef TW_OSL_NON_DMA_MEM_ALLOC_PER_REQUEST + tw_osl_free_lock(ctlr->ctlr_handle, ctlr->intr_lock); /* Call the CL internal callback, if there's one. */ if (req->tw_cli_callback) req->tw_cli_callback(req); + tw_osl_get_lock(ctlr->ctlr_handle, ctlr->intr_lock); #endif /* TW_OSL_NON_DMA_MEM_ALLOC_PER_REQUEST */ } |