2 * This file is part of the zfcp device driver for
3 * FCP adapters for IBM System z9 and zSeries.
5 * (C) Copyright IBM Corp. 2002, 2006
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <linux/ctype.h>
23 #include <asm/debug.h>
26 static u32 dbfsize
= 4;
28 module_param(dbfsize
, uint
, 0400);
29 MODULE_PARM_DESC(dbfsize
,
30 "number of pages for each debug feature area (default 4)");
32 #define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER
35 zfcp_dbf_stck(char *out_buf
, const char *label
, unsigned long long stck
)
37 unsigned long long sec
;
38 struct timespec dbftime
;
41 stck
-= 0x8126d60e46000000LL
- (0x3c26700LL
* 1000000 * 4096);
45 stck
-= (sec
* 1000000) << 12;
46 dbftime
.tv_nsec
= ((stck
* 1000) >> 12);
47 len
+= sprintf(out_buf
+ len
, "%-24s%011lu:%06lu\n",
48 label
, dbftime
.tv_sec
, dbftime
.tv_nsec
);
53 static int zfcp_dbf_tag(char *out_buf
, const char *label
, const char *tag
)
57 len
+= sprintf(out_buf
+ len
, "%-24s", label
);
58 for (i
= 0; i
< ZFCP_DBF_TAG_SIZE
; i
++)
59 len
+= sprintf(out_buf
+ len
, "%c", tag
[i
]);
60 len
+= sprintf(out_buf
+ len
, "\n");
66 zfcp_dbf_view(char *out_buf
, const char *label
, const char *format
, ...)
71 len
+= sprintf(out_buf
+ len
, "%-24s", label
);
72 va_start(arg
, format
);
73 len
+= vsprintf(out_buf
+ len
, format
, arg
);
75 len
+= sprintf(out_buf
+ len
, "\n");
81 zfcp_dbf_view_dump(char *out_buf
, const char *label
,
82 char *buffer
, int buflen
, int offset
, int total_size
)
87 len
+= sprintf(out_buf
+ len
, "%-24s ", label
);
91 if ((offset
% 32) == 0)
92 len
+= sprintf(out_buf
+ len
, "\n%-24c ", ' ');
93 else if ((offset
% 4) == 0)
94 len
+= sprintf(out_buf
+ len
, " ");
96 len
+= sprintf(out_buf
+ len
, "%02x", *buffer
++);
97 if (++offset
== total_size
) {
98 len
+= sprintf(out_buf
+ len
, "\n");
104 len
+= sprintf(out_buf
+ len
, "\n");
110 zfcp_dbf_view_header(debug_info_t
* id
, struct debug_view
*view
, int area
,
111 debug_entry_t
* entry
, char *out_buf
)
113 struct zfcp_dbf_dump
*dump
= (struct zfcp_dbf_dump
*)DEBUG_DATA(entry
);
116 if (strncmp(dump
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) != 0) {
117 len
+= zfcp_dbf_stck(out_buf
+ len
, "timestamp",
119 len
+= zfcp_dbf_view(out_buf
+ len
, "cpu", "%02i",
120 entry
->id
.fields
.cpuid
);
122 len
+= zfcp_dbf_view_dump(out_buf
+ len
, NULL
,
125 dump
->offset
, dump
->total_size
);
126 if ((dump
->offset
+ dump
->size
) == dump
->total_size
)
127 len
+= sprintf(out_buf
+ len
, "\n");
133 void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req
*fsf_req
)
135 struct zfcp_adapter
*adapter
= fsf_req
->adapter
;
136 struct fsf_qtcb
*qtcb
= fsf_req
->qtcb
;
137 union fsf_prot_status_qual
*prot_status_qual
=
138 &qtcb
->prefix
.prot_status_qual
;
139 union fsf_status_qual
*fsf_status_qual
= &qtcb
->header
.fsf_status_qual
;
140 struct scsi_cmnd
*scsi_cmnd
;
141 struct zfcp_port
*port
;
142 struct zfcp_unit
*unit
;
143 struct zfcp_send_els
*send_els
;
144 struct zfcp_hba_dbf_record
*rec
= &adapter
->hba_dbf_buf
;
145 struct zfcp_hba_dbf_record_response
*response
= &rec
->type
.response
;
149 spin_lock_irqsave(&adapter
->hba_dbf_lock
, flags
);
150 memset(rec
, 0, sizeof(struct zfcp_hba_dbf_record
));
151 strncpy(rec
->tag
, "resp", ZFCP_DBF_TAG_SIZE
);
153 if ((qtcb
->prefix
.prot_status
!= FSF_PROT_GOOD
) &&
154 (qtcb
->prefix
.prot_status
!= FSF_PROT_FSF_STATUS_PRESENTED
)) {
155 strncpy(rec
->tag2
, "perr", ZFCP_DBF_TAG_SIZE
);
157 } else if (qtcb
->header
.fsf_status
!= FSF_GOOD
) {
158 strncpy(rec
->tag2
, "ferr", ZFCP_DBF_TAG_SIZE
);
160 } else if ((fsf_req
->fsf_command
== FSF_QTCB_OPEN_PORT_WITH_DID
) ||
161 (fsf_req
->fsf_command
== FSF_QTCB_OPEN_LUN
)) {
162 strncpy(rec
->tag2
, "open", ZFCP_DBF_TAG_SIZE
);
164 } else if ((prot_status_qual
->doubleword
[0] != 0) ||
165 (prot_status_qual
->doubleword
[1] != 0) ||
166 (fsf_status_qual
->doubleword
[0] != 0) ||
167 (fsf_status_qual
->doubleword
[1] != 0)) {
168 strncpy(rec
->tag2
, "qual", ZFCP_DBF_TAG_SIZE
);
171 strncpy(rec
->tag2
, "norm", ZFCP_DBF_TAG_SIZE
);
175 response
->fsf_command
= fsf_req
->fsf_command
;
176 response
->fsf_reqid
= (unsigned long)fsf_req
;
177 response
->fsf_seqno
= fsf_req
->seq_no
;
178 response
->fsf_issued
= fsf_req
->issued
;
179 response
->fsf_prot_status
= qtcb
->prefix
.prot_status
;
180 response
->fsf_status
= qtcb
->header
.fsf_status
;
181 memcpy(response
->fsf_prot_status_qual
,
182 prot_status_qual
, FSF_PROT_STATUS_QUAL_SIZE
);
183 memcpy(response
->fsf_status_qual
,
184 fsf_status_qual
, FSF_STATUS_QUALIFIER_SIZE
);
185 response
->fsf_req_status
= fsf_req
->status
;
186 response
->sbal_first
= fsf_req
->sbal_first
;
187 response
->sbal_curr
= fsf_req
->sbal_curr
;
188 response
->sbal_last
= fsf_req
->sbal_last
;
189 response
->pool
= fsf_req
->pool
!= NULL
;
190 response
->erp_action
= (unsigned long)fsf_req
->erp_action
;
192 switch (fsf_req
->fsf_command
) {
193 case FSF_QTCB_FCP_CMND
:
194 if (fsf_req
->status
& ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT
)
196 scsi_cmnd
= (struct scsi_cmnd
*)fsf_req
->data
;
197 if (scsi_cmnd
!= NULL
) {
198 response
->data
.send_fcp
.scsi_cmnd
199 = (unsigned long)scsi_cmnd
;
200 response
->data
.send_fcp
.scsi_serial
201 = scsi_cmnd
->serial_number
;
205 case FSF_QTCB_OPEN_PORT_WITH_DID
:
206 case FSF_QTCB_CLOSE_PORT
:
207 case FSF_QTCB_CLOSE_PHYSICAL_PORT
:
208 port
= (struct zfcp_port
*)fsf_req
->data
;
209 response
->data
.port
.wwpn
= port
->wwpn
;
210 response
->data
.port
.d_id
= port
->d_id
;
211 response
->data
.port
.port_handle
= qtcb
->header
.port_handle
;
214 case FSF_QTCB_OPEN_LUN
:
215 case FSF_QTCB_CLOSE_LUN
:
216 unit
= (struct zfcp_unit
*)fsf_req
->data
;
218 response
->data
.unit
.wwpn
= port
->wwpn
;
219 response
->data
.unit
.fcp_lun
= unit
->fcp_lun
;
220 response
->data
.unit
.port_handle
= qtcb
->header
.port_handle
;
221 response
->data
.unit
.lun_handle
= qtcb
->header
.lun_handle
;
224 case FSF_QTCB_SEND_ELS
:
225 send_els
= (struct zfcp_send_els
*)fsf_req
->data
;
226 response
->data
.send_els
.d_id
= qtcb
->bottom
.support
.d_id
;
227 response
->data
.send_els
.ls_code
= send_els
->ls_code
>> 24;
230 case FSF_QTCB_ABORT_FCP_CMND
:
231 case FSF_QTCB_SEND_GENERIC
:
232 case FSF_QTCB_EXCHANGE_CONFIG_DATA
:
233 case FSF_QTCB_EXCHANGE_PORT_DATA
:
234 case FSF_QTCB_DOWNLOAD_CONTROL_FILE
:
235 case FSF_QTCB_UPLOAD_CONTROL_FILE
:
239 debug_event(adapter
->hba_dbf
, level
,
240 rec
, sizeof(struct zfcp_hba_dbf_record
));
241 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
245 zfcp_hba_dbf_event_fsf_unsol(const char *tag
, struct zfcp_adapter
*adapter
,
246 struct fsf_status_read_buffer
*status_buffer
)
248 struct zfcp_hba_dbf_record
*rec
= &adapter
->hba_dbf_buf
;
251 spin_lock_irqsave(&adapter
->hba_dbf_lock
, flags
);
252 memset(rec
, 0, sizeof(struct zfcp_hba_dbf_record
));
253 strncpy(rec
->tag
, "stat", ZFCP_DBF_TAG_SIZE
);
254 strncpy(rec
->tag2
, tag
, ZFCP_DBF_TAG_SIZE
);
256 rec
->type
.status
.failed
= adapter
->status_read_failed
;
257 if (status_buffer
!= NULL
) {
258 rec
->type
.status
.status_type
= status_buffer
->status_type
;
259 rec
->type
.status
.status_subtype
= status_buffer
->status_subtype
;
260 memcpy(&rec
->type
.status
.queue_designator
,
261 &status_buffer
->queue_designator
,
262 sizeof(struct fsf_queue_designator
));
264 switch (status_buffer
->status_type
) {
265 case FSF_STATUS_READ_SENSE_DATA_AVAIL
:
266 rec
->type
.status
.payload_size
=
267 ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL
;
270 case FSF_STATUS_READ_BIT_ERROR_THRESHOLD
:
271 rec
->type
.status
.payload_size
=
272 ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD
;
275 case FSF_STATUS_READ_LINK_DOWN
:
276 switch (status_buffer
->status_subtype
) {
277 case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK
:
278 case FSF_STATUS_READ_SUB_FDISC_FAILED
:
279 rec
->type
.status
.payload_size
=
280 sizeof(struct fsf_link_down_info
);
284 case FSF_STATUS_READ_FEATURE_UPDATE_ALERT
:
285 rec
->type
.status
.payload_size
=
286 ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT
;
289 memcpy(&rec
->type
.status
.payload
,
290 &status_buffer
->payload
, rec
->type
.status
.payload_size
);
293 debug_event(adapter
->hba_dbf
, 2,
294 rec
, sizeof(struct zfcp_hba_dbf_record
));
295 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
299 zfcp_hba_dbf_event_qdio(struct zfcp_adapter
*adapter
, unsigned int status
,
300 unsigned int qdio_error
, unsigned int siga_error
,
301 int sbal_index
, int sbal_count
)
303 struct zfcp_hba_dbf_record
*rec
= &adapter
->hba_dbf_buf
;
306 spin_lock_irqsave(&adapter
->hba_dbf_lock
, flags
);
307 memset(rec
, 0, sizeof(struct zfcp_hba_dbf_record
));
308 strncpy(rec
->tag
, "qdio", ZFCP_DBF_TAG_SIZE
);
309 rec
->type
.qdio
.status
= status
;
310 rec
->type
.qdio
.qdio_error
= qdio_error
;
311 rec
->type
.qdio
.siga_error
= siga_error
;
312 rec
->type
.qdio
.sbal_index
= sbal_index
;
313 rec
->type
.qdio
.sbal_count
= sbal_count
;
314 debug_event(adapter
->hba_dbf
, 0,
315 rec
, sizeof(struct zfcp_hba_dbf_record
));
316 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
320 zfcp_hba_dbf_view_response(char *out_buf
,
321 struct zfcp_hba_dbf_record_response
*rec
)
325 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_command", "0x%08x",
327 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
329 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
331 len
+= zfcp_dbf_stck(out_buf
+ len
, "fsf_issued", rec
->fsf_issued
);
332 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_prot_status", "0x%08x",
333 rec
->fsf_prot_status
);
334 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_status", "0x%08x",
336 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "fsf_prot_status_qual",
337 rec
->fsf_prot_status_qual
,
338 FSF_PROT_STATUS_QUAL_SIZE
,
339 0, FSF_PROT_STATUS_QUAL_SIZE
);
340 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "fsf_status_qual",
341 rec
->fsf_status_qual
,
342 FSF_STATUS_QUALIFIER_SIZE
,
343 0, FSF_STATUS_QUALIFIER_SIZE
);
344 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_req_status", "0x%08x",
345 rec
->fsf_req_status
);
346 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_first", "0x%02x",
348 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_curr", "0x%02x",
350 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_last", "0x%02x",
352 len
+= zfcp_dbf_view(out_buf
+ len
, "pool", "0x%02x", rec
->pool
);
354 switch (rec
->fsf_command
) {
355 case FSF_QTCB_FCP_CMND
:
356 if (rec
->fsf_req_status
& ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT
)
358 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_cmnd", "0x%0Lx",
359 rec
->data
.send_fcp
.scsi_cmnd
);
360 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_serial", "0x%016Lx",
361 rec
->data
.send_fcp
.scsi_serial
);
364 case FSF_QTCB_OPEN_PORT_WITH_DID
:
365 case FSF_QTCB_CLOSE_PORT
:
366 case FSF_QTCB_CLOSE_PHYSICAL_PORT
:
367 len
+= zfcp_dbf_view(out_buf
+ len
, "wwpn", "0x%016Lx",
368 rec
->data
.port
.wwpn
);
369 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x",
370 rec
->data
.port
.d_id
);
371 len
+= zfcp_dbf_view(out_buf
+ len
, "port_handle", "0x%08x",
372 rec
->data
.port
.port_handle
);
375 case FSF_QTCB_OPEN_LUN
:
376 case FSF_QTCB_CLOSE_LUN
:
377 len
+= zfcp_dbf_view(out_buf
+ len
, "wwpn", "0x%016Lx",
378 rec
->data
.unit
.wwpn
);
379 len
+= zfcp_dbf_view(out_buf
+ len
, "fcp_lun", "0x%016Lx",
380 rec
->data
.unit
.fcp_lun
);
381 len
+= zfcp_dbf_view(out_buf
+ len
, "port_handle", "0x%08x",
382 rec
->data
.unit
.port_handle
);
383 len
+= zfcp_dbf_view(out_buf
+ len
, "lun_handle", "0x%08x",
384 rec
->data
.unit
.lun_handle
);
387 case FSF_QTCB_SEND_ELS
:
388 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x",
389 rec
->data
.send_els
.d_id
);
390 len
+= zfcp_dbf_view(out_buf
+ len
, "ls_code", "0x%02x",
391 rec
->data
.send_els
.ls_code
);
394 case FSF_QTCB_ABORT_FCP_CMND
:
395 case FSF_QTCB_SEND_GENERIC
:
396 case FSF_QTCB_EXCHANGE_CONFIG_DATA
:
397 case FSF_QTCB_EXCHANGE_PORT_DATA
:
398 case FSF_QTCB_DOWNLOAD_CONTROL_FILE
:
399 case FSF_QTCB_UPLOAD_CONTROL_FILE
:
407 zfcp_hba_dbf_view_status(char *out_buf
, struct zfcp_hba_dbf_record_status
*rec
)
411 len
+= zfcp_dbf_view(out_buf
+ len
, "failed", "0x%02x", rec
->failed
);
412 len
+= zfcp_dbf_view(out_buf
+ len
, "status_type", "0x%08x",
414 len
+= zfcp_dbf_view(out_buf
+ len
, "status_subtype", "0x%08x",
415 rec
->status_subtype
);
416 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "queue_designator",
417 (char *)&rec
->queue_designator
,
418 sizeof(struct fsf_queue_designator
),
419 0, sizeof(struct fsf_queue_designator
));
420 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "payload",
421 (char *)&rec
->payload
,
422 rec
->payload_size
, 0, rec
->payload_size
);
428 zfcp_hba_dbf_view_qdio(char *out_buf
, struct zfcp_hba_dbf_record_qdio
*rec
)
432 len
+= zfcp_dbf_view(out_buf
+ len
, "status", "0x%08x", rec
->status
);
433 len
+= zfcp_dbf_view(out_buf
+ len
, "qdio_error", "0x%08x",
435 len
+= zfcp_dbf_view(out_buf
+ len
, "siga_error", "0x%08x",
437 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_index", "0x%02x",
439 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_count", "0x%02x",
446 zfcp_hba_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
447 char *out_buf
, const char *in_buf
)
449 struct zfcp_hba_dbf_record
*rec
= (struct zfcp_hba_dbf_record
*)in_buf
;
452 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
455 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
456 if (isalpha(rec
->tag2
[0]))
457 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag2", rec
->tag2
);
458 if (strncmp(rec
->tag
, "resp", ZFCP_DBF_TAG_SIZE
) == 0)
459 len
+= zfcp_hba_dbf_view_response(out_buf
+ len
,
460 &rec
->type
.response
);
461 else if (strncmp(rec
->tag
, "stat", ZFCP_DBF_TAG_SIZE
) == 0)
462 len
+= zfcp_hba_dbf_view_status(out_buf
+ len
,
464 else if (strncmp(rec
->tag
, "qdio", ZFCP_DBF_TAG_SIZE
) == 0)
465 len
+= zfcp_hba_dbf_view_qdio(out_buf
+ len
, &rec
->type
.qdio
);
467 len
+= sprintf(out_buf
+ len
, "\n");
472 static struct debug_view zfcp_hba_dbf_view
= {
475 &zfcp_dbf_view_header
,
476 &zfcp_hba_dbf_view_format
,
482 _zfcp_san_dbf_event_common_ct(const char *tag
, struct zfcp_fsf_req
*fsf_req
,
483 u32 s_id
, u32 d_id
, void *buffer
, int buflen
)
485 struct zfcp_send_ct
*send_ct
= (struct zfcp_send_ct
*)fsf_req
->data
;
486 struct zfcp_port
*port
= send_ct
->port
;
487 struct zfcp_adapter
*adapter
= port
->adapter
;
488 struct ct_hdr
*header
= (struct ct_hdr
*)buffer
;
489 struct zfcp_san_dbf_record
*rec
= &adapter
->san_dbf_buf
;
490 struct zfcp_san_dbf_record_ct
*ct
= &rec
->type
.ct
;
493 spin_lock_irqsave(&adapter
->san_dbf_lock
, flags
);
494 memset(rec
, 0, sizeof(struct zfcp_san_dbf_record
));
495 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
496 rec
->fsf_reqid
= (unsigned long)fsf_req
;
497 rec
->fsf_seqno
= fsf_req
->seq_no
;
500 if (strncmp(tag
, "octc", ZFCP_DBF_TAG_SIZE
) == 0) {
501 ct
->type
.request
.cmd_req_code
= header
->cmd_rsp_code
;
502 ct
->type
.request
.revision
= header
->revision
;
503 ct
->type
.request
.gs_type
= header
->gs_type
;
504 ct
->type
.request
.gs_subtype
= header
->gs_subtype
;
505 ct
->type
.request
.options
= header
->options
;
506 ct
->type
.request
.max_res_size
= header
->max_res_size
;
507 } else if (strncmp(tag
, "rctc", ZFCP_DBF_TAG_SIZE
) == 0) {
508 ct
->type
.response
.cmd_rsp_code
= header
->cmd_rsp_code
;
509 ct
->type
.response
.revision
= header
->revision
;
510 ct
->type
.response
.reason_code
= header
->reason_code
;
511 ct
->type
.response
.reason_code_expl
= header
->reason_code_expl
;
512 ct
->type
.response
.vendor_unique
= header
->vendor_unique
;
515 min(buflen
- (int)sizeof(struct ct_hdr
), ZFCP_DBF_CT_PAYLOAD
);
516 memcpy(ct
->payload
, buffer
+ sizeof(struct ct_hdr
), ct
->payload_size
);
517 debug_event(adapter
->san_dbf
, 3,
518 rec
, sizeof(struct zfcp_san_dbf_record
));
519 spin_unlock_irqrestore(&adapter
->san_dbf_lock
, flags
);
522 void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req
*fsf_req
)
524 struct zfcp_send_ct
*ct
= (struct zfcp_send_ct
*)fsf_req
->data
;
525 struct zfcp_port
*port
= ct
->port
;
526 struct zfcp_adapter
*adapter
= port
->adapter
;
528 _zfcp_san_dbf_event_common_ct("octc", fsf_req
,
529 fc_host_port_id(adapter
->scsi_host
),
530 port
->d_id
, zfcp_sg_to_address(ct
->req
),
534 void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req
*fsf_req
)
536 struct zfcp_send_ct
*ct
= (struct zfcp_send_ct
*)fsf_req
->data
;
537 struct zfcp_port
*port
= ct
->port
;
538 struct zfcp_adapter
*adapter
= port
->adapter
;
540 _zfcp_san_dbf_event_common_ct("rctc", fsf_req
, port
->d_id
,
541 fc_host_port_id(adapter
->scsi_host
),
542 zfcp_sg_to_address(ct
->resp
),
547 _zfcp_san_dbf_event_common_els(const char *tag
, int level
,
548 struct zfcp_fsf_req
*fsf_req
, u32 s_id
,
549 u32 d_id
, u8 ls_code
, void *buffer
, int buflen
)
551 struct zfcp_adapter
*adapter
= fsf_req
->adapter
;
552 struct zfcp_san_dbf_record
*rec
= &adapter
->san_dbf_buf
;
553 struct zfcp_dbf_dump
*dump
= (struct zfcp_dbf_dump
*)rec
;
557 spin_lock_irqsave(&adapter
->san_dbf_lock
, flags
);
559 memset(rec
, 0, sizeof(struct zfcp_san_dbf_record
));
561 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
562 rec
->fsf_reqid
= (unsigned long)fsf_req
;
563 rec
->fsf_seqno
= fsf_req
->seq_no
;
566 rec
->type
.els
.ls_code
= ls_code
;
567 buflen
= min(buflen
, ZFCP_DBF_ELS_MAX_PAYLOAD
);
568 rec
->type
.els
.payload_size
= buflen
;
569 memcpy(rec
->type
.els
.payload
,
570 buffer
, min(buflen
, ZFCP_DBF_ELS_PAYLOAD
));
571 offset
+= min(buflen
, ZFCP_DBF_ELS_PAYLOAD
);
573 strncpy(dump
->tag
, "dump", ZFCP_DBF_TAG_SIZE
);
574 dump
->total_size
= buflen
;
575 dump
->offset
= offset
;
576 dump
->size
= min(buflen
- offset
,
577 (int)sizeof(struct zfcp_san_dbf_record
)
578 - (int)sizeof(struct zfcp_dbf_dump
));
579 memcpy(dump
->data
, buffer
+ offset
, dump
->size
);
580 offset
+= dump
->size
;
582 debug_event(adapter
->san_dbf
, level
,
583 rec
, sizeof(struct zfcp_san_dbf_record
));
584 } while (offset
< buflen
);
585 spin_unlock_irqrestore(&adapter
->san_dbf_lock
, flags
);
588 void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req
*fsf_req
)
590 struct zfcp_send_els
*els
= (struct zfcp_send_els
*)fsf_req
->data
;
592 _zfcp_san_dbf_event_common_els("oels", 2, fsf_req
,
593 fc_host_port_id(els
->adapter
->scsi_host
),
595 *(u8
*) zfcp_sg_to_address(els
->req
),
596 zfcp_sg_to_address(els
->req
),
600 void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req
*fsf_req
)
602 struct zfcp_send_els
*els
= (struct zfcp_send_els
*)fsf_req
->data
;
604 _zfcp_san_dbf_event_common_els("rels", 2, fsf_req
, els
->d_id
,
605 fc_host_port_id(els
->adapter
->scsi_host
),
606 *(u8
*) zfcp_sg_to_address(els
->req
),
607 zfcp_sg_to_address(els
->resp
),
611 void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req
*fsf_req
)
613 struct zfcp_adapter
*adapter
= fsf_req
->adapter
;
614 struct fsf_status_read_buffer
*status_buffer
=
615 (struct fsf_status_read_buffer
*)fsf_req
->data
;
616 int length
= (int)status_buffer
->length
-
617 (int)((void *)&status_buffer
->payload
- (void *)status_buffer
);
619 _zfcp_san_dbf_event_common_els("iels", 1, fsf_req
, status_buffer
->d_id
,
620 fc_host_port_id(adapter
->scsi_host
),
621 *(u8
*) status_buffer
->payload
,
622 (void *)status_buffer
->payload
, length
);
626 zfcp_san_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
627 char *out_buf
, const char *in_buf
)
629 struct zfcp_san_dbf_record
*rec
= (struct zfcp_san_dbf_record
*)in_buf
;
631 int buflen
= 0, total
= 0;
634 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
637 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
638 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
640 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
642 len
+= zfcp_dbf_view(out_buf
+ len
, "s_id", "0x%06x", rec
->s_id
);
643 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x", rec
->d_id
);
645 if (strncmp(rec
->tag
, "octc", ZFCP_DBF_TAG_SIZE
) == 0) {
646 len
+= zfcp_dbf_view(out_buf
+ len
, "cmd_req_code", "0x%04x",
647 rec
->type
.ct
.type
.request
.cmd_req_code
);
648 len
+= zfcp_dbf_view(out_buf
+ len
, "revision", "0x%02x",
649 rec
->type
.ct
.type
.request
.revision
);
650 len
+= zfcp_dbf_view(out_buf
+ len
, "gs_type", "0x%02x",
651 rec
->type
.ct
.type
.request
.gs_type
);
652 len
+= zfcp_dbf_view(out_buf
+ len
, "gs_subtype", "0x%02x",
653 rec
->type
.ct
.type
.request
.gs_subtype
);
654 len
+= zfcp_dbf_view(out_buf
+ len
, "options", "0x%02x",
655 rec
->type
.ct
.type
.request
.options
);
656 len
+= zfcp_dbf_view(out_buf
+ len
, "max_res_size", "0x%04x",
657 rec
->type
.ct
.type
.request
.max_res_size
);
658 total
= rec
->type
.ct
.payload_size
;
659 buffer
= rec
->type
.ct
.payload
;
660 buflen
= min(total
, ZFCP_DBF_CT_PAYLOAD
);
661 } else if (strncmp(rec
->tag
, "rctc", ZFCP_DBF_TAG_SIZE
) == 0) {
662 len
+= zfcp_dbf_view(out_buf
+ len
, "cmd_rsp_code", "0x%04x",
663 rec
->type
.ct
.type
.response
.cmd_rsp_code
);
664 len
+= zfcp_dbf_view(out_buf
+ len
, "revision", "0x%02x",
665 rec
->type
.ct
.type
.response
.revision
);
666 len
+= zfcp_dbf_view(out_buf
+ len
, "reason_code", "0x%02x",
667 rec
->type
.ct
.type
.response
.reason_code
);
669 zfcp_dbf_view(out_buf
+ len
, "reason_code_expl", "0x%02x",
670 rec
->type
.ct
.type
.response
.reason_code_expl
);
672 zfcp_dbf_view(out_buf
+ len
, "vendor_unique", "0x%02x",
673 rec
->type
.ct
.type
.response
.vendor_unique
);
674 total
= rec
->type
.ct
.payload_size
;
675 buffer
= rec
->type
.ct
.payload
;
676 buflen
= min(total
, ZFCP_DBF_CT_PAYLOAD
);
677 } else if (strncmp(rec
->tag
, "oels", ZFCP_DBF_TAG_SIZE
) == 0 ||
678 strncmp(rec
->tag
, "rels", ZFCP_DBF_TAG_SIZE
) == 0 ||
679 strncmp(rec
->tag
, "iels", ZFCP_DBF_TAG_SIZE
) == 0) {
680 len
+= zfcp_dbf_view(out_buf
+ len
, "ls_code", "0x%02x",
681 rec
->type
.els
.ls_code
);
682 total
= rec
->type
.els
.payload_size
;
683 buffer
= rec
->type
.els
.payload
;
684 buflen
= min(total
, ZFCP_DBF_ELS_PAYLOAD
);
687 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "payload",
688 buffer
, buflen
, 0, total
);
691 len
+= sprintf(out_buf
+ len
, "\n");
696 static struct debug_view zfcp_san_dbf_view
= {
699 &zfcp_dbf_view_header
,
700 &zfcp_san_dbf_view_format
,
706 _zfcp_scsi_dbf_event_common(const char *tag
, const char *tag2
, int level
,
707 struct zfcp_adapter
*adapter
,
708 struct scsi_cmnd
*scsi_cmnd
,
709 struct zfcp_fsf_req
*fsf_req
,
710 unsigned long old_req_id
)
712 struct zfcp_scsi_dbf_record
*rec
= &adapter
->scsi_dbf_buf
;
713 struct zfcp_dbf_dump
*dump
= (struct zfcp_dbf_dump
*)rec
;
715 struct fcp_rsp_iu
*fcp_rsp
;
716 char *fcp_rsp_info
= NULL
, *fcp_sns_info
= NULL
;
717 int offset
= 0, buflen
= 0;
719 spin_lock_irqsave(&adapter
->scsi_dbf_lock
, flags
);
721 memset(rec
, 0, sizeof(struct zfcp_scsi_dbf_record
));
723 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
724 strncpy(rec
->tag2
, tag2
, ZFCP_DBF_TAG_SIZE
);
725 if (scsi_cmnd
!= NULL
) {
726 if (scsi_cmnd
->device
) {
727 rec
->scsi_id
= scsi_cmnd
->device
->id
;
728 rec
->scsi_lun
= scsi_cmnd
->device
->lun
;
730 rec
->scsi_result
= scsi_cmnd
->result
;
731 rec
->scsi_cmnd
= (unsigned long)scsi_cmnd
;
732 rec
->scsi_serial
= scsi_cmnd
->serial_number
;
733 memcpy(rec
->scsi_opcode
, &scsi_cmnd
->cmnd
,
734 min((int)scsi_cmnd
->cmd_len
,
735 ZFCP_DBF_SCSI_OPCODE
));
736 rec
->scsi_retries
= scsi_cmnd
->retries
;
737 rec
->scsi_allowed
= scsi_cmnd
->allowed
;
739 if (fsf_req
!= NULL
) {
740 fcp_rsp
= (struct fcp_rsp_iu
*)
741 &(fsf_req
->qtcb
->bottom
.io
.fcp_rsp
);
743 zfcp_get_fcp_rsp_info_ptr(fcp_rsp
);
745 zfcp_get_fcp_sns_info_ptr(fcp_rsp
);
747 rec
->type
.fcp
.rsp_validity
=
748 fcp_rsp
->validity
.value
;
749 rec
->type
.fcp
.rsp_scsi_status
=
750 fcp_rsp
->scsi_status
;
751 rec
->type
.fcp
.rsp_resid
= fcp_rsp
->fcp_resid
;
752 if (fcp_rsp
->validity
.bits
.fcp_rsp_len_valid
)
753 rec
->type
.fcp
.rsp_code
=
755 if (fcp_rsp
->validity
.bits
.fcp_sns_len_valid
) {
756 buflen
= min((int)fcp_rsp
->fcp_sns_len
,
757 ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO
);
758 rec
->type
.fcp
.sns_info_len
= buflen
;
759 memcpy(rec
->type
.fcp
.sns_info
,
762 ZFCP_DBF_SCSI_FCP_SNS_INFO
));
763 offset
+= min(buflen
,
764 ZFCP_DBF_SCSI_FCP_SNS_INFO
);
767 rec
->fsf_reqid
= (unsigned long)fsf_req
;
768 rec
->fsf_seqno
= fsf_req
->seq_no
;
769 rec
->fsf_issued
= fsf_req
->issued
;
771 rec
->type
.old_fsf_reqid
= old_req_id
;
773 strncpy(dump
->tag
, "dump", ZFCP_DBF_TAG_SIZE
);
774 dump
->total_size
= buflen
;
775 dump
->offset
= offset
;
776 dump
->size
= min(buflen
- offset
,
778 zfcp_scsi_dbf_record
) -
779 (int)sizeof(struct zfcp_dbf_dump
));
780 memcpy(dump
->data
, fcp_sns_info
+ offset
, dump
->size
);
781 offset
+= dump
->size
;
783 debug_event(adapter
->scsi_dbf
, level
,
784 rec
, sizeof(struct zfcp_scsi_dbf_record
));
785 } while (offset
< buflen
);
786 spin_unlock_irqrestore(&adapter
->scsi_dbf_lock
, flags
);
790 zfcp_scsi_dbf_event_result(const char *tag
, int level
,
791 struct zfcp_adapter
*adapter
,
792 struct scsi_cmnd
*scsi_cmnd
,
793 struct zfcp_fsf_req
*fsf_req
)
795 _zfcp_scsi_dbf_event_common("rslt", tag
, level
,
796 adapter
, scsi_cmnd
, fsf_req
, 0);
800 zfcp_scsi_dbf_event_abort(const char *tag
, struct zfcp_adapter
*adapter
,
801 struct scsi_cmnd
*scsi_cmnd
,
802 struct zfcp_fsf_req
*new_fsf_req
,
803 unsigned long old_req_id
)
805 _zfcp_scsi_dbf_event_common("abrt", tag
, 1,
806 adapter
, scsi_cmnd
, new_fsf_req
, old_req_id
);
810 zfcp_scsi_dbf_event_devreset(const char *tag
, u8 flag
, struct zfcp_unit
*unit
,
811 struct scsi_cmnd
*scsi_cmnd
)
813 struct zfcp_adapter
*adapter
= unit
->port
->adapter
;
815 _zfcp_scsi_dbf_event_common(flag
== FCP_TARGET_RESET
? "trst" : "lrst",
816 tag
, 1, adapter
, scsi_cmnd
, NULL
, 0);
820 zfcp_scsi_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
821 char *out_buf
, const char *in_buf
)
823 struct zfcp_scsi_dbf_record
*rec
=
824 (struct zfcp_scsi_dbf_record
*)in_buf
;
827 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
830 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
831 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag2", rec
->tag2
);
832 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_id", "0x%08x", rec
->scsi_id
);
833 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_lun", "0x%08x",
835 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_result", "0x%08x",
837 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_cmnd", "0x%0Lx",
839 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_serial", "0x%016Lx",
841 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "scsi_opcode",
843 ZFCP_DBF_SCSI_OPCODE
,
844 0, ZFCP_DBF_SCSI_OPCODE
);
845 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_retries", "0x%02x",
847 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_allowed", "0x%02x",
849 if (strncmp(rec
->tag
, "abrt", ZFCP_DBF_TAG_SIZE
) == 0) {
850 len
+= zfcp_dbf_view(out_buf
+ len
, "old_fsf_reqid", "0x%0Lx",
851 rec
->type
.old_fsf_reqid
);
853 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
855 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
857 len
+= zfcp_dbf_stck(out_buf
+ len
, "fsf_issued", rec
->fsf_issued
);
858 if (strncmp(rec
->tag
, "rslt", ZFCP_DBF_TAG_SIZE
) == 0) {
860 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_validity", "0x%02x",
861 rec
->type
.fcp
.rsp_validity
);
863 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_scsi_status",
864 "0x%02x", rec
->type
.fcp
.rsp_scsi_status
);
866 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_resid", "0x%08x",
867 rec
->type
.fcp
.rsp_resid
);
869 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_code", "0x%08x",
870 rec
->type
.fcp
.rsp_code
);
872 zfcp_dbf_view(out_buf
+ len
, "fcp_sns_info_len", "0x%08x",
873 rec
->type
.fcp
.sns_info_len
);
875 zfcp_dbf_view_dump(out_buf
+ len
, "fcp_sns_info",
876 rec
->type
.fcp
.sns_info
,
877 min((int)rec
->type
.fcp
.sns_info_len
,
878 ZFCP_DBF_SCSI_FCP_SNS_INFO
), 0,
879 rec
->type
.fcp
.sns_info_len
);
882 len
+= sprintf(out_buf
+ len
, "\n");
887 static struct debug_view zfcp_scsi_dbf_view
= {
890 &zfcp_dbf_view_header
,
891 &zfcp_scsi_dbf_view_format
,
897 * zfcp_adapter_debug_register - registers debug feature for an adapter
898 * @adapter: pointer to adapter for which debug features should be registered
899 * return: -ENOMEM on error, 0 otherwise
901 int zfcp_adapter_debug_register(struct zfcp_adapter
*adapter
)
903 char dbf_name
[DEBUG_MAX_NAME_LEN
];
905 /* debug feature area which records recovery activity */
906 sprintf(dbf_name
, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter
));
907 adapter
->erp_dbf
= debug_register(dbf_name
, dbfsize
, 2,
908 sizeof(struct zfcp_erp_dbf_record
));
909 if (!adapter
->erp_dbf
)
911 debug_register_view(adapter
->erp_dbf
, &debug_hex_ascii_view
);
912 debug_set_level(adapter
->erp_dbf
, 3);
914 /* debug feature area which records HBA (FSF and QDIO) conditions */
915 sprintf(dbf_name
, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter
));
916 adapter
->hba_dbf
= debug_register(dbf_name
, dbfsize
, 1,
917 sizeof(struct zfcp_hba_dbf_record
));
918 if (!adapter
->hba_dbf
)
920 debug_register_view(adapter
->hba_dbf
, &debug_hex_ascii_view
);
921 debug_register_view(adapter
->hba_dbf
, &zfcp_hba_dbf_view
);
922 debug_set_level(adapter
->hba_dbf
, 3);
924 /* debug feature area which records SAN command failures and recovery */
925 sprintf(dbf_name
, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter
));
926 adapter
->san_dbf
= debug_register(dbf_name
, dbfsize
, 1,
927 sizeof(struct zfcp_san_dbf_record
));
928 if (!adapter
->san_dbf
)
930 debug_register_view(adapter
->san_dbf
, &debug_hex_ascii_view
);
931 debug_register_view(adapter
->san_dbf
, &zfcp_san_dbf_view
);
932 debug_set_level(adapter
->san_dbf
, 6);
934 /* debug feature area which records SCSI command failures and recovery */
935 sprintf(dbf_name
, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter
));
936 adapter
->scsi_dbf
= debug_register(dbf_name
, dbfsize
, 1,
937 sizeof(struct zfcp_scsi_dbf_record
));
938 if (!adapter
->scsi_dbf
)
940 debug_register_view(adapter
->scsi_dbf
, &debug_hex_ascii_view
);
941 debug_register_view(adapter
->scsi_dbf
, &zfcp_scsi_dbf_view
);
942 debug_set_level(adapter
->scsi_dbf
, 3);
947 zfcp_adapter_debug_unregister(adapter
);
953 * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
954 * @adapter: pointer to adapter for which debug features should be unregistered
956 void zfcp_adapter_debug_unregister(struct zfcp_adapter
*adapter
)
958 debug_unregister(adapter
->scsi_dbf
);
959 debug_unregister(adapter
->san_dbf
);
960 debug_unregister(adapter
->hba_dbf
);
961 debug_unregister(adapter
->erp_dbf
);
962 adapter
->scsi_dbf
= NULL
;
963 adapter
->san_dbf
= NULL
;
964 adapter
->hba_dbf
= NULL
;
965 adapter
->erp_dbf
= NULL
;