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