/* * Function name: tw_cli_process_resp_intr * Description: Looks for cmd completions from fw; queues cmds completed * by fw into complete queue. * * Input: ctlr -- ptr to CL internal ctlr context * Output: None * Return value: 0 -- no ctlr error * non-zero-- ctlr error */ TW_INT32 tw_cli_process_resp_intr(struct tw_cli_ctlr_context *ctlr) { TW_UINT32 resp; struct tw_cli_req_context *req; TW_INT32 error; TW_UINT32 status_reg; tw_cli_dbg_printf(10, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); for (;;) { status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr->ctlr_handle); if ((error = tw_cli_check_ctlr_state(ctlr, status_reg))) break; if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY) { tw_cli_dbg_printf(7, ctlr->ctlr_handle, tw_osl_cur_func(), "Response queue empty"); break; } /* Response queue is not empty. */ resp = TW_CLI_READ_RESPONSE_QUEUE(ctlr->ctlr_handle); { req = &(ctlr->req_ctxt_buf[GET_RESP_ID(resp)]); } if (req->state != TW_CLI_REQ_STATE_BUSY) { tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 0x1201, 0x1, TW_CL_SEVERITY_ERROR_STRING, "Unposted command completed!!", "request = %p, status = %d", req, req->state); #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); } /* * Remove the request from the busy queue, mark it as complete, * and enqueue it in the complete queue. */ 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); } /* Complete this, and other requests in the complete queue. */ tw_cli_process_complete_queue(ctlr); return(error); }
/* * Function name: twa_report_stats * Description: For being called from ddb. Calls functions that print * OSL and CL internal stats for the controller. * * Input: None * Output: None * Return value: None */ TW_VOID twa_report_stats(TW_VOID) { struct twa_softc *sc; TW_INT32 i; for (i = 0; (sc = devclass_get_softc(twa_devclass, i)) != NULL; i++) { tw_osli_print_ctlr_stats(sc); tw_cl_print_ctlr_stats(&sc->ctlr_handle); } }
/* * Function name: tw_cli_complete_io * Description: CL internal callback for SCSI/fw passthru requests. * * Input: req -- ptr to CL internal request context * Output: None * Return value: None */ TW_VOID tw_cli_complete_io(struct tw_cli_req_context *req) { struct tw_cli_ctlr_context *ctlr = req->ctlr; struct tw_cl_req_packet *req_pkt = (struct tw_cl_req_packet *)(req->orig_req); tw_cli_dbg_printf(8, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); req_pkt->status = TW_CL_ERR_REQ_SUCCESS; if (req->error_code) { req_pkt->status = TW_CL_ERR_REQ_UNABLE_TO_SUBMIT_COMMAND; goto out; } if (req->state != TW_CLI_REQ_STATE_COMPLETE) { tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 0x1203, 0x1, TW_CL_SEVERITY_ERROR_STRING, "I/O completion on incomplete command!!", "request = %p, status = %d", req, req->state); #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; } if (req->flags & TW_CLI_REQ_FLAGS_PASSTHRU) { /* Copy the command packet back into OSL's space. */ tw_osl_memcpy(req_pkt->gen_req_pkt.pt_req.cmd_pkt, req->cmd_pkt, sizeof(struct tw_cl_command_packet)); } else tw_cli_scsi_complete(req); out: req_pkt->tw_osl_callback(req->req_handle); tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); }