Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed3efb77 authored by Dan Williams's avatar Dan Williams
Browse files

isci: unify rnc suspend/resume handlers



Unify rnc suspend/resume handlers and delete the state handlers.

Reported-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent c845ae96
Loading
Loading
Loading
Loading
+96 −210
Original line number Diff line number Diff line
@@ -195,60 +195,6 @@ static void scic_sds_remote_node_context_setup_to_destory(
	sci_rnc->user_cookie       = callback_parameter;
}

/**
 *
 * @sci_rnc:
 * @callback:
 *
 * This method will continue to resume a remote node context.  This is used in
 * the states where a resume is requested while a resume is in progress.
 */
static enum sci_status scic_sds_remote_node_context_continue_to_resume_handler(
	struct scic_sds_remote_node_context *sci_rnc,
	scics_sds_remote_node_context_callback callback,
	void *callback_parameter)
{
	if (sci_rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY) {
		sci_rnc->user_callback = callback;
		sci_rnc->user_cookie   = callback_parameter;

		return SCI_SUCCESS;
	}

	return SCI_FAILURE_INVALID_STATE;
}

static enum sci_status scic_sds_remote_node_context_default_suspend_handler(
	struct scic_sds_remote_node_context *sci_rnc,
	u32 suspend_type,
	scics_sds_remote_node_context_callback callback,
	void *callback_parameter)
{
	dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
		 "%s: SCIC Remote Node Context 0x%p requested to suspend "
		 "while in wrong state %d\n",
		 __func__,
		 sci_rnc,
		 sci_base_state_machine_get_state(&sci_rnc->state_machine));

	return SCI_FAILURE_INVALID_STATE;
}

static enum sci_status scic_sds_remote_node_context_default_resume_handler(
	struct scic_sds_remote_node_context *sci_rnc,
	scics_sds_remote_node_context_callback callback,
	void *callback_parameter)
{
	dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
		 "%s: SCIC Remote Node Context 0x%p requested to resume "
		 "while in wrong state %d\n",
		 __func__,
		 sci_rnc,
		 sci_base_state_machine_get_state(&sci_rnc->state_machine));

	return SCI_FAILURE_INVALID_STATE;
}

static enum sci_status scic_sds_remote_node_context_default_start_io_handler(
	struct scic_sds_remote_node_context *sci_rnc,
	struct scic_sds_request *sci_req)
@@ -295,61 +241,6 @@ static enum sci_status scic_sds_remote_node_context_success_start_task_handler(
	return SCI_SUCCESS;
}

static enum sci_status scic_sds_remote_node_context_initial_state_resume_handler(
	struct scic_sds_remote_node_context *sci_rnc,
	scics_sds_remote_node_context_callback callback,
	void *callback_parameter)
{
	if (sci_rnc->remote_node_index != SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
		scic_sds_remote_node_context_setup_to_resume(
			sci_rnc, callback, callback_parameter
			);

		scic_sds_remote_node_context_construct_buffer(sci_rnc);

		sci_base_state_machine_change_state(
			&sci_rnc->state_machine,
			SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE
			);

		return SCI_SUCCESS;
	}

	return SCI_FAILURE_INVALID_STATE;
}

/**
 *
 * @sci_rnc: The remote node context object being suspended.
 * @callback: The callback when the suspension is complete.
 * @callback_parameter: The parameter that is to be passed into the callback.
 *
 * This method will handle the suspend requests from the ready state.
 * SCI_SUCCESS
 */
static enum sci_status scic_sds_remote_node_context_ready_state_suspend_handler(
	struct scic_sds_remote_node_context *sci_rnc,
	u32 suspend_type,
	scics_sds_remote_node_context_callback callback,
	void *callback_parameter)
{
	sci_rnc->user_callback   = callback;
	sci_rnc->user_cookie     = callback_parameter;
	sci_rnc->suspension_code = suspend_type;

	if (suspend_type == SCI_SOFTWARE_SUSPENSION) {
		scic_sds_remote_device_post_request(rnc_to_dev(sci_rnc),
						    SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX);
	}

	sci_base_state_machine_change_state(
		&sci_rnc->state_machine,
		SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE
		);

	return SCI_SUCCESS;
}

