浏览代码

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>
Dan Williams 14 年之前
父节点
当前提交
e622571f0f
共有 2 个文件被更改,包括 82 次插入160 次删除
  1. 82 159
      drivers/scsi/isci/remote_device.c
  2. 0 1
      drivers/scsi/isci/remote_device.h

+ 82 - 159
drivers/scsi/isci/remote_device.c

@@ -293,19 +293,84 @@ enum sci_status scic_sds_remote_device_frame_handler(
 	return sci_dev->state_handlers->frame_handler(sci_dev, frame_index);
 }
 
-/**
- *
- * @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)
+static bool is_remote_device_ready(struct scic_sds_remote_device *sci_dev)
 {
-	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,
@@ -646,103 +711,13 @@ void scic_sds_remote_device_post_request(
 static void remote_device_resume_done(void *_dev)
 {
 	struct scic_sds_remote_device *sci_dev = _dev;
-	enum scic_sds_remote_device_states state;
 
-	state = sci_dev->state_machine.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:
-		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;
-	}
-}
+	if (is_remote_device_ready(sci_dev))
+		return;
 
-/**
- *
- * @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_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);
+	/* 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);
 }
 
 /**
@@ -824,43 +799,6 @@ static enum sci_status scic_sds_remote_device_general_frame_handler(
 	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,
 										   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[] = {
 	[SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = {
-		.event_handler		= scic_sds_remote_device_default_event_handler,
 		.frame_handler		= scic_sds_remote_device_default_frame_handler
 	},
 	[SCI_BASE_REMOTE_DEVICE_STATE_STOPPED] = {
-		.event_handler		= scic_sds_remote_device_default_event_handler,
 		.frame_handler		= scic_sds_remote_device_default_frame_handler
 	},
 	[SCI_BASE_REMOTE_DEVICE_STATE_STARTING] = {
-		.event_handler		= scic_sds_remote_device_general_event_handler,
 		.frame_handler		= scic_sds_remote_device_default_frame_handler
 	},
 	[SCI_BASE_REMOTE_DEVICE_STATE_READY] = {
-		.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] = {
-		.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] = {
-		.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] = {
-		.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] = {
-		.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] = {
-		.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] = {
-		.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] = {
-		.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] = {
-		.event_handler		= scic_sds_remote_device_general_event_handler,
 		.frame_handler		= scic_sds_remote_device_general_frame_handler
 	},
 	[SCI_BASE_REMOTE_DEVICE_STATE_FAILED] = {
-		.event_handler		= scic_sds_remote_device_default_event_handler,
 		.frame_handler		= scic_sds_remote_device_general_frame_handler
 	},
 	[SCI_BASE_REMOTE_DEVICE_STATE_RESETTING] = {
-		.event_handler		= scic_sds_remote_device_default_event_handler,
 		.frame_handler		= scic_sds_remote_device_general_frame_handler
 	},
 	[SCI_BASE_REMOTE_DEVICE_STATE_FINAL] = {
-		.event_handler		= scic_sds_remote_device_default_event_handler,
 		.frame_handler		= scic_sds_remote_device_default_frame_handler
 	}
 };

+ 0 - 1
drivers/scsi/isci/remote_device.h

@@ -386,7 +386,6 @@ typedef void (*scic_sds_remote_device_ready_not_ready_handler_t)(
  *
  */
 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;
 };