Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2b604c9b | 2 | /* |
a54ca0f6 SS |
3 | * zfcp device driver |
4 | * debug feature declarations | |
2b604c9b | 5 | * |
9fe5d2b2 | 6 | * Copyright IBM Corp. 2008, 2017 |
2b604c9b CS |
7 | */ |
8 | ||
9 | #ifndef ZFCP_DBF_H | |
10 | #define ZFCP_DBF_H | |
11 | ||
4318e08c | 12 | #include <scsi/fc/fc_fcp.h> |
dcd20e23 | 13 | #include "zfcp_ext.h" |
2b604c9b | 14 | #include "zfcp_fsf.h" |
dcd20e23 | 15 | #include "zfcp_def.h" |
2b604c9b | 16 | |
ae0904f6 | 17 | #define ZFCP_DBF_TAG_LEN 7 |
2b604c9b | 18 | |
d21e9daa CS |
19 | #define ZFCP_DBF_INVALID_LUN 0xFFFFFFFFFFFFFFFFull |
20 | ||
4eeaa4f3 SM |
21 | enum zfcp_dbf_pseudo_erp_act_type { |
22 | ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD = 0xff, | |
23 | ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL = 0xfe, | |
24 | }; | |
25 | ||
ae0904f6 SS |
26 | /** |
27 | * struct zfcp_dbf_rec_trigger - trace record for triggered recovery action | |
28 | * @ready: number of ready recovery actions | |
29 | * @running: number of running recovery actions | |
30 | * @want: wanted recovery action | |
31 | * @need: needed recovery action | |
32 | */ | |
33 | struct zfcp_dbf_rec_trigger { | |
2b604c9b CS |
34 | u32 ready; |
35 | u32 running; | |
2b604c9b CS |
36 | u8 want; |
37 | u8 need; | |
ae0904f6 SS |
38 | } __packed; |
39 | ||
40 | /** | |
41 | * struct zfcp_dbf_rec_running - trace record for running recovery | |
42 | * @fsf_req_id: request id for fsf requests | |
43 | * @rec_status: status of the fsf request | |
44 | * @rec_step: current step of the recovery action | |
45 | * rec_count: recovery counter | |
46 | */ | |
47 | struct zfcp_dbf_rec_running { | |
48 | u64 fsf_req_id; | |
49 | u32 rec_status; | |
50 | u16 rec_step; | |
51 | u8 rec_action; | |
52 | u8 rec_count; | |
53 | } __packed; | |
2b604c9b | 54 | |
ae0904f6 SS |
55 | /** |
56 | * enum zfcp_dbf_rec_id - recovery trace record id | |
57 | * @ZFCP_DBF_REC_TRIG: triggered recovery identifier | |
58 | * @ZFCP_DBF_REC_RUN: running recovery identifier | |
59 | */ | |
60 | enum zfcp_dbf_rec_id { | |
61 | ZFCP_DBF_REC_TRIG = 1, | |
62 | ZFCP_DBF_REC_RUN = 2, | |
7337891f | 63 | }; |
2b604c9b | 64 | |
ae0904f6 SS |
65 | /** |
66 | * struct zfcp_dbf_rec - trace record for error recovery actions | |
67 | * @id: unique number of recovery record type | |
68 | * @tag: identifier string specifying the location of initiation | |
69 | * @lun: logical unit number | |
70 | * @wwpn: word wide port number | |
71 | * @d_id: destination ID | |
72 | * @adapter_status: current status of the adapter | |
73 | * @port_status: current status of the port | |
74 | * @lun_status: current status of the lun | |
75 | * @u.trig: structure zfcp_dbf_rec_trigger | |
76 | * @u.run: structure zfcp_dbf_rec_running | |
77 | */ | |
78 | struct zfcp_dbf_rec { | |
2b604c9b | 79 | u8 id; |
ae0904f6 SS |
80 | char tag[ZFCP_DBF_TAG_LEN]; |
81 | u64 lun; | |
82 | u64 wwpn; | |
83 | u32 d_id; | |
84 | u32 adapter_status; | |
85 | u32 port_status; | |
86 | u32 lun_status; | |
2b604c9b | 87 | union { |
ae0904f6 SS |
88 | struct zfcp_dbf_rec_trigger trig; |
89 | struct zfcp_dbf_rec_running run; | |
2b604c9b | 90 | } u; |
ae0904f6 | 91 | } __packed; |
2b604c9b | 92 | |
2c55b750 SS |
93 | /** |
94 | * enum zfcp_dbf_san_id - SAN trace record identifier | |
95 | * @ZFCP_DBF_SAN_REQ: request trace record id | |
96 | * @ZFCP_DBF_SAN_RES: response trace record id | |
97 | * @ZFCP_DBF_SAN_ELS: extended link service record id | |
98 | */ | |
99 | enum zfcp_dbf_san_id { | |
100 | ZFCP_DBF_SAN_REQ = 1, | |
101 | ZFCP_DBF_SAN_RES = 2, | |
102 | ZFCP_DBF_SAN_ELS = 3, | |
103 | }; | |
104 | ||
105 | /** struct zfcp_dbf_san - trace record for SAN requests and responses | |
106 | * @id: unique number of recovery record type | |
107 | * @tag: identifier string specifying the location of initiation | |
108 | * @fsf_req_id: request id for fsf requests | |
109 | * @payload: unformatted information related to request/response | |
110 | * @d_id: destination id | |
111 | */ | |
112 | struct zfcp_dbf_san { | |
113 | u8 id; | |
114 | char tag[ZFCP_DBF_TAG_LEN]; | |
115 | u64 fsf_req_id; | |
116 | u32 d_id; | |
117 | #define ZFCP_DBF_SAN_MAX_PAYLOAD (FC_CT_HDR_LEN + 32) | |
118 | char payload[ZFCP_DBF_SAN_MAX_PAYLOAD]; | |
aceeffbb | 119 | u16 pl_len; |
2c55b750 SS |
120 | } __packed; |
121 | ||
a54ca0f6 SS |
122 | /** |
123 | * struct zfcp_dbf_hba_res - trace record for hba responses | |
124 | * @req_issued: timestamp when request was issued | |
125 | * @prot_status: protocol status | |
126 | * @prot_status_qual: protocol status qualifier | |
127 | * @fsf_status: fsf status | |
128 | * @fsf_status_qual: fsf status qualifier | |
129 | */ | |
130 | struct zfcp_dbf_hba_res { | |
131 | u64 req_issued; | |
132 | u32 prot_status; | |
133 | u8 prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE]; | |
2b604c9b | 134 | u32 fsf_status; |
a54ca0f6 | 135 | u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; |
7c964ffe SM |
136 | u32 port_handle; |
137 | u32 lun_handle; | |
a54ca0f6 | 138 | } __packed; |
2b604c9b | 139 | |
a54ca0f6 SS |
140 | /** |
141 | * struct zfcp_dbf_hba_uss - trace record for unsolicited status | |
142 | * @status_type: type of unsolicited status | |
143 | * @status_subtype: subtype of unsolicited status | |
144 | * @d_id: destination ID | |
145 | * @lun: logical unit number | |
146 | * @queue_designator: queue designator | |
147 | */ | |
148 | struct zfcp_dbf_hba_uss { | |
2b604c9b CS |
149 | u32 status_type; |
150 | u32 status_subtype; | |
a54ca0f6 SS |
151 | u32 d_id; |
152 | u64 lun; | |
153 | u64 queue_designator; | |
154 | } __packed; | |
2b604c9b | 155 | |
a54ca0f6 SS |
156 | /** |
157 | * enum zfcp_dbf_hba_id - HBA trace record identifier | |
158 | * @ZFCP_DBF_HBA_RES: response trace record | |
159 | * @ZFCP_DBF_HBA_USS: unsolicited status trace record | |
160 | * @ZFCP_DBF_HBA_BIT: bit error trace record | |
161 | */ | |
162 | enum zfcp_dbf_hba_id { | |
163 | ZFCP_DBF_HBA_RES = 1, | |
164 | ZFCP_DBF_HBA_USS = 2, | |
165 | ZFCP_DBF_HBA_BIT = 3, | |
cb452149 | 166 | ZFCP_DBF_HBA_BASIC = 4, |
a54ca0f6 | 167 | }; |
2b604c9b | 168 | |
a54ca0f6 SS |
169 | /** |
170 | * struct zfcp_dbf_hba - common trace record for HBA records | |
171 | * @id: unique number of recovery record type | |
172 | * @tag: identifier string specifying the location of initiation | |
173 | * @fsf_req_id: request id for fsf requests | |
174 | * @fsf_req_status: status of fsf request | |
175 | * @fsf_cmd: fsf command | |
176 | * @fsf_seq_no: fsf sequence number | |
177 | * @pl_len: length of payload stored as zfcp_dbf_pay | |
178 | * @u: record type specific data | |
179 | */ | |
180 | struct zfcp_dbf_hba { | |
181 | u8 id; | |
182 | char tag[ZFCP_DBF_TAG_LEN]; | |
183 | u64 fsf_req_id; | |
184 | u32 fsf_req_status; | |
185 | u32 fsf_cmd; | |
186 | u32 fsf_seq_no; | |
187 | u16 pl_len; | |
2b604c9b | 188 | union { |
a54ca0f6 SS |
189 | struct zfcp_dbf_hba_res res; |
190 | struct zfcp_dbf_hba_uss uss; | |
191 | struct fsf_bit_error_payload be; | |
6bc473dd | 192 | } u; |
a54ca0f6 SS |
193 | } __packed; |
194 | ||
250a1352 SS |
195 | /** |
196 | * enum zfcp_dbf_scsi_id - scsi trace record identifier | |
197 | * @ZFCP_DBF_SCSI_CMND: scsi command trace record | |
198 | */ | |
199 | enum zfcp_dbf_scsi_id { | |
200 | ZFCP_DBF_SCSI_CMND = 1, | |
201 | }; | |
202 | ||
203 | /** | |
204 | * struct zfcp_dbf_scsi - common trace record for SCSI records | |
205 | * @id: unique number of recovery record type | |
206 | * @tag: identifier string specifying the location of initiation | |
207 | * @scsi_id: scsi device id | |
5d4a3d0a | 208 | * @scsi_lun: scsi device logical unit number, low part of 64 bit, old 32 bit |
250a1352 SS |
209 | * @scsi_result: scsi result |
210 | * @scsi_retries: current retry number of scsi request | |
211 | * @scsi_allowed: allowed retries | |
5b2fc2a1 | 212 | * @fcp_rsp_info: FCP response info code |
250a1352 SS |
213 | * @scsi_opcode: scsi opcode |
214 | * @fsf_req_id: request id of fsf request | |
215 | * @host_scribble: LLD specific data attached to SCSI request | |
5b2fc2a1 SM |
216 | * @pl_len: length of payload stored as zfcp_dbf_pay |
217 | * @fcp_rsp: response for FCP request | |
5d4a3d0a | 218 | * @scsi_lun_64_hi: scsi device logical unit number, high part of 64 bit |
250a1352 SS |
219 | */ |
220 | struct zfcp_dbf_scsi { | |
221 | u8 id; | |
222 | char tag[ZFCP_DBF_TAG_LEN]; | |
223 | u32 scsi_id; | |
224 | u32 scsi_lun; | |
225 | u32 scsi_result; | |
226 | u8 scsi_retries; | |
227 | u8 scsi_allowed; | |
228 | u8 fcp_rsp_info; | |
229 | #define ZFCP_DBF_SCSI_OPCODE 16 | |
230 | u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE]; | |
231 | u64 fsf_req_id; | |
232 | u64 host_scribble; | |
233 | u16 pl_len; | |
234 | struct fcp_resp_with_ext fcp_rsp; | |
5d4a3d0a | 235 | u32 scsi_lun_64_hi; |
250a1352 SS |
236 | } __packed; |
237 | ||
a54ca0f6 SS |
238 | /** |
239 | * struct zfcp_dbf_pay - trace record for unformatted payload information | |
240 | * @area: area this record is originated from | |
241 | * @counter: ascending record number | |
242 | * @fsf_req_id: request id of fsf request | |
243 | * @data: unformatted data | |
244 | */ | |
245 | struct zfcp_dbf_pay { | |
ea4a3a6a | 246 | u8 counter; |
a54ca0f6 | 247 | char area[ZFCP_DBF_TAG_LEN]; |
a54ca0f6 SS |
248 | u64 fsf_req_id; |
249 | #define ZFCP_DBF_PAY_MAX_REC 0x100 | |
250 | char data[ZFCP_DBF_PAY_MAX_REC]; | |
251 | } __packed; | |
2b604c9b | 252 | |
ea4a3a6a SS |
253 | /** |
254 | * struct zfcp_dbf - main dbf trace structure | |
255 | * @pay: reference to payload trace area | |
256 | * @rec: reference to recovery trace area | |
257 | * @hba: reference to hba trace area | |
258 | * @san: reference to san trace area | |
259 | * @scsi: reference to scsi trace area | |
260 | * @pay_lock: lock protecting payload trace buffer | |
261 | * @rec_lock: lock protecting recovery trace buffer | |
262 | * @hba_lock: lock protecting hba trace buffer | |
263 | * @san_lock: lock protecting san trace buffer | |
264 | * @scsi_lock: lock protecting scsi trace buffer | |
265 | * @pay_buf: pre-allocated buffer for payload | |
266 | * @rec_buf: pre-allocated buffer for recovery | |
267 | * @hba_buf: pre-allocated buffer for hba | |
268 | * @san_buf: pre-allocated buffer for san | |
269 | * @scsi_buf: pre-allocated buffer for scsi | |
270 | */ | |
d46f384a | 271 | struct zfcp_dbf { |
a54ca0f6 | 272 | debug_info_t *pay; |
5771710b SS |
273 | debug_info_t *rec; |
274 | debug_info_t *hba; | |
275 | debug_info_t *san; | |
276 | debug_info_t *scsi; | |
a54ca0f6 | 277 | spinlock_t pay_lock; |
5771710b SS |
278 | spinlock_t rec_lock; |
279 | spinlock_t hba_lock; | |
280 | spinlock_t san_lock; | |
281 | spinlock_t scsi_lock; | |
ea4a3a6a | 282 | struct zfcp_dbf_pay pay_buf; |
ae0904f6 | 283 | struct zfcp_dbf_rec rec_buf; |
a54ca0f6 | 284 | struct zfcp_dbf_hba hba_buf; |
2c55b750 | 285 | struct zfcp_dbf_san san_buf; |
250a1352 | 286 | struct zfcp_dbf_scsi scsi_buf; |
d46f384a CS |
287 | }; |
288 | ||
56d23ed7 SM |
289 | /** |
290 | * zfcp_dbf_hba_fsf_resp_suppress - true if we should not trace by default | |
291 | * @req: request that has been completed | |
292 | * | |
293 | * Returns true if FCP response with only benign residual under count. | |
294 | */ | |
295 | static inline | |
296 | bool zfcp_dbf_hba_fsf_resp_suppress(struct zfcp_fsf_req *req) | |
297 | { | |
298 | struct fsf_qtcb *qtcb = req->qtcb; | |
299 | u32 fsf_stat = qtcb->header.fsf_status; | |
300 | struct fcp_resp *fcp_rsp; | |
301 | u8 rsp_flags, fr_status; | |
302 | ||
303 | if (qtcb->prefix.qtcb_type != FSF_IO_COMMAND) | |
304 | return false; /* not an FCP response */ | |
df00d7b8 | 305 | fcp_rsp = &qtcb->bottom.io.fcp_rsp.iu.resp; |
56d23ed7 SM |
306 | rsp_flags = fcp_rsp->fr_flags; |
307 | fr_status = fcp_rsp->fr_status; | |
308 | return (fsf_stat == FSF_FCP_RSP_AVAILABLE) && | |
309 | (rsp_flags == FCP_RESID_UNDER) && | |
310 | (fr_status == SAM_STAT_GOOD); | |
311 | } | |
312 | ||
2e261af8 | 313 | static inline |
a54ca0f6 | 314 | void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req) |
2e261af8 | 315 | { |
8e6a8285 | 316 | if (debug_level_enabled(req->adapter->dbf->hba, level)) |
35f040df | 317 | zfcp_dbf_hba_fsf_res(tag, level, req); |
2e261af8 CS |
318 | } |
319 | ||
320 | /** | |
5771710b | 321 | * zfcp_dbf_hba_fsf_response - trace event for request completion |
250a1352 | 322 | * @req: request that has been completed |
2e261af8 | 323 | */ |
a54ca0f6 SS |
324 | static inline |
325 | void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req) | |
2e261af8 | 326 | { |
2e261af8 CS |
327 | struct fsf_qtcb *qtcb = req->qtcb; |
328 | ||
fdb7cee3 SM |
329 | if (unlikely(req->status & (ZFCP_STATUS_FSFREQ_DISMISSED | |
330 | ZFCP_STATUS_FSFREQ_ERROR))) { | |
331 | zfcp_dbf_hba_fsf_resp("fs_rerr", 3, req); | |
332 | ||
333 | } else if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && | |
2e261af8 | 334 | (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) { |
a54ca0f6 | 335 | zfcp_dbf_hba_fsf_resp("fs_perr", 1, req); |
2e261af8 CS |
336 | |
337 | } else if (qtcb->header.fsf_status != FSF_GOOD) { | |
56d23ed7 SM |
338 | zfcp_dbf_hba_fsf_resp("fs_ferr", |
339 | zfcp_dbf_hba_fsf_resp_suppress(req) | |
340 | ? 5 : 1, req); | |
2e261af8 CS |
341 | |
342 | } else if ((req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) || | |
343 | (req->fsf_command == FSF_QTCB_OPEN_LUN)) { | |
a54ca0f6 | 344 | zfcp_dbf_hba_fsf_resp("fs_open", 4, req); |
2e261af8 CS |
345 | |
346 | } else if (qtcb->header.log_length) { | |
a54ca0f6 | 347 | zfcp_dbf_hba_fsf_resp("fs_qtcb", 5, req); |
2e261af8 CS |
348 | |
349 | } else { | |
a54ca0f6 | 350 | zfcp_dbf_hba_fsf_resp("fs_norm", 6, req); |
2e261af8 | 351 | } |
2e261af8 CS |
352 | } |
353 | ||
dcd20e23 | 354 | static inline |
250a1352 SS |
355 | void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd, |
356 | struct zfcp_fsf_req *req) | |
dcd20e23 | 357 | { |
250a1352 SS |
358 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) |
359 | scmd->device->host->hostdata[0]; | |
360 | ||
8e6a8285 | 361 | if (debug_level_enabled(adapter->dbf->scsi, level)) |
35f040df | 362 | zfcp_dbf_scsi(tag, level, scmd, req); |
dcd20e23 CS |
363 | } |
364 | ||
365 | /** | |
5771710b | 366 | * zfcp_dbf_scsi_result - trace event for SCSI command completion |
dcd20e23 | 367 | * @scmd: SCSI command pointer |
ab72528a | 368 | * @req: FSF request used to issue SCSI command |
dcd20e23 CS |
369 | */ |
370 | static inline | |
250a1352 | 371 | void zfcp_dbf_scsi_result(struct scsi_cmnd *scmd, struct zfcp_fsf_req *req) |
dcd20e23 | 372 | { |
ab72528a | 373 | if (scmd->result != 0) |
250a1352 | 374 | _zfcp_dbf_scsi("rsl_err", 3, scmd, req); |
ab72528a | 375 | else if (scmd->retries > 0) |
250a1352 | 376 | _zfcp_dbf_scsi("rsl_ret", 4, scmd, req); |
ab72528a | 377 | else |
250a1352 | 378 | _zfcp_dbf_scsi("rsl_nor", 6, scmd, req); |
ab72528a CS |
379 | } |
380 | ||
381 | /** | |
382 | * zfcp_dbf_scsi_fail_send - trace event for failure to send SCSI command | |
ab72528a CS |
383 | * @scmd: SCSI command pointer |
384 | */ | |
385 | static inline | |
250a1352 | 386 | void zfcp_dbf_scsi_fail_send(struct scsi_cmnd *scmd) |
ab72528a | 387 | { |
250a1352 | 388 | _zfcp_dbf_scsi("rsl_fai", 4, scmd, NULL); |
dcd20e23 CS |
389 | } |
390 | ||
391 | /** | |
5771710b | 392 | * zfcp_dbf_scsi_abort - trace event for SCSI command abort |
dcd20e23 | 393 | * @tag: tag indicating success or failure of abort operation |
dcd20e23 | 394 | * @scmd: SCSI command to be aborted |
250a1352 | 395 | * @fsf_req: request containing abort (might be NULL) |
dcd20e23 CS |
396 | */ |
397 | static inline | |
250a1352 SS |
398 | void zfcp_dbf_scsi_abort(char *tag, struct scsi_cmnd *scmd, |
399 | struct zfcp_fsf_req *fsf_req) | |
dcd20e23 | 400 | { |
250a1352 | 401 | _zfcp_dbf_scsi(tag, 1, scmd, fsf_req); |
dcd20e23 CS |
402 | } |
403 | ||
404 | /** | |
5771710b | 405 | * zfcp_dbf_scsi_devreset - trace event for Logical Unit or Target Reset |
dcd20e23 | 406 | * @tag: tag indicating success or failure of reset operation |
b62a8d9b | 407 | * @scmnd: SCSI command which caused this error recovery |
dcd20e23 | 408 | * @flag: indicates type of reset (Target Reset, Logical Unit Reset) |
dcd20e23 CS |
409 | */ |
410 | static inline | |
9fe5d2b2 SM |
411 | void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag, |
412 | struct zfcp_fsf_req *fsf_req) | |
dcd20e23 | 413 | { |
250a1352 SS |
414 | char tmp_tag[ZFCP_DBF_TAG_LEN]; |
415 | ||
416 | if (flag == FCP_TMF_TGT_RESET) | |
417 | memcpy(tmp_tag, "tr_", 3); | |
418 | else | |
419 | memcpy(tmp_tag, "lr_", 3); | |
b62a8d9b | 420 | |
250a1352 | 421 | memcpy(&tmp_tag[3], tag, 4); |
9fe5d2b2 | 422 | _zfcp_dbf_scsi(tmp_tag, 1, scmnd, fsf_req); |
dcd20e23 CS |
423 | } |
424 | ||
dac37e15 BB |
425 | /** |
426 | * zfcp_dbf_scsi_nullcmnd() - trace NULLify of SCSI command in dev/tgt-reset. | |
427 | * @scmnd: SCSI command that was NULLified. | |
428 | * @fsf_req: request that owned @scmnd. | |
429 | */ | |
430 | static inline void zfcp_dbf_scsi_nullcmnd(struct scsi_cmnd *scmnd, | |
431 | struct zfcp_fsf_req *fsf_req) | |
432 | { | |
433 | _zfcp_dbf_scsi("scfc__1", 3, scmnd, fsf_req); | |
434 | } | |
435 | ||
2b604c9b | 436 | #endif /* ZFCP_DBF_H */ |