/**
 *
 * @sci_rnc: The rnc for which the io request is targeted.
@@ -366,39 +257,6 @@ static enum sci_status scic_sds_remote_node_context_ready_state_start_io_handler
	return SCI_SUCCESS;
}

static enum sci_status scic_sds_remote_node_context_tx_suspended_state_resume_handler(
	struct scic_sds_remote_node_context *sci_rnc,
	scics_sds_remote_node_context_callback callback,
	void *callback_parameter)
{
	struct scic_sds_remote_device *sci_dev = rnc_to_dev(sci_rnc);
	struct domain_device *dev = sci_dev_to_domain(sci_dev);
	enum sci_status status = SCI_SUCCESS;

	scic_sds_remote_node_context_setup_to_resume(sci_rnc, callback,
						     callback_parameter);

	/* TODO: consider adding a resume action of NONE, INVALIDATE, WRITE_TLCR */
	if (dev->dev_type == SAS_END_DEV || dev_is_expander(dev))
		sci_base_state_machine_change_state(&sci_rnc->state_machine,
						    SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE);
	else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
		if (sci_dev->is_direct_attached) {
			/* @todo Fix this since I am being silly in writing to the STPTLDARNI register. */
			sci_base_state_machine_change_state(
				&sci_rnc->state_machine,
				SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE);
		} else {
			sci_base_state_machine_change_state(
				&sci_rnc->state_machine,
				SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE);
		}
	} else
		status = SCI_FAILURE;

	return status;
}

/**
 *
 * @sci_rnc: The remote node context which is to receive the task request.
@@ -419,44 +277,6 @@ static enum sci_status scic_sds_remote_node_context_suspended_start_task_handler
	return SCI_SUCCESS;
}

/* --------------------------------------------------------------------------- */

static enum sci_status scic_sds_remote_node_context_tx_rx_suspended_state_resume_handler(
	struct scic_sds_remote_node_context *sci_rnc,
	scics_sds_remote_node_context_callback callback,
	void *callback_parameter)
{
	scic_sds_remote_node_context_setup_to_resume(
		sci_rnc, callback, callback_parameter
		);

	sci_base_state_machine_change_state(
		&sci_rnc->state_machine,
		SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE
		);

	return SCI_FAILURE_INVALID_STATE;
}

/* --------------------------------------------------------------------------- */

/**
 *
 *
 *
 */
static enum sci_status scic_sds_remote_node_context_await_suspension_state_resume_handler(
	struct scic_sds_remote_node_context *sci_rnc,
	scics_sds_remote_node_context_callback callback,
	void *callback_parameter)
{
	scic_sds_remote_node_context_setup_to_resume(
		sci_rnc, callback, callback_parameter
		);

	return SCI_SUCCESS;
}

