aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/isci/remote_node_context.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/isci/remote_node_context.h')
-rw-r--r--drivers/scsi/isci/remote_node_context.h142
1 files changed, 77 insertions, 65 deletions
diff --git a/drivers/scsi/isci/remote_node_context.h b/drivers/scsi/isci/remote_node_context.h
index 41580ad1252..c7ee81d0112 100644
--- a/drivers/scsi/isci/remote_node_context.h
+++ b/drivers/scsi/isci/remote_node_context.h
@@ -75,8 +75,13 @@
*/
#define SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX 0x0FFF
-#define SCU_HARDWARE_SUSPENSION (0)
-#define SCI_SOFTWARE_SUSPENSION (1)
+enum sci_remote_node_suspension_reasons {
+ SCI_HW_SUSPEND,
+ SCI_SW_SUSPEND_NORMAL,
+ SCI_SW_SUSPEND_LINKHANG_DETECT
+};
+#define SCI_SOFTWARE_SUSPEND_CMD SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX
+#define SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT SCU_EVENT_TL_RNC_SUSPEND_TX_RX
struct isci_request;
struct isci_remote_device;
@@ -85,61 +90,50 @@ struct sci_remote_node_context;
typedef void (*scics_sds_remote_node_context_callback)(void *);
/**
- * This is the enumeration of the remote node context states.
+ * enum sci_remote_node_context_states
+ * @SCI_RNC_INITIAL initial state for a remote node context. On a resume
+ * request the remote node context will transition to the posting state.
+ *
+ * @SCI_RNC_POSTING: transition state that posts the RNi to the hardware. Once
+ * the RNC is posted the remote node context will be made ready.
+ *
+ * @SCI_RNC_INVALIDATING: transition state that will post an RNC invalidate to
+ * the hardware. Once the invalidate is complete the remote node context will
+ * transition to the posting state.
+ *
+ * @SCI_RNC_RESUMING: transition state that will post an RNC resume to the
+ * hardare. Once the event notification of resume complete is received the
+ * remote node context will transition to the ready state.
+ *
+ * @SCI_RNC_READY: state that the remote node context must be in to accept io
+ * request operations.
+ *
+ * @SCI_RNC_TX_SUSPENDED: state that the remote node context transitions to when
+ * it gets a TX suspend notification from the hardware.
+ *
+ * @SCI_RNC_TX_RX_SUSPENDED: state that the remote node context transitions to
+ * when it gets a TX RX suspend notification from the hardware.
+ *
+ * @SCI_RNC_AWAIT_SUSPENSION: wait state for the remote node context that waits
+ * for a suspend notification from the hardware. This state is entered when
+ * either there is a request to supend the remote node context or when there is
+ * a TC completion where the remote node will be suspended by the hardware.
*/
-enum scis_sds_remote_node_context_states {
- /**
- * This state is the initial state for a remote node context. On a resume
- * request the remote node context will transition to the posting state.
- */
- SCI_RNC_INITIAL,
-
- /**
- * This is a transition state that posts the RNi to the hardware. Once the RNC
- * is posted the remote node context will be made ready.
- */
- SCI_RNC_POSTING,
-
- /**
- * This is a transition state that will post an RNC invalidate to the
- * hardware. Once the invalidate is complete the remote node context will
- * transition to the posting state.
- */
- SCI_RNC_INVALIDATING,
-
- /**
- * This is a transition state that will post an RNC resume to the hardare.
- * Once the event notification of resume complete is received the remote node
- * context will transition to the ready state.
- */
- SCI_RNC_RESUMING,
-
- /**
- * This is the state that the remote node context must be in to accept io
- * request operations.
- */
- SCI_RNC_READY,
-
- /**
- * This is the state that the remote node context transitions to when it gets
- * a TX suspend notification from the hardware.
- */
- SCI_RNC_TX_SUSPENDED,
-
- /**
- * This is the state that the remote node context transitions to when it gets
- * a TX RX suspend notification from the hardware.
- */
- SCI_RNC_TX_RX_SUSPENDED,
-
- /**
- * This state is a wait state for the remote node context that waits for a
- * suspend notification from the hardware. This state is entered when either
- * there is a request to supend the remote node context or when there is a TC
- * completion where the remote node will be suspended by the hardware.
- */
- SCI_RNC_AWAIT_SUSPENSION
-};
+#define RNC_STATES {\
+ C(RNC_INITIAL),\
+ C(RNC_POSTING),\
+ C(RNC_INVALIDATING),\
+ C(RNC_RESUMING),\
+ C(RNC_READY),\
+ C(RNC_TX_SUSPENDED),\
+ C(RNC_TX_RX_SUSPENDED),\
+ C(RNC_AWAIT_SUSPENSION),\
+ }
+#undef C
+#define C(a) SCI_##a
+enum scis_sds_remote_node_context_states RNC_STATES;
+#undef C
+const char *rnc_state_name(enum scis_sds_remote_node_context_states state);
/**
*
@@ -148,9 +142,13 @@ enum scis_sds_remote_node_context_states {
* node context.
*/
enum sci_remote_node_context_destination_state {
- SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED,
- SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY,
- SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL
+ RNC_DEST_UNSPECIFIED,
+ RNC_DEST_READY,
+ RNC_DEST_FINAL,
+ RNC_DEST_SUSPENDED, /* Set when suspend during post/invalidate */
+ RNC_DEST_SUSPENDED_RESUME /* Set when a resume was done during posting
+ * or invalidating and already suspending.
+ */
};
/**
@@ -167,10 +165,12 @@ struct sci_remote_node_context {
u16 remote_node_index;
/**
- * This field is the recored suspension code or the reason for the remote node
+ * This field is the recored suspension type of the remote node
* context suspension.
*/
- u32 suspension_code;
+ u32 suspend_type;
+ enum sci_remote_node_suspension_reasons suspend_reason;
+ u32 suspend_count;
/**
* This field is true if the remote node context is resuming from its current
@@ -204,21 +204,33 @@ void sci_remote_node_context_construct(struct sci_remote_node_context *rnc,
bool sci_remote_node_context_is_ready(
struct sci_remote_node_context *sci_rnc);
+bool sci_remote_node_context_is_suspended(struct sci_remote_node_context *sci_rnc);
+
enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_context *sci_rnc,
u32 event_code);
enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context *sci_rnc,
scics_sds_remote_node_context_callback callback,
void *callback_parameter);
enum sci_status sci_remote_node_context_suspend(struct sci_remote_node_context *sci_rnc,
- u32 suspend_type,
- scics_sds_remote_node_context_callback cb_fn,
- void *cb_p);
+ enum sci_remote_node_suspension_reasons reason,
+ u32 suspension_code);
enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *sci_rnc,
scics_sds_remote_node_context_callback cb_fn,
void *cb_p);
enum sci_status sci_remote_node_context_start_task(struct sci_remote_node_context *sci_rnc,
- struct isci_request *ireq);
+ struct isci_request *ireq,
+ scics_sds_remote_node_context_callback cb_fn,
+ void *cb_p);
enum sci_status sci_remote_node_context_start_io(struct sci_remote_node_context *sci_rnc,
struct isci_request *ireq);
+int sci_remote_node_context_is_safe_to_abort(
+ struct sci_remote_node_context *sci_rnc);
+static inline bool sci_remote_node_context_is_being_destroyed(
+ struct sci_remote_node_context *sci_rnc)
+{
+ return (sci_rnc->destination_state == RNC_DEST_FINAL)
+ || ((sci_rnc->sm.current_state_id == SCI_RNC_INITIAL)
+ && (sci_rnc->destination_state == RNC_DEST_UNSPECIFIED));
+}
#endif /* _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ */