Skip to content

Commit

Permalink
isci: unify remote_device start_task_handlers
Browse files Browse the repository at this point in the history
Implement all states in scic_sds_remote_device_start_task() and delete
the state handler.

Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Dan Williams committed Jul 3, 2011
1 parent c027a20 commit 84b9b02
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 152 deletions.
236 changes: 90 additions & 146 deletions drivers/scsi/isci/remote_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,22 +521,97 @@ enum sci_status scic_sds_remote_device_complete_io(struct scic_sds_controller *s
return status;
}

/**
*
* @controller: The controller that is starting the task request.
* @sci_dev: The remote device for which the start task handling is being
* requested.
* @io_request: The task request that is being started.
*
* This method invokes the remote device start task handler. enum sci_status
*/
enum sci_status scic_sds_remote_device_start_task(
struct scic_sds_controller *controller,
struct scic_sds_remote_device *sci_dev,
struct scic_sds_request *io_request)
static void scic_sds_remote_device_continue_request(void *dev)
{
struct scic_sds_remote_device *sci_dev = dev;

/* we need to check if this request is still valid to continue. */
if (sci_dev->working_request)
scic_controller_continue_io(sci_dev->working_request);
}

enum sci_status scic_sds_remote_device_start_task(struct scic_sds_controller *scic,
struct scic_sds_remote_device *sci_dev,
struct scic_sds_request *sci_req)
{
return sci_dev->state_handlers->start_task_handler(
sci_dev, io_request);
struct sci_base_state_machine *sm = &sci_dev->state_machine;
enum scic_sds_remote_device_states state = sm->current_state_id;
struct scic_sds_port *sci_port = sci_dev->owning_port;
enum sci_status status;

switch (state) {
case SCI_BASE_REMOTE_DEVICE_STATE_INITIAL:
case SCI_BASE_REMOTE_DEVICE_STATE_STOPPED:
case SCI_BASE_REMOTE_DEVICE_STATE_STARTING:
case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE:
case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD:
case SCI_BASE_REMOTE_DEVICE_STATE_STOPPING:
case SCI_BASE_REMOTE_DEVICE_STATE_FAILED:
case SCI_BASE_REMOTE_DEVICE_STATE_RESETTING:
case SCI_BASE_REMOTE_DEVICE_STATE_FINAL:
default:
dev_warn(scirdev_to_dev(sci_dev), "%s: in wrong state: %d\n",
__func__, state);
return SCI_FAILURE_INVALID_STATE;
case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE:
case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD:
case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ:
case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR:
case SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET:
status = scic_sds_port_start_io(sci_port, sci_dev, sci_req);
if (status != SCI_SUCCESS)
return status;

status = scic_sds_remote_node_context_start_task(&sci_dev->rnc, sci_req);
if (status != SCI_SUCCESS)
goto out;

status = sci_req->state_handlers->start_handler(sci_req);
if (status != SCI_SUCCESS)
goto out;

/* Note: If the remote device state is not IDLE this will
* replace the request that probably resulted in the task
* management request.
*/
sci_dev->working_request = sci_req;
sci_base_state_machine_change_state(sm, SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);

/* The remote node context must cleanup the TCi to NCQ mapping
* table. The only way to do this correctly is to either write
* to the TLCR register or to invalidate and repost the RNC. In
* either case the remote node context state machine will take
* the correct action when the remote node context is suspended
* and later resumed.
*/
scic_sds_remote_node_context_suspend(&sci_dev->rnc,
SCI_SOFTWARE_SUSPENSION, NULL, NULL);
scic_sds_remote_node_context_resume(&sci_dev->rnc,
scic_sds_remote_device_continue_request,
sci_dev);

out:
scic_sds_remote_device_start_request(sci_dev, sci_req, status);
/* We need to let the controller start request handler know that
* it can't post TC yet. We will provide a callback function to
* post TC when RNC gets resumed.
*/
return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
case SCI_BASE_REMOTE_DEVICE_STATE_READY:
status = scic_sds_port_start_io(sci_port, sci_dev, sci_req);
if (status != SCI_SUCCESS)
return status;

status = scic_sds_remote_node_context_start_task(&sci_dev->rnc, sci_req);
if (status != SCI_SUCCESS)
break;

status = scic_sds_request_start(sci_req);
break;
}
scic_sds_remote_device_start_request(sci_dev, sci_req, status);

return status;
}

