isci: unify remote_device event_handlers

Implement all states in scic_sds_remote_device_event() and delete
the state handler.

Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
Dan Williams 2011-05-01 16:26:09 -07:00
Родитель 978edfef46
Коммит e622571f0f
2 изменённых файлов: 82 добавлений и 160 удалений

Просмотреть файл

@ -293,19 +293,84 @@ enum sci_status scic_sds_remote_device_frame_handler(
return sci_dev->state_handlers->frame_handler(sci_dev, frame_index); return sci_dev->state_handlers->frame_handler(sci_dev, frame_index);
} }
/** static bool is_remote_device_ready(struct scic_sds_remote_device *sci_dev)
*
* @sci_dev: The remote device for which the event handling is being
* requested.
* @event_code: This is the event code that is to be processed.
*
* This method invokes the remote device event handler. enum sci_status
*/
enum sci_status scic_sds_remote_device_event_handler(
struct scic_sds_remote_device *sci_dev,
u32 event_code)
{ {
return sci_dev->state_handlers->event_handler(sci_dev, event_code);
struct sci_base_state_machine *sm = &sci_dev->state_machine;
enum scic_sds_remote_device_states state = sm->current_state_id;
switch (state) {
case SCI_BASE_REMOTE_DEVICE_STATE_READY:
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:
case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE:
case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD:
return true;
default:
return false;
}
}
enum sci_status scic_sds_remote_device_event_handler(struct scic_sds_remote_device *sci_dev,
u32 event_code)
{
struct sci_base_state_machine *sm = &sci_dev->state_machine;
enum scic_sds_remote_device_states state = sm->current_state_id;
enum sci_status status;
switch (scu_get_event_type(event_code)) {
case SCU_EVENT_TYPE_RNC_OPS_MISC:
case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
status = scic_sds_remote_node_context_event_handler(&sci_dev->rnc, event_code);
break;
case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT:
if (scu_get_event_code(event_code) == SCU_EVENT_IT_NEXUS_TIMEOUT) {
status = SCI_SUCCESS;
/* Suspend the associated RNC */
scic_sds_remote_node_context_suspend(&sci_dev->rnc,
SCI_SOFTWARE_SUSPENSION,
NULL, NULL);
dev_dbg(scirdev_to_dev(sci_dev),
"%s: device: %p event code: %x: %s\n",
__func__, sci_dev, event_code,
is_remote_device_ready(sci_dev)
? "I_T_Nexus_Timeout event"
: "I_T_Nexus_Timeout event in wrong state");
break;
}
/* Else, fall through and treat as unhandled... */
default:
dev_dbg(scirdev_to_dev(sci_dev),
"%s: device: %p event code: %x: %s\n",
__func__, sci_dev, event_code,
is_remote_device_ready(sci_dev)
? "unexpected event"
: "unexpected event in wrong state");
status = SCI_FAILURE_INVALID_STATE;
break;
}
if (status != SCI_SUCCESS)
return status;
if (state == SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE) {
/* We pick up suspension events to handle specifically to this
* state. We resume the RNC right away.
*/
if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX ||
scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
status = scic_sds_remote_node_context_resume(&sci_dev->rnc, NULL, NULL);
}
return status;
} }
static void scic_sds_remote_device_start_request(struct scic_sds_remote_device *sci_dev, static void scic_sds_remote_device_start_request(struct scic_sds_remote_device *sci_dev,
@ -646,103 +711,13 @@ void scic_sds_remote_device_post_request(
static void remote_device_resume_done(void *_dev) static void remote_device_resume_done(void *_dev)
{ {
struct scic_sds_remote_device *sci_dev = _dev; struct scic_sds_remote_device *sci_dev = _dev;
enum scic_sds_remote_device_states state;
state = sci_dev->state_machine.current_state_id; if (is_remote_device_ready(sci_dev))
switch (state) { return;
case SCI_BASE_REMOTE_DEVICE_STATE_READY:
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:
case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE:
case SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD:
break;
default:
/* go 'ready' if we are not already in a ready state */
sci_base_state_machine_change_state(&sci_dev->state_machine,
SCI_BASE_REMOTE_DEVICE_STATE_READY);
break;
}
}
/** /* go 'ready' if we are not already in a ready state */
* sci_base_state_machine_change_state(&sci_dev->state_machine,
* @device: The struct scic_sds_remote_device which is then cast into a SCI_BASE_REMOTE_DEVICE_STATE_READY);
* struct scic_sds_remote_device.
* @event_code: The event code that the struct scic_sds_controller wants the device
* object to process.
*
* This method is the default event handler. It will call the RNC state
* machine handler for any RNC events otherwise it will log a warning and
* returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE
*/
static enum sci_status scic_sds_remote_device_core_event_handler(
struct scic_sds_remote_device *sci_dev,
u32 event_code,
bool is_ready_state)
{
enum sci_status status;
switch (scu_get_event_type(event_code)) {
case SCU_EVENT_TYPE_RNC_OPS_MISC:
case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
status = scic_sds_remote_node_context_event_handler(&sci_dev->rnc, event_code);
break;
case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT:
if (scu_get_event_code(event_code) == SCU_EVENT_IT_NEXUS_TIMEOUT) {
status = SCI_SUCCESS;
/* Suspend the associated RNC */
scic_sds_remote_node_context_suspend(&sci_dev->rnc,
SCI_SOFTWARE_SUSPENSION,
NULL, NULL);
dev_dbg(scirdev_to_dev(sci_dev),
"%s: device: %p event code: %x: %s\n",
__func__, sci_dev, event_code,
(is_ready_state)
? "I_T_Nexus_Timeout event"
: "I_T_Nexus_Timeout event in wrong state");
break;
}
/* Else, fall through and treat as unhandled... */
default:
dev_dbg(scirdev_to_dev(sci_dev),
"%s: device: %p event code: %x: %s\n",
__func__, sci_dev, event_code,
(is_ready_state)
? "unexpected event"
: "unexpected event in wrong state");
status = SCI_FAILURE_INVALID_STATE;
break;
}
return status;
}
/**
*
* @device: The struct scic_sds_remote_device which is then cast into a
* struct scic_sds_remote_device.
* @event_code: The event code that the struct scic_sds_controller wants the device
* object to process.
*
* This method is the default event handler. It will call the RNC state
* machine handler for any RNC events otherwise it will log a warning and
* returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE
*/
static enum sci_status scic_sds_remote_device_default_event_handler(
struct scic_sds_remote_device *sci_dev,
u32 event_code)
{
return scic_sds_remote_device_core_event_handler(sci_dev,
event_code,
false);
} }
/** /**
@ -824,43 +799,6 @@ static enum sci_status scic_sds_remote_device_general_frame_handler(
return result; return result;
} }
/**
*
* @[in]: sci_dev This is the device object that is receiving the event.
* @[in]: event_code The event code to process.
*
* This is a common method for handling events reported to the remote device
* from the controller object. enum sci_status
*/
static enum sci_status scic_sds_remote_device_general_event_handler(
struct scic_sds_remote_device *sci_dev,
u32 event_code)
{
return scic_sds_remote_device_core_event_handler(sci_dev,
event_code,
true);
}
static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler(
struct scic_sds_remote_device *sci_dev,
u32 event_code)
{
enum sci_status status;
status = scic_sds_remote_device_general_event_handler(sci_dev, event_code);
if (status != SCI_SUCCESS)
return status;
/* We pick up suspension events to handle specifically to this state. We
* resume the RNC right away. enum sci_status
*/
if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX ||
scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
status = scic_sds_remote_node_context_resume(&sci_dev->rnc, NULL, NULL);
return status;
}
static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(struct scic_sds_remote_device *sci_dev, static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(struct scic_sds_remote_device *sci_dev,
u32 frame_index) u32 frame_index)
{ {
@ -945,63 +883,48 @@ 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[] = { static const struct scic_sds_remote_device_state_handler scic_sds_remote_device_state_handler_table[] = {
[SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = { [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = {
.event_handler = scic_sds_remote_device_default_event_handler,
.frame_handler = scic_sds_remote_device_default_frame_handler .frame_handler = scic_sds_remote_device_default_frame_handler
}, },
[SCI_BASE_REMOTE_DEVICE_STATE_STOPPED] = { [SCI_BASE_REMOTE_DEVICE_STATE_STOPPED] = {
.event_handler = scic_sds_remote_device_default_event_handler,
.frame_handler = scic_sds_remote_device_default_frame_handler .frame_handler = scic_sds_remote_device_default_frame_handler
}, },
[SCI_BASE_REMOTE_DEVICE_STATE_STARTING] = { [SCI_BASE_REMOTE_DEVICE_STATE_STARTING] = {
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_default_frame_handler .frame_handler = scic_sds_remote_device_default_frame_handler
}, },
[SCI_BASE_REMOTE_DEVICE_STATE_READY] = { [SCI_BASE_REMOTE_DEVICE_STATE_READY] = {
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler, .frame_handler = scic_sds_remote_device_general_frame_handler,
}, },
[SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
.event_handler = scic_sds_stp_remote_device_ready_idle_substate_event_handler,
.frame_handler = scic_sds_remote_device_default_frame_handler .frame_handler = scic_sds_remote_device_default_frame_handler
}, },
[SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler .frame_handler = scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
}, },
[SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = { [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler .frame_handler = scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
}, },
[SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = { [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler .frame_handler = scic_sds_remote_device_general_frame_handler
}, },
[SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = { [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler .frame_handler = scic_sds_remote_device_general_frame_handler
}, },
[SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = { [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_default_frame_handler .frame_handler = scic_sds_remote_device_default_frame_handler
}, },
[SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = { [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_smp_remote_device_ready_cmd_substate_frame_handler .frame_handler = scic_sds_smp_remote_device_ready_cmd_substate_frame_handler
}, },
[SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = { [SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = {
.event_handler = scic_sds_remote_device_general_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler .frame_handler = scic_sds_remote_device_general_frame_handler
}, },
[SCI_BASE_REMOTE_DEVICE_STATE_FAILED] = { [SCI_BASE_REMOTE_DEVICE_STATE_FAILED] = {
.event_handler = scic_sds_remote_device_default_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler .frame_handler = scic_sds_remote_device_general_frame_handler
}, },
[SCI_BASE_REMOTE_DEVICE_STATE_RESETTING] = { [SCI_BASE_REMOTE_DEVICE_STATE_RESETTING] = {
.event_handler = scic_sds_remote_device_default_event_handler,
.frame_handler = scic_sds_remote_device_general_frame_handler .frame_handler = scic_sds_remote_device_general_frame_handler
}, },
[SCI_BASE_REMOTE_DEVICE_STATE_FINAL] = { [SCI_BASE_REMOTE_DEVICE_STATE_FINAL] = {
.event_handler = scic_sds_remote_device_default_event_handler,
.frame_handler = scic_sds_remote_device_default_frame_handler .frame_handler = scic_sds_remote_device_default_frame_handler
} }
}; };

Просмотреть файл

@ -386,7 +386,6 @@ typedef void (*scic_sds_remote_device_ready_not_ready_handler_t)(
* *
*/ */
struct scic_sds_remote_device_state_handler { struct scic_sds_remote_device_state_handler {
scic_sds_remote_device_event_handler_t event_handler;
scic_sds_remote_device_frame_handler_t frame_handler; scic_sds_remote_device_frame_handler_t frame_handler;
}; };