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
);
165 strncpy(rec
->tag2
, "norm", ZFCP_DBF_TAG_SIZE
);
169 response
->fsf_command
= fsf_req
->fsf_command
;
170 response
->fsf_reqid
= (unsigned long)fsf_req
;
171 response
->fsf_seqno
= fsf_req
->seq_no
;
172 response
->fsf_issued
= fsf_req
->issued
;
173 response
->fsf_prot_status
= qtcb
->prefix
.prot_status
;
174 response
->fsf_status
= qtcb
->header
.fsf_status
;
175 memcpy(response
->fsf_prot_status_qual
,
176 prot_status_qual
, FSF_PROT_STATUS_QUAL_SIZE
);
177 memcpy(response
->fsf_status_qual
,
178 fsf_status_qual
, FSF_STATUS_QUALIFIER_SIZE
);
179 response
->fsf_req_status
= fsf_req
->status
;
180 response
->sbal_first
= fsf_req
->sbal_first
;
181 response
->sbal_curr
= fsf_req
->sbal_curr
;
182 response
->sbal_last
= fsf_req
->sbal_last
;
183 response
->pool
= fsf_req
->pool
!= NULL
;
184 response
->erp_action
= (unsigned long)fsf_req
->erp_action
;
186 switch (fsf_req
->fsf_command
) {
187 case FSF_QTCB_FCP_CMND
:
188 if (fsf_req
->status
& ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT
)
190 scsi_cmnd
= (struct scsi_cmnd
*)fsf_req
->data
;
191 if (scsi_cmnd
!= NULL
) {
192 response
->data
.send_fcp
.scsi_cmnd
193 = (unsigned long)scsi_cmnd
;
194 response
->data
.send_fcp
.scsi_serial
195 = scsi_cmnd
->serial_number
;
199 case FSF_QTCB_OPEN_PORT_WITH_DID
:
200 case FSF_QTCB_CLOSE_PORT
:
201 case FSF_QTCB_CLOSE_PHYSICAL_PORT
:
202 port
= (struct zfcp_port
*)fsf_req
->data
;
203 response
->data
.port
.wwpn
= port
->wwpn
;
204 response
->data
.port
.d_id
= port
->d_id
;
205 response
->data
.port
.port_handle
= qtcb
->header
.port_handle
;
208 case FSF_QTCB_OPEN_LUN
:
209 case FSF_QTCB_CLOSE_LUN
:
210 unit
= (struct zfcp_unit
*)fsf_req
->data
;
212 response
->data
.unit
.wwpn
= port
->wwpn
;
213 response
->data
.unit
.fcp_lun
= unit
->fcp_lun
;
214 response
->data
.unit
.port_handle
= qtcb
->header
.port_handle
;
215 response
->data
.unit
.lun_handle
= qtcb
->header
.lun_handle
;
218 case FSF_QTCB_SEND_ELS
:
219 send_els
= (struct zfcp_send_els
*)fsf_req
->data
;
220 response
->data
.send_els
.d_id
= qtcb
->bottom
.support
.d_id
;
221 response
->data
.send_els
.ls_code
= send_els
->ls_code
>> 24;
224 case FSF_QTCB_ABORT_FCP_CMND
:
225 case FSF_QTCB_SEND_GENERIC
:
226 case FSF_QTCB_EXCHANGE_CONFIG_DATA
:
227 case FSF_QTCB_EXCHANGE_PORT_DATA
:
228 case FSF_QTCB_DOWNLOAD_CONTROL_FILE
:
229 case FSF_QTCB_UPLOAD_CONTROL_FILE
:
233 debug_event(adapter
->hba_dbf
, level
,
234 rec
, sizeof(struct zfcp_hba_dbf_record
));
235 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
239 zfcp_hba_dbf_event_fsf_unsol(const char *tag
, struct zfcp_adapter
*adapter
,
240 struct fsf_status_read_buffer
*status_buffer
)
242 struct zfcp_hba_dbf_record
*rec
= &adapter
->hba_dbf_buf
;
245 spin_lock_irqsave(&adapter
->hba_dbf_lock
, flags
);
246 memset(rec
, 0, sizeof(struct zfcp_hba_dbf_record
));
247 strncpy(rec
->tag
, "stat", ZFCP_DBF_TAG_SIZE
);
248 strncpy(rec
->tag2
, tag
, ZFCP_DBF_TAG_SIZE
);
250 rec
->type
.status
.failed
= adapter
->status_read_failed
;
251 if (status_buffer
!= NULL
) {
252 rec
->type
.status
.status_type
= status_buffer
->status_type
;
253 rec
->type
.status
.status_subtype
= status_buffer
->status_subtype
;
254 memcpy(&rec
->type
.status
.queue_designator
,
255 &status_buffer
->queue_designator
,
256 sizeof(struct fsf_queue_designator
));
258 switch (status_buffer
->status_type
) {
259 case FSF_STATUS_READ_SENSE_DATA_AVAIL
:
260 rec
->type
.status
.payload_size
=
261 ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL
;
264 case FSF_STATUS_READ_BIT_ERROR_THRESHOLD
:
265 rec
->type
.status
.payload_size
=
266 ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD
;
269 case FSF_STATUS_READ_LINK_DOWN
:
270 switch (status_buffer
->status_subtype
) {
271 case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK
:
272 case FSF_STATUS_READ_SUB_FDISC_FAILED
:
273 rec
->type
.status
.payload_size
=
274 sizeof(struct fsf_link_down_info
);
278 case FSF_STATUS_READ_FEATURE_UPDATE_ALERT
:
279 rec
->type
.status
.payload_size
=
280 ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT
;
283 memcpy(&rec
->type
.status
.payload
,
284 &status_buffer
->payload
, rec
->type
.status
.payload_size
);
287 debug_event(adapter
->hba_dbf
, 2,
288 rec
, sizeof(struct zfcp_hba_dbf_record
));
289 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
293 zfcp_hba_dbf_event_qdio(struct zfcp_adapter
*adapter
, unsigned int status
,
294 unsigned int qdio_error
, unsigned int siga_error
,
295 int sbal_index
, int sbal_count
)
297 struct zfcp_hba_dbf_record
*rec
= &adapter
->hba_dbf_buf
;
300 spin_lock_irqsave(&adapter
->hba_dbf_lock
, flags
);
301 memset(rec
, 0, sizeof(struct zfcp_hba_dbf_record
));
302 strncpy(rec
->tag
, "qdio", ZFCP_DBF_TAG_SIZE
);
303 rec
->type
.qdio
.status
= status
;
304 rec
->type
.qdio
.qdio_error
= qdio_error
;
305 rec
->type
.qdio
.siga_error
= siga_error
;
306 rec
->type
.qdio
.sbal_index
= sbal_index
;
307 rec
->type
.qdio
.sbal_count
= sbal_count
;
308 debug_event(adapter
->hba_dbf
, 0,
309 rec
, sizeof(struct zfcp_hba_dbf_record
));
310 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
314 zfcp_hba_dbf_view_response(char *out_buf
,
315 struct zfcp_hba_dbf_record_response
*rec
)
319 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_command", "0x%08x",
321 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
323 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
325 len
+= zfcp_dbf_stck(out_buf
+ len
, "fsf_issued", rec
->fsf_issued
);
326 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_prot_status", "0x%08x",
327 rec
->fsf_prot_status
);
328 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_status", "0x%08x",
330 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "fsf_prot_status_qual",
331 rec
->fsf_prot_status_qual
,
332 FSF_PROT_STATUS_QUAL_SIZE
,
333 0, FSF_PROT_STATUS_QUAL_SIZE
);
334 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "fsf_status_qual",
335 rec
->fsf_status_qual
,
336 FSF_STATUS_QUALIFIER_SIZE
,
337 0, FSF_STATUS_QUALIFIER_SIZE
);
338 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_req_status", "0x%08x",
339 rec
->fsf_req_status
);
340 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_first", "0x%02x",
342 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_curr", "0x%02x",
344 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_last", "0x%02x",
346 len
+= zfcp_dbf_view(out_buf
+ len
, "pool", "0x%02x", rec
->pool
);
348 switch (rec
->fsf_command
) {
349 case FSF_QTCB_FCP_CMND
:
350 if (rec
->fsf_req_status
& ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT
)
352 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_cmnd", "0x%0Lx",
353 rec
->data
.send_fcp
.scsi_cmnd
);
354 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_serial", "0x%016Lx",
355 rec
->data
.send_fcp
.scsi_serial
);
358 case FSF_QTCB_OPEN_PORT_WITH_DID
:
359 case FSF_QTCB_CLOSE_PORT
:
360 case FSF_QTCB_CLOSE_PHYSICAL_PORT
:
361 len
+= zfcp_dbf_view(out_buf
+ len
, "wwpn", "0x%016Lx",
362 rec
->data
.port
.wwpn
);
363 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x",
364 rec
->data
.port
.d_id
);
365 len
+= zfcp_dbf_view(out_buf
+ len
, "port_handle", "0x%08x",
366 rec
->data
.port
.port_handle
);
369 case FSF_QTCB_OPEN_LUN
:
370 case FSF_QTCB_CLOSE_LUN
:
371 len
+= zfcp_dbf_view(out_buf
+ len
, "wwpn", "0x%016Lx",
372 rec
->data
.unit
.wwpn
);
373 len
+= zfcp_dbf_view(out_buf
+ len
, "fcp_lun", "0x%016Lx",
374 rec
->data
.unit
.fcp_lun
);
375 len
+= zfcp_dbf_view(out_buf
+ len
, "port_handle", "0x%08x",
376 rec
->data
.unit
.port_handle
);
377 len
+= zfcp_dbf_view(out_buf
+ len
, "lun_handle", "0x%08x",
378 rec
->data
.unit
.lun_handle
);
381 case FSF_QTCB_SEND_ELS
:
382 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x",
383 rec
->data
.send_els
.d_id
);
384 len
+= zfcp_dbf_view(out_buf
+ len
, "ls_code", "0x%02x",
385 rec
->data
.send_els
.ls_code
);
388 case FSF_QTCB_ABORT_FCP_CMND
:
389 case FSF_QTCB_SEND_GENERIC
:
390 case FSF_QTCB_EXCHANGE_CONFIG_DATA
:
391 case FSF_QTCB_EXCHANGE_PORT_DATA
:
392 case FSF_QTCB_DOWNLOAD_CONTROL_FILE
:
393 case FSF_QTCB_UPLOAD_CONTROL_FILE
:
401 zfcp_hba_dbf_view_status(char *out_buf
, struct zfcp_hba_dbf_record_status
*rec
)
405 len
+= zfcp_dbf_view(out_buf
+ len
, "failed", "0x%02x", rec
->failed
);
406 len
+= zfcp_dbf_view(out_buf
+ len
, "status_type", "0x%08x",
408 len
+= zfcp_dbf_view(out_buf
+ len
, "status_subtype", "0x%08x",
409 rec
->status_subtype
);
410 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "queue_designator",
411 (char *)&rec
->queue_designator
,
412 sizeof(struct fsf_queue_designator
),
413 0, sizeof(struct fsf_queue_designator
));
414 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "payload",
415 (char *)&rec
->payload
,
416 rec
->payload_size
, 0, rec
->payload_size
);
422 zfcp_hba_dbf_view_qdio(char *out_buf
, struct zfcp_hba_dbf_record_qdio
*rec
)
426 len
+= zfcp_dbf_view(out_buf
+ len
, "status", "0x%08x", rec
->status
);
427 len
+= zfcp_dbf_view(out_buf
+ len
, "qdio_error", "0x%08x",
429 len
+= zfcp_dbf_view(out_buf
+ len
, "siga_error", "0x%08x",
431 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_index", "0x%02x",
433 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_count", "0x%02x",
440 zfcp_hba_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
441 char *out_buf
, const char *in_buf
)
443 struct zfcp_hba_dbf_record
*rec
= (struct zfcp_hba_dbf_record
*)in_buf
;
446 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
449 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
450 if (isalpha(rec
->tag2
[0]))
451 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag2", rec
->tag2
);
452 if (strncmp(rec
->tag
, "resp", ZFCP_DBF_TAG_SIZE
) == 0)
453 len
+= zfcp_hba_dbf_view_response(out_buf
+ len
,
454 &rec
->type
.response
);
455 else if (strncmp(rec
->tag
, "stat", ZFCP_DBF_TAG_SIZE
) == 0)
456 len
+= zfcp_hba_dbf_view_status(out_buf
+ len
,
458 else if (strncmp(rec
->tag
, "qdio", ZFCP_DBF_TAG_SIZE
) == 0)
459 len
+= zfcp_hba_dbf_view_qdio(out_buf
+ len
, &rec
->type
.qdio
);
461 len
+= sprintf(out_buf
+ len
, "\n");
466 static struct debug_view zfcp_hba_dbf_view
= {
469 &zfcp_dbf_view_header
,
470 &zfcp_hba_dbf_view_format
,
476 _zfcp_san_dbf_event_common_ct(const char *tag
, struct zfcp_fsf_req
*fsf_req
,
477 u32 s_id
, u32 d_id
, void *buffer
, int buflen
)
479 struct zfcp_send_ct
*send_ct
= (struct zfcp_send_ct
*)fsf_req
->data
;
480 struct zfcp_port
*port
= send_ct
->port
;
481 struct zfcp_adapter
*adapter
= port
->adapter
;
482 struct ct_hdr
*header
= (struct ct_hdr
*)buffer
;
483 struct zfcp_san_dbf_record
*rec
= &adapter
->san_dbf_buf
;
484 struct zfcp_san_dbf_record_ct
*ct
= &rec
->type
.ct
;
487 spin_lock_irqsave(&adapter
->san_dbf_lock
, flags
);
488 memset(rec
, 0, sizeof(struct zfcp_san_dbf_record
));
489 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
490 rec
->fsf_reqid
= (unsigned long)fsf_req
;
491 rec
->fsf_seqno
= fsf_req
->seq_no
;
494 if (strncmp(tag
, "octc", ZFCP_DBF_TAG_SIZE
) == 0) {
495 ct
->type
.request
.cmd_req_code
= header
->cmd_rsp_code
;
496 ct
->type
.request
.revision
= header
->revision
;
497 ct
->type
.request
.gs_type
= header
->gs_type
;
498 ct
->type
.request
.gs_subtype
= header
->gs_subtype
;
499 ct
->type
.request
.options
= header
->options
;
500 ct
->type
.request
.max_res_size
= header
->max_res_size
;
501 } else if (strncmp(tag
, "rctc", ZFCP_DBF_TAG_SIZE
) == 0) {
502 ct
->type
.response
.cmd_rsp_code
= header
->cmd_rsp_code
;
503 ct
->type
.response
.revision
= header
->revision
;
504 ct
->type
.response
.reason_code
= header
->reason_code
;
505 ct
->type
.response
.reason_code_expl
= header
->reason_code_expl
;
506 ct
->type
.response
.vendor_unique
= header
->vendor_unique
;
509 min(buflen
- (int)sizeof(struct ct_hdr
), ZFCP_DBF_CT_PAYLOAD
);
510 memcpy(ct
->payload
, buffer
+ sizeof(struct ct_hdr
), ct
->payload_size
);
511 debug_event(adapter
->san_dbf
, 3,
512 rec
, sizeof(struct zfcp_san_dbf_record
));
513 spin_unlock_irqrestore(&adapter
->san_dbf_lock
, flags
);
516 void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req
*fsf_req
)
518 struct zfcp_send_ct
*ct
= (struct zfcp_send_ct
*)fsf_req
->data
;
519 struct zfcp_port
*port
= ct
->port
;
520 struct zfcp_adapter
*adapter
= port
->adapter
;
522 _zfcp_san_dbf_event_common_ct("octc", fsf_req
,
523 fc_host_port_id(adapter
->scsi_host
),
524 port
->d_id
, zfcp_sg_to_address(ct
->req
),
528 void zfcp_san_dbf_event_ct_response(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("rctc", fsf_req
, port
->d_id
,
535 fc_host_port_id(adapter
->scsi_host
),
536 zfcp_sg_to_address(ct
->resp
),
541 _zfcp_san_dbf_event_common_els(const char *tag
, int level
,
542 struct zfcp_fsf_req
*fsf_req
, u32 s_id
,
543 u32 d_id
, u8 ls_code
, void *buffer
, int buflen
)
545 struct zfcp_adapter
*adapter
= fsf_req
->adapter
;
546 struct zfcp_san_dbf_record
*rec
= &adapter
->san_dbf_buf
;
547 struct zfcp_dbf_dump
*dump
= (struct zfcp_dbf_dump
*)rec
;
551 spin_lock_irqsave(&adapter
->san_dbf_lock
, flags
);
553 memset(rec
, 0, sizeof(struct zfcp_san_dbf_record
));
555 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
556 rec
->fsf_reqid
= (unsigned long)fsf_req
;
557 rec
->fsf_seqno
= fsf_req
->seq_no
;
560 rec
->type
.els
.ls_code
= ls_code
;
561 buflen
= min(buflen
, ZFCP_DBF_ELS_MAX_PAYLOAD
);
562 rec
->type
.els
.payload_size
= buflen
;
563 memcpy(rec
->type
.els
.payload
,
564 buffer
, min(buflen
, ZFCP_DBF_ELS_PAYLOAD
));
565 offset
+= min(buflen
, ZFCP_DBF_ELS_PAYLOAD
);
567 strncpy(dump
->tag
, "dump", ZFCP_DBF_TAG_SIZE
);
568 dump
->total_size
= buflen
;
569 dump
->offset
= offset
;
570 dump
->size
= min(buflen
- offset
,
571 (int)sizeof(struct zfcp_san_dbf_record
)
572 - (int)sizeof(struct zfcp_dbf_dump
));
573 memcpy(dump
->data
, buffer
+ offset
, dump
->size
);
574 offset
+= dump
->size
;
576 debug_event(adapter
->san_dbf
, level
,
577 rec
, sizeof(struct zfcp_san_dbf_record
));
578 } while (offset
< buflen
);
579 spin_unlock_irqrestore(&adapter
->san_dbf_lock
, flags
);
582 void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req
*fsf_req
)
584 struct zfcp_send_els
*els
= (struct zfcp_send_els
*)fsf_req
->data
;
586 _zfcp_san_dbf_event_common_els("oels", 2, fsf_req
,
587 fc_host_port_id(els
->adapter
->scsi_host
),
589 *(u8
*) zfcp_sg_to_address(els
->req
),
590 zfcp_sg_to_address(els
->req
),
594 void zfcp_san_dbf_event_els_response(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("rels", 2, fsf_req
, els
->d_id
,
599 fc_host_port_id(els
->adapter
->scsi_host
),
600 *(u8
*) zfcp_sg_to_address(els
->req
),
601 zfcp_sg_to_address(els
->resp
),
605 void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req
*fsf_req
)
607 struct zfcp_adapter
*adapter
= fsf_req
->adapter
;
608 struct fsf_status_read_buffer
*status_buffer
=
609 (struct fsf_status_read_buffer
*)fsf_req
->data
;
610 int length
= (int)status_buffer
->length
-
611 (int)((void *)&status_buffer
->payload
- (void *)status_buffer
);
613 _zfcp_san_dbf_event_common_els("iels", 1, fsf_req
, status_buffer
->d_id
,
614 fc_host_port_id(adapter
->scsi_host
),
615 *(u8
*) status_buffer
->payload
,
616 (void *)status_buffer
->payload
, length
);
620 zfcp_san_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
621 char *out_buf
, const char *in_buf
)
623 struct zfcp_san_dbf_record
*rec
= (struct zfcp_san_dbf_record
*)in_buf
;
625 int buflen
= 0, total
= 0;
628 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
631 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
632 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
634 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
636 len
+= zfcp_dbf_view(out_buf
+ len
, "s_id", "0x%06x", rec
->s_id
);
637 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x", rec
->d_id
);
639 if (strncmp(rec
->tag
, "octc", ZFCP_DBF_TAG_SIZE
) == 0) {
640 len
+= zfcp_dbf_view(out_buf
+ len
, "cmd_req_code", "0x%04x",
641 rec
->type
.ct
.type
.request
.cmd_req_code
);
642 len
+= zfcp_dbf_view(out_buf
+ len
, "revision", "0x%02x",
643 rec
->type
.ct
.type
.request
.revision
);
644 len
+= zfcp_dbf_view(out_buf
+ len
, "gs_type", "0x%02x",
645 rec
->type
.ct
.type
.request
.gs_type
);
646 len
+= zfcp_dbf_view(out_buf
+ len
, "gs_subtype", "0x%02x",
647 rec
->type
.ct
.type
.request
.gs_subtype
);
648 len
+= zfcp_dbf_view(out_buf
+ len
, "options", "0x%02x",
649 rec
->type
.ct
.type
.request
.options
);
650 len
+= zfcp_dbf_view(out_buf
+ len
, "max_res_size", "0x%04x",
651 rec
->type
.ct
.type
.request
.max_res_size
);
652 total
= rec
->type
.ct
.payload_size
;
653 buffer
= rec
->type
.ct
.payload
;
654 buflen
= min(total
, ZFCP_DBF_CT_PAYLOAD
);
655 } else if (strncmp(rec
->tag
, "rctc", ZFCP_DBF_TAG_SIZE
) == 0) {
656 len
+= zfcp_dbf_view(out_buf
+ len
, "cmd_rsp_code", "0x%04x",
657 rec
->type
.ct
.type
.response
.cmd_rsp_code
);
658 len
+= zfcp_dbf_view(out_buf
+ len
, "revision", "0x%02x",
659 rec
->type
.ct
.type
.response
.revision
);
660 len
+= zfcp_dbf_view(out_buf
+ len
, "reason_code", "0x%02x",
661 rec
->type
.ct
.type
.response
.reason_code
);
663 zfcp_dbf_view(out_buf
+ len
, "reason_code_expl", "0x%02x",
664 rec
->type
.ct
.type
.response
.reason_code_expl
);
666 zfcp_dbf_view(out_buf
+ len
, "vendor_unique", "0x%02x",
667 rec
->type
.ct
.type
.response
.vendor_unique
);
668 total
= rec
->type
.ct
.payload_size
;
669 buffer
= rec
->type
.ct
.payload
;
670 buflen
= min(total
, ZFCP_DBF_CT_PAYLOAD
);
671 } else if (strncmp(rec
->tag
, "oels", ZFCP_DBF_TAG_SIZE
) == 0 ||
672 strncmp(rec
->tag
, "rels", ZFCP_DBF_TAG_SIZE
) == 0 ||
673 strncmp(rec
->tag
, "iels", ZFCP_DBF_TAG_SIZE
) == 0) {
674 len
+= zfcp_dbf_view(out_buf
+ len
, "ls_code", "0x%02x",
675 rec
->type
.els
.ls_code
);
676 total
= rec
->type
.els
.payload_size
;
677 buffer
= rec
->type
.els
.payload
;
678 buflen
= min(total
, ZFCP_DBF_ELS_PAYLOAD
);
681 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "payload",
682 buffer
, buflen
, 0, total
);
685 len
+= sprintf(out_buf
+ len
, "\n");
690 static struct debug_view zfcp_san_dbf_view
= {
693 &zfcp_dbf_view_header
,
694 &zfcp_san_dbf_view_format
,
700 _zfcp_scsi_dbf_event_common(const char *tag
, const char *tag2
, int level
,
701 struct zfcp_adapter
*adapter
,
702 struct scsi_cmnd
*scsi_cmnd
,
703 struct zfcp_fsf_req
*fsf_req
,
704 unsigned long old_req_id
)
706 struct zfcp_scsi_dbf_record
*rec
= &adapter
->scsi_dbf_buf
;
707 struct zfcp_dbf_dump
*dump
= (struct zfcp_dbf_dump
*)rec
;
709 struct fcp_rsp_iu
*fcp_rsp
;
710 char *fcp_rsp_info
= NULL
, *fcp_sns_info
= NULL
;
711 int offset
= 0, buflen
= 0;
713 spin_lock_irqsave(&adapter
->scsi_dbf_lock
, flags
);
715 memset(rec
, 0, sizeof(struct zfcp_scsi_dbf_record
));
717 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
718 strncpy(rec
->tag2
, tag2
, ZFCP_DBF_TAG_SIZE
);
719 if (scsi_cmnd
!= NULL
) {
720 if (scsi_cmnd
->device
) {
721 rec
->scsi_id
= scsi_cmnd
->device
->id
;
722 rec
->scsi_lun
= scsi_cmnd
->device
->lun
;
724 rec
->scsi_result
= scsi_cmnd
->result
;
725 rec
->scsi_cmnd
= (unsigned long)scsi_cmnd
;
726 rec
->scsi_serial
= scsi_cmnd
->serial_number
;
727 memcpy(rec
->scsi_opcode
, &scsi_cmnd
->cmnd
,
728 min((int)scsi_cmnd
->cmd_len
,
729 ZFCP_DBF_SCSI_OPCODE
));
730 rec
->scsi_retries
= scsi_cmnd
->retries
;
731 rec
->scsi_allowed
= scsi_cmnd
->allowed
;
733 if (fsf_req
!= NULL
) {
734 fcp_rsp
= (struct fcp_rsp_iu
*)
735 &(fsf_req
->qtcb
->bottom
.io
.fcp_rsp
);
737 zfcp_get_fcp_rsp_info_ptr(fcp_rsp
);
739 zfcp_get_fcp_sns_info_ptr(fcp_rsp
);
741 rec
->type
.fcp
.rsp_validity
=
742 fcp_rsp
->validity
.value
;
743 rec
->type
.fcp
.rsp_scsi_status
=
744 fcp_rsp
->scsi_status
;
745 rec
->type
.fcp
.rsp_resid
= fcp_rsp
->fcp_resid
;
746 if (fcp_rsp
->validity
.bits
.fcp_rsp_len_valid
)
747 rec
->type
.fcp
.rsp_code
=
749 if (fcp_rsp
->validity
.bits
.fcp_sns_len_valid
) {
750 buflen
= min((int)fcp_rsp
->fcp_sns_len
,
751 ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO
);
752 rec
->type
.fcp
.sns_info_len
= buflen
;
753 memcpy(rec
->type
.fcp
.sns_info
,
756 ZFCP_DBF_SCSI_FCP_SNS_INFO
));
757 offset
+= min(buflen
,
758 ZFCP_DBF_SCSI_FCP_SNS_INFO
);
761 rec
->fsf_reqid
= (unsigned long)fsf_req
;
762 rec
->fsf_seqno
= fsf_req
->seq_no
;
763 rec
->fsf_issued
= fsf_req
->issued
;
765 rec
->type
.old_fsf_reqid
= old_req_id
;
767 strncpy(dump
->tag
, "dump", ZFCP_DBF_TAG_SIZE
);
768 dump
->total_size
= buflen
;
769 dump
->offset
= offset
;
770 dump
->size
= min(buflen
- offset
,
772 zfcp_scsi_dbf_record
) -
773 (int)sizeof(struct zfcp_dbf_dump
));
774 memcpy(dump
->data
, fcp_sns_info
+ offset
, dump
->size
);
775 offset
+= dump
->size
;
777 debug_event(adapter
->scsi_dbf
, level
,
778 rec
, sizeof(struct zfcp_scsi_dbf_record
));
779 } while (offset
< buflen
);
780 spin_unlock_irqrestore(&adapter
->scsi_dbf_lock
, flags
);
784 zfcp_scsi_dbf_event_result(const char *tag
, int level
,
785 struct zfcp_adapter
*adapter
,
786 struct scsi_cmnd
*scsi_cmnd
,
787 struct zfcp_fsf_req
*fsf_req
)
789 _zfcp_scsi_dbf_event_common("rslt", tag
, level
,
790 adapter
, scsi_cmnd
, fsf_req
, 0);
794 zfcp_scsi_dbf_event_abort(const char *tag
, struct zfcp_adapter
*adapter
,
795 struct scsi_cmnd
*scsi_cmnd
,
796 struct zfcp_fsf_req
*new_fsf_req
,
797 unsigned long old_req_id
)
799 _zfcp_scsi_dbf_event_common("abrt", tag
, 1,
800 adapter
, scsi_cmnd
, new_fsf_req
, old_req_id
);
804 zfcp_scsi_dbf_event_devreset(const char *tag
, u8 flag
, struct zfcp_unit
*unit
,
805 struct scsi_cmnd
*scsi_cmnd
)
807 struct zfcp_adapter
*adapter
= unit
->port
->adapter
;
809 _zfcp_scsi_dbf_event_common(flag
== FCP_TARGET_RESET
? "trst" : "lrst",
810 tag
, 1, adapter
, scsi_cmnd
, NULL
, 0);
814 zfcp_scsi_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
815 char *out_buf
, const char *in_buf
)
817 struct zfcp_scsi_dbf_record
*rec
=
818 (struct zfcp_scsi_dbf_record
*)in_buf
;
821 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
824 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
825 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag2", rec
->tag2
);
826 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_id", "0x%08x", rec
->scsi_id
);
827 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_lun", "0x%08x",
829 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_result", "0x%08x",
831 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_cmnd", "0x%0Lx",
833 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_serial", "0x%016Lx",
835 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "scsi_opcode",
837 ZFCP_DBF_SCSI_OPCODE
,
838 0, ZFCP_DBF_SCSI_OPCODE
);
839 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_retries", "0x%02x",
841 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_allowed", "0x%02x",
843 if (strncmp(rec
->tag
, "abrt", ZFCP_DBF_TAG_SIZE
) == 0) {
844 len
+= zfcp_dbf_view(out_buf
+ len
, "old_fsf_reqid", "0x%0Lx",
845 rec
->type
.old_fsf_reqid
);
847 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
849 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
851 len
+= zfcp_dbf_stck(out_buf
+ len
, "fsf_issued", rec
->fsf_issued
);
852 if (strncmp(rec
->tag
, "rslt", ZFCP_DBF_TAG_SIZE
) == 0) {
854 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_validity", "0x%02x",
855 rec
->type
.fcp
.rsp_validity
);
857 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_scsi_status",
858 "0x%02x", rec
->type
.fcp
.rsp_scsi_status
);
860 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_resid", "0x%08x",
861 rec
->type
.fcp
.rsp_resid
);
863 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_code", "0x%08x",
864 rec
->type
.fcp
.rsp_code
);
866 zfcp_dbf_view(out_buf
+ len
, "fcp_sns_info_len", "0x%08x",
867 rec
->type
.fcp
.sns_info_len
);
869 zfcp_dbf_view_dump(out_buf
+ len
, "fcp_sns_info",
870 rec
->type
.fcp
.sns_info
,
871 min((int)rec
->type
.fcp
.sns_info_len
,
872 ZFCP_DBF_SCSI_FCP_SNS_INFO
), 0,
873 rec
->type
.fcp
.sns_info_len
);
876 len
+= sprintf(out_buf
+ len
, "\n");
881 static struct debug_view zfcp_scsi_dbf_view
= {
884 &zfcp_dbf_view_header
,
885 &zfcp_scsi_dbf_view_format
,
891 * zfcp_adapter_debug_register - registers debug feature for an adapter
892 * @adapter: pointer to adapter for which debug features should be registered
893 * return: -ENOMEM on error, 0 otherwise
895 int zfcp_adapter_debug_register(struct zfcp_adapter
*adapter
)
897 char dbf_name
[DEBUG_MAX_NAME_LEN
];
899 /* debug feature area which records recovery activity */
900 sprintf(dbf_name
, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter
));
901 adapter
->erp_dbf
= debug_register(dbf_name
, dbfsize
, 2,
902 sizeof(struct zfcp_erp_dbf_record
));
903 if (!adapter
->erp_dbf
)
905 debug_register_view(adapter
->erp_dbf
, &debug_hex_ascii_view
);
906 debug_set_level(adapter
->erp_dbf
, 3);
908 /* debug feature area which records HBA (FSF and QDIO) conditions */
909 sprintf(dbf_name
, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter
));
910 adapter
->hba_dbf
= debug_register(dbf_name
, dbfsize
, 1,
911 sizeof(struct zfcp_hba_dbf_record
));
912 if (!adapter
->hba_dbf
)
914 debug_register_view(adapter
->hba_dbf
, &debug_hex_ascii_view
);
915 debug_register_view(adapter
->hba_dbf
, &zfcp_hba_dbf_view
);
916 debug_set_level(adapter
->hba_dbf
, 3);
918 /* debug feature area which records SAN command failures and recovery */
919 sprintf(dbf_name
, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter
));
920 adapter
->san_dbf
= debug_register(dbf_name
, dbfsize
, 1,
921 sizeof(struct zfcp_san_dbf_record
));
922 if (!adapter
->san_dbf
)
924 debug_register_view(adapter
->san_dbf
, &debug_hex_ascii_view
);
925 debug_register_view(adapter
->san_dbf
, &zfcp_san_dbf_view
);
926 debug_set_level(adapter
->san_dbf
, 6);
928 /* debug feature area which records SCSI command failures and recovery */
929 sprintf(dbf_name
, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter
));
930 adapter
->scsi_dbf
= debug_register(dbf_name
, dbfsize
, 1,
931 sizeof(struct zfcp_scsi_dbf_record
));
932 if (!adapter
->scsi_dbf
)
934 debug_register_view(adapter
->scsi_dbf
, &debug_hex_ascii_view
);
935 debug_register_view(adapter
->scsi_dbf
, &zfcp_scsi_dbf_view
);
936 debug_set_level(adapter
->scsi_dbf
, 3);
941 zfcp_adapter_debug_unregister(adapter
);
947 * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
948 * @adapter: pointer to adapter for which debug features should be unregistered
950 void zfcp_adapter_debug_unregister(struct zfcp_adapter
*adapter
)
952 debug_unregister(adapter
->scsi_dbf
);
953 debug_unregister(adapter
->san_dbf
);
954 debug_unregister(adapter
->hba_dbf
);
955 debug_unregister(adapter
->erp_dbf
);
956 adapter
->scsi_dbf
= NULL
;
957 adapter
->san_dbf
= NULL
;
958 adapter
->hba_dbf
= NULL
;
959 adapter
->erp_dbf
= NULL
;