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 #include <asm/debug.h>
27 #include <linux/ctype.h>
30 static u32 dbfsize
= 4;
32 module_param(dbfsize
, uint
, 0400);
33 MODULE_PARM_DESC(dbfsize
,
34 "number of pages for each debug feature area (default 4)");
36 #define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER
39 zfcp_dbf_stck(char *out_buf
, const char *label
, unsigned long long stck
)
41 unsigned long long sec
;
42 struct timespec xtime
;
45 stck
-= 0x8126d60e46000000LL
- (0x3c26700LL
* 1000000 * 4096);
49 stck
-= (sec
* 1000000) << 12;
50 xtime
.tv_nsec
= ((stck
* 1000) >> 12);
51 len
+= sprintf(out_buf
+ len
, "%-24s%011lu:%06lu\n",
52 label
, xtime
.tv_sec
, xtime
.tv_nsec
);
57 static int zfcp_dbf_tag(char *out_buf
, const char *label
, const char *tag
)
61 len
+= sprintf(out_buf
+ len
, "%-24s", label
);
62 for (i
= 0; i
< ZFCP_DBF_TAG_SIZE
; i
++)
63 len
+= sprintf(out_buf
+ len
, "%c", tag
[i
]);
64 len
+= sprintf(out_buf
+ len
, "\n");
70 zfcp_dbf_view(char *out_buf
, const char *label
, const char *format
, ...)
75 len
+= sprintf(out_buf
+ len
, "%-24s", label
);
76 va_start(arg
, format
);
77 len
+= vsprintf(out_buf
+ len
, format
, arg
);
79 len
+= sprintf(out_buf
+ len
, "\n");
85 zfcp_dbf_view_dump(char *out_buf
, const char *label
,
86 char *buffer
, int buflen
, int offset
, int total_size
)
91 len
+= sprintf(out_buf
+ len
, "%-24s ", label
);
95 if ((offset
% 32) == 0)
96 len
+= sprintf(out_buf
+ len
, "\n%-24c ", ' ');
97 else if ((offset
% 4) == 0)
98 len
+= sprintf(out_buf
+ len
, " ");
100 len
+= sprintf(out_buf
+ len
, "%02x", *buffer
++);
101 if (++offset
== total_size
) {
102 len
+= sprintf(out_buf
+ len
, "\n");
108 len
+= sprintf(out_buf
+ len
, "\n");
114 zfcp_dbf_view_header(debug_info_t
* id
, struct debug_view
*view
, int area
,
115 debug_entry_t
* entry
, char *out_buf
)
117 struct zfcp_dbf_dump
*dump
= (struct zfcp_dbf_dump
*)DEBUG_DATA(entry
);
120 if (strncmp(dump
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) != 0) {
121 len
+= zfcp_dbf_stck(out_buf
+ len
, "timestamp",
123 len
+= zfcp_dbf_view(out_buf
+ len
, "cpu", "%02i",
124 entry
->id
.fields
.cpuid
);
126 len
+= zfcp_dbf_view_dump(out_buf
+ len
, NULL
,
129 dump
->offset
, dump
->total_size
);
130 if ((dump
->offset
+ dump
->size
) == dump
->total_size
)
131 len
+= sprintf(out_buf
+ len
, "\n");
137 inline void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req
*fsf_req
)
139 struct zfcp_adapter
*adapter
= fsf_req
->adapter
;
140 struct fsf_qtcb
*qtcb
= fsf_req
->qtcb
;
141 union fsf_prot_status_qual
*prot_status_qual
=
142 &qtcb
->prefix
.prot_status_qual
;
143 union fsf_status_qual
*fsf_status_qual
= &qtcb
->header
.fsf_status_qual
;
144 struct scsi_cmnd
*scsi_cmnd
;
145 struct zfcp_port
*port
;
146 struct zfcp_unit
*unit
;
147 struct zfcp_send_els
*send_els
;
148 struct zfcp_hba_dbf_record
*rec
= &adapter
->hba_dbf_buf
;
149 struct zfcp_hba_dbf_record_response
*response
= &rec
->type
.response
;
153 spin_lock_irqsave(&adapter
->hba_dbf_lock
, flags
);
154 memset(rec
, 0, sizeof(struct zfcp_hba_dbf_record
));
155 strncpy(rec
->tag
, "resp", ZFCP_DBF_TAG_SIZE
);
157 if ((qtcb
->prefix
.prot_status
!= FSF_PROT_GOOD
) &&
158 (qtcb
->prefix
.prot_status
!= FSF_PROT_FSF_STATUS_PRESENTED
)) {
159 strncpy(rec
->tag2
, "perr", ZFCP_DBF_TAG_SIZE
);
161 } else if (qtcb
->header
.fsf_status
!= FSF_GOOD
) {
162 strncpy(rec
->tag2
, "ferr", ZFCP_DBF_TAG_SIZE
);
164 } else if ((fsf_req
->fsf_command
== FSF_QTCB_OPEN_PORT_WITH_DID
) ||
165 (fsf_req
->fsf_command
== FSF_QTCB_OPEN_LUN
)) {
166 strncpy(rec
->tag2
, "open", ZFCP_DBF_TAG_SIZE
);
168 } else if ((prot_status_qual
->doubleword
[0] != 0) ||
169 (prot_status_qual
->doubleword
[1] != 0) ||
170 (fsf_status_qual
->doubleword
[0] != 0) ||
171 (fsf_status_qual
->doubleword
[1] != 0)) {
172 strncpy(rec
->tag2
, "qual", ZFCP_DBF_TAG_SIZE
);
175 strncpy(rec
->tag2
, "norm", ZFCP_DBF_TAG_SIZE
);
179 response
->fsf_command
= fsf_req
->fsf_command
;
180 response
->fsf_reqid
= (unsigned long)fsf_req
;
181 response
->fsf_seqno
= fsf_req
->seq_no
;
182 response
->fsf_issued
= fsf_req
->issued
;
183 response
->fsf_prot_status
= qtcb
->prefix
.prot_status
;
184 response
->fsf_status
= qtcb
->header
.fsf_status
;
185 memcpy(response
->fsf_prot_status_qual
,
186 prot_status_qual
, FSF_PROT_STATUS_QUAL_SIZE
);
187 memcpy(response
->fsf_status_qual
,
188 fsf_status_qual
, FSF_STATUS_QUALIFIER_SIZE
);
189 response
->fsf_req_status
= fsf_req
->status
;
190 response
->sbal_first
= fsf_req
->sbal_first
;
191 response
->sbal_curr
= fsf_req
->sbal_curr
;
192 response
->sbal_last
= fsf_req
->sbal_last
;
193 response
->pool
= fsf_req
->pool
!= NULL
;
194 response
->erp_action
= (unsigned long)fsf_req
->erp_action
;
196 switch (fsf_req
->fsf_command
) {
197 case FSF_QTCB_FCP_CMND
:
198 if (fsf_req
->status
& ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT
)
200 scsi_cmnd
= (struct scsi_cmnd
*)fsf_req
->data
;
201 if (scsi_cmnd
!= NULL
) {
202 response
->data
.send_fcp
.scsi_cmnd
203 = (unsigned long)scsi_cmnd
;
204 response
->data
.send_fcp
.scsi_serial
205 = scsi_cmnd
->serial_number
;
209 case FSF_QTCB_OPEN_PORT_WITH_DID
:
210 case FSF_QTCB_CLOSE_PORT
:
211 case FSF_QTCB_CLOSE_PHYSICAL_PORT
:
212 port
= (struct zfcp_port
*)fsf_req
->data
;
213 response
->data
.port
.wwpn
= port
->wwpn
;
214 response
->data
.port
.d_id
= port
->d_id
;
215 response
->data
.port
.port_handle
= qtcb
->header
.port_handle
;
218 case FSF_QTCB_OPEN_LUN
:
219 case FSF_QTCB_CLOSE_LUN
:
220 unit
= (struct zfcp_unit
*)fsf_req
->data
;
222 response
->data
.unit
.wwpn
= port
->wwpn
;
223 response
->data
.unit
.fcp_lun
= unit
->fcp_lun
;
224 response
->data
.unit
.port_handle
= qtcb
->header
.port_handle
;
225 response
->data
.unit
.lun_handle
= qtcb
->header
.lun_handle
;
228 case FSF_QTCB_SEND_ELS
:
229 send_els
= (struct zfcp_send_els
*)fsf_req
->data
;
230 response
->data
.send_els
.d_id
= qtcb
->bottom
.support
.d_id
;
231 response
->data
.send_els
.ls_code
= send_els
->ls_code
>> 24;
234 case FSF_QTCB_ABORT_FCP_CMND
:
235 case FSF_QTCB_SEND_GENERIC
:
236 case FSF_QTCB_EXCHANGE_CONFIG_DATA
:
237 case FSF_QTCB_EXCHANGE_PORT_DATA
:
238 case FSF_QTCB_DOWNLOAD_CONTROL_FILE
:
239 case FSF_QTCB_UPLOAD_CONTROL_FILE
:
243 debug_event(adapter
->hba_dbf
, level
,
244 rec
, sizeof(struct zfcp_hba_dbf_record
));
245 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
249 zfcp_hba_dbf_event_fsf_unsol(const char *tag
, struct zfcp_adapter
*adapter
,
250 struct fsf_status_read_buffer
*status_buffer
)
252 struct zfcp_hba_dbf_record
*rec
= &adapter
->hba_dbf_buf
;
255 spin_lock_irqsave(&adapter
->hba_dbf_lock
, flags
);
256 memset(rec
, 0, sizeof(struct zfcp_hba_dbf_record
));
257 strncpy(rec
->tag
, "stat", ZFCP_DBF_TAG_SIZE
);
258 strncpy(rec
->tag2
, tag
, ZFCP_DBF_TAG_SIZE
);
260 rec
->type
.status
.failed
= adapter
->status_read_failed
;
261 if (status_buffer
!= NULL
) {
262 rec
->type
.status
.status_type
= status_buffer
->status_type
;
263 rec
->type
.status
.status_subtype
= status_buffer
->status_subtype
;
264 memcpy(&rec
->type
.status
.queue_designator
,
265 &status_buffer
->queue_designator
,
266 sizeof(struct fsf_queue_designator
));
268 switch (status_buffer
->status_type
) {
269 case FSF_STATUS_READ_SENSE_DATA_AVAIL
:
270 rec
->type
.status
.payload_size
=
271 ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL
;
274 case FSF_STATUS_READ_BIT_ERROR_THRESHOLD
:
275 rec
->type
.status
.payload_size
=
276 ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD
;
279 case FSF_STATUS_READ_LINK_DOWN
:
280 switch (status_buffer
->status_subtype
) {
281 case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK
:
282 case FSF_STATUS_READ_SUB_FDISC_FAILED
:
283 rec
->type
.status
.payload_size
=
284 sizeof(struct fsf_link_down_info
);
288 case FSF_STATUS_READ_FEATURE_UPDATE_ALERT
:
289 rec
->type
.status
.payload_size
=
290 ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT
;
293 memcpy(&rec
->type
.status
.payload
,
294 &status_buffer
->payload
, rec
->type
.status
.payload_size
);
297 debug_event(adapter
->hba_dbf
, 2,
298 rec
, sizeof(struct zfcp_hba_dbf_record
));
299 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
303 zfcp_hba_dbf_event_qdio(struct zfcp_adapter
*adapter
, unsigned int status
,
304 unsigned int qdio_error
, unsigned int siga_error
,
305 int sbal_index
, int sbal_count
)
307 struct zfcp_hba_dbf_record
*rec
= &adapter
->hba_dbf_buf
;
310 spin_lock_irqsave(&adapter
->hba_dbf_lock
, flags
);
311 memset(rec
, 0, sizeof(struct zfcp_hba_dbf_record
));
312 strncpy(rec
->tag
, "qdio", ZFCP_DBF_TAG_SIZE
);
313 rec
->type
.qdio
.status
= status
;
314 rec
->type
.qdio
.qdio_error
= qdio_error
;
315 rec
->type
.qdio
.siga_error
= siga_error
;
316 rec
->type
.qdio
.sbal_index
= sbal_index
;
317 rec
->type
.qdio
.sbal_count
= sbal_count
;
318 debug_event(adapter
->hba_dbf
, 0,
319 rec
, sizeof(struct zfcp_hba_dbf_record
));
320 spin_unlock_irqrestore(&adapter
->hba_dbf_lock
, flags
);
324 zfcp_hba_dbf_view_response(char *out_buf
,
325 struct zfcp_hba_dbf_record_response
*rec
)
329 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_command", "0x%08x",
331 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
333 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
335 len
+= zfcp_dbf_stck(out_buf
+ len
, "fsf_issued", rec
->fsf_issued
);
336 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_prot_status", "0x%08x",
337 rec
->fsf_prot_status
);
338 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_status", "0x%08x",
340 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "fsf_prot_status_qual",
341 rec
->fsf_prot_status_qual
,
342 FSF_PROT_STATUS_QUAL_SIZE
,
343 0, FSF_PROT_STATUS_QUAL_SIZE
);
344 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "fsf_status_qual",
345 rec
->fsf_status_qual
,
346 FSF_STATUS_QUALIFIER_SIZE
,
347 0, FSF_STATUS_QUALIFIER_SIZE
);
348 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_req_status", "0x%08x",
349 rec
->fsf_req_status
);
350 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_first", "0x%02x",
352 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_curr", "0x%02x",
354 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_last", "0x%02x",
356 len
+= zfcp_dbf_view(out_buf
+ len
, "pool", "0x%02x", rec
->pool
);
358 switch (rec
->fsf_command
) {
359 case FSF_QTCB_FCP_CMND
:
360 if (rec
->fsf_req_status
& ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT
)
362 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_cmnd", "0x%0Lx",
363 rec
->data
.send_fcp
.scsi_cmnd
);
364 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_serial", "0x%016Lx",
365 rec
->data
.send_fcp
.scsi_serial
);
368 case FSF_QTCB_OPEN_PORT_WITH_DID
:
369 case FSF_QTCB_CLOSE_PORT
:
370 case FSF_QTCB_CLOSE_PHYSICAL_PORT
:
371 len
+= zfcp_dbf_view(out_buf
+ len
, "wwpn", "0x%016Lx",
372 rec
->data
.port
.wwpn
);
373 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x",
374 rec
->data
.port
.d_id
);
375 len
+= zfcp_dbf_view(out_buf
+ len
, "port_handle", "0x%08x",
376 rec
->data
.port
.port_handle
);
379 case FSF_QTCB_OPEN_LUN
:
380 case FSF_QTCB_CLOSE_LUN
:
381 len
+= zfcp_dbf_view(out_buf
+ len
, "wwpn", "0x%016Lx",
382 rec
->data
.unit
.wwpn
);
383 len
+= zfcp_dbf_view(out_buf
+ len
, "fcp_lun", "0x%016Lx",
384 rec
->data
.unit
.fcp_lun
);
385 len
+= zfcp_dbf_view(out_buf
+ len
, "port_handle", "0x%08x",
386 rec
->data
.unit
.port_handle
);
387 len
+= zfcp_dbf_view(out_buf
+ len
, "lun_handle", "0x%08x",
388 rec
->data
.unit
.lun_handle
);
391 case FSF_QTCB_SEND_ELS
:
392 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x",
393 rec
->data
.send_els
.d_id
);
394 len
+= zfcp_dbf_view(out_buf
+ len
, "ls_code", "0x%02x",
395 rec
->data
.send_els
.ls_code
);
398 case FSF_QTCB_ABORT_FCP_CMND
:
399 case FSF_QTCB_SEND_GENERIC
:
400 case FSF_QTCB_EXCHANGE_CONFIG_DATA
:
401 case FSF_QTCB_EXCHANGE_PORT_DATA
:
402 case FSF_QTCB_DOWNLOAD_CONTROL_FILE
:
403 case FSF_QTCB_UPLOAD_CONTROL_FILE
:
411 zfcp_hba_dbf_view_status(char *out_buf
, struct zfcp_hba_dbf_record_status
*rec
)
415 len
+= zfcp_dbf_view(out_buf
+ len
, "failed", "0x%02x", rec
->failed
);
416 len
+= zfcp_dbf_view(out_buf
+ len
, "status_type", "0x%08x",
418 len
+= zfcp_dbf_view(out_buf
+ len
, "status_subtype", "0x%08x",
419 rec
->status_subtype
);
420 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "queue_designator",
421 (char *)&rec
->queue_designator
,
422 sizeof(struct fsf_queue_designator
),
423 0, sizeof(struct fsf_queue_designator
));
424 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "payload",
425 (char *)&rec
->payload
,
426 rec
->payload_size
, 0, rec
->payload_size
);
432 zfcp_hba_dbf_view_qdio(char *out_buf
, struct zfcp_hba_dbf_record_qdio
*rec
)
436 len
+= zfcp_dbf_view(out_buf
+ len
, "status", "0x%08x", rec
->status
);
437 len
+= zfcp_dbf_view(out_buf
+ len
, "qdio_error", "0x%08x",
439 len
+= zfcp_dbf_view(out_buf
+ len
, "siga_error", "0x%08x",
441 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_index", "0x%02x",
443 len
+= zfcp_dbf_view(out_buf
+ len
, "sbal_count", "0x%02x",
450 zfcp_hba_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
451 char *out_buf
, const char *in_buf
)
453 struct zfcp_hba_dbf_record
*rec
= (struct zfcp_hba_dbf_record
*)in_buf
;
456 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
459 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
460 if (isalpha(rec
->tag2
[0]))
461 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag2", rec
->tag2
);
462 if (strncmp(rec
->tag
, "resp", ZFCP_DBF_TAG_SIZE
) == 0)
463 len
+= zfcp_hba_dbf_view_response(out_buf
+ len
,
464 &rec
->type
.response
);
465 else if (strncmp(rec
->tag
, "stat", ZFCP_DBF_TAG_SIZE
) == 0)
466 len
+= zfcp_hba_dbf_view_status(out_buf
+ len
,
468 else if (strncmp(rec
->tag
, "qdio", ZFCP_DBF_TAG_SIZE
) == 0)
469 len
+= zfcp_hba_dbf_view_qdio(out_buf
+ len
, &rec
->type
.qdio
);
471 len
+= sprintf(out_buf
+ len
, "\n");
476 struct debug_view zfcp_hba_dbf_view
= {
479 &zfcp_dbf_view_header
,
480 &zfcp_hba_dbf_view_format
,
486 _zfcp_san_dbf_event_common_ct(const char *tag
, struct zfcp_fsf_req
*fsf_req
,
487 u32 s_id
, u32 d_id
, void *buffer
, int buflen
)
489 struct zfcp_send_ct
*send_ct
= (struct zfcp_send_ct
*)fsf_req
->data
;
490 struct zfcp_port
*port
= send_ct
->port
;
491 struct zfcp_adapter
*adapter
= port
->adapter
;
492 struct ct_hdr
*header
= (struct ct_hdr
*)buffer
;
493 struct zfcp_san_dbf_record
*rec
= &adapter
->san_dbf_buf
;
494 struct zfcp_san_dbf_record_ct
*ct
= &rec
->type
.ct
;
497 spin_lock_irqsave(&adapter
->san_dbf_lock
, flags
);
498 memset(rec
, 0, sizeof(struct zfcp_san_dbf_record
));
499 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
500 rec
->fsf_reqid
= (unsigned long)fsf_req
;
501 rec
->fsf_seqno
= fsf_req
->seq_no
;
504 if (strncmp(tag
, "octc", ZFCP_DBF_TAG_SIZE
) == 0) {
505 ct
->type
.request
.cmd_req_code
= header
->cmd_rsp_code
;
506 ct
->type
.request
.revision
= header
->revision
;
507 ct
->type
.request
.gs_type
= header
->gs_type
;
508 ct
->type
.request
.gs_subtype
= header
->gs_subtype
;
509 ct
->type
.request
.options
= header
->options
;
510 ct
->type
.request
.max_res_size
= header
->max_res_size
;
511 } else if (strncmp(tag
, "rctc", ZFCP_DBF_TAG_SIZE
) == 0) {
512 ct
->type
.response
.cmd_rsp_code
= header
->cmd_rsp_code
;
513 ct
->type
.response
.revision
= header
->revision
;
514 ct
->type
.response
.reason_code
= header
->reason_code
;
515 ct
->type
.response
.reason_code_expl
= header
->reason_code_expl
;
516 ct
->type
.response
.vendor_unique
= header
->vendor_unique
;
519 min(buflen
- (int)sizeof(struct ct_hdr
), ZFCP_DBF_CT_PAYLOAD
);
520 memcpy(ct
->payload
, buffer
+ sizeof(struct ct_hdr
), ct
->payload_size
);
521 debug_event(adapter
->san_dbf
, 3,
522 rec
, sizeof(struct zfcp_san_dbf_record
));
523 spin_unlock_irqrestore(&adapter
->san_dbf_lock
, flags
);
526 inline void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req
*fsf_req
)
528 struct zfcp_send_ct
*ct
= (struct zfcp_send_ct
*)fsf_req
->data
;
529 struct zfcp_port
*port
= ct
->port
;
530 struct zfcp_adapter
*adapter
= port
->adapter
;
532 _zfcp_san_dbf_event_common_ct("octc", fsf_req
,
533 fc_host_port_id(adapter
->scsi_host
),
534 port
->d_id
, zfcp_sg_to_address(ct
->req
),
538 inline void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req
*fsf_req
)
540 struct zfcp_send_ct
*ct
= (struct zfcp_send_ct
*)fsf_req
->data
;
541 struct zfcp_port
*port
= ct
->port
;
542 struct zfcp_adapter
*adapter
= port
->adapter
;
544 _zfcp_san_dbf_event_common_ct("rctc", fsf_req
, port
->d_id
,
545 fc_host_port_id(adapter
->scsi_host
),
546 zfcp_sg_to_address(ct
->resp
),
551 _zfcp_san_dbf_event_common_els(const char *tag
, int level
,
552 struct zfcp_fsf_req
*fsf_req
, u32 s_id
,
553 u32 d_id
, u8 ls_code
, void *buffer
, int buflen
)
555 struct zfcp_adapter
*adapter
= fsf_req
->adapter
;
556 struct zfcp_san_dbf_record
*rec
= &adapter
->san_dbf_buf
;
557 struct zfcp_dbf_dump
*dump
= (struct zfcp_dbf_dump
*)rec
;
561 spin_lock_irqsave(&adapter
->san_dbf_lock
, flags
);
563 memset(rec
, 0, sizeof(struct zfcp_san_dbf_record
));
565 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
566 rec
->fsf_reqid
= (unsigned long)fsf_req
;
567 rec
->fsf_seqno
= fsf_req
->seq_no
;
570 rec
->type
.els
.ls_code
= ls_code
;
571 buflen
= min(buflen
, ZFCP_DBF_ELS_MAX_PAYLOAD
);
572 rec
->type
.els
.payload_size
= buflen
;
573 memcpy(rec
->type
.els
.payload
,
574 buffer
, min(buflen
, ZFCP_DBF_ELS_PAYLOAD
));
575 offset
+= min(buflen
, ZFCP_DBF_ELS_PAYLOAD
);
577 strncpy(dump
->tag
, "dump", ZFCP_DBF_TAG_SIZE
);
578 dump
->total_size
= buflen
;
579 dump
->offset
= offset
;
580 dump
->size
= min(buflen
- offset
,
581 (int)sizeof(struct zfcp_san_dbf_record
)
582 - (int)sizeof(struct zfcp_dbf_dump
));
583 memcpy(dump
->data
, buffer
+ offset
, dump
->size
);
584 offset
+= dump
->size
;
586 debug_event(adapter
->san_dbf
, level
,
587 rec
, sizeof(struct zfcp_san_dbf_record
));
588 } while (offset
< buflen
);
589 spin_unlock_irqrestore(&adapter
->san_dbf_lock
, flags
);
592 inline void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req
*fsf_req
)
594 struct zfcp_send_els
*els
= (struct zfcp_send_els
*)fsf_req
->data
;
596 _zfcp_san_dbf_event_common_els("oels", 2, fsf_req
,
597 fc_host_port_id(els
->adapter
->scsi_host
),
599 *(u8
*) zfcp_sg_to_address(els
->req
),
600 zfcp_sg_to_address(els
->req
),
604 inline void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req
*fsf_req
)
606 struct zfcp_send_els
*els
= (struct zfcp_send_els
*)fsf_req
->data
;
608 _zfcp_san_dbf_event_common_els("rels", 2, fsf_req
, els
->d_id
,
609 fc_host_port_id(els
->adapter
->scsi_host
),
610 *(u8
*) zfcp_sg_to_address(els
->req
),
611 zfcp_sg_to_address(els
->resp
),
615 inline void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req
*fsf_req
)
617 struct zfcp_adapter
*adapter
= fsf_req
->adapter
;
618 struct fsf_status_read_buffer
*status_buffer
=
619 (struct fsf_status_read_buffer
*)fsf_req
->data
;
620 int length
= (int)status_buffer
->length
-
621 (int)((void *)&status_buffer
->payload
- (void *)status_buffer
);
623 _zfcp_san_dbf_event_common_els("iels", 1, fsf_req
, status_buffer
->d_id
,
624 fc_host_port_id(adapter
->scsi_host
),
625 *(u8
*) status_buffer
->payload
,
626 (void *)status_buffer
->payload
, length
);
630 zfcp_san_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
631 char *out_buf
, const char *in_buf
)
633 struct zfcp_san_dbf_record
*rec
= (struct zfcp_san_dbf_record
*)in_buf
;
635 int buflen
= 0, total
= 0;
638 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
641 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
642 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
644 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
646 len
+= zfcp_dbf_view(out_buf
+ len
, "s_id", "0x%06x", rec
->s_id
);
647 len
+= zfcp_dbf_view(out_buf
+ len
, "d_id", "0x%06x", rec
->d_id
);
649 if (strncmp(rec
->tag
, "octc", ZFCP_DBF_TAG_SIZE
) == 0) {
650 len
+= zfcp_dbf_view(out_buf
+ len
, "cmd_req_code", "0x%04x",
651 rec
->type
.ct
.type
.request
.cmd_req_code
);
652 len
+= zfcp_dbf_view(out_buf
+ len
, "revision", "0x%02x",
653 rec
->type
.ct
.type
.request
.revision
);
654 len
+= zfcp_dbf_view(out_buf
+ len
, "gs_type", "0x%02x",
655 rec
->type
.ct
.type
.request
.gs_type
);
656 len
+= zfcp_dbf_view(out_buf
+ len
, "gs_subtype", "0x%02x",
657 rec
->type
.ct
.type
.request
.gs_subtype
);
658 len
+= zfcp_dbf_view(out_buf
+ len
, "options", "0x%02x",
659 rec
->type
.ct
.type
.request
.options
);
660 len
+= zfcp_dbf_view(out_buf
+ len
, "max_res_size", "0x%04x",
661 rec
->type
.ct
.type
.request
.max_res_size
);
662 total
= rec
->type
.ct
.payload_size
;
663 buffer
= rec
->type
.ct
.payload
;
664 buflen
= min(total
, ZFCP_DBF_CT_PAYLOAD
);
665 } else if (strncmp(rec
->tag
, "rctc", ZFCP_DBF_TAG_SIZE
) == 0) {
666 len
+= zfcp_dbf_view(out_buf
+ len
, "cmd_rsp_code", "0x%04x",
667 rec
->type
.ct
.type
.response
.cmd_rsp_code
);
668 len
+= zfcp_dbf_view(out_buf
+ len
, "revision", "0x%02x",
669 rec
->type
.ct
.type
.response
.revision
);
670 len
+= zfcp_dbf_view(out_buf
+ len
, "reason_code", "0x%02x",
671 rec
->type
.ct
.type
.response
.reason_code
);
673 zfcp_dbf_view(out_buf
+ len
, "reason_code_expl", "0x%02x",
674 rec
->type
.ct
.type
.response
.reason_code_expl
);
676 zfcp_dbf_view(out_buf
+ len
, "vendor_unique", "0x%02x",
677 rec
->type
.ct
.type
.response
.vendor_unique
);
678 total
= rec
->type
.ct
.payload_size
;
679 buffer
= rec
->type
.ct
.payload
;
680 buflen
= min(total
, ZFCP_DBF_CT_PAYLOAD
);
681 } else if (strncmp(rec
->tag
, "oels", ZFCP_DBF_TAG_SIZE
) == 0 ||
682 strncmp(rec
->tag
, "rels", ZFCP_DBF_TAG_SIZE
) == 0 ||
683 strncmp(rec
->tag
, "iels", ZFCP_DBF_TAG_SIZE
) == 0) {
684 len
+= zfcp_dbf_view(out_buf
+ len
, "ls_code", "0x%02x",
685 rec
->type
.els
.ls_code
);
686 total
= rec
->type
.els
.payload_size
;
687 buffer
= rec
->type
.els
.payload
;
688 buflen
= min(total
, ZFCP_DBF_ELS_PAYLOAD
);
691 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "payload",
692 buffer
, buflen
, 0, total
);
695 len
+= sprintf(out_buf
+ len
, "\n");
700 struct debug_view zfcp_san_dbf_view
= {
703 &zfcp_dbf_view_header
,
704 &zfcp_san_dbf_view_format
,
710 _zfcp_scsi_dbf_event_common(const char *tag
, const char *tag2
, int level
,
711 struct zfcp_adapter
*adapter
,
712 struct scsi_cmnd
*scsi_cmnd
,
713 struct zfcp_fsf_req
*fsf_req
,
714 struct zfcp_fsf_req
*old_fsf_req
)
716 struct zfcp_scsi_dbf_record
*rec
= &adapter
->scsi_dbf_buf
;
717 struct zfcp_dbf_dump
*dump
= (struct zfcp_dbf_dump
*)rec
;
719 struct fcp_rsp_iu
*fcp_rsp
;
720 char *fcp_rsp_info
= NULL
, *fcp_sns_info
= NULL
;
721 int offset
= 0, buflen
= 0;
723 spin_lock_irqsave(&adapter
->scsi_dbf_lock
, flags
);
725 memset(rec
, 0, sizeof(struct zfcp_scsi_dbf_record
));
727 strncpy(rec
->tag
, tag
, ZFCP_DBF_TAG_SIZE
);
728 strncpy(rec
->tag2
, tag2
, ZFCP_DBF_TAG_SIZE
);
729 if (scsi_cmnd
!= NULL
) {
730 if (scsi_cmnd
->device
) {
731 rec
->scsi_id
= scsi_cmnd
->device
->id
;
732 rec
->scsi_lun
= scsi_cmnd
->device
->lun
;
734 rec
->scsi_result
= scsi_cmnd
->result
;
735 rec
->scsi_cmnd
= (unsigned long)scsi_cmnd
;
736 rec
->scsi_serial
= scsi_cmnd
->serial_number
;
737 memcpy(rec
->scsi_opcode
, &scsi_cmnd
->cmnd
,
738 min((int)scsi_cmnd
->cmd_len
,
739 ZFCP_DBF_SCSI_OPCODE
));
740 rec
->scsi_retries
= scsi_cmnd
->retries
;
741 rec
->scsi_allowed
= scsi_cmnd
->allowed
;
743 if (fsf_req
!= NULL
) {
744 fcp_rsp
= (struct fcp_rsp_iu
*)
745 &(fsf_req
->qtcb
->bottom
.io
.fcp_rsp
);
747 zfcp_get_fcp_rsp_info_ptr(fcp_rsp
);
749 zfcp_get_fcp_sns_info_ptr(fcp_rsp
);
751 rec
->type
.fcp
.rsp_validity
=
752 fcp_rsp
->validity
.value
;
753 rec
->type
.fcp
.rsp_scsi_status
=
754 fcp_rsp
->scsi_status
;
755 rec
->type
.fcp
.rsp_resid
= fcp_rsp
->fcp_resid
;
756 if (fcp_rsp
->validity
.bits
.fcp_rsp_len_valid
)
757 rec
->type
.fcp
.rsp_code
=
759 if (fcp_rsp
->validity
.bits
.fcp_sns_len_valid
) {
760 buflen
= min((int)fcp_rsp
->fcp_sns_len
,
761 ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO
);
762 rec
->type
.fcp
.sns_info_len
= buflen
;
763 memcpy(rec
->type
.fcp
.sns_info
,
766 ZFCP_DBF_SCSI_FCP_SNS_INFO
));
767 offset
+= min(buflen
,
768 ZFCP_DBF_SCSI_FCP_SNS_INFO
);
771 rec
->fsf_reqid
= (unsigned long)fsf_req
;
772 rec
->fsf_seqno
= fsf_req
->seq_no
;
773 rec
->fsf_issued
= fsf_req
->issued
;
775 rec
->type
.old_fsf_reqid
=
776 (unsigned long) old_fsf_req
;
778 strncpy(dump
->tag
, "dump", ZFCP_DBF_TAG_SIZE
);
779 dump
->total_size
= buflen
;
780 dump
->offset
= offset
;
781 dump
->size
= min(buflen
- offset
,
783 zfcp_scsi_dbf_record
) -
784 (int)sizeof(struct zfcp_dbf_dump
));
785 memcpy(dump
->data
, fcp_sns_info
+ offset
, dump
->size
);
786 offset
+= dump
->size
;
788 debug_event(adapter
->scsi_dbf
, level
,
789 rec
, sizeof(struct zfcp_scsi_dbf_record
));
790 } while (offset
< buflen
);
791 spin_unlock_irqrestore(&adapter
->scsi_dbf_lock
, flags
);
795 zfcp_scsi_dbf_event_result(const char *tag
, int level
,
796 struct zfcp_adapter
*adapter
,
797 struct scsi_cmnd
*scsi_cmnd
,
798 struct zfcp_fsf_req
*fsf_req
)
800 _zfcp_scsi_dbf_event_common("rslt", tag
, level
,
801 adapter
, scsi_cmnd
, fsf_req
, NULL
);
805 zfcp_scsi_dbf_event_abort(const char *tag
, struct zfcp_adapter
*adapter
,
806 struct scsi_cmnd
*scsi_cmnd
,
807 struct zfcp_fsf_req
*new_fsf_req
,
808 struct zfcp_fsf_req
*old_fsf_req
)
810 _zfcp_scsi_dbf_event_common("abrt", tag
, 1,
811 adapter
, scsi_cmnd
, new_fsf_req
, old_fsf_req
);
815 zfcp_scsi_dbf_event_devreset(const char *tag
, u8 flag
, struct zfcp_unit
*unit
,
816 struct scsi_cmnd
*scsi_cmnd
)
818 struct zfcp_adapter
*adapter
= unit
->port
->adapter
;
820 _zfcp_scsi_dbf_event_common(flag
== FCP_TARGET_RESET
? "trst" : "lrst",
821 tag
, 1, adapter
, scsi_cmnd
, NULL
, NULL
);
825 zfcp_scsi_dbf_view_format(debug_info_t
* id
, struct debug_view
*view
,
826 char *out_buf
, const char *in_buf
)
828 struct zfcp_scsi_dbf_record
*rec
=
829 (struct zfcp_scsi_dbf_record
*)in_buf
;
832 if (strncmp(rec
->tag
, "dump", ZFCP_DBF_TAG_SIZE
) == 0)
835 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag", rec
->tag
);
836 len
+= zfcp_dbf_tag(out_buf
+ len
, "tag2", rec
->tag2
);
837 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_id", "0x%08x", rec
->scsi_id
);
838 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_lun", "0x%08x",
840 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_result", "0x%08x",
842 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_cmnd", "0x%0Lx",
844 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_serial", "0x%016Lx",
846 len
+= zfcp_dbf_view_dump(out_buf
+ len
, "scsi_opcode",
848 ZFCP_DBF_SCSI_OPCODE
,
849 0, ZFCP_DBF_SCSI_OPCODE
);
850 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_retries", "0x%02x",
852 len
+= zfcp_dbf_view(out_buf
+ len
, "scsi_allowed", "0x%02x",
854 if (strncmp(rec
->tag
, "abrt", ZFCP_DBF_TAG_SIZE
) == 0) {
855 len
+= zfcp_dbf_view(out_buf
+ len
, "old_fsf_reqid", "0x%0Lx",
856 rec
->type
.old_fsf_reqid
);
858 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_reqid", "0x%0Lx",
860 len
+= zfcp_dbf_view(out_buf
+ len
, "fsf_seqno", "0x%08x",
862 len
+= zfcp_dbf_stck(out_buf
+ len
, "fsf_issued", rec
->fsf_issued
);
863 if (strncmp(rec
->tag
, "rslt", ZFCP_DBF_TAG_SIZE
) == 0) {
865 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_validity", "0x%02x",
866 rec
->type
.fcp
.rsp_validity
);
868 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_scsi_status",
869 "0x%02x", rec
->type
.fcp
.rsp_scsi_status
);
871 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_resid", "0x%08x",
872 rec
->type
.fcp
.rsp_resid
);
874 zfcp_dbf_view(out_buf
+ len
, "fcp_rsp_code", "0x%08x",
875 rec
->type
.fcp
.rsp_code
);
877 zfcp_dbf_view(out_buf
+ len
, "fcp_sns_info_len", "0x%08x",
878 rec
->type
.fcp
.sns_info_len
);
880 zfcp_dbf_view_dump(out_buf
+ len
, "fcp_sns_info",
881 rec
->type
.fcp
.sns_info
,
882 min((int)rec
->type
.fcp
.sns_info_len
,
883 ZFCP_DBF_SCSI_FCP_SNS_INFO
), 0,
884 rec
->type
.fcp
.sns_info_len
);
887 len
+= sprintf(out_buf
+ len
, "\n");
892 struct debug_view zfcp_scsi_dbf_view
= {
895 &zfcp_dbf_view_header
,
896 &zfcp_scsi_dbf_view_format
,
902 * zfcp_adapter_debug_register - registers debug feature for an adapter
903 * @adapter: pointer to adapter for which debug features should be registered
904 * return: -ENOMEM on error, 0 otherwise
906 int zfcp_adapter_debug_register(struct zfcp_adapter
*adapter
)
908 char dbf_name
[DEBUG_MAX_NAME_LEN
];
910 /* debug feature area which records recovery activity */
911 sprintf(dbf_name
, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter
));
912 adapter
->erp_dbf
= debug_register(dbf_name
, dbfsize
, 2,
913 sizeof(struct zfcp_erp_dbf_record
));
914 if (!adapter
->erp_dbf
)
916 debug_register_view(adapter
->erp_dbf
, &debug_hex_ascii_view
);
917 debug_set_level(adapter
->erp_dbf
, 3);
919 /* debug feature area which records HBA (FSF and QDIO) conditions */
920 sprintf(dbf_name
, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter
));
921 adapter
->hba_dbf
= debug_register(dbf_name
, dbfsize
, 1,
922 sizeof(struct zfcp_hba_dbf_record
));
923 if (!adapter
->hba_dbf
)
925 debug_register_view(adapter
->hba_dbf
, &debug_hex_ascii_view
);
926 debug_register_view(adapter
->hba_dbf
, &zfcp_hba_dbf_view
);
927 debug_set_level(adapter
->hba_dbf
, 3);
929 /* debug feature area which records SAN command failures and recovery */
930 sprintf(dbf_name
, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter
));
931 adapter
->san_dbf
= debug_register(dbf_name
, dbfsize
, 1,
932 sizeof(struct zfcp_san_dbf_record
));
933 if (!adapter
->san_dbf
)
935 debug_register_view(adapter
->san_dbf
, &debug_hex_ascii_view
);
936 debug_register_view(adapter
->san_dbf
, &zfcp_san_dbf_view
);
937 debug_set_level(adapter
->san_dbf
, 6);
939 /* debug feature area which records SCSI command failures and recovery */
940 sprintf(dbf_name
, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter
));
941 adapter
->scsi_dbf
= debug_register(dbf_name
, dbfsize
, 1,
942 sizeof(struct zfcp_scsi_dbf_record
));
943 if (!adapter
->scsi_dbf
)
945 debug_register_view(adapter
->scsi_dbf
, &debug_hex_ascii_view
);
946 debug_register_view(adapter
->scsi_dbf
, &zfcp_scsi_dbf_view
);
947 debug_set_level(adapter
->scsi_dbf
, 3);
952 zfcp_adapter_debug_unregister(adapter
);
958 * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
959 * @adapter: pointer to adapter for which debug features should be unregistered
961 void zfcp_adapter_debug_unregister(struct zfcp_adapter
*adapter
)
963 debug_unregister(adapter
->scsi_dbf
);
964 debug_unregister(adapter
->san_dbf
);
965 debug_unregister(adapter
->hba_dbf
);
966 debug_unregister(adapter
->erp_dbf
);
967 adapter
->scsi_dbf
= NULL
;
968 adapter
->san_dbf
= NULL
;
969 adapter
->hba_dbf
= NULL
;
970 adapter
->erp_dbf
= NULL
;