Beispiel #1
0
/*
 * Function name:	tw_cli_submit_pending_queue
 * Description:		Kick starts any requests in the pending queue.
 *
 * Input:		ctlr	-- ptr to CL internal ctlr context
 * Output:		None
 * Return value:	0	-- all pending requests submitted successfully
 *			non-zero-- otherwise
 */
TW_INT32
tw_cli_submit_pending_queue(struct tw_cli_ctlr_context *ctlr)
{
	struct tw_cli_req_context	*req;
	TW_INT32			error = TW_OSL_ESUCCESS;
    
	tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
	
	/*
	 * Pull requests off the pending queue, and submit them.
	 */
	while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_PENDING_Q)) !=
		TW_CL_NULL) {
		if ((error = tw_cli_submit_cmd(req))) {
			if (error == TW_OSL_EBUSY) {
				tw_cli_dbg_printf(2, ctlr->ctlr_handle,
					tw_osl_cur_func(),
					"Requeueing pending request");
				req->state = TW_CLI_REQ_STATE_PENDING;
				/*
				 * Queue the request at the head of the pending
				 * queue, and break away, so we don't try to
				 * submit any more requests.
				 */
				tw_cli_req_q_insert_head(req, TW_CLI_PENDING_Q);
				break;
			} else {
				tw_cl_create_event(ctlr->ctlr_handle,
					TW_CL_FALSE,
					TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
					0x1202, 0x1,
					TW_CL_SEVERITY_ERROR_STRING,
					"Could not start request "
					"in pending queue",
					"request = %p, opcode = 0x%x, "
					"error = %d", req,
					GET_OPCODE(req->cmd_pkt->
						command.cmd_pkt_9k.res__opcode),
					error);
				/*
				 * Set the appropriate error and call the CL
				 * internal callback if there's one.  If the
				 * request originator is polling for completion,
				 * he should be checking req->error to
				 * determine that the request did not go
				 * through.  The request originators are
				 * responsible for the clean-up.
				 */
				req->error_code = error;
				req->state = TW_CLI_REQ_STATE_COMPLETE;
				if (req->tw_cli_callback)
					req->tw_cli_callback(req);
				error = TW_OSL_ESUCCESS;
			}
		}
	}
	return(error);
}
Beispiel #2
0
/*
 * Function name:	tw_cli_process_complete_queue
 * Description:		Calls the CL internal callback routine, if any, for
 *			each request in the complete queue.
 *
 * Input:		ctlr	-- ptr to CL internal ctlr context
 * Output:		None
 * Return value:	None
 */
TW_VOID
tw_cli_process_complete_queue(struct tw_cli_ctlr_context *ctlr)
{
	struct tw_cli_req_context	*req;
    
	tw_cli_dbg_printf(10, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");

	/*
	 * Pull commands off the completed list, dispatch them appropriately.
	 */
	while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_COMPLETE_Q)) !=
		TW_CL_NULL) {
		/* Call the CL internal callback, if there's one. */
		if (req->tw_cli_callback)
			req->tw_cli_callback(req);
	}
}
Beispiel #3
0
/*
 * Function name:	tw_cli_get_request
 * Description:		Gets a request pkt from the free queue.
 *
 * Input:		ctlr	-- ptr to CL internal ctlr context
 *			req_pkt -- ptr to OSL built req_pkt, if there's one
 * Output:		None
 * Return value:	ptr to request pkt	-- success
 *			TW_CL_NULL		-- failure
 */
struct tw_cli_req_context *
tw_cli_get_request(struct tw_cli_ctlr_context *ctlr
	)
{
	struct tw_cli_req_context	*req;

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

	{
		/* Get a free request packet. */
		req = tw_cli_req_q_remove_head(ctlr, TW_CLI_FREE_Q);
	}

	/* Initialize some fields to their defaults. */
	if (req) {
		req->req_handle = TW_CL_NULL;
		req->data = TW_CL_NULL;
		req->length = 0;
		req->data_phys = 0;
		req->state = TW_CLI_REQ_STATE_INIT; /* req being initialized */
		req->flags = 0;
		req->error_code = 0;
		req->orig_req = TW_CL_NULL;
		req->tw_cli_callback = TW_CL_NULL;

		/*
		 * Look at the status field in the command packet to see how
		 * it completed the last time it was used, and zero out only
		 * the portions that might have changed.  Note that we don't
		 * care to zero out the sglist.
		 */
		if (req->cmd_pkt->command.cmd_pkt_9k.status)
			tw_osl_memzero(req->cmd_pkt,
				sizeof(struct tw_cl_command_header) +
				28 /* max bytes before sglist */);
		else
			tw_osl_memzero(&(req->cmd_pkt->command),
				28 /* max bytes before sglist */);

	}
	return(req);
}
Beispiel #4
0
TW_VOID
tw_cli_drain_pending_queue(struct tw_cli_ctlr_context *ctlr)
{
	struct tw_cli_req_context	*req;
	struct tw_cl_req_packet		*req_pkt;
    
	tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
	
	/*
	 * Pull requests off the pending queue, and complete them.
	 */
	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
			 * error and call the CL internal callback if there's
			 * one.  If the request originator is polling for
			 * completion, he should be checking req->error to
			 * determine that the request did not go through.
			 * The request originators are responsible for the
			 * clean-up.
			 */
			req->error_code = TW_CL_ERR_REQ_BUS_RESET;
			if (req->tw_cli_callback)
				req->tw_cli_callback(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;

				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 */
}