1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /******************************************************************************* |
3 | * IBM Virtual SCSI Target Driver |
4 | * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp. |
5 | * Santiago Leon (santil@us.ibm.com) IBM Corp. |
6 | * Linda Xie (lxie@us.ibm.com) IBM Corp. |
7 | * |
8 | * Copyright (C) 2005-2011 FUJITA Tomonori <tomof@acm.org> |
9 | * Copyright (C) 2010 Nicholas A. Bellinger <nab@kernel.org> |
10 | * Copyright (C) 2016 Bryant G. Ly <bryantly@linux.vnet.ibm.com> IBM Corp. |
11 | * |
12 | * Authors: Bryant G. Ly <bryantly@linux.vnet.ibm.com> |
13 | * Authors: Michael Cyr <mikecyr@linux.vnet.ibm.com> |
14 | * |
15 | ****************************************************************************/ |
16 | |
17 | #ifndef __H_IBMVSCSI_TGT |
18 | #define __H_IBMVSCSI_TGT |
19 | |
20 | #include <linux/interrupt.h> |
21 | #include "libsrp.h" |
22 | |
23 | #define SYS_ID_NAME_LEN 64 |
24 | #define PARTITION_NAMELEN 96 |
25 | #define IBMVSCSIS_NAMELEN 32 |
26 | |
27 | #define MSG_HI 0 |
28 | #define MSG_LOW 1 |
29 | |
30 | #define MAX_CMD_Q_PAGES 4 |
31 | #define CRQ_PER_PAGE (PAGE_SIZE / sizeof(struct viosrp_crq)) |
32 | /* in terms of number of elements */ |
33 | #define DEFAULT_CMD_Q_SIZE CRQ_PER_PAGE |
34 | #define MAX_CMD_Q_SIZE (DEFAULT_CMD_Q_SIZE * MAX_CMD_Q_PAGES) |
35 | |
36 | #define SRP_VIOLATION 0x102 /* general error code */ |
37 | |
38 | /* |
39 | * SRP buffer formats defined as of 16.a supported by this driver. |
40 | */ |
41 | #define SUPPORTED_FORMATS ((SRP_DATA_DESC_DIRECT << 1) | \ |
42 | (SRP_DATA_DESC_INDIRECT << 1)) |
43 | |
44 | #define SCSI_LUN_ADDR_METHOD_FLAT 1 |
45 | |
46 | struct dma_window { |
47 | u32 liobn; /* Unique per vdevice */ |
48 | u64 tce_base; /* Physical location of the TCE table */ |
49 | u64 tce_size; /* Size of the TCE table in bytes */ |
50 | }; |
51 | |
52 | struct target_dds { |
53 | u64 unit_id; /* 64 bit will force alignment */ |
54 | #define NUM_DMA_WINDOWS 2 |
55 | #define LOCAL 0 |
56 | #define REMOTE 1 |
57 | struct dma_window window[NUM_DMA_WINDOWS]; |
58 | |
59 | /* root node property "ibm,partition-no" */ |
60 | uint partition_num; |
61 | char partition_name[PARTITION_NAMELEN]; |
62 | }; |
63 | |
64 | #define MAX_NUM_PORTS 1 |
65 | #define MAX_H_COPY_RDMA (128 * 1024) |
66 | |
67 | #define MAX_EYE 64 |
68 | |
69 | /* Return codes */ |
70 | #define ADAPT_SUCCESS 0L |
71 | /* choose error codes that do not conflict with PHYP */ |
72 | #define ERROR -40L |
73 | |
74 | struct format_code { |
75 | u8 reserved; |
76 | u8 buffers; |
77 | }; |
78 | |
79 | struct client_info { |
80 | #define SRP_VERSION "16.a" |
81 | char srp_version[8]; |
82 | /* root node property ibm,partition-name */ |
83 | char partition_name[PARTITION_NAMELEN]; |
84 | /* root node property ibm,partition-no */ |
85 | u32 partition_number; |
86 | /* initially 1 */ |
87 | u32 mad_version; |
88 | u32 os_type; |
89 | }; |
90 | |
91 | /* |
92 | * Changing this constant changes the number of seconds to wait before |
93 | * considering the client will never service its queue again. |
94 | */ |
95 | #define SECONDS_TO_CONSIDER_FAILED 30 |
96 | /* |
97 | * These constants set the polling period used to determine if the client |
98 | * has freed at least one element in the response queue. |
99 | */ |
100 | #define WAIT_SECONDS 1 |
101 | #define WAIT_NANO_SECONDS 5000 |
102 | #define MAX_TIMER_POPS ((1000000 / WAIT_NANO_SECONDS) * \ |
103 | SECONDS_TO_CONSIDER_FAILED) |
104 | /* |
105 | * general purpose timer control block |
106 | * which can be used for multiple functions |
107 | */ |
108 | struct timer_cb { |
109 | struct hrtimer timer; |
110 | /* |
111 | * how long has it been since the client |
112 | * serviced the queue. The variable is incrmented |
113 | * in the service_wait_q routine and cleared |
114 | * in send messages |
115 | */ |
116 | int timer_pops; |
117 | /* the timer is started */ |
118 | bool started; |
119 | }; |
120 | |
121 | struct cmd_queue { |
122 | /* kva */ |
123 | struct viosrp_crq *base_addr; |
124 | dma_addr_t crq_token; |
125 | /* used to maintain index */ |
126 | uint mask; |
127 | /* current element */ |
128 | uint index; |
129 | int size; |
130 | }; |
131 | |
132 | #define SCSOLNT_RESP_SHIFT 1 |
133 | #define UCSOLNT_RESP_SHIFT 2 |
134 | |
135 | #define SCSOLNT BIT(SCSOLNT_RESP_SHIFT) |
136 | #define UCSOLNT BIT(UCSOLNT_RESP_SHIFT) |
137 | |
138 | enum cmd_type { |
139 | SCSI_CDB = 0x01, |
140 | TASK_MANAGEMENT = 0x02, |
141 | /* MAD or addressed to port 0 */ |
142 | ADAPTER_MAD = 0x04, |
143 | UNSET_TYPE = 0x08, |
144 | }; |
145 | |
146 | struct iu_rsp { |
147 | u8 format; |
148 | u8 sol_not; |
149 | u16 len; |
150 | /* tag is just to help client identify cmd, so don't translate be/le */ |
151 | u64 tag; |
152 | }; |
153 | |
154 | struct ibmvscsis_cmd { |
155 | struct list_head list; |
156 | /* Used for TCM Core operations */ |
157 | struct se_cmd se_cmd; |
158 | struct iu_entry *iue; |
159 | struct iu_rsp rsp; |
160 | struct work_struct work; |
161 | struct scsi_info *adapter; |
162 | struct ibmvscsis_cmd *abort_cmd; |
163 | /* Sense buffer that will be mapped into outgoing status */ |
164 | unsigned char sense_buf[TRANSPORT_SENSE_BUFFER]; |
165 | u64 init_time; |
166 | #define CMD_FAST_FAIL BIT(0) |
167 | #define DELAY_SEND BIT(1) |
168 | u32 flags; |
169 | char type; |
170 | }; |
171 | |
172 | struct ibmvscsis_nexus { |
173 | struct se_session *se_sess; |
174 | }; |
175 | |
176 | struct ibmvscsis_tport { |
177 | /* SCSI protocol the tport is providing */ |
178 | u8 tport_proto_id; |
179 | /* ASCII formatted WWPN for SRP Target port */ |
180 | char tport_name[IBMVSCSIS_NAMELEN]; |
181 | /* Returned by ibmvscsis_make_tport() */ |
182 | struct se_wwn tport_wwn; |
183 | /* Returned by ibmvscsis_make_tpg() */ |
184 | struct se_portal_group se_tpg; |
185 | /* ibmvscsis port target portal group tag for TCM */ |
186 | u16 tport_tpgt; |
187 | /* Pointer to TCM session for I_T Nexus */ |
188 | struct ibmvscsis_nexus *ibmv_nexus; |
189 | bool enabled; |
190 | bool releasing; |
191 | }; |
192 | |
193 | struct scsi_info { |
194 | struct list_head list; |
195 | char eye[MAX_EYE]; |
196 | |
197 | /* commands waiting for space on repsonse queue */ |
198 | struct list_head waiting_rsp; |
199 | #define NO_QUEUE 0x00 |
200 | #define WAIT_ENABLED 0X01 |
201 | #define WAIT_CONNECTION 0x04 |
202 | /* have established a connection */ |
203 | #define CONNECTED 0x08 |
204 | /* at least one port is processing SRP IU */ |
205 | #define SRP_PROCESSING 0x10 |
206 | /* remove request received */ |
207 | #define UNCONFIGURING 0x20 |
208 | /* disconnect by letting adapter go idle, no error */ |
209 | #define WAIT_IDLE 0x40 |
210 | /* disconnecting to clear an error */ |
211 | #define ERR_DISCONNECT 0x80 |
212 | /* disconnect to clear error state, then come back up */ |
213 | #define ERR_DISCONNECT_RECONNECT 0x100 |
214 | /* disconnected after clearing an error */ |
215 | #define ERR_DISCONNECTED 0x200 |
216 | /* A series of errors caused unexpected errors */ |
217 | #define UNDEFINED 0x400 |
218 | u16 state; |
219 | int fast_fail; |
220 | struct target_dds dds; |
221 | char *cmd_pool; |
222 | /* list of free commands */ |
223 | struct list_head free_cmd; |
224 | /* command elements ready for scheduler */ |
225 | struct list_head schedule_q; |
226 | /* commands sent to TCM */ |
227 | struct list_head active_q; |
228 | caddr_t *map_buf; |
229 | /* ioba of map buffer */ |
230 | dma_addr_t map_ioba; |
231 | /* allowable number of outstanding SRP requests */ |
232 | int request_limit; |
233 | /* extra credit */ |
234 | int credit; |
235 | /* outstanding transactions against credit limit */ |
236 | int debit; |
237 | |
238 | /* allow only one outstanding mad request */ |
239 | #define PROCESSING_MAD 0x00002 |
240 | /* Waiting to go idle */ |
241 | #define WAIT_FOR_IDLE 0x00004 |
242 | /* H_REG_CRQ called */ |
243 | #define CRQ_CLOSED 0x00010 |
244 | /* detected that client has failed */ |
245 | #define CLIENT_FAILED 0x00040 |
246 | /* detected that transport event occurred */ |
247 | #define TRANS_EVENT 0x00080 |
248 | /* don't attempt to send anything to the client */ |
249 | #define RESPONSE_Q_DOWN 0x00100 |
250 | /* request made to schedule disconnect handler */ |
251 | #define SCHEDULE_DISCONNECT 0x00400 |
252 | /* disconnect handler is scheduled */ |
253 | #define DISCONNECT_SCHEDULED 0x00800 |
254 | /* remove function is sleeping */ |
255 | #define CFG_SLEEPING 0x01000 |
256 | /* Register for Prepare for Suspend Transport Events */ |
257 | #define PREP_FOR_SUSPEND_ENABLED 0x02000 |
258 | /* Prepare for Suspend event sent */ |
259 | #define PREP_FOR_SUSPEND_PENDING 0x04000 |
260 | /* Resume from Suspend event sent */ |
261 | #define PREP_FOR_SUSPEND_ABORTED 0x08000 |
262 | /* Prepare for Suspend event overwrote another CRQ entry */ |
263 | #define PREP_FOR_SUSPEND_OVERWRITE 0x10000 |
264 | u32 flags; |
265 | /* adapter lock */ |
266 | spinlock_t intr_lock; |
267 | /* information needed to manage command queue */ |
268 | struct cmd_queue cmd_q; |
269 | /* used in hcall to copy response back into srp buffer */ |
270 | u64 empty_iu_id; |
271 | /* used in crq, to tag what iu the response is for */ |
272 | u64 empty_iu_tag; |
273 | uint new_state; |
274 | uint resume_state; |
275 | /* control block for the response queue timer */ |
276 | struct timer_cb rsp_q_timer; |
277 | /* keep last client to enable proper accounting */ |
278 | struct client_info client_data; |
279 | /* what can this client do */ |
280 | u32 client_cap; |
281 | /* |
282 | * The following two fields capture state and flag changes that |
283 | * can occur when the lock is given up. In the orginal design, |
284 | * the lock was held during calls into phyp; |
285 | * however, phyp did not meet PAPR architecture. This is |
286 | * a work around. |
287 | */ |
288 | u16 phyp_acr_state; |
289 | u32 phyp_acr_flags; |
290 | |
291 | struct workqueue_struct *work_q; |
292 | struct completion wait_idle; |
293 | struct completion unconfig; |
294 | struct device dev; |
295 | struct vio_dev *dma_dev; |
296 | struct srp_target target; |
297 | struct ibmvscsis_tport tport; |
298 | struct tasklet_struct work_task; |
299 | struct work_struct proc_work; |
300 | }; |
301 | |
302 | /* |
303 | * Provide a constant that allows software to detect the adapter is |
304 | * disconnecting from the client from one of several states. |
305 | */ |
306 | #define IS_DISCONNECTING (UNCONFIGURING | ERR_DISCONNECT_RECONNECT | \ |
307 | ERR_DISCONNECT) |
308 | |
309 | /* |
310 | * Provide a constant that can be used with interrupt handling that |
311 | * essentially lets the interrupt handler know that all requests should |
312 | * be thrown out, |
313 | */ |
314 | #define DONT_PROCESS_STATE (IS_DISCONNECTING | UNDEFINED | \ |
315 | ERR_DISCONNECTED | WAIT_IDLE) |
316 | |
317 | /* |
318 | * If any of these flag bits are set then do not allow the interrupt |
319 | * handler to schedule the off level handler. |
320 | */ |
321 | #define BLOCK (DISCONNECT_SCHEDULED) |
322 | |
323 | /* State and transition events that stop the interrupt handler */ |
324 | #define TARGET_STOP(VSCSI) (long)(((VSCSI)->state & DONT_PROCESS_STATE) | \ |
325 | ((VSCSI)->flags & BLOCK)) |
326 | |
327 | #define PREP_FOR_SUSPEND_FLAGS (PREP_FOR_SUSPEND_ENABLED | \ |
328 | PREP_FOR_SUSPEND_PENDING | \ |
329 | PREP_FOR_SUSPEND_ABORTED | \ |
330 | PREP_FOR_SUSPEND_OVERWRITE) |
331 | |
332 | /* flag bit that are not reset during disconnect */ |
333 | #define PRESERVE_FLAG_FIELDS (PREP_FOR_SUSPEND_FLAGS) |
334 | |
335 | #define vio_iu(IUE) ((union viosrp_iu *)((IUE)->sbuf->buf)) |
336 | |
337 | #define READ_CMD(cdb) (((cdb)[0] & 0x1F) == 8) |
338 | #define WRITE_CMD(cdb) (((cdb)[0] & 0x1F) == 0xA) |
339 | |
340 | #ifndef H_GET_PARTNER_INFO |
341 | #define H_GET_PARTNER_INFO 0x0000000000000008LL |
342 | #endif |
343 | #ifndef H_ENABLE_PREPARE_FOR_SUSPEND |
344 | #define H_ENABLE_PREPARE_FOR_SUSPEND 0x000000000000001DLL |
345 | #endif |
346 | #ifndef H_READY_FOR_SUSPEND |
347 | #define H_READY_FOR_SUSPEND 0x000000000000001ELL |
348 | #endif |
349 | |
350 | |
351 | #define h_copy_rdma(l, sa, sb, da, db) \ |
352 | plpar_hcall_norets(H_COPY_RDMA, l, sa, sb, da, db) |
353 | #define h_vioctl(u, o, a, u1, u2, u3, u4) \ |
354 | plpar_hcall_norets(H_VIOCTL, u, o, a, u1, u2) |
355 | #define h_reg_crq(ua, tok, sz) \ |
356 | plpar_hcall_norets(H_REG_CRQ, ua, tok, sz) |
357 | #define h_free_crq(ua) \ |
358 | plpar_hcall_norets(H_FREE_CRQ, ua) |
359 | #define h_send_crq(ua, d1, d2) \ |
360 | plpar_hcall_norets(H_SEND_CRQ, ua, d1, d2) |
361 | |
362 | #endif |
363 | |