Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 254495
b: refs/heads/master
c: f139303
h: refs/heads/master
i:
  254493: 60bf26c
  254491: 1990df7
  254487: e7d0699
  254479: b7fc053
  254463: 5f432e8
v: v3
  • Loading branch information
Dan Williams committed Jul 3, 2011
1 parent 588c5b1 commit a3a755b
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 287 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e2f8db509fdd354bb7a68c86515e9d2d8909ccc9
refs/heads/master: f139303d17c47eff4c5b5407dee0a6d43e8fd146
1 change: 0 additions & 1 deletion trunk/drivers/scsi/isci/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@ isci-objs := init.o phy.o request.o sata.o \
remote_node_table.o \
unsolicited_frame_control.o \
stp_request.o \
ssp_request.o \
smp_request.o \
port_config.o \
185 changes: 164 additions & 21 deletions trunk/drivers/scsi/isci/request.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ enum sci_status scic_sds_io_request_frame_handler(
* @sci_req: This parameter specifies the request object for which to copy
* the response data.
*/
void scic_sds_io_request_copy_response(struct scic_sds_request *sci_req)
static void scic_sds_io_request_copy_response(struct scic_sds_request *sci_req)
{
void *resp_buf;
u32 len;
Expand Down Expand Up @@ -978,7 +978,6 @@ scic_sds_io_request_tc_completion(struct scic_sds_request *request, u32 completi
sci_base_state_machine_get_state(&request->state_machine));

return SCI_FAILURE_INVALID_STATE;

}

/*
Expand Down Expand Up @@ -1151,9 +1150,119 @@ static enum sci_status scic_sds_request_aborting_state_frame_handler(
return SCI_SUCCESS;
}

/**
* This method processes the completions transport layer (TL) status to
* determine if the RAW task management frame was sent successfully. If the
* raw frame was sent successfully, then the state for the task request
* transitions to waiting for a response frame.
* @sci_req: This parameter specifies the request for which the TC
* completion was received.
* @completion_code: This parameter indicates the completion status information
* for the TC.
*
* Indicate if the tc completion handler was successful. SCI_SUCCESS currently
* this method always returns success.
*/
static enum sci_status scic_sds_ssp_task_request_await_tc_completion_tc_completion_handler(
struct scic_sds_request *sci_req,
u32 completion_code)
{
switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
scic_sds_request_set_status(sci_req, SCU_TASK_DONE_GOOD,
SCI_SUCCESS);

sci_base_state_machine_change_state(&sci_req->state_machine,
SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE);
break;

case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
/*
* Currently, the decision is to simply allow the task request to
* timeout if the task IU wasn't received successfully.
* There is a potential for receiving multiple task responses if we
* decide to send the task IU again. */
dev_warn(scic_to_dev(sci_req->owning_controller),
"%s: TaskRequest:0x%p CompletionCode:%x - "
"ACK/NAK timeout\n",
__func__,
sci_req,
completion_code);

sci_base_state_machine_change_state(&sci_req->state_machine,
SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE);
break;

default:
/*
* All other completion status cause the IO to be complete. If a NAK
* was received, then it is up to the user to retry the request. */
scic_sds_request_set_status(
sci_req,
SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
);

sci_base_state_machine_change_state(&sci_req->state_machine,
SCI_BASE_REQUEST_STATE_COMPLETED);
break;
}

return SCI_SUCCESS;
}

/**
* This method is responsible for processing a terminate/abort request for this
* TC while the request is waiting for the task management response
* unsolicited frame.
* @sci_req: This parameter specifies the request for which the
* termination was requested.
*
* This method returns an indication as to whether the abort request was
* successfully handled. need to update to ensure the received UF doesn't cause
* damage to subsequent requests (i.e. put the extended tag in a holding
* pattern for this particular device).
*/
static enum sci_status scic_sds_ssp_task_request_await_tc_response_abort_handler(
struct scic_sds_request *request)
{
sci_base_state_machine_change_state(&request->state_machine,
SCI_BASE_REQUEST_STATE_ABORTING);
sci_base_state_machine_change_state(&request->state_machine,
SCI_BASE_REQUEST_STATE_COMPLETED);
return SCI_SUCCESS;
}