/**
 *
 * @sci_rnc: The remote node context which is to receive the task request.
@@ -477,50 +297,34 @@ static enum sci_status scic_sds_remote_node_context_await_suspension_state_start

static struct scic_sds_remote_node_context_handlers scic_sds_remote_node_context_state_handler_table[] = {
	[SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE] = {
		.suspend_handler	= scic_sds_remote_node_context_default_suspend_handler,
		.resume_handler		= scic_sds_remote_node_context_initial_state_resume_handler,
		.start_io_handler	= scic_sds_remote_node_context_default_start_io_handler,
		.start_task_handler	= scic_sds_remote_node_context_default_start_task_handler,
	},
	[SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE] = {
		.suspend_handler	= scic_sds_remote_node_context_default_suspend_handler,
		.resume_handler		= scic_sds_remote_node_context_continue_to_resume_handler,
		.start_io_handler	= scic_sds_remote_node_context_default_start_io_handler,
		.start_task_handler	= scic_sds_remote_node_context_default_start_task_handler,
	},
	[SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE] = {
		.suspend_handler	= scic_sds_remote_node_context_default_suspend_handler,
		.resume_handler		= scic_sds_remote_node_context_continue_to_resume_handler,
		.start_io_handler	= scic_sds_remote_node_context_default_start_io_handler,
		.start_task_handler	= scic_sds_remote_node_context_default_start_task_handler,
	},
	[SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE] = {
		.suspend_handler	= scic_sds_remote_node_context_default_suspend_handler,
		.resume_handler		= scic_sds_remote_node_context_continue_to_resume_handler,
		.start_io_handler	= scic_sds_remote_node_context_default_start_io_handler,
		.start_task_handler	= scic_sds_remote_node_context_success_start_task_handler,
	},
	[SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE] = {
		.suspend_handler	= scic_sds_remote_node_context_ready_state_suspend_handler,
		.resume_handler		= scic_sds_remote_node_context_default_resume_handler,
		.start_io_handler	= scic_sds_remote_node_context_ready_state_start_io_handler,
		.start_task_handler	= scic_sds_remote_node_context_success_start_task_handler,
	},
	[SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE] = {
		.suspend_handler	= scic_sds_remote_node_context_default_suspend_handler,
		.resume_handler		= scic_sds_remote_node_context_tx_suspended_state_resume_handler,
		.start_io_handler	= scic_sds_remote_node_context_default_start_io_handler,
		.start_task_handler	= scic_sds_remote_node_context_suspended_start_task_handler,
	},
	[SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE] = {
		.suspend_handler	= scic_sds_remote_node_context_default_suspend_handler,
		.resume_handler		= scic_sds_remote_node_context_tx_rx_suspended_state_resume_handler,
		.start_io_handler	= scic_sds_remote_node_context_default_start_io_handler,
		.start_task_handler	= scic_sds_remote_node_context_suspended_start_task_handler,
	},
	[SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE] = {
		.suspend_handler	= scic_sds_remote_node_context_default_suspend_handler,
		.resume_handler		= scic_sds_remote_node_context_await_suspension_state_resume_handler,
		.start_io_handler	= scic_sds_remote_node_context_default_start_io_handler,
		.start_task_handler	= scic_sds_remote_node_context_await_suspension_state_start_task_handler,
	}
@@ -548,21 +352,11 @@ static void scic_sds_remote_node_context_notify_user(
	}
}

/**
 *
 *
 * This method will continue the remote node context state machine by
 * requesting to resume the remote node context state machine from its current
 * state.
 */
static void scic_sds_remote_node_context_continue_state_transitions(
	struct scic_sds_remote_node_context *rnc)
static void scic_sds_remote_node_context_continue_state_transitions(struct scic_sds_remote_node_context *rnc)
{
	if (rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY) {
		rnc->state_handlers->resume_handler(
			rnc, rnc->user_callback, rnc->user_cookie
			);
	}
	if (rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY)
		scic_sds_remote_node_context_resume(rnc, rnc->user_callback,
						    rnc->user_cookie);
}

