xref: /openbmc/linux/include/scsi/libiscsi.h (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1  /* SPDX-License-Identifier: GPL-2.0-or-later */
2  /*
3   * iSCSI lib definitions
4   *
5   * Copyright (C) 2006 Red Hat, Inc.  All rights reserved.
6   * Copyright (C) 2004 - 2006 Mike Christie
7   * Copyright (C) 2004 - 2005 Dmitry Yusupov
8   * Copyright (C) 2004 - 2005 Alex Aizman
9   */
10  #ifndef LIBISCSI_H
11  #define LIBISCSI_H
12  
13  #include <linux/types.h>
14  #include <linux/wait.h>
15  #include <linux/mutex.h>
16  #include <linux/timer.h>
17  #include <linux/workqueue.h>
18  #include <linux/kfifo.h>
19  #include <linux/refcount.h>
20  #include <scsi/iscsi_proto.h>
21  #include <scsi/iscsi_if.h>
22  #include <scsi/scsi_cmnd.h>
23  #include <scsi/scsi_transport_iscsi.h>
24  
25  struct scsi_transport_template;
26  struct scsi_host_template;
27  struct scsi_device;
28  struct Scsi_Host;
29  struct scsi_target;
30  struct scsi_cmnd;
31  struct socket;
32  struct iscsi_transport;
33  struct iscsi_cls_session;
34  struct iscsi_cls_conn;
35  struct iscsi_session;
36  struct iscsi_nopin;
37  struct device;
38  
39  #define ISCSI_DEF_XMIT_CMDS_MAX	128	/* must be power of 2 */
40  #define ISCSI_MGMT_CMDS_MAX	15
41  
42  #define ISCSI_DEF_CMD_PER_LUN	32
43  
44  /* Task Mgmt states */
45  enum {
46  	TMF_INITIAL,
47  	TMF_QUEUED,
48  	TMF_SUCCESS,
49  	TMF_FAILED,
50  	TMF_TIMEDOUT,
51  	TMF_NOT_FOUND,
52  };
53  
54  #define ISID_SIZE			6
55  
56  /* Connection flags */
57  #define ISCSI_CONN_FLAG_SUSPEND_TX	0
58  #define ISCSI_CONN_FLAG_SUSPEND_RX	1
59  #define ISCSI_CONN_FLAG_BOUND		2
60  
61  #define ISCSI_ITT_MASK			0x1fff
62  #define ISCSI_TOTAL_CMDS_MAX		4096
63  /* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */
64  #define ISCSI_TOTAL_CMDS_MIN		16
65  #define ISCSI_AGE_SHIFT			28
66  #define ISCSI_AGE_MASK			0xf
67  
68  #define ISCSI_ADDRESS_BUF_LEN		64
69  
70  enum {
71  	/* this is the maximum possible storage for AHSs */
72  	ISCSI_MAX_AHS_SIZE = sizeof(struct iscsi_ecdb_ahdr) +
73  				sizeof(struct iscsi_rlength_ahdr),
74  	ISCSI_DIGEST_SIZE = sizeof(__u32),
75  };
76  
77  
78  enum {
79  	ISCSI_TASK_FREE,
80  	ISCSI_TASK_COMPLETED,
81  	ISCSI_TASK_PENDING,
82  	ISCSI_TASK_RUNNING,
83  	ISCSI_TASK_ABRT_TMF,		/* aborted due to TMF */
84  	ISCSI_TASK_ABRT_SESS_RECOV,	/* aborted due to session recovery */
85  	ISCSI_TASK_REQUEUE_SCSIQ,	/* qcmd requeueing to scsi-ml */
86  };
87  
88  struct iscsi_r2t_info {
89  	__be32			ttt;		/* copied from R2T */
90  	__be32			exp_statsn;	/* copied from R2T */
91  	uint32_t		data_length;	/* copied from R2T */
92  	uint32_t		data_offset;	/* copied from R2T */
93  	int			data_count;	/* DATA-Out payload progress */
94  	int			datasn;
95  	/* LLDs should set/update these values */
96  	int			sent;		/* R2T sequence progress */
97  };
98  
99  struct iscsi_task {
100  	/*
101  	 * Because LLDs allocate their hdr differently, this is a pointer
102  	 * and length to that storage. It must be setup at session
103  	 * creation time.
104  	 */
105  	struct iscsi_hdr	*hdr;
106  	unsigned short		hdr_max;
107  	unsigned short		hdr_len;	/* accumulated size of hdr used */
108  	/* copied values in case we need to send tmfs */
109  	itt_t			hdr_itt;
110  	__be32			cmdsn;
111  	struct scsi_lun		lun;
112  
113  	int			itt;		/* this ITT */
114  
115  	unsigned		imm_count;	/* imm-data (bytes)   */
116  	/* offset in unsolicited stream (bytes); */
117  	struct iscsi_r2t_info	unsol_r2t;
118  	char			*data;		/* mgmt payload */
119  	unsigned		data_count;
120  	struct scsi_cmnd	*sc;		/* associated SCSI cmd*/
121  	struct iscsi_conn	*conn;		/* used connection    */
122  
123  	/* data processing tracking */
124  	unsigned long		last_xfer;
125  	unsigned long		last_timeout;
126  	bool			have_checked_conn;
127  
128  	/* T10 protection information */
129  	bool			protected;
130  
131  	/* state set/tested under session->lock */
132  	int			state;
133  	refcount_t		refcount;
134  	struct list_head	running;	/* running cmd list */
135  	void			*dd_data;	/* driver/transport data */
136  };
137  
iscsi_task_has_unsol_data(struct iscsi_task * task)138  static inline int iscsi_task_has_unsol_data(struct iscsi_task *task)
139  {
140  	return task->unsol_r2t.data_length > task->unsol_r2t.sent;
141  }
142  
iscsi_next_hdr(struct iscsi_task * task)143  static inline void* iscsi_next_hdr(struct iscsi_task *task)
144  {
145  	return (void*)task->hdr + task->hdr_len;
146  }
147  
iscsi_task_is_completed(struct iscsi_task * task)148  static inline bool iscsi_task_is_completed(struct iscsi_task *task)
149  {
150  	return task->state == ISCSI_TASK_COMPLETED ||
151  	       task->state == ISCSI_TASK_ABRT_TMF ||
152  	       task->state == ISCSI_TASK_ABRT_SESS_RECOV;
153  }
154  
155  /* Private data associated with struct scsi_cmnd. */
156  struct iscsi_cmd {
157  	struct iscsi_task	*task;
158  	int			age;
159  };
160  
iscsi_cmd(struct scsi_cmnd * cmd)161  static inline struct iscsi_cmd *iscsi_cmd(struct scsi_cmnd *cmd)
162  {
163  	return scsi_cmd_priv(cmd);
164  }
165  
166  /* Connection's states */
167  enum {
168  	ISCSI_CONN_INITIAL_STAGE,
169  	ISCSI_CONN_STARTED,
170  	ISCSI_CONN_STOPPED,
171  	ISCSI_CONN_CLEANUP_WAIT,
172  };
173  
174  struct iscsi_conn {
175  	struct iscsi_cls_conn	*cls_conn;	/* ptr to class connection */
176  	void			*dd_data;	/* iscsi_transport data */
177  	struct iscsi_session	*session;	/* parent session */
178  	/*
179  	 * conn_stop() flag: stop to recover, stop to terminate
180  	 */
181          int			stop_stage;
182  	struct timer_list	transport_timer;
183  	unsigned long		last_recv;
184  	unsigned long		last_ping;
185  	int			ping_timeout;
186  	int			recv_timeout;
187  	struct iscsi_task 	*ping_task;
188  
189  	/* iSCSI connection-wide sequencing */
190  	uint32_t		exp_statsn;
191  	uint32_t		statsn;
192  
193  	/* control data */
194  	int			id;		/* CID */
195  	int			c_stage;	/* connection state */
196  	/*
197  	 * Preallocated buffer for pdus that have data but do not
198  	 * originate from scsi-ml. We never have two pdus using the
199  	 * buffer at the same time. It is only allocated to
200  	 * the default max recv size because the pdus we support
201  	 * should always fit in this buffer
202  	 */
203  	char			*data;
204  	struct iscsi_task 	*login_task;	/* mtask used for login/text */
205  	struct iscsi_task	*task;		/* xmit task in progress */
206  
207  	/* xmit */
208  	/* items must be added/deleted under frwd lock */
209  	struct list_head	mgmtqueue;	/* mgmt (control) xmit queue */
210  	struct list_head	cmdqueue;	/* data-path cmd queue */
211  	struct list_head	requeue;	/* tasks needing another run */
212  	struct work_struct	xmitwork;	/* per-conn. xmit workqueue */
213  	/* recv */
214  	struct work_struct	recvwork;
215  	unsigned long		flags;		/* ISCSI_CONN_FLAGs */
216  
217  	/* negotiated params */
218  	unsigned		max_recv_dlength; /* initiator_max_recv_dsl*/
219  	unsigned		max_xmit_dlength; /* target_max_recv_dsl */
220  	int			hdrdgst_en;
221  	int			datadgst_en;
222  	int			ifmarker_en;
223  	int			ofmarker_en;
224  	/* values userspace uses to id a conn */
225  	int			persistent_port;
226  	char			*persistent_address;
227  
228  	unsigned		max_segment_size;
229  	unsigned		tcp_xmit_wsf;
230  	unsigned		tcp_recv_wsf;
231  	uint16_t		keepalive_tmo;
232  	uint16_t		local_port;
233  	uint8_t			tcp_timestamp_stat;
234  	uint8_t			tcp_nagle_disable;
235  	uint8_t			tcp_wsf_disable;
236  	uint8_t			tcp_timer_scale;
237  	uint8_t			tcp_timestamp_en;
238  	uint8_t			fragment_disable;
239  	uint8_t			ipv4_tos;
240  	uint8_t			ipv6_traffic_class;
241  	uint8_t			ipv6_flow_label;
242  	uint8_t			is_fw_assigned_ipv6;
243  	char			*local_ipaddr;
244  
245  	/* MIB-statistics */
246  	uint64_t		txdata_octets;
247  	uint64_t		rxdata_octets;
248  	uint32_t		scsicmd_pdus_cnt;
249  	uint32_t		dataout_pdus_cnt;
250  	uint32_t		scsirsp_pdus_cnt;
251  	uint32_t		datain_pdus_cnt;
252  	uint32_t		r2t_pdus_cnt;
253  	uint32_t		tmfcmd_pdus_cnt;
254  	int32_t			tmfrsp_pdus_cnt;
255  
256  	/* custom statistics */
257  	uint32_t		eh_abort_cnt;
258  	uint32_t		fmr_unalign_cnt;
259  };
260  
261  struct iscsi_pool {
262  	struct kfifo		queue;		/* FIFO Queue */
263  	void			**pool;		/* Pool of elements */
264  	int			max;		/* Max number of elements */
265  };
266  
267  /* Session's states */
268  enum {
269  	ISCSI_STATE_FREE = 1,
270  	ISCSI_STATE_LOGGED_IN,
271  	ISCSI_STATE_FAILED,
272  	ISCSI_STATE_TERMINATE,
273  	ISCSI_STATE_IN_RECOVERY,
274  	ISCSI_STATE_RECOVERY_FAILED,
275  	ISCSI_STATE_LOGGING_OUT,
276  };
277  
278  struct iscsi_session {
279  	struct iscsi_cls_session *cls_session;
280  	/*
281  	 * Syncs up the scsi eh thread with the iscsi eh thread when sending
282  	 * task management functions. This must be taken before the session
283  	 * and recv lock.
284  	 */
285  	struct mutex		eh_mutex;
286  	/* abort */
287  	wait_queue_head_t	ehwait;		/* used in eh_abort() */
288  	struct iscsi_tm		tmhdr;
289  	struct timer_list	tmf_timer;
290  	int			tmf_state;	/* see TMF_INITIAL, etc.*/
291  	struct iscsi_task	*running_aborted_task;
292  
293  	/* iSCSI session-wide sequencing */
294  	uint32_t		cmdsn;
295  	uint32_t		exp_cmdsn;
296  	uint32_t		max_cmdsn;
297  
298  	/* This tracks the reqs queued into the initiator */
299  	uint32_t		queued_cmdsn;
300  
301  	/* configuration */
302  	int			abort_timeout;
303  	int			lu_reset_timeout;
304  	int			tgt_reset_timeout;
305  	int			initial_r2t_en;
306  	unsigned short		max_r2t;
307  	int			imm_data_en;
308  	unsigned		first_burst;
309  	unsigned		max_burst;
310  	int			time2wait;
311  	int			time2retain;
312  	int			pdu_inorder_en;
313  	int			dataseq_inorder_en;
314  	int			erl;
315  	int			fast_abort;
316  	int			tpgt;
317  	char			*username;
318  	char			*username_in;
319  	char			*password;
320  	char			*password_in;
321  	char			*targetname;
322  	char			*targetalias;
323  	char			*ifacename;
324  	char			*initiatorname;
325  	char			*boot_root;
326  	char			*boot_nic;
327  	char			*boot_target;
328  	char			*portal_type;
329  	char			*discovery_parent_type;
330  	uint16_t		discovery_parent_idx;
331  	uint16_t		def_taskmgmt_tmo;
332  	uint16_t		tsid;
333  	uint8_t			auto_snd_tgt_disable;
334  	uint8_t			discovery_sess;
335  	uint8_t			chap_auth_en;
336  	uint8_t			discovery_logout_en;
337  	uint8_t			bidi_chap_en;
338  	uint8_t			discovery_auth_optional;
339  	uint8_t			isid[ISID_SIZE];
340  
341  	/* control data */
342  	struct iscsi_transport	*tt;
343  	struct Scsi_Host	*host;
344  	struct iscsi_conn	*leadconn;	/* leading connection */
345  	/* Between the forward and the backward locks exists a strict locking
346  	 * hierarchy. The mutual exclusion zone protected by the forward lock
347  	 * can enclose the mutual exclusion zone protected by the backward lock
348  	 * but not vice versa.
349  	 */
350  	spinlock_t		frwd_lock;	/* protects session state, *
351  						 * cmdsn, queued_cmdsn     *
352  						 * session resources:      *
353  						 * - cmdpool kfifo_out ,   *
354  						 * - mgmtpool, queues	   */
355  	spinlock_t		back_lock;	/* protects cmdsn_exp      *
356  						 * cmdsn_max,              *
357  						 * cmdpool kfifo_in        */
358  	int			state;		/* session state           */
359  	int			age;		/* counts session re-opens */
360  
361  	int			scsi_cmds_max; 	/* max scsi commands */
362  	int			cmds_max;	/* size of cmds array */
363  	struct iscsi_task	**cmds;		/* Original Cmds arr */
364  	struct iscsi_pool	cmdpool;	/* PDU's pool */
365  	void			*dd_data;	/* LLD private data */
366  };
367  
368  enum {
369  	ISCSI_HOST_SETUP,
370  	ISCSI_HOST_REMOVED,
371  };
372  
373  struct iscsi_host {
374  	char			*initiatorname;
375  	/* hw address or netdev iscsi connection is bound to */
376  	char			*hwaddress;
377  	char			*netdev;
378  
379  	wait_queue_head_t	session_removal_wq;
380  	/* protects sessions and state */
381  	spinlock_t		lock;
382  	int			num_sessions;
383  	int			state;
384  
385  	struct workqueue_struct	*workq;
386  };
387  
388  /*
389   * scsi host template
390   */
391  extern int iscsi_eh_abort(struct scsi_cmnd *sc);
392  extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);
393  extern int iscsi_eh_session_reset(struct scsi_cmnd *sc);
394  extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
395  extern int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc);
396  extern enum scsi_timeout_action iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc);
397  
398  /*
399   * iSCSI host helpers.
400   */
401  #define iscsi_host_priv(_shost) \
402  	(shost_priv(_shost) + sizeof(struct iscsi_host))
403  
404  extern int iscsi_host_set_param(struct Scsi_Host *shost,
405  				enum iscsi_host_param param, char *buf,
406  				int buflen);
407  extern int iscsi_host_get_param(struct Scsi_Host *shost,
408  				enum iscsi_host_param param, char *buf);
409  extern int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev);
410  extern struct Scsi_Host *iscsi_host_alloc(const struct scsi_host_template *sht,
411  					  int dd_data_size,
412  					  bool xmit_can_sleep);
413  extern void iscsi_host_remove(struct Scsi_Host *shost, bool is_shutdown);
414  extern void iscsi_host_free(struct Scsi_Host *shost);
415  extern int iscsi_target_alloc(struct scsi_target *starget);
416  extern int iscsi_host_get_max_scsi_cmds(struct Scsi_Host *shost,
417  					uint16_t requested_cmds_max);
418  
419  /*
420   * session management
421   */
422  extern struct iscsi_cls_session *
423  iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost,
424  		    uint16_t, int, int, uint32_t, unsigned int);
425  void iscsi_session_remove(struct iscsi_cls_session *cls_session);
426  void iscsi_session_free(struct iscsi_cls_session *cls_session);
427  extern void iscsi_session_teardown(struct iscsi_cls_session *);
428  extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
429  extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
430  			   enum iscsi_param param, char *buf, int buflen);
431  extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
432  				   enum iscsi_param param, char *buf);
433  
434  #define iscsi_session_printk(prefix, _sess, fmt, a...)	\
435  	iscsi_cls_session_printk(prefix, _sess->cls_session, fmt, ##a)
436  
437  /*
438   * connection management
439   */
440  extern struct iscsi_cls_conn *iscsi_conn_setup(struct iscsi_cls_session *,
441  					       int, uint32_t);
442  extern void iscsi_conn_teardown(struct iscsi_cls_conn *);
443  extern int iscsi_conn_start(struct iscsi_cls_conn *);
444  extern void iscsi_conn_stop(struct iscsi_cls_conn *, int);
445  extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *,
446  			   int);
447  extern void iscsi_conn_unbind(struct iscsi_cls_conn *cls_conn, bool is_active);
448  extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
449  extern void iscsi_session_failure(struct iscsi_session *session,
450  				  enum iscsi_err err);
451  extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
452  				enum iscsi_param param, char *buf);
453  extern int iscsi_conn_get_addr_param(struct sockaddr_storage *addr,
454  				     enum iscsi_param param, char *buf);
455  extern void iscsi_suspend_tx(struct iscsi_conn *conn);
456  extern void iscsi_suspend_rx(struct iscsi_conn *conn);
457  extern void iscsi_suspend_queue(struct iscsi_conn *conn);
458  extern void iscsi_conn_queue_xmit(struct iscsi_conn *conn);
459  extern void iscsi_conn_queue_recv(struct iscsi_conn *conn);
460  
461  #define iscsi_conn_printk(prefix, _c, fmt, a...) \
462  	iscsi_cls_conn_printk(prefix, ((struct iscsi_conn *)_c)->cls_conn, \
463  			      fmt, ##a)
464  
465  /*
466   * pdu and task processing
467   */
468  extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *);
469  extern void iscsi_prep_data_out_pdu(struct iscsi_task *task,
470  				    struct iscsi_r2t_info *r2t,
471  				    struct iscsi_data *hdr);
472  extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
473  				char *, uint32_t);
474  extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
475  			      char *, int);
476  extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
477  				char *, int);
478  extern int iscsi_verify_itt(struct iscsi_conn *, itt_t);
479  extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
480  extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t);
481  extern void iscsi_requeue_task(struct iscsi_task *task);
482  extern void iscsi_put_task(struct iscsi_task *task);
483  extern void __iscsi_put_task(struct iscsi_task *task);
484  extern bool iscsi_get_task(struct iscsi_task *task);
485  extern void iscsi_complete_scsi_task(struct iscsi_task *task,
486  				     uint32_t exp_cmdsn, uint32_t max_cmdsn);
487  
488  /*
489   * generic helpers
490   */
491  extern void iscsi_pool_free(struct iscsi_pool *);
492  extern int iscsi_pool_init(struct iscsi_pool *, int, void ***, int);
493  extern int iscsi_switch_str_param(char **, char *);
494  
495  /*
496   * inline functions to deal with padding.
497   */
498  static inline unsigned int
iscsi_padded(unsigned int len)499  iscsi_padded(unsigned int len)
500  {
501  	return (len + ISCSI_PAD_LEN - 1) & ~(ISCSI_PAD_LEN - 1);
502  }
503  
504  static inline unsigned int
iscsi_padding(unsigned int len)505  iscsi_padding(unsigned int len)
506  {
507  	len &= (ISCSI_PAD_LEN - 1);
508  	if (len)
509  		len = ISCSI_PAD_LEN - len;
510  	return len;
511  }
512  
513  #endif
514