3 * linux/drivers/s390/scsi/zfcp_dbf.c
5 * FCP adapter driver for IBM eServer zSeries
9 * (C) Copyright IBM Corp. 2005
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #define ZFCP_DBF_REVISION "$Revision$"
28 #include <asm/debug.h>
29 #include <linux/ctype.h>
32 static u32 dbfsize
= 4;
34 module_param(dbfsize
, uint
, 0400);
35 MODULE_PARM_DESC(dbfsize
,
36 "number of pages for each debug feature area (default 4)");
38 #define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER
41 zfcp_dbf_stck(char *out_buf
, const char *label
, unsigned long long stck
)
43 unsigned long long sec
;
44 struct timespec xtime
;
47 stck
-= 0x8126d60e46000000LL
- (0x3c26700LL
* 1000000 * 4096);
51 stck
-= (sec
* 1000000) << 12;
52 xtime
.tv_nsec
= ((stck
* 1000) >> 12);
53 len
+= sprintf(out_buf
+ len
, "%-24s%011lu:%06lu\n",
54 label
, xtime
.tv_sec
, xtime
.tv_nsec
);
59 static int zfcp_dbf_tag(char *out_buf
, const char *label
, const char *tag
)
63 len
+= sprintf(out_buf
+ len
, "%-24s", label
);
64 for (i
= 0; i
< ZFCP_DBF_TAG_SIZE
; i
++)
65 len
+= sprintf(out_buf
+ len
, "%c", tag
[i
]);
66 len
+= sprintf(out_buf
+ len
, "\n");
72 zfcp_dbf_view(char *out_buf
, const char *label
, const char *format
, ...)
77 len
+= sprintf(out_buf
+ len
, "%-24s", label
);
78 va_start(arg
, format
);
79 len
+= vsprintf(out_buf
+ len
, format
, arg
);
81 len
+= sprintf(out_buf
+ len
, "\n");
87 zfcp_dbf_view_dump(char *out_buf
, const char *label
,
88 char *buffer
, int buflen
, int offset
, int total_size
)
93 len
+= sprintf(out_buf
+ len
, "%-24s ", label
);
97 if ((offset
% 32) == 0)
98 len
+= sprintf(out_buf
+ len
, "\n%-24c ", ' ');
99 else if ((offset
% 4) == 0)
100 len
+= sprintf(out_buf
+ len
, " ");
102 len
+= sprintf(out_buf
+ len
, "%02x", *buffer
++);
103 if (++offset
== total_size
) {
104 len
+= sprintf(out_buf
+ len
, "\n");
110 len
+= sprintf(out_buf
+ len
, "\n");
116 zfcp_dbf_view_header(debug_info_t
* id
, struct debug_view
*view
, int area
,
117 debug_entry_t
* entry
, char *out_buf
)
119 struct zfcp_dbf_dump
*dump
= (struct zfcp_dbf_dump
*)DEBUG_DATA(entry
);
122 if (strncmp(dump
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) != 0) {
123 len
+= zfcp_dbf_stck(out_buf
+ len
, "timestamp",
125 len
+= zfcp_dbf_view(out_buf
+ len
, "cpu", "%02i",
126 entry
->id
.fields
.cpuid
);
128 len
+= zfcp_dbf_view_dump(out_buf
+ len
, NULL
,
131 dump
->offset
, dump
->total_size
);
132 if ((dump
->offset
+ dump
->size
) == dump
->total_size
)
133 len
+= sprintf(out_buf
+ len
, "\n");
139 inline void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req
*fsf_req
)
141 struct zfcp_adapter
*adapter
= fsf_req
->adapter
;
142 struct fsf_qtcb
*qtcb
= fsf_req
->qtcb
;
143 union fsf_prot_status_qual
*prot_status_qual
=
144 &qtcb
->prefix
.prot_status_qual
;
145 union fsf_status_qual
*fsf_status_qual
= &qtcb
->header
.fsf_status_qual
;
146 struct scsi_cmnd
*scsi_cmnd
;
147 struct zfcp_port
*port
;
148 struct zfcp_unit
*unit
;
149 struct zfcp_send_els
*send_els
;
150 struct zfcp_hba_dbf_record
*rec
= &adapter
->hba_dbf_buf
;
151 struct zfcp_hba_dbf_record_response
*response
= &rec
->type
.response
;
155 spin_lock_irqsave(&adapter
->hba_dbf_lock
, flags
);
156 memset(rec
, 0, sizeof(struct zfcp_hba_dbf_record
));
157 strncpy(rec
->tag
, "resp", ZFCP_DBF_TAG_SIZE
);
159 if ((qtcb
->prefix
.prot_status
!= FSF_PROT_GOOD
) &&
160 (qtcb
->prefix
.prot_status
!= FSF_PROT_FSF_STATUS_PRESENTED
)) {
161 strncpy(rec
->tag2
, "perr", ZFCP_DBF_TAG_SIZE
);
163 } else if (qtcb
->header
.fsf_status
!= FSF_GOOD
) {
164 strncpy(rec
->tag2
, "ferr", ZFCP_DBF_TAG_SIZE
);
166 } else if ((fsf_req
->fsf_command
== FSF_QTCB_OPEN_PORT_WITH_DID
) ||
167 (fsf_req
->fsf_command
== FSF_QTCB_OPEN_LUN
)) {
168 strncpy(rec
->tag2
, "open", ZFCP_DBF_TAG_SIZE
);
170 } else if ((prot_status_qual
->doubleword
[0] != 0) ||
171 (prot_status_qual
->doubleword
[1] != 0) ||
172 (fsf_status_qual
->doubleword
[0] != 0) ||
173 (fsf_status_qual
->doubleword
[1] != 0)) {
174 strncpy(rec
->tag2
, "qual", ZFCP_DBF_TAG_SIZE
);
177 strncpy(rec
->tag2
, "norm", ZFCP_DBF_TAG_SIZE
);
181 response
->fsf_command
= fsf_req
->fsf_command
;
182 response
->fsf_reqid
= (unsigned long)fsf_req
;
183 response
->fsf_seqno
= fsf_req
->seq_no
;
184 response
->fsf_issued
= fsf_req
->issued
;
185 response
->fsf_prot_status
= qtcb
->prefix
.prot_status
;
186 response
->fsf_status
= qtcb
->header
.fsf_status
;
187 memcpy(response
->fsf_prot_status_qual
,
188 prot_status_qual
, FSF_PROT_STATUS_QUAL_SIZE
);
189 memcpy(response
->fsf_status_qual
,
190 fsf_status_qual
, FSF_STATUS_QUALIFIER_SIZE
);
191 response
->fsf_req_status
= fsf_req
->status
;
192 response
->sbal_first
= fsf_req
->sbal_first
;
193 response
->sbal_curr
= fsf_req
->sbal_curr
;
194 response
->sbal_last
= fsf_req
->sbal_last
;
195 response
->pool
= fsf_req
->pool
!= NULL
;
196 response
->erp_action
= (unsigned long)fsf_req
->erp_action
;
198 switch (fsf_req
->fsf_command
) {
199 case FSF_QTCB_FCP_CMND
:
200 if (fsf_req
->status
& ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT
)
202 scsi_cmnd
= (struct scsi_cmnd
*)fsf_req
->data
;
203 if (scsi_cmnd
!= NULL
) {
204 response
->data
.send_fcp
.scsi_cmnd
205 = (unsigned long)scsi_cmnd
;
206 response
->data
.send_fcp
.scsi_serial
207 = scsi_cmnd
->serial_number
;
211 case FSF_QTCB_OPEN_PORT_WITH_DID
:
212 case FSF_QTCB_CLOSE_PORT
:
213 case FSF_QTCB_CLOSE_PHYSICAL_PORT
:
214 port
= (struct zfcp_port
*)fsf_req
->data
;
215 response
->data
.port
.wwpn
= port
->wwpn
;
216 response
->data
.port
.d_id
= port
->d_id
;
217 response
->data
.port
.port_handle
= qtcb
->header
.port_handle
;
220 case FSF_QTCB_OPEN_LUN
:
221 case FSF_QTCB_CLOSE_LUN
:
222 unit
= (struct zfcp_unit
*)fsf_req
->data
;
224 response
->data
.unit
.wwpn
= port
->wwpn
;
225 response
->data
.unit
.fcp_lun
= unit
->fcp_lun
;
226 response
->data
.unit
.port_handle
= qtcb
->header
.port_handle
;
227 response
->data
.unit
.lun_handle
= qtcb
->header
.lun_handle
;
230 case FSF_QTCB_SEND_ELS
:
231 send_els
= (struct zfcp_send_els
*)fsf_req
->data
;
232 response
->data
.send_els
.d_id
= qtcb
->bottom
.support
.d_id
;
233 response
->data
.send_els
.ls_code
= send_els
->ls_code
>> 24;
236 case FSF_QTCB_ABORT_FCP_CMND
:
237 case FSF_QTCB_SEND_GENERIC
:
238 case FSF_QTCB_EXCHANGE_CONFIG_DATA
:
239 case FSF_QTCB_EXCHANGE_PORT_DATA
:
240 case FSF_QTCB_DOWNLOAD_CONTROL_FILE
:
241 case FSF_QTCB_UPLOAD_CONTROL_FILE
:
245 debug_event(adapter
->hba_dbf
, level
,
246 rec
, sizeof(struct zfcp_hba_dbf_record
));
247 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
251 zfcp_hba_dbf_event_fsf_unsol(const char *tag
, struct zfcp_adapter
*adapter
,
252 struct fsf_status_read_buffer
*status_buffer
)
254 struct zfcp_hba_dbf_record
*rec
= &adapter
->hba_dbf_buf
;
257 spin_lock_irqsave(&adapter
->hba_dbf_lock
, flags
);
258 memset(rec
, 0, sizeof(struct zfcp_hba_dbf_record
));
259 strncpy(rec
->tag
, "stat", ZFCP_DBF_TAG_SIZE
);
260 strncpy(rec
->tag2
, tag
, ZFCP_DBF_TAG_SIZE
);
262 rec
->type
.status
.failed
= adapter
->status_read_failed
;
263 if (status_buffer
!= NULL
) {
264 rec
->type
.status
.status_type
= status_buffer
->status_type
;
265 rec
->type
.status
.status_subtype
= status_buffer
->status_subtype
;
266 memcpy(&rec
->type
.status
.queue_designator
,
267 &status_buffer
->queue_designator
,
268 sizeof(struct fsf_queue_designator
));
270 switch (status_buffer
->status_type
) {
271 case FSF_STATUS_READ_SENSE_DATA_AVAIL
:
272 rec
->type
.status
.payload_size
=
273 ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL
;
276 case FSF_STATUS_READ_BIT_ERROR_THRESHOLD
:
277 rec
->type
.status
.payload_size
=
278 ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD
;
281 case FSF_STATUS_READ_LINK_DOWN
:
282 switch (status_buffer
->status_subtype
) {
283 case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK
:
284 case FSF_STATUS_READ_SUB_FDISC_FAILED
:
285 rec
->type
.status
.payload_size
=
286 sizeof(struct fsf_link_down_info
);
290 case FSF_STATUS_READ_FEATURE_UPDATE_ALERT
:
291 rec
->type
.status
.payload_size
=
292 ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT
;
295 memcpy(&rec
->type
.status
.payload
,
296 &status_buffer
->payload
, rec
->type
.status
.payload_size
);
299 debug_event(adapter
->hba_dbf
, 2,
300 rec
, sizeof(struct zfcp_hba_dbf_record
));
301 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
305 zfcp_hba_dbf_event_qdio(struct zfcp_adapter
*adapter
, unsigned int status
,
306 unsigned int qdio_error
, unsigned int siga_error
,
307 int sbal_index
, int sbal_count
)
309 struct zfcp_hba_dbf_record
*rec
= &adapter
->hba_dbf_buf
;
312 spin_lock_irqsave(&adapter
->hba_dbf_lock
, flags
);
313 memset(rec
, 0, sizeof(struct zfcp_hba_dbf_record
));
314 strncpy(rec
->tag
, "qdio", ZFCP_DBF_TAG_SIZE
);
315 rec
->type
.qdio
.status
= status
;
316 rec
->type
.qdio
.qdio_error
= qdio_error
;
317 rec
->type
.qdio
.siga_error
= siga_error
;
318 rec
->type
.qdio
.sbal_index
= sbal_index
;
319 rec
->type
.qdio
.sbal_count
= sbal_count
;
320 debug_event(adapter
->hba_dbf
, 0,
321 rec
, sizeof(struct zfcp_hba_dbf_record
));
322 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
326 zfcp_hba_dbf_view_response(char *out_buf
,
327 struct zfcp_hba_dbf_record_response
*rec
)
331 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_command", "0x%08x",
333 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
335 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
337 len
+= zfcp_dbf_stck(out_buf
+ len
, "fsf_issued", rec
->fsf_issued
);
338 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_prot_status", "0x%08x",
339 rec
->fsf_prot_status
);
340 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_status", "0x%08x",
342 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "fsf_prot_status_qual",
343 rec
->fsf_prot_status_qual
,
344 FSF_PROT_STATUS_QUAL_SIZE
,
345 0, FSF_PROT_STATUS_QUAL_SIZE
);
346 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "fsf_status_qual",
347 rec
->fsf_status_qual
,
348 FSF_STATUS_QUALIFIER_SIZE
,
349 0, FSF_STATUS_QUALIFIER_SIZE
);
350 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_req_status", "0x%08x",
351 rec
->fsf_req_status
);
352 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_first", "0x%02x",
354 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_curr", "0x%02x",
356 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_last", "0x%02x",
358 len
+= zfcp_dbf_view(out_buf
+ len
, "pool", "0x%02x", rec
->pool
);
360 switch (rec
->fsf_command
) {
361 case FSF_QTCB_FCP_CMND
:
362 if (rec
->fsf_req_status
& ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT
)
364 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_cmnd", "0x%0Lx",
365 rec
->data
.send_fcp
.scsi_cmnd
);
366 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_serial", "0x%016Lx",
367 rec
->data
.send_fcp
.scsi_serial
);
370 case FSF_QTCB_OPEN_PORT_WITH_DID
:
371 case FSF_QTCB_CLOSE_PORT
:
372 case FSF_QTCB_CLOSE_PHYSICAL_PORT
:
373 len
+= zfcp_dbf_view(out_buf
+ len
, "wwpn", "0x%016Lx",
374 rec
->data
.port
.wwpn
);
375 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x",
376 rec
->data
.port
.d_id
);
377 len
+= zfcp_dbf_view(out_buf
+ len
, "port_handle", "0x%08x",
378 rec
->data
.port
.port_handle
);
381 case FSF_QTCB_OPEN_LUN
:
382 case FSF_QTCB_CLOSE_LUN
:
383 len
+= zfcp_dbf_view(out_buf
+ len
, "wwpn", "0x%016Lx",
384 rec
->data
.unit
.wwpn
);
385 len
+= zfcp_dbf_view(out_buf
+ len
, "fcp_lun", "0x%016Lx",
386 rec
->data
.unit
.fcp_lun
);
387 len
+= zfcp_dbf_view(out_buf
+ len
, "port_handle", "0x%08x",
388 rec
->data
.unit
.port_handle
);
389 len
+= zfcp_dbf_view(out_buf
+ len
, "lun_handle", "0x%08x",
390 rec
->data
.unit
.lun_handle
);
393 case FSF_QTCB_SEND_ELS
:
394 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x",
395 rec
->data
.send_els
.d_id
);
396 len
+= zfcp_dbf_view(out_buf
+ len
, "ls_code", "0x%02x",
397 rec
->data
.send_els
.ls_code
);
400 case FSF_QTCB_ABORT_FCP_CMND
:
401 case FSF_QTCB_SEND_GENERIC
:
402 case FSF_QTCB_EXCHANGE_CONFIG_DATA
:
403 case FSF_QTCB_EXCHANGE_PORT_DATA
:
404 case FSF_QTCB_DOWNLOAD_CONTROL_FILE
:
405 case FSF_QTCB_UPLOAD_CONTROL_FILE
:
413 zfcp_hba_dbf_view_status(char *out_buf
, struct zfcp_hba_dbf_record_status
*rec
)
417 len
+= zfcp_dbf_view(out_buf
+ len
, "failed", "0x%02x", rec
->failed
);
418 len
+= zfcp_dbf_view(out_buf
+ len
, "status_type", "0x%08x",
420 len
+= zfcp_dbf_view(out_buf
+ len
, "status_subtype", "0x%08x",
421 rec
->status_subtype
);
422 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "queue_designator",
423 (char *)&rec
->queue_designator
,
424 sizeof(struct fsf_queue_designator
),
425 0, sizeof(struct fsf_queue_designator
));
426 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "payload",
427 (char *)&rec
->payload
,
428 rec
->payload_size
, 0, rec
->payload_size
);
434 zfcp_hba_dbf_view_qdio(char *out_buf
, struct zfcp_hba_dbf_record_qdio
*rec
)
438 len
+= zfcp_dbf_view(out_buf
+ len
, "status", "0x%08x", rec
->status
);
439 len
+= zfcp_dbf_view(out_buf
+ len
, "qdio_error", "0x%08x",
441 len
+= zfcp_dbf_view(out_buf
+ len
, "siga_error", "0x%08x",
443 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_index", "0x%02x",
445 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_count", "0x%02x",
452 zfcp_hba_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
453 char *out_buf
, const char *in_buf
)
455 struct zfcp_hba_dbf_record
*rec
= (struct zfcp_hba_dbf_record
*)in_buf
;
458 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
461 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
462 if (isalpha(rec
->tag2
[0]))
463 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag2", rec
->tag2
);
464 if (strncmp(rec
->tag
, "resp", ZFCP_DBF_TAG_SIZE
) == 0)
465 len
+= zfcp_hba_dbf_view_response(out_buf
+ len
,
466 &rec
->type
.response
);
467 else if (strncmp(rec
->tag
, "stat", ZFCP_DBF_TAG_SIZE
) == 0)
468 len
+= zfcp_hba_dbf_view_status(out_buf
+ len
,
470 else if (strncmp(rec
->tag
, "qdio", ZFCP_DBF_TAG_SIZE
) == 0)
471 len
+= zfcp_hba_dbf_view_qdio(out_buf
+ len
, &rec
->type
.qdio
);
473 len
+= sprintf(out_buf
+ len
, "\n");
478 struct debug_view zfcp_hba_dbf_view
= {
481 &zfcp_dbf_view_header
,
482 &zfcp_hba_dbf_view_format
,
488 _zfcp_san_dbf_event_common_ct(const char *tag
, struct zfcp_fsf_req
*fsf_req
,
489 u32 s_id
, u32 d_id
, void *buffer
, int buflen
)
491 struct zfcp_send_ct
*send_ct
= (struct zfcp_send_ct
*)fsf_req
->data
;
492 struct zfcp_port
*port
= send_ct
->port
;
493 struct zfcp_adapter
*adapter
= port
->adapter
;
494 struct ct_hdr
*header
= (struct ct_hdr
*)buffer
;
495 struct zfcp_san_dbf_record
*rec
= &adapter
->san_dbf_buf
;
496 struct zfcp_san_dbf_record_ct
*ct
= &rec
->type
.ct
;
499 spin_lock_irqsave(&adapter
->san_dbf_lock
, flags
);
500 memset(rec
, 0, sizeof(struct zfcp_san_dbf_record
));
501 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
502 rec
->fsf_reqid
= (unsigned long)fsf_req
;
503 rec
->fsf_seqno
= fsf_req
->seq_no
;
506 if (strncmp(tag
, "octc", ZFCP_DBF_TAG_SIZE
) == 0) {
507 ct
->type
.request
.cmd_req_code
= header
->cmd_rsp_code
;
508 ct
->type
.request
.revision
= header
->revision
;
509 ct
->type
.request
.gs_type
= header
->gs_type
;
510 ct
->type
.request
.gs_subtype
= header
->gs_subtype
;
511 ct
->type
.request
.options
= header
->options
;
512 ct
->type
.request
.max_res_size
= header
->max_res_size
;
513 } else if (strncmp(tag
, "rctc", ZFCP_DBF_TAG_SIZE
) == 0) {
514 ct
->type
.response
.cmd_rsp_code
= header
->cmd_rsp_code
;
515 ct
->type
.response
.revision
= header
->revision
;
516 ct
->type
.response
.reason_code
= header
->reason_code
;
517 ct
->type
.response
.reason_code_expl
= header
->reason_code_expl
;
518 ct
->type
.response
.vendor_unique
= header
->vendor_unique
;
521 min(buflen
- (int)sizeof(struct ct_hdr
), ZFCP_DBF_CT_PAYLOAD
);
522 memcpy(ct
->payload
, buffer
+ sizeof(struct ct_hdr
), ct
->payload_size
);
523 debug_event(adapter
->san_dbf
, 3,
524 rec
, sizeof(struct zfcp_san_dbf_record
));
525 spin_unlock_irqrestore(&adapter
->san_dbf_lock
, flags
);
528 inline void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req
*fsf_req
)
530 struct zfcp_send_ct
*ct
= (struct zfcp_send_ct
*)fsf_req
->data
;
531 struct zfcp_port
*port
= ct
->port
;
532 struct zfcp_adapter
*adapter
= port
->adapter
;
534 _zfcp_san_dbf_event_common_ct("octc", fsf_req
,
535 fc_host_port_id(adapter
->scsi_host
),
536 port
->d_id
, zfcp_sg_to_address(ct
->req
),
540 inline void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req
*fsf_req
)
542 struct zfcp_send_ct
*ct
= (struct zfcp_send_ct
*)fsf_req
->data
;
543 struct zfcp_port
*port
= ct
->port
;
544 struct zfcp_adapter
*adapter
= port
->adapter
;
546 _zfcp_san_dbf_event_common_ct("rctc", fsf_req
, port
->d_id
,
547 fc_host_port_id(adapter
->scsi_host
),
548 zfcp_sg_to_address(ct
->resp
),
553 _zfcp_san_dbf_event_common_els(const char *tag
, int level
,
554 struct zfcp_fsf_req
*fsf_req
, u32 s_id
,
555 u32 d_id
, u8 ls_code
, void *buffer
, int buflen
)
557 struct zfcp_adapter
*adapter
= fsf_req
->adapter
;
558 struct zfcp_san_dbf_record
*rec
= &adapter
->san_dbf_buf
;
559 struct zfcp_dbf_dump
*dump
= (struct zfcp_dbf_dump
*)rec
;
563 spin_lock_irqsave(&adapter
->san_dbf_lock
, flags
);
565 memset(rec
, 0, sizeof(struct zfcp_san_dbf_record
));
567 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
568 rec
->fsf_reqid
= (unsigned long)fsf_req
;
569 rec
->fsf_seqno
= fsf_req
->seq_no
;
572 rec
->type
.els
.ls_code
= ls_code
;
573 buflen
= min(buflen
, ZFCP_DBF_ELS_MAX_PAYLOAD
);
574 rec
->type
.els
.payload_size
= buflen
;
575 memcpy(rec
->type
.els
.payload
,
576 buffer
, min(buflen
, ZFCP_DBF_ELS_PAYLOAD
));
577 offset
+= min(buflen
, ZFCP_DBF_ELS_PAYLOAD
);
579 strncpy(dump
->tag
, "dump", ZFCP_DBF_TAG_SIZE
);
580 dump
->total_size
= buflen
;
581 dump
->offset
= offset
;
582 dump
->size
= min(buflen
- offset
,
583 (int)sizeof(struct zfcp_san_dbf_record
)
584 - (int)sizeof(struct zfcp_dbf_dump
));
585 memcpy(dump
->data
, buffer
+ offset
, dump
->size
);
586 offset
+= dump
->size
;
588 debug_event(adapter
->san_dbf
, level
,
589 rec
, sizeof(struct zfcp_san_dbf_record
));
590 } while (offset
< buflen
);
591 spin_unlock_irqrestore(&adapter
->san_dbf_lock
, flags
);
594 inline void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req
*fsf_req
)
596 struct zfcp_send_els
*els
= (struct zfcp_send_els
*)fsf_req
->data
;
598 _zfcp_san_dbf_event_common_els("oels", 2, fsf_req
,
599 fc_host_port_id(els
->adapter
->scsi_host
),
601 *(u8
*) zfcp_sg_to_address(els
->req
),
602 zfcp_sg_to_address(els
->req
),
606 inline void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req
*fsf_req
)
608 struct zfcp_send_els
*els
= (struct zfcp_send_els
*)fsf_req
->data
;
610 _zfcp_san_dbf_event_common_els("rels", 2, fsf_req
, els
->d_id
,
611 fc_host_port_id(els
->adapter
->scsi_host
),
612 *(u8
*) zfcp_sg_to_address(els
->req
),
613 zfcp_sg_to_address(els
->resp
),
617 inline void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req
*fsf_req
)
619 struct zfcp_adapter
*adapter
= fsf_req
->adapter
;
620 struct fsf_status_read_buffer
*status_buffer
=
621 (struct fsf_status_read_buffer
*)fsf_req
->data
;
622 int length
= (int)status_buffer
->length
-
623 (int)((void *)&status_buffer
->payload
- (void *)status_buffer
);
625 _zfcp_san_dbf_event_common_els("iels", 1, fsf_req
, status_buffer
->d_id
,
626 fc_host_port_id(adapter
->scsi_host
),
627 *(u8
*) status_buffer
->payload
,
628 (void *)status_buffer
->payload
, length
);
632 zfcp_san_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
633 char *out_buf
, const char *in_buf
)
635 struct zfcp_san_dbf_record
*rec
= (struct zfcp_san_dbf_record
*)in_buf
;
637 int buflen
= 0, total
= 0;
640 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
643 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
644 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
646 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
648 len
+= zfcp_dbf_view(out_buf
+ len
, "s_id", "0x%06x", rec
->s_id
);
649 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x", rec
->d_id
);
651 if (strncmp(rec
->tag
, "octc", ZFCP_DBF_TAG_SIZE
) == 0) {
652 len
+= zfcp_dbf_view(out_buf
+ len
, "cmd_req_code", "0x%04x",
653 rec
->type
.ct
.type
.request
.cmd_req_code
);
654 len
+= zfcp_dbf_view(out_buf
+ len
, "revision", "0x%02x",
655 rec
->type
.ct
.type
.request
.revision
);
656 len
+= zfcp_dbf_view(out_buf
+ len
, "gs_type", "0x%02x",
657 rec
->type
.ct
.type
.request
.gs_type
);
658 len
+= zfcp_dbf_view(out_buf
+ len
, "gs_subtype", "0x%02x",
659 rec
->type
.ct
.type
.request
.gs_subtype
);
660 len
+= zfcp_dbf_view(out_buf
+ len
, "options", "0x%02x",
661 rec
->type
.ct
.type
.request
.options
);
662 len
+= zfcp_dbf_view(out_buf
+ len
, "max_res_size", "0x%04x",
663 rec
->type
.ct
.type
.request
.max_res_size
);
664 total
= rec
->type
.ct
.payload_size
;
665 buffer
= rec
->type
.ct
.payload
;
666 buflen
= min(total
, ZFCP_DBF_CT_PAYLOAD
);
667 } else if (strncmp(rec
->tag
, "rctc", ZFCP_DBF_TAG_SIZE
) == 0) {
668 len
+= zfcp_dbf_view(out_buf
+ len
, "cmd_rsp_code", "0x%04x",
669 rec
->type
.ct
.type
.response
.cmd_rsp_code
);
670 len
+= zfcp_dbf_view(out_buf
+ len
, "revision", "0x%02x",
671 rec
->type
.ct
.type
.response
.revision
);
672 len
+= zfcp_dbf_view(out_buf
+ len
, "reason_code", "0x%02x",
673 rec
->type
.ct
.type
.response
.reason_code
);
675 zfcp_dbf_view(out_buf
+ len
, "reason_code_expl", "0x%02x",
676 rec
->type
.ct
.type
.response
.reason_code_expl
);
678 zfcp_dbf_view(out_buf
+ len
, "vendor_unique", "0x%02x",
679 rec
->type
.ct
.type
.response
.vendor_unique
);
680 total
= rec
->type
.ct
.payload_size
;
681 buffer
= rec
->type
.ct
.payload
;
682 buflen
= min(total
, ZFCP_DBF_CT_PAYLOAD
);
683 } else if (strncmp(rec
->tag
, "oels", ZFCP_DBF_TAG_SIZE
) == 0 ||
684 strncmp(rec
->tag
, "rels", ZFCP_DBF_TAG_SIZE
) == 0 ||
685 strncmp(rec
->tag
, "iels", ZFCP_DBF_TAG_SIZE
) == 0) {
686 len
+= zfcp_dbf_view(out_buf
+ len
, "ls_code", "0x%02x",
687 rec
->type
.els
.ls_code
);
688 total
= rec
->type
.els
.payload_size
;
689 buffer
= rec
->type
.els
.payload
;
690 buflen
= min(total
, ZFCP_DBF_ELS_PAYLOAD
);
693 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "payload",
694 buffer
, buflen
, 0, total
);
697 len
+= sprintf(out_buf
+ len
, "\n");
702 struct debug_view zfcp_san_dbf_view
= {
705 &zfcp_dbf_view_header
,
706 &zfcp_san_dbf_view_format
,
712 _zfcp_scsi_dbf_event_common(const char *tag
, const char *tag2
, int level
,
713 struct zfcp_adapter
*adapter
,
714 struct scsi_cmnd
*scsi_cmnd
,
715 struct zfcp_fsf_req
*new_fsf_req
)
717 struct zfcp_fsf_req
*fsf_req
=
718 (struct zfcp_fsf_req
*)scsi_cmnd
->host_scribble
;
719 struct zfcp_scsi_dbf_record
*rec
= &adapter
->scsi_dbf_buf
;
720 struct zfcp_dbf_dump
*dump
= (struct zfcp_dbf_dump
*)rec
;
722 struct fcp_rsp_iu
*fcp_rsp
;
723 char *fcp_rsp_info
= NULL
, *fcp_sns_info
= NULL
;
724 int offset
= 0, buflen
= 0;
726 spin_lock_irqsave(&adapter
->scsi_dbf_lock
, flags
);
728 memset(rec
, 0, sizeof(struct zfcp_scsi_dbf_record
));
730 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
731 strncpy(rec
->tag2
, tag2
, ZFCP_DBF_TAG_SIZE
);
732 if (scsi_cmnd
->device
) {
733 rec
->scsi_id
= scsi_cmnd
->device
->id
;
734 rec
->scsi_lun
= scsi_cmnd
->device
->lun
;
736 rec
->scsi_result
= scsi_cmnd
->result
;
737 rec
->scsi_cmnd
= (unsigned long)scsi_cmnd
;
738 rec
->scsi_serial
= scsi_cmnd
->serial_number
;
739 memcpy(rec
->scsi_opcode
,
741 min((int)scsi_cmnd
->cmd_len
,
742 ZFCP_DBF_SCSI_OPCODE
));
743 rec
->scsi_retries
= scsi_cmnd
->retries
;
744 rec
->scsi_allowed
= scsi_cmnd
->allowed
;
745 if (fsf_req
!= NULL
) {
746 fcp_rsp
= (struct fcp_rsp_iu
*)
747 &(fsf_req
->qtcb
->bottom
.io
.fcp_rsp
);
749 zfcp_get_fcp_rsp_info_ptr(fcp_rsp
);
751 zfcp_get_fcp_sns_info_ptr(fcp_rsp
);
753 rec
->type
.fcp
.rsp_validity
=
754 fcp_rsp
->validity
.value
;
755 rec
->type
.fcp
.rsp_scsi_status
=
756 fcp_rsp
->scsi_status
;
757 rec
->type
.fcp
.rsp_resid
= fcp_rsp
->fcp_resid
;
758 if (fcp_rsp
->validity
.bits
.fcp_rsp_len_valid
)
759 rec
->type
.fcp
.rsp_code
=
761 if (fcp_rsp
->validity
.bits
.fcp_sns_len_valid
) {
762 buflen
= min((int)fcp_rsp
->fcp_sns_len
,
763 ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO
);
764 rec
->type
.fcp
.sns_info_len
= buflen
;
765 memcpy(rec
->type
.fcp
.sns_info
,
768 ZFCP_DBF_SCSI_FCP_SNS_INFO
));
769 offset
+= min(buflen
,
770 ZFCP_DBF_SCSI_FCP_SNS_INFO
);
773 rec
->fsf_reqid
= (unsigned long)fsf_req
;
774 rec
->fsf_seqno
= fsf_req
->seq_no
;
775 rec
->fsf_issued
= fsf_req
->issued
;
777 if (new_fsf_req
!= NULL
) {
778 rec
->type
.new_fsf_req
.fsf_reqid
=
781 rec
->type
.new_fsf_req
.fsf_seqno
=
783 rec
->type
.new_fsf_req
.fsf_issued
=
787 strncpy(dump
->tag
, "dump", ZFCP_DBF_TAG_SIZE
);
788 dump
->total_size
= buflen
;
789 dump
->offset
= offset
;
790 dump
->size
= min(buflen
- offset
,
792 zfcp_scsi_dbf_record
) -
793 (int)sizeof(struct zfcp_dbf_dump
));
794 memcpy(dump
->data
, fcp_sns_info
+ offset
, dump
->size
);
795 offset
+= dump
->size
;
797 debug_event(adapter
->scsi_dbf
, level
,
798 rec
, sizeof(struct zfcp_scsi_dbf_record
));
799 } while (offset
< buflen
);
800 spin_unlock_irqrestore(&adapter
->scsi_dbf_lock
, flags
);
804 zfcp_scsi_dbf_event_result(const char *tag
, int level
,
805 struct zfcp_adapter
*adapter
,
806 struct scsi_cmnd
*scsi_cmnd
)
808 _zfcp_scsi_dbf_event_common("rslt",
809 tag
, level
, adapter
, scsi_cmnd
, NULL
);
813 zfcp_scsi_dbf_event_abort(const char *tag
, struct zfcp_adapter
*adapter
,
814 struct scsi_cmnd
*scsi_cmnd
,
815 struct zfcp_fsf_req
*new_fsf_req
)
817 _zfcp_scsi_dbf_event_common("abrt",
818 tag
, 1, adapter
, scsi_cmnd
, new_fsf_req
);
822 zfcp_scsi_dbf_event_devreset(const char *tag
, u8 flag
, struct zfcp_unit
*unit
,
823 struct scsi_cmnd
*scsi_cmnd
)
825 struct zfcp_adapter
*adapter
= unit
->port
->adapter
;
827 _zfcp_scsi_dbf_event_common(flag
== FCP_TARGET_RESET
? "trst" : "lrst",
828 tag
, 1, adapter
, scsi_cmnd
, NULL
);
832 zfcp_scsi_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
833 char *out_buf
, const char *in_buf
)
835 struct zfcp_scsi_dbf_record
*rec
=
836 (struct zfcp_scsi_dbf_record
*)in_buf
;
839 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
842 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
843 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag2", rec
->tag2
);
844 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_id", "0x%08x", rec
->scsi_id
);
845 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_lun", "0x%08x",
847 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_result", "0x%08x",
849 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_cmnd", "0x%0Lx",
851 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_serial", "0x%016Lx",
853 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "scsi_opcode",
855 ZFCP_DBF_SCSI_OPCODE
,
856 0, ZFCP_DBF_SCSI_OPCODE
);
857 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_retries", "0x%02x",
859 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_allowed", "0x%02x",
861 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
863 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
865 len
+= zfcp_dbf_stck(out_buf
+ len
, "fsf_issued", rec
->fsf_issued
);
866 if (strncmp(rec
->tag
, "rslt", ZFCP_DBF_TAG_SIZE
) == 0) {
868 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_validity", "0x%02x",
869 rec
->type
.fcp
.rsp_validity
);
871 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_scsi_status",
872 "0x%02x", rec
->type
.fcp
.rsp_scsi_status
);
874 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_resid", "0x%08x",
875 rec
->type
.fcp
.rsp_resid
);
877 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_code", "0x%08x",
878 rec
->type
.fcp
.rsp_code
);
880 zfcp_dbf_view(out_buf
+ len
, "fcp_sns_info_len", "0x%08x",
881 rec
->type
.fcp
.sns_info_len
);
883 zfcp_dbf_view_dump(out_buf
+ len
, "fcp_sns_info",
884 rec
->type
.fcp
.sns_info
,
885 min((int)rec
->type
.fcp
.sns_info_len
,
886 ZFCP_DBF_SCSI_FCP_SNS_INFO
), 0,
887 rec
->type
.fcp
.sns_info_len
);
888 } else if (strncmp(rec
->tag
, "abrt", ZFCP_DBF_TAG_SIZE
) == 0) {
889 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid_abort", "0x%0Lx",
890 rec
->type
.new_fsf_req
.fsf_reqid
);
891 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno_abort", "0x%08x",
892 rec
->type
.new_fsf_req
.fsf_seqno
);
893 len
+= zfcp_dbf_stck(out_buf
+ len
, "fsf_issued",
894 rec
->type
.new_fsf_req
.fsf_issued
);
895 } else if ((strncmp(rec
->tag
, "trst", ZFCP_DBF_TAG_SIZE
) == 0) ||
896 (strncmp(rec
->tag
, "lrst", ZFCP_DBF_TAG_SIZE
) == 0)) {
897 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid_reset", "0x%0Lx",
898 rec
->type
.new_fsf_req
.fsf_reqid
);
899 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno_reset", "0x%08x",
900 rec
->type
.new_fsf_req
.fsf_seqno
);
901 len
+= zfcp_dbf_stck(out_buf
+ len
, "fsf_issued",
902 rec
->type
.new_fsf_req
.fsf_issued
);
905 len
+= sprintf(out_buf
+ len
, "\n");
910 struct debug_view zfcp_scsi_dbf_view
= {
913 &zfcp_dbf_view_header
,
914 &zfcp_scsi_dbf_view_format
,
920 * zfcp_adapter_debug_register - registers debug feature for an adapter
921 * @adapter: pointer to adapter for which debug features should be registered
922 * return: -ENOMEM on error, 0 otherwise
924 int zfcp_adapter_debug_register(struct zfcp_adapter
*adapter
)
926 char dbf_name
[DEBUG_MAX_NAME_LEN
];
928 /* debug feature area which records recovery activity */
929 spin_lock_init(&adapter
->erp_dbf_lock
);
930 sprintf(dbf_name
, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter
));
931 adapter
->erp_dbf
= debug_register(dbf_name
, dbfsize
, 2,
932 sizeof(struct zfcp_erp_dbf_record
));
933 if (!adapter
->erp_dbf
)
935 debug_register_view(adapter
->erp_dbf
, &debug_hex_ascii_view
);
936 debug_set_level(adapter
->erp_dbf
, 3);
938 /* debug feature area which records HBA (FSF and QDIO) conditions */
939 spin_lock_init(&adapter
->hba_dbf_lock
);
940 sprintf(dbf_name
, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter
));
941 adapter
->hba_dbf
= debug_register(dbf_name
, dbfsize
, 1,
942 sizeof(struct zfcp_hba_dbf_record
));
943 if (!adapter
->hba_dbf
)
945 debug_register_view(adapter
->hba_dbf
, &debug_hex_ascii_view
);
946 debug_register_view(adapter
->hba_dbf
, &zfcp_hba_dbf_view
);
947 debug_set_level(adapter
->hba_dbf
, 3);
949 /* debug feature area which records SAN command failures and recovery */
950 spin_lock_init(&adapter
->san_dbf_lock
);
951 sprintf(dbf_name
, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter
));
952 adapter
->san_dbf
= debug_register(dbf_name
, dbfsize
, 1,
953 sizeof(struct zfcp_san_dbf_record
));
954 if (!adapter
->san_dbf
)
956 debug_register_view(adapter
->san_dbf
, &debug_hex_ascii_view
);
957 debug_register_view(adapter
->san_dbf
, &zfcp_san_dbf_view
);
958 debug_set_level(adapter
->san_dbf
, 6);
960 /* debug feature area which records SCSI command failures and recovery */
961 spin_lock_init(&adapter
->scsi_dbf_lock
);
962 sprintf(dbf_name
, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter
));
963 adapter
->scsi_dbf
= debug_register(dbf_name
, dbfsize
, 1,
964 sizeof(struct zfcp_scsi_dbf_record
));
965 if (!adapter
->scsi_dbf
)
967 debug_register_view(adapter
->scsi_dbf
, &debug_hex_ascii_view
);
968 debug_register_view(adapter
->scsi_dbf
, &zfcp_scsi_dbf_view
);
969 debug_set_level(adapter
->scsi_dbf
, 3);
974 zfcp_adapter_debug_unregister(adapter
);
980 * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
981 * @adapter: pointer to adapter for which debug features should be unregistered
983 void zfcp_adapter_debug_unregister(struct zfcp_adapter
*adapter
)
985 debug_unregister(adapter
->scsi_dbf
);
986 debug_unregister(adapter
->san_dbf
);
987 debug_unregister(adapter
->hba_dbf
);
988 debug_unregister(adapter
->erp_dbf
);
989 adapter
->scsi_dbf
= NULL
;
990 adapter
->san_dbf
= NULL
;
991 adapter
->hba_dbf
= NULL
;
992 adapter
->erp_dbf
= NULL
;