/**
@@ -989,3 +783,95 @@ enum sci_status scic_sds_remote_node_context_destruct(struct scic_sds_remote_nod
		return SCI_FAILURE_INVALID_STATE;
	}
}

enum sci_status scic_sds_remote_node_context_suspend(struct scic_sds_remote_node_context *sci_rnc,
						     u32 suspend_type,
						     scics_sds_remote_node_context_callback cb_fn,
						     void *cb_p)
{
	enum scis_sds_remote_node_context_states state;

	state = sci_rnc->state_machine.current_state_id;
	if (state != SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE) {
		dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
			 "%s: invalid state %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}

	sci_rnc->user_callback   = cb_fn;
	sci_rnc->user_cookie     = cb_p;
	sci_rnc->suspension_code = suspend_type;

	if (suspend_type == SCI_SOFTWARE_SUSPENSION) {
		scic_sds_remote_device_post_request(rnc_to_dev(sci_rnc),
						    SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX);
	}

	sci_base_state_machine_change_state(&sci_rnc->state_machine,
					    SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE);
	return SCI_SUCCESS;
}

enum sci_status scic_sds_remote_node_context_resume(struct scic_sds_remote_node_context *sci_rnc,
						    scics_sds_remote_node_context_callback cb_fn,
						    void *cb_p)
{
	enum scis_sds_remote_node_context_states state;

	state = sci_rnc->state_machine.current_state_id;
	switch (state) {
	case SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE:
		if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
			return SCI_FAILURE_INVALID_STATE;

		scic_sds_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p);
		scic_sds_remote_node_context_construct_buffer(sci_rnc);
		sci_base_state_machine_change_state(&sci_rnc->state_machine,
						    SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE);
		return SCI_SUCCESS;
	case SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE:
	case SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE:
	case SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE:
		if (sci_rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY)
			return SCI_FAILURE_INVALID_STATE;

		sci_rnc->user_callback = cb_fn;
		sci_rnc->user_cookie   = cb_p;
		return SCI_SUCCESS;
	case SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE: {
		struct scic_sds_remote_device *sci_dev = rnc_to_dev(sci_rnc);
		struct domain_device *dev = sci_dev_to_domain(sci_dev);

		scic_sds_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p);

		/* TODO: consider adding a resume action of NONE, INVALIDATE, WRITE_TLCR */
		if (dev->dev_type == SAS_END_DEV || dev_is_expander(dev))
			sci_base_state_machine_change_state(&sci_rnc->state_machine,
							    SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE);
		else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
			if (sci_dev->is_direct_attached) {
				/* @todo Fix this since I am being silly in writing to the STPTLDARNI register. */
				sci_base_state_machine_change_state(&sci_rnc->state_machine,
					SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE);
			} else {
				sci_base_state_machine_change_state(&sci_rnc->state_machine,
					SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE);
			}
		} else
			return SCI_FAILURE;
		return SCI_SUCCESS;
	}
	case SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE:
		scic_sds_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p);
		sci_base_state_machine_change_state(&sci_rnc->state_machine,
						    SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE);
		return SCI_FAILURE_INVALID_STATE;
	case SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE:
		scic_sds_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p);
		return SCI_SUCCESS;
	default:
		dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
			 "%s: invalid state %d\n", __func__, state);
		return SCI_FAILURE_INVALID_STATE;
	}
}
+8 −24
Original line number Diff line number Diff line
@@ -90,32 +90,12 @@ typedef enum sci_status (*scic_sds_remote_node_context_operation)(
	void *callback_parameter
	);

typedef enum sci_status (*scic_sds_remote_node_context_suspend_operation)(
	struct scic_sds_remote_node_context *sci_rnc,
	u32 suspension_type,
	scics_sds_remote_node_context_callback callback,
	void *callback_parameter
	);

typedef enum sci_status (*scic_sds_remote_node_context_io_request)(
	struct scic_sds_remote_node_context *sci_rnc,
	struct scic_sds_request *sci_req
	);

struct scic_sds_remote_node_context_handlers {
	/**
	 * This handler is invoked when there is a request to suspend  the RNC.  The
	 * callback is invoked after the hardware notification that the remote node is
	 * suspended.
	 */
	scic_sds_remote_node_context_suspend_operation suspend_handler;

	/**
	 * This handler is invoked when there is a request to resume the RNC.  The
	 * callback is invoked when after the RNC has reached the ready state.
	 */
	scic_sds_remote_node_context_operation resume_handler;

	/**
	 * This handler is invoked when there is a request to start an io request
	 * operation.
@@ -260,11 +240,15 @@ enum sci_status scic_sds_remote_node_context_event_handler(struct scic_sds_remot
enum sci_status scic_sds_remote_node_context_destruct(struct scic_sds_remote_node_context *sci_rnc,
						      scics_sds_remote_node_context_callback callback,
						      void *callback_parameter);
#define scic_sds_remote_node_context_resume(rnc, callback, parameter) \
	((rnc)->state_handlers->resume_handler(rnc, callback, parameter))

#define scic_sds_remote_node_context_suspend(rnc, suspend_type, callback, parameter) \
	((rnc)->state_handlers->suspend_handler(rnc, suspend_type, callback, parameter))
enum sci_status scic_sds_remote_node_context_suspend(struct scic_sds_remote_node_context *sci_rnc,
						     u32 suspend_type,
						     scics_sds_remote_node_context_callback cb_fn,
						     void *cb_p);

enum sci_status scic_sds_remote_node_context_resume(struct scic_sds_remote_node_context *sci_rnc,
						    scics_sds_remote_node_context_callback cb_fn,
						    void *cb_p);

#define scic_sds_remote_node_context_start_io(rnc, request) \
	((rnc)->state_handlers->start_io_handler(rnc, request))