summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/elx/efct/efct_io.h
blob: bb0f51811a7cb72860877d290abb764aa6e50b9d (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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
 */

#if !defined(__EFCT_IO_H__)
#define __EFCT_IO_H__

#include "efct_lio.h"

#define EFCT_LOG_ENABLE_IO_ERRORS(efct)		\
		(((efct) != NULL) ? (((efct)->logmask & (1U << 6)) != 0) : 0)

#define io_error_log(io, fmt, ...)  \
	do { \
		if (EFCT_LOG_ENABLE_IO_ERRORS(io->efct)) \
			efc_log_warn(io->efct, fmt, ##__VA_ARGS__); \
	} while (0)

#define SCSI_CMD_BUF_LENGTH	48
#define SCSI_RSP_BUF_LENGTH	(FCP_RESP_WITH_EXT + SCSI_SENSE_BUFFERSIZE)
#define EFCT_NUM_SCSI_IOS	8192

enum efct_io_type {
	EFCT_IO_TYPE_IO = 0,
	EFCT_IO_TYPE_ELS,
	EFCT_IO_TYPE_CT,
	EFCT_IO_TYPE_CT_RESP,
	EFCT_IO_TYPE_BLS_RESP,
	EFCT_IO_TYPE_ABORT,

	EFCT_IO_TYPE_MAX,
};

enum efct_els_state {
	EFCT_ELS_REQUEST = 0,
	EFCT_ELS_REQUEST_DELAYED,
	EFCT_ELS_REQUEST_DELAY_ABORT,
	EFCT_ELS_REQ_ABORT,
	EFCT_ELS_REQ_ABORTED,
	EFCT_ELS_ABORT_IO_COMPL,
};

/**
 * Scsi target IO object
 * @efct:		pointer back to efct
 * @instance_index:	unique instance index value
 * @io:			IO display name
 * @node:		pointer to node
 * @list_entry:		io list entry
 * @io_pending_link:	io pending list entry
 * @ref:		reference counter
 * @release:		release callback function
 * @init_task_tag:	initiator task tag (OX_ID) for back-end and SCSI logging
 * @tgt_task_tag:	target task tag (RX_ID) for back-end and SCSI logging
 * @hw_tag:		HW layer unique IO id
 * @tag:		unique IO identifier
 * @sgl:		SGL
 * @sgl_allocated:	Number of allocated SGEs
 * @sgl_count:		Number of SGEs in this SGL
 * @tgt_io:		backend target private IO data
 * @exp_xfer_len:	expected data transfer length, based on FC header
 * @hw_priv:		Declarations private to HW/SLI
 * @io_type:		indicates what this struct efct_io structure is used for
 * @hio:		hw io object
 * @transferred:	Number of bytes transferred
 * @auto_resp:		set if auto_trsp was set
 * @low_latency:	set if low latency request
 * @wq_steering:	selected WQ steering request
 * @wq_class:		selected WQ class if steering is class
 * @xfer_req:		transfer size for current request
 * @scsi_tgt_cb:	target callback function
 * @scsi_tgt_cb_arg:	target callback function argument
 * @abort_cb:		abort callback function
 * @abort_cb_arg:	abort callback function argument
 * @bls_cb:		BLS callback function
 * @bls_cb_arg:		BLS callback function argument
 * @tmf_cmd:		TMF command being processed
 * @abort_rx_id:	rx_id from the ABTS that initiated the command abort
 * @cmd_tgt:		True if this is a Target command
 * @send_abts:		when aborting, indicates ABTS is to be sent
 * @cmd_ini:		True if this is an Initiator command
 * @seq_init:		True if local node has sequence initiative
 * @iparam:		iparams for hw io send call
 * @hio_type:		HW IO type
 * @wire_len:		wire length
 * @hw_cb:		saved HW callback
 * @io_to_abort:	for abort handling, pointer to IO to abort
 * @rspbuf:		SCSI Response buffer
 * @timeout:		Timeout value in seconds for this IO
 * @cs_ctl:		CS_CTL priority for this IO
 * @io_free:		Is io object in freelist
 * @app_id:		application id
 */
struct efct_io {
	struct efct		*efct;
	u32			instance_index;
	const char		*display_name;
	struct efct_node	*node;

	struct list_head	list_entry;
	struct list_head	io_pending_link;
	struct kref		ref;
	void (*release)(struct kref *arg);
	u32			init_task_tag;
	u32			tgt_task_tag;
	u32			hw_tag;
	u32			tag;
	struct efct_scsi_sgl	*sgl;
	u32			sgl_allocated;
	u32			sgl_count;
	struct efct_scsi_tgt_io tgt_io;
	u32			exp_xfer_len;

	void			*hw_priv;

	enum efct_io_type	io_type;
	struct efct_hw_io	*hio;
	size_t			transferred;

	bool			auto_resp;
	bool			low_latency;
	u8			wq_steering;
	u8			wq_class;
	u64			xfer_req;
	efct_scsi_io_cb_t	scsi_tgt_cb;
	void			*scsi_tgt_cb_arg;
	efct_scsi_io_cb_t	abort_cb;
	void			*abort_cb_arg;
	efct_scsi_io_cb_t	bls_cb;
	void			*bls_cb_arg;
	enum efct_scsi_tmf_cmd	tmf_cmd;
	u16			abort_rx_id;

	bool			cmd_tgt;
	bool			send_abts;
	bool			cmd_ini;
	bool			seq_init;
	union efct_hw_io_param_u iparam;
	enum efct_hw_io_type	hio_type;
	u64			wire_len;
	void			*hw_cb;

	struct efct_io		*io_to_abort;

	struct efc_dma		rspbuf;
	u32			timeout;
	u8			cs_ctl;
	u8			io_free;
	u32			app_id;
};

struct efct_io_cb_arg {
	int status;
	int ext_status;
	void *app;
};

struct efct_io_pool *
efct_io_pool_create(struct efct *efct, u32 num_sgl);
int
efct_io_pool_free(struct efct_io_pool *io_pool);
u32
efct_io_pool_allocated(struct efct_io_pool *io_pool);

struct efct_io *
efct_io_pool_io_alloc(struct efct_io_pool *io_pool);
void
efct_io_pool_io_free(struct efct_io_pool *io_pool, struct efct_io *io);
struct efct_io *
efct_io_find_tgt_io(struct efct *efct, struct efct_node *node,
		    u16 ox_id, u16 rx_id);
#endif /* __EFCT_IO_H__ */