aboutsummaryrefslogtreecommitdiff
path: root/include/scsi/scsi_transport_srp.h
blob: d22df12584f996ded6810581c24db785d82024d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SCSI_TRANSPORT_SRP_H
#define SCSI_TRANSPORT_SRP_H

#include <linux/transport_class.h>
#include <linux/types.h>
#include <linux/mutex.h>

#define SRP_RPORT_ROLE_INITIATOR 0
#define SRP_RPORT_ROLE_TARGET 1

struct srp_rport_identifiers {
	u8 port_id[16];
	u8 roles;
};

/**
 * enum srp_rport_state - SRP transport layer state
 * @SRP_RPORT_RUNNING:   Transport layer operational.
 * @SRP_RPORT_BLOCKED:   Transport layer not operational; fast I/O fail timer
 *                       is running and I/O has been blocked.
 * @SRP_RPORT_FAIL_FAST: Fast I/O fail timer has expired; fail I/O fast.
 * @SRP_RPORT_LOST:      Port is being removed.
 */
enum srp_rport_state {
	SRP_RPORT_RUNNING,
	SRP_RPORT_BLOCKED,
	SRP_RPORT_FAIL_FAST,
	SRP_RPORT_LOST,
};

/**
 * struct srp_rport - SRP initiator or target port
 *
 * Fields that are relevant for SRP initiator and SRP target drivers:
 * @dev:               Device associated with this rport.
 * @port_id:           16-byte port identifier.
 * @roles:             Role of this port - initiator or target.
 *
 * Fields that are only relevant for SRP initiator drivers:
 * @lld_data:          LLD private data.
 * @mutex:             Protects against concurrent rport reconnect /
 *                     fast_io_fail / dev_loss_tmo activity.
 * @state:             rport state.
 * @reconnect_delay:   Reconnect delay in seconds.
 * @failed_reconnects: Number of failed reconnect attempts.
 * @reconnect_work:    Work structure used for scheduling reconnect attempts.
 * @fast_io_fail_tmo:  Fast I/O fail timeout in seconds.
 * @dev_loss_tmo:      Device loss timeout in seconds.
 * @fast_io_fail_work: Work structure used for scheduling fast I/O fail work.
 * @dev_loss_work:     Work structure used for scheduling device loss work.
 */
struct srp_rport {
	/* for initiator and target drivers */

	struct device dev;

	u8 port_id[16];
	u8 roles;

	/* for initiator drivers */

	void			*lld_data;

	struct mutex		mutex;
	enum srp_rport_state	state;
	int			reconnect_delay;
	int			failed_reconnects;
	struct delayed_work	reconnect_work;
	int			fast_io_fail_tmo;
	int			dev_loss_tmo;
	struct delayed_work	fast_io_fail_work;
	struct delayed_work	dev_loss_work;
};

/**
 * struct srp_function_template
 *
 * Fields that are only relevant for SRP initiator drivers:
 * @has_rport_state: Whether or not to create the state, fast_io_fail_tmo and
 *     dev_loss_tmo sysfs attribute for an rport.
 * @reset_timer_if_blocked: Whether or srp_timed_out() should reset the command
 *     timer if the device on which it has been queued is blocked.
 * @reconnect_delay: If not NULL, points to the default reconnect_delay value.
 * @fast_io_fail_tmo: If not NULL, points to the default fast_io_fail_tmo value.
 * @dev_loss_tmo: If not NULL, points to the default dev_loss_tmo value.
 * @reconnect: Callback function for reconnecting to the target. See also
 *     srp_reconnect_rport().
 * @terminate_rport_io: Callback function for terminating all outstanding I/O
 *     requests for an rport.
 * @rport_delete: Callback function that deletes an rport.
 */
struct srp_function_template {
	/* for initiator drivers */
	bool has_rport_state;
	bool reset_timer_if_blocked;
	int *reconnect_delay;
	int *fast_io_fail_tmo;
	int *dev_loss_tmo;
	int (*reconnect)(struct srp_rport *rport);
	void (*terminate_rport_io)(struct srp_rport *rport);
	void (*rport_delete)(struct srp_rport *rport);
};

extern struct scsi_transport_template *
srp_attach_transport(struct srp_function_template *);
extern void srp_release_transport(struct scsi_transport_template *);

extern void srp_rport_get(struct srp_rport *rport);
extern void srp_rport_put(struct srp_rport *rport);
extern struct srp_rport *srp_rport_add(struct Scsi_Host *,
				       struct srp_rport_identifiers *);
extern void srp_rport_del(struct srp_rport *);
extern int srp_tmo_valid(int reconnect_delay, int fast_io_fail_tmo,
			 long dev_loss_tmo);
int srp_parse_tmo(int *tmo, const char *buf);
extern int srp_reconnect_rport(struct srp_rport *rport);
extern void srp_start_tl_fail_timers(struct srp_rport *rport);
extern void srp_remove_host(struct Scsi_Host *);
extern void srp_stop_rport_timers(struct srp_rport *rport);
enum blk_eh_timer_return srp_timed_out(struct scsi_cmnd *scmd);

/**
 * srp_chkready() - evaluate the transport layer state before I/O
 * @rport: SRP target port pointer.
 *
 * Returns a SCSI result code that can be returned by the LLD queuecommand()
 * implementation. The role of this function is similar to that of
 * fc_remote_port_chkready().
 */
static inline int srp_chkready(struct srp_rport *rport)
{
	switch (rport->state) {
	case SRP_RPORT_RUNNING:
	case SRP_RPORT_BLOCKED:
	default:
		return 0;
	case SRP_RPORT_FAIL_FAST:
		return DID_TRANSPORT_FAILFAST << 16;
	case SRP_RPORT_LOST:
		return DID_NO_CONNECT << 16;
	}
}

#endif