/**
* This method processes an unsolicited frame while the task mgmt request is
* waiting for a response frame. It will copy the response data, release
* the unsolicited frame, and transition the request to the
* SCI_BASE_REQUEST_STATE_COMPLETED state.
* @sci_req: This parameter specifies the request for which the
* unsolicited frame was received.
* @frame_index: This parameter indicates the unsolicited frame index that
* should contain the response.
*
* This method returns an indication of whether the TC response frame was
* handled successfully or not. SCI_SUCCESS Currently this value is always
* returned and indicates successful processing of the TC response. Should
* probably update to check frame type and make sure it is a response frame.
*/
static enum sci_status scic_sds_ssp_task_request_await_tc_response_frame_handler(
struct scic_sds_request *request,
u32 frame_index)
{
scic_sds_io_request_copy_response(request);

sci_base_state_machine_change_state(&request->state_machine,
SCI_BASE_REQUEST_STATE_COMPLETED);
scic_sds_controller_release_frame(request->owning_controller,
frame_index);
return SCI_SUCCESS;
}

static const struct scic_sds_io_request_state_handler scic_sds_request_state_handler_table[] = {
[SCI_BASE_REQUEST_STATE_INITIAL] = {
},
[SCI_BASE_REQUEST_STATE_INITIAL] = { },
[SCI_BASE_REQUEST_STATE_CONSTRUCTED] = {
.start_handler = scic_sds_request_constructed_state_start_handler,
.abort_handler = scic_sds_request_constructed_state_abort_handler,
Expand All @@ -1163,6 +1272,14 @@ static const struct scic_sds_io_request_state_handler scic_sds_request_state_han
.tc_completion_handler = scic_sds_request_started_state_tc_completion_handler,
.frame_handler = scic_sds_request_started_state_frame_handler,
},
[SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION] = {
.abort_handler = scic_sds_request_started_state_abort_handler,
.tc_completion_handler = scic_sds_ssp_task_request_await_tc_completion_tc_completion_handler,
},
[SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE] = {
.abort_handler = scic_sds_ssp_task_request_await_tc_response_abort_handler,
.frame_handler = scic_sds_ssp_task_request_await_tc_response_frame_handler,
},
[SCI_BASE_REQUEST_STATE_COMPLETED] = {
.complete_handler = scic_sds_request_completed_state_complete_handler,
},
Expand All @@ -1171,8 +1288,7 @@ static const struct scic_sds_io_request_state_handler scic_sds_request_state_han
.tc_completion_handler = scic_sds_request_aborting_state_tc_completion_handler,
.frame_handler = scic_sds_request_aborting_state_frame_handler,
},
[SCI_BASE_REQUEST_STATE_FINAL] = {
},
[SCI_BASE_REQUEST_STATE_FINAL] = { },
};


Expand Down Expand Up @@ -1919,16 +2035,23 @@ static void scic_sds_request_constructed_state_enter(void *object)
static void scic_sds_request_started_state_enter(void *object)
{
struct scic_sds_request *sci_req = object;
struct sci_base_state_machine *sm = &sci_req->state_machine;
struct isci_request *ireq = sci_req_to_ireq(sci_req);
struct domain_device *dev = sci_dev_to_domain(sci_req->target_device);

SET_STATE_HANDLER(
sci_req,
scic_sds_request_state_handler_table,
SCI_BASE_REQUEST_STATE_STARTED
);

/*
* Most of the request state machines have a started substate machine so
* start its execution on the entry to the started state. */
if (ireq->ttype == tmf_task && dev->dev_type == SAS_END_DEV)
sci_base_state_machine_change_state(sm,
SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION);

/* Most of the request state machines have a started substate machine so
* start its execution on the entry to the started state.
*/
if (sci_req->has_started_substate_machine == true)
sci_base_state_machine_start(&sci_req->started_substate_machine);
}
Expand Down Expand Up @@ -2026,6 +2149,30 @@ static void scic_sds_request_final_state_enter(void *object)
);
}

static void scic_sds_io_request_started_task_mgmt_await_tc_completion_substate_enter(
void *object)
{
struct scic_sds_request *sci_req = object;

SET_STATE_HANDLER(
sci_req,
scic_sds_request_state_handler_table,
SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION
);
}

static void scic_sds_io_request_started_task_mgmt_await_task_response_substate_enter(
void *object)
{
struct scic_sds_request *sci_req = object;

SET_STATE_HANDLER(
sci_req,
scic_sds_request_state_handler_table,
SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE
);
}

static const struct sci_base_state scic_sds_request_state_table[] = {
[SCI_BASE_REQUEST_STATE_INITIAL] = {
.enter_state = scic_sds_request_initial_state_enter,
Expand All @@ -2037,6 +2184,12 @@ static const struct sci_base_state scic_sds_request_state_table[] = {
.enter_state = scic_sds_request_started_state_enter,
.exit_state = scic_sds_request_started_state_exit
},
[SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION] = {
.enter_state = scic_sds_io_request_started_task_mgmt_await_tc_completion_substate_enter,
},
[SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE] = {
.enter_state = scic_sds_io_request_started_task_mgmt_await_task_response_substate_enter,
},
[SCI_BASE_REQUEST_STATE_COMPLETED] = {
.enter_state = scic_sds_request_completed_state_enter,
},
Expand Down Expand Up @@ -2126,19 +2279,9 @@ enum sci_status scic_task_request_construct(struct scic_sds_controller *scic,
/* Build the common part of the request */
scic_sds_general_request_construct(scic, sci_dev, io_tag, sci_req);

if (dev->dev_type == SAS_END_DEV) {
if (dev->dev_type == SAS_END_DEV)
scic_sds_ssp_task_request_assign_buffers(sci_req);

sci_req->has_started_substate_machine = true;

/* Construct the started sub-state machine. */
sci_base_state_machine_construct(
&sci_req->started_substate_machine,
sci_req,
scic_sds_io_request_started_task_mgmt_substate_table,
SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION
);
} else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))
else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))
scic_sds_stp_request_assign_buffers(sci_req);
else
status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
Expand Down
38 changes: 14 additions & 24 deletions trunk/drivers/scsi/isci/request.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,20 @@ enum sci_base_request_states {
*/
SCI_BASE_REQUEST_STATE_STARTED,

/**
* The AWAIT_TC_COMPLETION sub-state indicates that the started raw
* task management request is waiting for the transmission of the
* initial frame (i.e. command, task, etc.).
*/
SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION,

/**
* This sub-state indicates that the started task management request
* is waiting for the reception of an unsolicited frame
* (i.e. response IU).
*/
SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE,

/**
* This state indicates that the request has completed.
* This state is entered from the STARTED state. This state is entered from
Expand Down Expand Up @@ -451,37 +465,13 @@ void scic_sds_stp_request_assign_buffers(struct scic_sds_request *sci_req);
void scic_sds_smp_request_assign_buffers(struct scic_sds_request *sci_req);
enum sci_status scic_sds_request_start(struct scic_sds_request *sci_req);
enum sci_status scic_sds_io_request_terminate(struct scic_sds_request *sci_req);
void scic_sds_io_request_copy_response(struct scic_sds_request *sci_req);
enum sci_status scic_sds_io_request_event_handler(struct scic_sds_request *sci_req,
u32 event_code);
enum sci_status scic_sds_io_request_frame_handler(struct scic_sds_request *sci_req,
u32 frame_index);
enum sci_status scic_sds_task_request_terminate(struct scic_sds_request *sci_req);
enum sci_status scic_sds_request_started_state_abort_handler(struct scic_sds_request *sci_req);

/**
* enum _scic_sds_io_request_started_task_mgmt_substates - This enumeration
* depicts all of the substates for a task management request to be
* performed in the STARTED super-state.
*
*
*/
enum scic_sds_raw_request_started_task_mgmt_substates {
/**
* The AWAIT_TC_COMPLETION sub-state indicates that the started raw
* task management request is waiting for the transmission of the
* initial frame (i.e. command, task, etc.).
*/
SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION,

/**
* This sub-state indicates that the started task management request
* is waiting for the reception of an unsolicited frame
* (i.e. response IU).
*/
SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE,
};


/**
* enum _scic_sds_smp_request_started_substates - This enumeration depicts all
Expand Down
Loading

0 comments on commit a3a755b

Please sign in to comment.