/**
Expand Down Expand Up @@ -589,23 +664,6 @@ static void remote_device_resume_done(void *_dev)
}
}

/**
*
* @request: This parameter specifies the request being continued.
*
* This method will continue to post tc for a STP request. This method usually
* serves as a callback when RNC gets resumed during a task management
* sequence. none
*/
static void scic_sds_remote_device_continue_request(void *dev)
{
struct scic_sds_remote_device *sci_dev = dev;

/* we need to check if this request is still valid to continue. */
if (sci_dev->working_request)
scic_controller_continue_io(sci_dev->working_request);
}

static enum sci_status
default_device_handler(struct scic_sds_remote_device *sci_dev,
const char *func)
Expand Down Expand Up @@ -737,13 +795,6 @@ static enum sci_status scic_sds_remote_device_default_frame_handler(
return SCI_FAILURE_INVALID_STATE;
}

static enum sci_status scic_sds_remote_device_default_start_request_handler(
struct scic_sds_remote_device *sci_dev,
struct scic_sds_request *request)
{
return default_device_handler(sci_dev, __func__);
}

static enum sci_status scic_sds_remote_device_default_complete_request_handler(
struct scic_sds_remote_device *sci_dev,
struct scic_sds_request *request)
Expand Down Expand Up @@ -816,36 +867,6 @@ static enum sci_status scic_sds_remote_device_general_event_handler(
true);
}

/*
* This method will attempt to start a task request for this device object. The
* remote device object will issue the start request for the task and if
* successful it will start the request for the port object then increment its
* own requet count. enum sci_status SCI_SUCCESS if the task request is started for
* this device object. SCI_FAILURE_INSUFFICIENT_RESOURCES if the io request
* object could not get the resources to start.
*/
static enum sci_status scic_sds_remote_device_ready_state_start_task_handler(
struct scic_sds_remote_device *sci_dev,
struct scic_sds_request *request)
{
enum sci_status result;

/* See if the port is in a state where we can start the IO request */
result = scic_sds_port_start_io(
scic_sds_remote_device_get_port(sci_dev), sci_dev, request);

if (result == SCI_SUCCESS) {
result = scic_sds_remote_node_context_start_task(&sci_dev->rnc,
request);
if (result == SCI_SUCCESS)
result = scic_sds_request_start(request);

scic_sds_remote_device_start_request(sci_dev, request, result);
}

return result;
}

/*
* This method will complete the request for the remote device object. The
* method will call the completion handler for the request object and if
Expand Down Expand Up @@ -976,68 +997,6 @@ static enum sci_status scic_sds_stp_remote_device_complete_request(struct scic_s
return status;
}

/* scic_sds_stp_remote_device_ready_substate_start_request_handler - start stp
* @device: The target device a task management request towards to.
* @request: The task request.
*
* This is the READY NCQ substate handler to start task management request. In
* this routine, we suspend and resume the RNC. enum sci_status Always return
* SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status to let
* controller_start_task_handler know that the controller can't post TC for
* task request yet, instead, when RNC gets resumed, a controller_continue_task
* callback will be called.
*/
static enum sci_status scic_sds_stp_remote_device_ready_substate_start_request_handler(
struct scic_sds_remote_device *device,
struct scic_sds_request *request)
{
enum sci_status status;

/* Will the port allow the io request to start? */
status = device->owning_port->state_handlers->start_io_handler(
device->owning_port, device, request);
if (status != SCI_SUCCESS)
return status;

status = scic_sds_remote_node_context_start_task(&device->rnc, request);
if (status != SCI_SUCCESS)
goto out;

status = request->state_handlers->start_handler(request);
if (status != SCI_SUCCESS)
goto out;

/*
* Note: If the remote device state is not IDLE this will replace
* the request that probably resulted in the task management request.
*/
device->working_request = request;
sci_base_state_machine_change_state(&device->state_machine,
SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD);

/*
* The remote node context must cleanup the TCi to NCQ mapping table.
* The only way to do this correctly is to either write to the TLCR
* register or to invalidate and repost the RNC. In either case the
* remote node context state machine will take the correct action when
* the remote node context is suspended and later resumed.
*/
scic_sds_remote_node_context_suspend(&device->rnc,
SCI_SOFTWARE_SUSPENSION, NULL, NULL);
scic_sds_remote_node_context_resume(&device->rnc,
scic_sds_remote_device_continue_request,
device);

out:
scic_sds_remote_device_start_request(device, request, status);
/*
* We need to let the controller start request handler know that it can't
* post TC yet. We will provide a callback function to post TC when RNC gets
* resumed.
*/
return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
}

