Example #1
0
/*
 * Function name:	tw_cli_aen_callback
 * Description:		Callback for requests to fetch AEN's.
 *
 * Input:		req	-- ptr to completed request pkt
 * Output:		None
 * Return value:	None
 */
TW_VOID
tw_cli_aen_callback(struct tw_cli_req_context *req)
{
	struct tw_cli_ctlr_context	*ctlr = req->ctlr;
	struct tw_cl_command_header	*cmd_hdr;
	struct tw_cl_command_9k		*cmd =
		&(req->cmd_pkt->command.cmd_pkt_9k);
	TW_UINT16			aen_code = TWA_AEN_QUEUE_EMPTY;
	TW_INT32			error;

	tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");

	tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(),
		"req_id = 0x%x, req error = %d, status = 0x%x",
		GET_REQ_ID(cmd->lun_l4__req_id), req->error_code, cmd->status);

	/*
	 * If the request was never submitted to the controller, the function
	 * that sets error is responsible for calling tw_cl_create_event.
	 */
	if (!(error = req->error_code))
		if ((error = cmd->status)) {
			cmd_hdr = (struct tw_cl_command_header *)
				(&(req->cmd_pkt->cmd_hdr));
			tw_cli_create_ctlr_event(ctlr,
				TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
				cmd_hdr);
			tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
				TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
				0x1206, 0x1, TW_CL_SEVERITY_ERROR_STRING,
				"Request Sense failed",
				"opcode = 0x%x, status = %d",
				GET_OPCODE(cmd->res__opcode), cmd->status);
		}

	if (error) {
		ctlr->internal_req_busy = TW_CL_FALSE;
		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
		return;
	}

	tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(),
		"Request Sense command succeeded");

	aen_code = tw_cli_manage_aen(ctlr, req);

	if (aen_code != TWA_AEN_SYNC_TIME_WITH_HOST) {
		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)))
				tw_cl_create_event(ctlr->ctlr_handle,
					TW_CL_FALSE,
					TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
					0x1207, 0x1,
					TW_CL_SEVERITY_ERROR_STRING,
					"Failed to fetch all AEN's",
					"error = %d", error);
	}
}
Example #2
0
/*
 * Function name:	tw_cli_drain_aen_queue
 * Description:		Fetches all un-retrieved AEN's posted by fw.
 *
 * Input:		ctlr	-- ptr to CL internal ctlr context
 * Output:		None
 * Return value:	0	-- success
 *			non-zero-- failure
 */
TW_INT32
tw_cli_drain_aen_queue(struct tw_cli_ctlr_context *ctlr)
{
	struct tw_cli_req_context	*req;
	struct tw_cl_command_header	*cmd_hdr;
	TW_TIME				end_time;
	TW_UINT16			aen_code;
	TW_INT32			error;

	tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");

	for (;;) {
		if ((req = tw_cli_get_request(ctlr
			)) == TW_CL_NULL) {
			error = TW_OSL_EBUSY;
			break;
		}

		req->flags |= TW_CLI_REQ_FLAGS_INTERNAL;
		req->tw_cli_callback = TW_CL_NULL;
		if ((error = tw_cli_send_scsi_cmd(req,
				0x03 /* REQUEST_SENSE */))) {
			tw_cli_dbg_printf(1, ctlr->ctlr_handle,
				tw_osl_cur_func(),
				"Cannot send command to fetch aen");
			break;
		}

		end_time = tw_osl_get_local_time() +
			TW_CLI_REQUEST_TIMEOUT_PERIOD;
		do {
			if ((error = req->error_code))
				/*
				 * This will take care of completion due to
				 * a reset, or a failure in
				 * tw_cli_submit_pending_queue.
				 */
				goto out;

			tw_cli_process_resp_intr(req->ctlr);

			if ((req->state != TW_CLI_REQ_STATE_BUSY) &&
				(req->state != TW_CLI_REQ_STATE_PENDING))
				break;
		} while (tw_osl_get_local_time() <= end_time);

		if (req->state != TW_CLI_REQ_STATE_COMPLETE) {
			error = TW_OSL_ETIMEDOUT;
			break;
		}

		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;
		}

		aen_code = tw_cli_manage_aen(ctlr, req);
		if (aen_code == TWA_AEN_QUEUE_EMPTY)
			break;
		if (aen_code == TWA_AEN_SYNC_TIME_WITH_HOST)
			continue;

		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->internal_req_busy = TW_CL_FALSE;
		tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
	}
	return(error);
}