static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler(
struct scic_sds_remote_device *sci_dev,
u32 event_code)
Expand Down Expand Up @@ -1154,119 +1113,104 @@ static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_frame_handl

static const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[] = {
[SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = {
.start_task_handler = scic_sds_remote_device_default_start_request_handler,
.complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_default_event_handler,
.frame_handler = scic_sds_remote_device_default_frame_handler
},
[SCI_BASE_REMOTE_DEVICE_STATE_STOPPED] = {
.start_task_handler = scic_sds_remote_device_default_start_request_handler,
.complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_default_event_handler,
.frame_handler = scic_sds_remote_device_default_frame_handler
},
[SCI_BASE_REMOTE_DEVICE_STATE_STARTING] = {
.start_task_handler = scic_sds_remote_device_default_start_request_handler,
.complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_default_frame_handler
},
[SCI_BASE_REMOTE_DEVICE_STATE_READY] = {
.start_task_handler = scic_sds_remote_device_ready_state_start_task_handler,
.complete_task_handler = scic_sds_remote_device_ready_state_complete_request_handler,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler,
},
[SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
.start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
.complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_stp_remote_device_ready_idle_substate_event_handler,
.frame_handler = scic_sds_remote_device_default_frame_handler
},
[SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
.start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
.complete_task_handler = scic_sds_stp_remote_device_complete_request,
.suspend_handler = scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
},
[SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
.start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
.complete_task_handler = scic_sds_stp_remote_device_complete_request,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
},
[SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
.start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
.complete_task_handler = scic_sds_stp_remote_device_complete_request,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler
},
[SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
.start_task_handler = scic_sds_stp_remote_device_ready_substate_start_request_handler,
.complete_task_handler = scic_sds_stp_remote_device_complete_request,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler
},
[SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
.start_task_handler = scic_sds_remote_device_default_start_request_handler,
.complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_default_frame_handler
},
[SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
.start_task_handler = scic_sds_remote_device_default_start_request_handler,
.complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_smp_remote_device_ready_cmd_substate_frame_handler
},
[SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = {
.start_task_handler = scic_sds_remote_device_default_start_request_handler,
.complete_task_handler = scic_sds_remote_device_stopping_state_complete_request_handler,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler
},
[SCI_BASE_REMOTE_DEVICE_STATE_FAILED] = {
.start_task_handler = scic_sds_remote_device_default_start_request_handler,
.complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_default_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler
},
[SCI_BASE_REMOTE_DEVICE_STATE_RESETTING] = {
.start_task_handler = scic_sds_remote_device_default_start_request_handler,
.complete_task_handler = scic_sds_remote_device_resetting_state_complete_request_handler,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
.event_handler = scic_sds_remote_device_default_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler
},
[SCI_BASE_REMOTE_DEVICE_STATE_FINAL] = {
.start_task_handler = scic_sds_remote_device_default_start_request_handler,
.complete_task_handler = scic_sds_remote_device_default_complete_request_handler,
.suspend_handler = scic_sds_remote_device_default_suspend_handler,
.resume_handler = scic_sds_remote_device_default_resume_handler,
Expand Down
6 changes: 0 additions & 6 deletions drivers/scsi/isci/remote_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,12 +386,6 @@ typedef void (*scic_sds_remote_device_ready_not_ready_handler_t)(
*
*/
struct scic_sds_remote_device_state_handler {
/**
* The start_task_handler specifies the method invoked when a user
* attempts to start a task management request for a remote device.
*/
scic_sds_remote_device_request_handler_t start_task_handler;

/**
* The complete_task_handler specifies the method invoked when a user
* attempts to complete a task management request for a remote device.
Expand Down

0 comments on commit 84b9b02

Please sign in to comment.