[SCSI] zfcp: simplify zfcp_dbf_timestamp()
[safe/jmp/linux-2.6] / drivers / s390 / scsi / zfcp_dbf.c
1 /*
2  * This file is part of the zfcp device driver for
3  * FCP adapters for IBM System z9 and zSeries.
4  *
5  * (C) Copyright IBM Corp. 2002, 2006
6  *
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)
10  * any later version.
11  *
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.
16  *
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.
20  */
21
22 #include <linux/ctype.h>
23 #include <asm/debug.h>
24 #include "zfcp_ext.h"
25
26 static u32 dbfsize = 4;
27
28 module_param(dbfsize, uint, 0400);
29 MODULE_PARM_DESC(dbfsize,
30                  "number of pages for each debug feature area (default 4)");
31
32 #define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_OTHER
33
34 static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len,
35                              int level, char *from, int from_len)
36 {
37         int offset;
38         struct zfcp_dbf_dump *dump = to;
39         int room = to_len - sizeof(*dump);
40
41         for (offset = 0; offset < from_len; offset += dump->size) {
42                 memset(to, 0, to_len);
43                 strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
44                 dump->total_size = from_len;
45                 dump->offset = offset;
46                 dump->size = min(from_len - offset, room);
47                 memcpy(dump->data, from + offset, dump->size);
48                 debug_event(dbf, level, dump, dump->size);
49         }
50 }
51
52 /* FIXME: this duplicate this code in s390 debug feature */
53 static void zfcp_dbf_timestamp(unsigned long long stck, struct timespec *time)
54 {
55         unsigned long long sec;
56
57         stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
58         sec = stck >> 12;
59         do_div(sec, 1000000);
60         time->tv_sec = sec;
61         stck -= (sec * 1000000) << 12;
62         time->tv_nsec = ((stck * 1000) >> 12);
63 }
64
65 static int zfcp_dbf_tag(char *out_buf, const char *label, const char *tag)
66 {
67         int len = 0, i;
68
69         len += sprintf(out_buf + len, "%-24s", label);
70         for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++)
71                 len += sprintf(out_buf + len, "%c", tag[i]);
72         len += sprintf(out_buf + len, "\n");
73
74         return len;
75 }
76
77 static int
78 zfcp_dbf_view(char *out_buf, const char *label, const char *format, ...)
79 {
80         va_list arg;
81         int len = 0;
82
83         len += sprintf(out_buf + len, "%-24s", label);
84         va_start(arg, format);
85         len += vsprintf(out_buf + len, format, arg);
86         va_end(arg);
87         len += sprintf(out_buf + len, "\n");
88
89         return len;
90 }
91
92 static void zfcp_dbf_outs(char **buf, const char *s1, const char *s2)
93 {
94         *buf += sprintf(*buf, "%-24s%s\n", s1, s2);
95 }
96
97 static void zfcp_dbf_out(char **buf, const char *s, const char *format, ...)
98 {
99         va_list arg;
100
101         *buf += sprintf(*buf, "%-24s", s);
102         va_start(arg, format);
103         *buf += vsprintf(*buf, format, arg);
104         va_end(arg);
105         *buf += sprintf(*buf, "\n");
106 }
107
108 static int
109 zfcp_dbf_view_dump(char *out_buf, const char *label,
110                    char *buffer, int buflen, int offset, int total_size)
111 {
112         int len = 0;
113
114         if (offset == 0)
115                 len += sprintf(out_buf + len, "%-24s  ", label);
116
117         while (buflen--) {
118                 if (offset > 0) {
119                         if ((offset % 32) == 0)
120                                 len += sprintf(out_buf + len, "\n%-24c  ", ' ');
121                         else if ((offset % 4) == 0)
122                                 len += sprintf(out_buf + len, " ");
123                 }
124                 len += sprintf(out_buf + len, "%02x", *buffer++);
125                 if (++offset == total_size) {
126                         len += sprintf(out_buf + len, "\n");
127                         break;
128                 }
129         }
130
131         if (total_size == 0)
132                 len += sprintf(out_buf + len, "\n");
133
134         return len;
135 }
136
137 static int
138 zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area,
139                      debug_entry_t * entry, char *out_buf)
140 {
141         struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry);
142         int len = 0;
143         struct timespec t;
144
145         if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) {
146                 zfcp_dbf_timestamp(entry->id.stck, &t);
147                 len += zfcp_dbf_view(out_buf + len, "timestamp", "%011lu:%06lu",
148                                      t.tv_sec, t.tv_nsec);
149                 len += zfcp_dbf_view(out_buf + len, "cpu", "%02i",
150                                      entry->id.fields.cpuid);
151         } else {
152                 len += zfcp_dbf_view_dump(out_buf + len, NULL,
153                                           dump->data,
154                                           dump->size,
155                                           dump->offset, dump->total_size);
156                 if ((dump->offset + dump->size) == dump->total_size)
157                         len += sprintf(out_buf + len, "\n");
158         }
159
160         return len;
161 }
162
163 void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
164 {
165         struct zfcp_adapter *adapter = fsf_req->adapter;
166         struct fsf_qtcb *qtcb = fsf_req->qtcb;
167         union fsf_prot_status_qual *prot_status_qual =
168             &qtcb->prefix.prot_status_qual;
169         union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual;
170         struct scsi_cmnd *scsi_cmnd;
171         struct zfcp_port *port;
172         struct zfcp_unit *unit;
173         struct zfcp_send_els *send_els;
174         struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
175         struct zfcp_hba_dbf_record_response *response = &rec->type.response;
176         int level;
177         unsigned long flags;
178
179         spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
180         memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
181         strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE);
182
183         if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
184             (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
185                 strncpy(rec->tag2, "perr", ZFCP_DBF_TAG_SIZE);
186                 level = 1;
187         } else if (qtcb->header.fsf_status != FSF_GOOD) {
188                 strncpy(rec->tag2, "ferr", ZFCP_DBF_TAG_SIZE);
189                 level = 1;
190         } else if ((fsf_req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
191                    (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) {
192                 strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE);
193                 level = 4;
194         } else if (qtcb->header.log_length) {
195                 strncpy(rec->tag2, "qtcb", ZFCP_DBF_TAG_SIZE);
196                 level = 5;
197         } else {
198                 strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE);
199                 level = 6;
200         }
201
202         response->fsf_command = fsf_req->fsf_command;
203         response->fsf_reqid = (unsigned long)fsf_req;
204         response->fsf_seqno = fsf_req->seq_no;
205         response->fsf_issued = fsf_req->issued;
206         response->fsf_prot_status = qtcb->prefix.prot_status;
207         response->fsf_status = qtcb->header.fsf_status;
208         memcpy(response->fsf_prot_status_qual,
209                prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE);
210         memcpy(response->fsf_status_qual,
211                fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);
212         response->fsf_req_status = fsf_req->status;
213         response->sbal_first = fsf_req->sbal_first;
214         response->sbal_curr = fsf_req->sbal_curr;
215         response->sbal_last = fsf_req->sbal_last;
216         response->pool = fsf_req->pool != NULL;
217         response->erp_action = (unsigned long)fsf_req->erp_action;
218
219         switch (fsf_req->fsf_command) {
220         case FSF_QTCB_FCP_CMND:
221                 if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
222                         break;
223                 scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
224                 if (scsi_cmnd != NULL) {
225                         response->data.send_fcp.scsi_cmnd
226                             = (unsigned long)scsi_cmnd;
227                         response->data.send_fcp.scsi_serial
228                             = scsi_cmnd->serial_number;
229                 }
230                 break;
231
232         case FSF_QTCB_OPEN_PORT_WITH_DID:
233         case FSF_QTCB_CLOSE_PORT:
234         case FSF_QTCB_CLOSE_PHYSICAL_PORT:
235                 port = (struct zfcp_port *)fsf_req->data;
236                 response->data.port.wwpn = port->wwpn;
237                 response->data.port.d_id = port->d_id;
238                 response->data.port.port_handle = qtcb->header.port_handle;
239                 break;
240
241         case FSF_QTCB_OPEN_LUN:
242         case FSF_QTCB_CLOSE_LUN:
243                 unit = (struct zfcp_unit *)fsf_req->data;
244                 port = unit->port;
245                 response->data.unit.wwpn = port->wwpn;
246                 response->data.unit.fcp_lun = unit->fcp_lun;
247                 response->data.unit.port_handle = qtcb->header.port_handle;
248                 response->data.unit.lun_handle = qtcb->header.lun_handle;
249                 break;
250
251         case FSF_QTCB_SEND_ELS:
252                 send_els = (struct zfcp_send_els *)fsf_req->data;
253                 response->data.send_els.d_id = qtcb->bottom.support.d_id;
254                 response->data.send_els.ls_code = send_els->ls_code >> 24;
255                 break;
256
257         case FSF_QTCB_ABORT_FCP_CMND:
258         case FSF_QTCB_SEND_GENERIC:
259         case FSF_QTCB_EXCHANGE_CONFIG_DATA:
260         case FSF_QTCB_EXCHANGE_PORT_DATA:
261         case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
262         case FSF_QTCB_UPLOAD_CONTROL_FILE:
263                 break;
264         }
265
266         debug_event(adapter->hba_dbf, level,
267                     rec, sizeof(struct zfcp_hba_dbf_record));
268
269         /* have fcp channel microcode fixed to use as little as possible */
270         if (fsf_req->fsf_command != FSF_QTCB_FCP_CMND) {
271                 /* adjust length skipping trailing zeros */
272                 char *buf = (char *)qtcb + qtcb->header.log_start;
273                 int len = qtcb->header.log_length;
274                 for (; len && !buf[len - 1]; len--);
275                 zfcp_dbf_hexdump(adapter->hba_dbf, rec, sizeof(*rec), level,
276                                  buf, len);
277         }
278
279         spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
280 }
281
282 void
283 zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
284                              struct fsf_status_read_buffer *status_buffer)
285 {
286         struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
287         unsigned long flags;
288
289         spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
290         memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
291         strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE);
292         strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE);
293
294         rec->type.status.failed = adapter->status_read_failed;
295         if (status_buffer != NULL) {
296                 rec->type.status.status_type = status_buffer->status_type;
297                 rec->type.status.status_subtype = status_buffer->status_subtype;
298                 memcpy(&rec->type.status.queue_designator,
299                        &status_buffer->queue_designator,
300                        sizeof(struct fsf_queue_designator));
301
302                 switch (status_buffer->status_type) {
303                 case FSF_STATUS_READ_SENSE_DATA_AVAIL:
304                         rec->type.status.payload_size =
305                             ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL;
306                         break;
307
308                 case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
309                         rec->type.status.payload_size =
310                             ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD;
311                         break;
312
313                 case FSF_STATUS_READ_LINK_DOWN:
314                         switch (status_buffer->status_subtype) {
315                         case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
316                         case FSF_STATUS_READ_SUB_FDISC_FAILED:
317                                 rec->type.status.payload_size =
318                                         sizeof(struct fsf_link_down_info);
319                         }
320                         break;
321
322                 case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
323                         rec->type.status.payload_size =
324                             ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT;
325                         break;
326                 }
327                 memcpy(&rec->type.status.payload,
328                        &status_buffer->payload, rec->type.status.payload_size);
329         }
330
331         debug_event(adapter->hba_dbf, 2,
332                     rec, sizeof(struct zfcp_hba_dbf_record));
333         spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
334 }
335
336 void
337 zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status,
338                         unsigned int qdio_error, unsigned int siga_error,
339                         int sbal_index, int sbal_count)
340 {
341         struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
342         unsigned long flags;
343
344         spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
345         memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
346         strncpy(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE);
347         rec->type.qdio.status = status;
348         rec->type.qdio.qdio_error = qdio_error;
349         rec->type.qdio.siga_error = siga_error;
350         rec->type.qdio.sbal_index = sbal_index;
351         rec->type.qdio.sbal_count = sbal_count;
352         debug_event(adapter->hba_dbf, 0,
353                     rec, sizeof(struct zfcp_hba_dbf_record));
354         spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
355 }
356
357 static int
358 zfcp_hba_dbf_view_response(char *out_buf,
359                            struct zfcp_hba_dbf_record_response *rec)
360 {
361         int len = 0;
362         struct timespec t;
363
364         len += zfcp_dbf_view(out_buf + len, "fsf_command", "0x%08x",
365                              rec->fsf_command);
366         len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
367                              rec->fsf_reqid);
368         len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
369                              rec->fsf_seqno);
370         zfcp_dbf_timestamp(rec->fsf_issued, &t);
371         len += zfcp_dbf_view(out_buf + len, "fsf_issued", "%011lu:%06lu",
372                              t.tv_sec, t.tv_nsec);
373         len += zfcp_dbf_view(out_buf + len, "fsf_prot_status", "0x%08x",
374                              rec->fsf_prot_status);
375         len += zfcp_dbf_view(out_buf + len, "fsf_status", "0x%08x",
376                              rec->fsf_status);
377         len += zfcp_dbf_view_dump(out_buf + len, "fsf_prot_status_qual",
378                                   rec->fsf_prot_status_qual,
379                                   FSF_PROT_STATUS_QUAL_SIZE,
380                                   0, FSF_PROT_STATUS_QUAL_SIZE);
381         len += zfcp_dbf_view_dump(out_buf + len, "fsf_status_qual",
382                                   rec->fsf_status_qual,
383                                   FSF_STATUS_QUALIFIER_SIZE,
384                                   0, FSF_STATUS_QUALIFIER_SIZE);
385         len += zfcp_dbf_view(out_buf + len, "fsf_req_status", "0x%08x",
386                              rec->fsf_req_status);
387         len += zfcp_dbf_view(out_buf + len, "sbal_first", "0x%02x",
388                              rec->sbal_first);
389         len += zfcp_dbf_view(out_buf + len, "sbal_curr", "0x%02x",
390                              rec->sbal_curr);
391         len += zfcp_dbf_view(out_buf + len, "sbal_last", "0x%02x",
392                              rec->sbal_last);
393         len += zfcp_dbf_view(out_buf + len, "pool", "0x%02x", rec->pool);
394
395         switch (rec->fsf_command) {
396         case FSF_QTCB_FCP_CMND:
397                 if (rec->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
398                         break;
399                 len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx",
400                                      rec->data.send_fcp.scsi_cmnd);
401                 len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx",
402                                      rec->data.send_fcp.scsi_serial);
403                 break;
404
405         case FSF_QTCB_OPEN_PORT_WITH_DID:
406         case FSF_QTCB_CLOSE_PORT:
407         case FSF_QTCB_CLOSE_PHYSICAL_PORT:
408                 len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx",
409                                      rec->data.port.wwpn);
410                 len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x",
411                                      rec->data.port.d_id);
412                 len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x",
413                                      rec->data.port.port_handle);
414                 break;
415
416         case FSF_QTCB_OPEN_LUN:
417         case FSF_QTCB_CLOSE_LUN:
418                 len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx",
419                                      rec->data.unit.wwpn);
420                 len += zfcp_dbf_view(out_buf + len, "fcp_lun", "0x%016Lx",
421                                      rec->data.unit.fcp_lun);
422                 len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x",
423                                      rec->data.unit.port_handle);
424                 len += zfcp_dbf_view(out_buf + len, "lun_handle", "0x%08x",
425                                      rec->data.unit.lun_handle);
426                 break;
427
428         case FSF_QTCB_SEND_ELS:
429                 len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x",
430                                      rec->data.send_els.d_id);
431                 len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x",
432                                      rec->data.send_els.ls_code);
433                 break;
434
435         case FSF_QTCB_ABORT_FCP_CMND:
436         case FSF_QTCB_SEND_GENERIC:
437         case FSF_QTCB_EXCHANGE_CONFIG_DATA:
438         case FSF_QTCB_EXCHANGE_PORT_DATA:
439         case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
440         case FSF_QTCB_UPLOAD_CONTROL_FILE:
441                 break;
442         }
443
444         return len;
445 }
446
447 static int
448 zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec)
449 {
450         int len = 0;
451
452         len += zfcp_dbf_view(out_buf + len, "failed", "0x%02x", rec->failed);
453         len += zfcp_dbf_view(out_buf + len, "status_type", "0x%08x",
454                              rec->status_type);
455         len += zfcp_dbf_view(out_buf + len, "status_subtype", "0x%08x",
456                              rec->status_subtype);
457         len += zfcp_dbf_view_dump(out_buf + len, "queue_designator",
458                                   (char *)&rec->queue_designator,
459                                   sizeof(struct fsf_queue_designator),
460                                   0, sizeof(struct fsf_queue_designator));
461         len += zfcp_dbf_view_dump(out_buf + len, "payload",
462                                   (char *)&rec->payload,
463                                   rec->payload_size, 0, rec->payload_size);
464
465         return len;
466 }
467
468 static int
469 zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec)
470 {
471         int len = 0;
472
473         len += zfcp_dbf_view(out_buf + len, "status", "0x%08x", rec->status);
474         len += zfcp_dbf_view(out_buf + len, "qdio_error", "0x%08x",
475                              rec->qdio_error);
476         len += zfcp_dbf_view(out_buf + len, "siga_error", "0x%08x",
477                              rec->siga_error);
478         len += zfcp_dbf_view(out_buf + len, "sbal_index", "0x%02x",
479                              rec->sbal_index);
480         len += zfcp_dbf_view(out_buf + len, "sbal_count", "0x%02x",
481                              rec->sbal_count);
482
483         return len;
484 }
485
486 static int
487 zfcp_hba_dbf_view_format(debug_info_t * id, struct debug_view *view,
488                          char *out_buf, const char *in_buf)
489 {
490         struct zfcp_hba_dbf_record *rec = (struct zfcp_hba_dbf_record *)in_buf;
491         int len = 0;
492
493         if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
494                 return 0;
495
496         len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
497         if (isalpha(rec->tag2[0]))
498                 len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2);
499         if (strncmp(rec->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0)
500                 len += zfcp_hba_dbf_view_response(out_buf + len,
501                                                   &rec->type.response);
502         else if (strncmp(rec->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0)
503                 len += zfcp_hba_dbf_view_status(out_buf + len,
504                                                 &rec->type.status);
505         else if (strncmp(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)
506                 len += zfcp_hba_dbf_view_qdio(out_buf + len, &rec->type.qdio);
507
508         len += sprintf(out_buf + len, "\n");
509
510         return len;
511 }
512
513 static struct debug_view zfcp_hba_dbf_view = {
514         "structured",
515         NULL,
516         &zfcp_dbf_view_header,
517         &zfcp_hba_dbf_view_format,
518         NULL,
519         NULL
520 };
521
522 static const char *zfcp_rec_dbf_tags[] = {
523         [ZFCP_REC_DBF_ID_THREAD] = "thread",
524         [ZFCP_REC_DBF_ID_TARGET] = "target",
525         [ZFCP_REC_DBF_ID_TRIGGER] = "trigger",
526         [ZFCP_REC_DBF_ID_ACTION] = "action",
527 };
528
529 static const char *zfcp_rec_dbf_ids[] = {
530         [1]     = "new",
531         [2]     = "ready",
532         [3]     = "kill",
533         [4]     = "down sleep",
534         [5]     = "down wakeup",
535         [6]     = "down sleep ecd",
536         [7]     = "down wakeup ecd",
537         [8]     = "down sleep epd",
538         [9]     = "down wakeup epd",
539         [10]    = "online",
540         [11]    = "operational",
541         [12]    = "scsi slave destroy",
542         [13]    = "propagate failed adapter",
543         [14]    = "propagate failed port",
544         [15]    = "block adapter",
545         [16]    = "unblock adapter",
546         [17]    = "block port",
547         [18]    = "unblock port",
548         [19]    = "block unit",
549         [20]    = "unblock unit",
550         [21]    = "unit recovery failed",
551         [22]    = "port recovery failed",
552         [23]    = "adapter recovery failed",
553         [24]    = "qdio queues down",
554         [25]    = "p2p failed",
555         [26]    = "nameserver lookup failed",
556         [27]    = "nameserver port failed",
557         [28]    = "link up",
558         [29]    = "link down",
559         [30]    = "link up status read",
560         [31]    = "open port failed",
561         [32]    = "open port failed",
562         [33]    = "close port",
563         [34]    = "open unit failed",
564         [35]    = "exclusive open unit failed",
565         [36]    = "shared open unit failed",
566         [37]    = "link down",
567         [38]    = "link down status read no link",
568         [39]    = "link down status read fdisc login",
569         [40]    = "link down status read firmware update",
570         [41]    = "link down status read unknown reason",
571         [42]    = "link down ecd incomplete",
572         [43]    = "link down epd incomplete",
573         [44]    = "sysfs adapter recovery",
574         [45]    = "sysfs port recovery",
575         [46]    = "sysfs unit recovery",
576         [47]    = "port boxed abort",
577         [48]    = "unit boxed abort",
578         [49]    = "port boxed ct",
579         [50]    = "port boxed close physical",
580         [51]    = "port boxed open unit",
581         [52]    = "port boxed close unit",
582         [53]    = "port boxed fcp",
583         [54]    = "unit boxed fcp",
584         [55]    = "port access denied ct",
585         [56]    = "port access denied els",
586         [57]    = "port access denied open port",
587         [58]    = "port access denied close physical",
588         [59]    = "unit access denied open unit",
589         [60]    = "shared unit access denied open unit",
590         [61]    = "unit access denied fcp",
591         [62]    = "request timeout",
592         [63]    = "adisc link test reject or timeout",
593         [64]    = "adisc link test d_id changed",
594         [65]    = "adisc link test failed",
595         [66]    = "recovery out of memory",
596         [67]    = "adapter recovery repeated after state change",
597         [68]    = "port recovery repeated after state change",
598         [69]    = "unit recovery repeated after state change",
599         [70]    = "port recovery follow-up after successful adapter recovery",
600         [71]    = "adapter recovery escalation after failed adapter recovery",
601         [72]    = "port recovery follow-up after successful physical port "
602                   "recovery",
603         [73]    = "adapter recovery escalation after failed physical port "
604                   "recovery",
605         [74]    = "unit recovery follow-up after successful port recovery",
606         [75]    = "physical port recovery escalation after failed port "
607                   "recovery",
608         [76]    = "port recovery escalation after failed unit recovery",
609         [77]    = "recovery opening nameserver port",
610         [78]    = "duplicate request id",
611         [79]    = "link down",
612         [80]    = "exclusive read-only unit access unsupported",
613         [81]    = "shared read-write unit access unsupported",
614         [82]    = "incoming rscn",
615         [83]    = "incoming plogi",
616         [84]    = "incoming logo",
617         [85]    = "online",
618         [86]    = "offline",
619         [87]    = "ccw device gone",
620         [88]    = "ccw device no path",
621         [89]    = "ccw device operational",
622         [90]    = "ccw device shutdown",
623         [91]    = "sysfs port addition",
624         [92]    = "sysfs port removal",
625         [93]    = "sysfs adapter recovery",
626         [94]    = "sysfs unit addition",
627         [95]    = "sysfs unit removal",
628         [96]    = "sysfs port recovery",
629         [97]    = "sysfs unit recovery",
630         [98]    = "sequence number mismatch",
631         [99]    = "link up",
632         [100]   = "error state",
633         [101]   = "status read physical port closed",
634         [102]   = "link up status read",
635         [103]   = "too many failed status read buffers",
636         [104]   = "port handle not valid abort",
637         [105]   = "lun handle not valid abort",
638         [106]   = "port handle not valid ct",
639         [107]   = "port handle not valid close port",
640         [108]   = "port handle not valid close physical port",
641         [109]   = "port handle not valid open unit",
642         [110]   = "port handle not valid close unit",
643         [111]   = "lun handle not valid close unit",
644         [112]   = "port handle not valid fcp",
645         [113]   = "lun handle not valid fcp",
646         [114]   = "handle mismatch fcp",
647         [115]   = "lun not valid fcp",
648         [116]   = "qdio send failed",
649         [117]   = "version mismatch",
650         [118]   = "incompatible qtcb type",
651         [119]   = "unknown protocol status",
652         [120]   = "unknown fsf command",
653         [121]   = "no recommendation for status qualifier",
654         [122]   = "status read physical port closed in error",
655         [123]   = "fc service class not supported ct",
656         [124]   = "fc service class not supported els",
657         [125]   = "need newer zfcp",
658         [126]   = "need newer microcode",
659         [127]   = "arbitrated loop not supported",
660         [128]   = "unknown topology",
661         [129]   = "qtcb size mismatch",
662         [130]   = "unknown fsf status ecd",
663         [131]   = "fcp request too big",
664         [132]   = "fc service class not supported fcp",
665         [133]   = "data direction not valid fcp",
666         [134]   = "command length not valid fcp",
667         [135]   = "status read act update",
668         [136]   = "status read cfdc update",
669         [137]   = "hbaapi port open",
670         [138]   = "hbaapi unit open",
671         [139]   = "hbaapi unit shutdown",
672         [140]   = "qdio error",
673         [141]   = "scsi host reset",
674         [142]   = "dismissing fsf request for recovery action",
675         [143]   = "recovery action timed out",
676         [144]   = "recovery action gone",
677         [145]   = "recovery action being processed",
678         [146]   = "recovery action ready for next step",
679 };
680
681 static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view,
682                                     char *buf, const char *_rec)
683 {
684         struct zfcp_rec_dbf_record *r = (struct zfcp_rec_dbf_record *)_rec;
685         char *p = buf;
686
687         zfcp_dbf_outs(&p, "tag", zfcp_rec_dbf_tags[r->id]);
688         zfcp_dbf_outs(&p, "hint", zfcp_rec_dbf_ids[r->id2]);
689         zfcp_dbf_out(&p, "id", "%d", r->id2);
690         switch (r->id) {
691         case ZFCP_REC_DBF_ID_THREAD:
692                 zfcp_dbf_out(&p, "sema", "%d", r->u.thread.sema);
693                 zfcp_dbf_out(&p, "total", "%d", r->u.thread.total);
694                 zfcp_dbf_out(&p, "ready", "%d", r->u.thread.ready);
695                 zfcp_dbf_out(&p, "running", "%d", r->u.thread.running);
696                 break;
697         case ZFCP_REC_DBF_ID_TARGET:
698                 zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.target.ref);
699                 zfcp_dbf_out(&p, "status", "0x%08x", r->u.target.status);
700                 zfcp_dbf_out(&p, "erp_count", "%d", r->u.target.erp_count);
701                 zfcp_dbf_out(&p, "d_id", "0x%06x", r->u.target.d_id);
702                 zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.target.wwpn);
703                 zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.target.fcp_lun);
704                 break;
705         case ZFCP_REC_DBF_ID_TRIGGER:
706                 zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.trigger.ref);
707                 zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.trigger.action);
708                 zfcp_dbf_out(&p, "requested", "%d", r->u.trigger.want);
709                 zfcp_dbf_out(&p, "executed", "%d", r->u.trigger.need);
710                 zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.trigger.wwpn);
711                 zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.trigger.fcp_lun);
712                 zfcp_dbf_out(&p, "adapter_status", "0x%08x", r->u.trigger.as);
713                 zfcp_dbf_out(&p, "port_status", "0x%08x", r->u.trigger.ps);
714                 zfcp_dbf_out(&p, "unit_status", "0x%08x", r->u.trigger.us);
715                 break;
716         case ZFCP_REC_DBF_ID_ACTION:
717                 zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.action.action);
718                 zfcp_dbf_out(&p, "fsf_req", "0x%016Lx", r->u.action.fsf_req);
719                 zfcp_dbf_out(&p, "status", "0x%08Lx", r->u.action.status);
720                 zfcp_dbf_out(&p, "step", "0x%08Lx", r->u.action.step);
721                 break;
722         }
723         sprintf(p, "\n");
724         return (p - buf) + 1;
725 }
726
727 static struct debug_view zfcp_rec_dbf_view = {
728         "structured",
729         NULL,
730         &zfcp_dbf_view_header,
731         &zfcp_rec_dbf_view_format,
732         NULL,
733         NULL
734 };
735
736 /**
737  * zfcp_rec_dbf_event_thread - trace event related to recovery thread operation
738  * @id2: identifier for event
739  * @adapter: adapter
740  * @lock: non-zero value indicates that erp_lock has not yet been acquired
741  */
742 void zfcp_rec_dbf_event_thread(u8 id2, struct zfcp_adapter *adapter, int lock)
743 {
744         struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
745         unsigned long flags = 0;
746         struct list_head *entry;
747         unsigned ready = 0, running = 0, total;
748
749         if (lock)
750                 read_lock_irqsave(&adapter->erp_lock, flags);
751         list_for_each(entry, &adapter->erp_ready_head)
752                 ready++;
753         list_for_each(entry, &adapter->erp_running_head)
754                 running++;
755         total = adapter->erp_total_count;
756         if (lock)
757                 read_unlock_irqrestore(&adapter->erp_lock, flags);
758
759         spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
760         memset(r, 0, sizeof(*r));
761         r->id = ZFCP_REC_DBF_ID_THREAD;
762         r->id2 = id2;
763         r->u.thread.sema = atomic_read(&adapter->erp_ready_sem.count);
764         r->u.thread.total = total;
765         r->u.thread.ready = ready;
766         r->u.thread.running = running;
767         debug_event(adapter->rec_dbf, 5, r, sizeof(*r));
768         spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
769 }
770
771 static void zfcp_rec_dbf_event_target(u8 id2, u64 ref,
772                                       struct zfcp_adapter *adapter,
773                                       atomic_t *status, atomic_t *erp_count,
774                                       u64 wwpn, u32 d_id, u64 fcp_lun)
775 {
776         struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
777         unsigned long flags;
778
779         spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
780         memset(r, 0, sizeof(*r));
781         r->id = ZFCP_REC_DBF_ID_TARGET;
782         r->id2 = id2;
783         r->u.target.ref = ref;
784         r->u.target.status = atomic_read(status);
785         r->u.target.wwpn = wwpn;
786         r->u.target.d_id = d_id;
787         r->u.target.fcp_lun = fcp_lun;
788         r->u.target.erp_count = atomic_read(erp_count);
789         debug_event(adapter->rec_dbf, 3, r, sizeof(*r));
790         spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
791 }
792
793 /**
794  * zfcp_rec_dbf_event_adapter - trace event for adapter state change
795  * @id: identifier for trigger of state change
796  * @ref: additional reference (e.g. request)
797  * @adapter: adapter
798  */
799 void zfcp_rec_dbf_event_adapter(u8 id, u64 ref, struct zfcp_adapter *adapter)
800 {
801         zfcp_rec_dbf_event_target(id, ref, adapter, &adapter->status,
802                                   &adapter->erp_counter, 0, 0, 0);
803 }
804
805 /**
806  * zfcp_rec_dbf_event_port - trace event for port state change
807  * @id: identifier for trigger of state change
808  * @ref: additional reference (e.g. request)
809  * @port: port
810  */
811 void zfcp_rec_dbf_event_port(u8 id, u64 ref, struct zfcp_port *port)
812 {
813         struct zfcp_adapter *adapter = port->adapter;
814
815         zfcp_rec_dbf_event_target(id, ref, adapter, &port->status,
816                                   &port->erp_counter, port->wwpn, port->d_id,
817                                   0);
818 }
819
820 /**
821  * zfcp_rec_dbf_event_unit - trace event for unit state change
822  * @id: identifier for trigger of state change
823  * @ref: additional reference (e.g. request)
824  * @unit: unit
825  */
826 void zfcp_rec_dbf_event_unit(u8 id, u64 ref, struct zfcp_unit *unit)
827 {
828         struct zfcp_port *port = unit->port;
829         struct zfcp_adapter *adapter = port->adapter;
830
831         zfcp_rec_dbf_event_target(id, ref, adapter, &unit->status,
832                                   &unit->erp_counter, port->wwpn, port->d_id,
833                                   unit->fcp_lun);
834 }
835
836 /**
837  * zfcp_rec_dbf_event_trigger - trace event for triggered error recovery
838  * @id2: identifier for error recovery trigger
839  * @ref: additional reference (e.g. request)
840  * @want: originally requested error recovery action
841  * @need: error recovery action actually initiated
842  * @action: address of error recovery action struct
843  * @adapter: adapter
844  * @port: port
845  * @unit: unit
846  */
847 void zfcp_rec_dbf_event_trigger(u8 id2, u64 ref, u8 want, u8 need, u64 action,
848                                 struct zfcp_adapter *adapter,
849                                 struct zfcp_port *port, struct zfcp_unit *unit)
850 {
851         struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
852         unsigned long flags;
853
854         spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
855         memset(r, 0, sizeof(*r));
856         r->id = ZFCP_REC_DBF_ID_TRIGGER;
857         r->id2 = id2;
858         r->u.trigger.ref = ref;
859         r->u.trigger.want = want;
860         r->u.trigger.need = need;
861         r->u.trigger.action = action;
862         r->u.trigger.as = atomic_read(&adapter->status);
863         if (port) {
864                 r->u.trigger.ps = atomic_read(&port->status);
865                 r->u.trigger.wwpn = port->wwpn;
866         }
867         if (unit) {
868                 r->u.trigger.us = atomic_read(&unit->status);
869                 r->u.trigger.fcp_lun = unit->fcp_lun;
870         }
871         debug_event(adapter->rec_dbf, action ? 1 : 4, r, sizeof(*r));
872         spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
873 }
874
875 /**
876  * zfcp_rec_dbf_event_action - trace event showing progress of recovery action
877  * @id2: identifier
878  * @erp_action: error recovery action struct pointer
879  */
880 void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action)
881 {
882         struct zfcp_adapter *adapter = erp_action->adapter;
883         struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
884         unsigned long flags;
885
886         spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
887         memset(r, 0, sizeof(*r));
888         r->id = ZFCP_REC_DBF_ID_ACTION;
889         r->id2 = id2;
890         r->u.action.action = (u64)erp_action;
891         r->u.action.status = erp_action->status;
892         r->u.action.step = erp_action->step;
893         r->u.action.fsf_req = (u64)erp_action->fsf_req;
894         debug_event(adapter->rec_dbf, 4, r, sizeof(*r));
895         spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
896 }
897
898 static void
899 _zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req,
900                               u32 s_id, u32 d_id, void *buffer, int buflen)
901 {
902         struct zfcp_send_ct *send_ct = (struct zfcp_send_ct *)fsf_req->data;
903         struct zfcp_port *port = send_ct->port;
904         struct zfcp_adapter *adapter = port->adapter;
905         struct ct_hdr *header = (struct ct_hdr *)buffer;
906         struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;
907         struct zfcp_san_dbf_record_ct *ct = &rec->type.ct;
908         unsigned long flags;
909
910         spin_lock_irqsave(&adapter->san_dbf_lock, flags);
911         memset(rec, 0, sizeof(struct zfcp_san_dbf_record));
912         strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
913         rec->fsf_reqid = (unsigned long)fsf_req;
914         rec->fsf_seqno = fsf_req->seq_no;
915         rec->s_id = s_id;
916         rec->d_id = d_id;
917         if (strncmp(tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
918                 ct->type.request.cmd_req_code = header->cmd_rsp_code;
919                 ct->type.request.revision = header->revision;
920                 ct->type.request.gs_type = header->gs_type;
921                 ct->type.request.gs_subtype = header->gs_subtype;
922                 ct->type.request.options = header->options;
923                 ct->type.request.max_res_size = header->max_res_size;
924         } else if (strncmp(tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
925                 ct->type.response.cmd_rsp_code = header->cmd_rsp_code;
926                 ct->type.response.revision = header->revision;
927                 ct->type.response.reason_code = header->reason_code;
928                 ct->type.response.reason_code_expl = header->reason_code_expl;
929                 ct->type.response.vendor_unique = header->vendor_unique;
930         }
931         ct->payload_size =
932             min(buflen - (int)sizeof(struct ct_hdr), ZFCP_DBF_CT_PAYLOAD);
933         memcpy(ct->payload, buffer + sizeof(struct ct_hdr), ct->payload_size);
934         debug_event(adapter->san_dbf, 3,
935                     rec, sizeof(struct zfcp_san_dbf_record));
936         spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
937 }
938
939 void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
940 {
941         struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
942         struct zfcp_port *port = ct->port;
943         struct zfcp_adapter *adapter = port->adapter;
944
945         _zfcp_san_dbf_event_common_ct("octc", fsf_req,
946                                       fc_host_port_id(adapter->scsi_host),
947                                       port->d_id, zfcp_sg_to_address(ct->req),
948                                       ct->req->length);
949 }
950
951 void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
952 {
953         struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
954         struct zfcp_port *port = ct->port;
955         struct zfcp_adapter *adapter = port->adapter;
956
957         _zfcp_san_dbf_event_common_ct("rctc", fsf_req, port->d_id,
958                                       fc_host_port_id(adapter->scsi_host),
959                                       zfcp_sg_to_address(ct->resp),
960                                       ct->resp->length);
961 }
962
963 static void
964 _zfcp_san_dbf_event_common_els(const char *tag, int level,
965                                struct zfcp_fsf_req *fsf_req, u32 s_id,
966                                u32 d_id, u8 ls_code, void *buffer, int buflen)
967 {
968         struct zfcp_adapter *adapter = fsf_req->adapter;
969         struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;
970         unsigned long flags;
971
972         spin_lock_irqsave(&adapter->san_dbf_lock, flags);
973         memset(rec, 0, sizeof(struct zfcp_san_dbf_record));
974         strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
975         rec->fsf_reqid = (unsigned long)fsf_req;
976         rec->fsf_seqno = fsf_req->seq_no;
977         rec->s_id = s_id;
978         rec->d_id = d_id;
979         rec->type.els.ls_code = ls_code;
980         debug_event(adapter->san_dbf, level, rec, sizeof(*rec));
981         zfcp_dbf_hexdump(adapter->san_dbf, rec, sizeof(*rec), level,
982                          buffer, min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD));
983         spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
984 }
985
986 void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
987 {
988         struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
989
990         _zfcp_san_dbf_event_common_els("oels", 2, fsf_req,
991                                        fc_host_port_id(els->adapter->scsi_host),
992                                        els->d_id,
993                                        *(u8 *) zfcp_sg_to_address(els->req),
994                                        zfcp_sg_to_address(els->req),
995                                        els->req->length);
996 }
997
998 void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
999 {
1000         struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
1001
1002         _zfcp_san_dbf_event_common_els("rels", 2, fsf_req, els->d_id,
1003                                        fc_host_port_id(els->adapter->scsi_host),
1004                                        *(u8 *) zfcp_sg_to_address(els->req),
1005                                        zfcp_sg_to_address(els->resp),
1006                                        els->resp->length);
1007 }
1008
1009 void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)
1010 {
1011         struct zfcp_adapter *adapter = fsf_req->adapter;
1012         struct fsf_status_read_buffer *status_buffer =
1013             (struct fsf_status_read_buffer *)fsf_req->data;
1014         int length = (int)status_buffer->length -
1015             (int)((void *)&status_buffer->payload - (void *)status_buffer);
1016
1017         _zfcp_san_dbf_event_common_els("iels", 1, fsf_req, status_buffer->d_id,
1018                                        fc_host_port_id(adapter->scsi_host),
1019                                        *(u8 *) status_buffer->payload,
1020                                        (void *)status_buffer->payload, length);
1021 }
1022
1023 static int
1024 zfcp_san_dbf_view_format(debug_info_t * id, struct debug_view *view,
1025                          char *out_buf, const char *in_buf)
1026 {
1027         struct zfcp_san_dbf_record *rec = (struct zfcp_san_dbf_record *)in_buf;
1028         char *buffer = NULL;
1029         int buflen = 0, total = 0;
1030         int len = 0;
1031
1032         if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
1033                 return 0;
1034
1035         len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
1036         len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
1037                              rec->fsf_reqid);
1038         len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
1039                              rec->fsf_seqno);
1040         len += zfcp_dbf_view(out_buf + len, "s_id", "0x%06x", rec->s_id);
1041         len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", rec->d_id);
1042
1043         if (strncmp(rec->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
1044                 len += zfcp_dbf_view(out_buf + len, "cmd_req_code", "0x%04x",
1045                                      rec->type.ct.type.request.cmd_req_code);
1046                 len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x",
1047                                      rec->type.ct.type.request.revision);
1048                 len += zfcp_dbf_view(out_buf + len, "gs_type", "0x%02x",
1049                                      rec->type.ct.type.request.gs_type);
1050                 len += zfcp_dbf_view(out_buf + len, "gs_subtype", "0x%02x",
1051                                      rec->type.ct.type.request.gs_subtype);
1052                 len += zfcp_dbf_view(out_buf + len, "options", "0x%02x",
1053                                      rec->type.ct.type.request.options);
1054                 len += zfcp_dbf_view(out_buf + len, "max_res_size", "0x%04x",
1055                                      rec->type.ct.type.request.max_res_size);
1056                 total = rec->type.ct.payload_size;
1057                 buffer = rec->type.ct.payload;
1058                 buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
1059         } else if (strncmp(rec->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
1060                 len += zfcp_dbf_view(out_buf + len, "cmd_rsp_code", "0x%04x",
1061                                      rec->type.ct.type.response.cmd_rsp_code);
1062                 len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x",
1063                                      rec->type.ct.type.response.revision);
1064                 len += zfcp_dbf_view(out_buf + len, "reason_code", "0x%02x",
1065                                      rec->type.ct.type.response.reason_code);
1066                 len +=
1067                     zfcp_dbf_view(out_buf + len, "reason_code_expl", "0x%02x",
1068                                   rec->type.ct.type.response.reason_code_expl);
1069                 len +=
1070                     zfcp_dbf_view(out_buf + len, "vendor_unique", "0x%02x",
1071                                   rec->type.ct.type.response.vendor_unique);
1072                 total = rec->type.ct.payload_size;
1073                 buffer = rec->type.ct.payload;
1074                 buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
1075         } else if (strncmp(rec->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
1076                    strncmp(rec->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
1077                    strncmp(rec->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
1078                 len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x",
1079                                      rec->type.els.ls_code);
1080                 total = rec->type.els.payload_size;
1081                 buffer = rec->type.els.payload;
1082                 buflen = min(total, ZFCP_DBF_ELS_PAYLOAD);
1083         }
1084
1085         len += zfcp_dbf_view_dump(out_buf + len, "payload",
1086                                   buffer, buflen, 0, total);
1087
1088         if (buflen == total)
1089                 len += sprintf(out_buf + len, "\n");
1090
1091         return len;
1092 }
1093
1094 static struct debug_view zfcp_san_dbf_view = {
1095         "structured",
1096         NULL,
1097         &zfcp_dbf_view_header,
1098         &zfcp_san_dbf_view_format,
1099         NULL,
1100         NULL
1101 };
1102
1103 static void
1104 _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
1105                             struct zfcp_adapter *adapter,
1106                             struct scsi_cmnd *scsi_cmnd,
1107                             struct zfcp_fsf_req *fsf_req,
1108                             unsigned long old_req_id)
1109 {
1110         struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf;
1111         struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
1112         unsigned long flags;
1113         struct fcp_rsp_iu *fcp_rsp;
1114         char *fcp_rsp_info = NULL, *fcp_sns_info = NULL;
1115         int offset = 0, buflen = 0;
1116
1117         spin_lock_irqsave(&adapter->scsi_dbf_lock, flags);
1118         do {
1119                 memset(rec, 0, sizeof(struct zfcp_scsi_dbf_record));
1120                 if (offset == 0) {
1121                         strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
1122                         strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
1123                         if (scsi_cmnd != NULL) {
1124                                 if (scsi_cmnd->device) {
1125                                         rec->scsi_id = scsi_cmnd->device->id;
1126                                         rec->scsi_lun = scsi_cmnd->device->lun;
1127                                 }
1128                                 rec->scsi_result = scsi_cmnd->result;
1129                                 rec->scsi_cmnd = (unsigned long)scsi_cmnd;
1130                                 rec->scsi_serial = scsi_cmnd->serial_number;
1131                                 memcpy(rec->scsi_opcode, &scsi_cmnd->cmnd,
1132                                         min((int)scsi_cmnd->cmd_len,
1133                                                 ZFCP_DBF_SCSI_OPCODE));
1134                                 rec->scsi_retries = scsi_cmnd->retries;
1135                                 rec->scsi_allowed = scsi_cmnd->allowed;
1136                         }
1137                         if (fsf_req != NULL) {
1138                                 fcp_rsp = (struct fcp_rsp_iu *)
1139                                     &(fsf_req->qtcb->bottom.io.fcp_rsp);
1140                                 fcp_rsp_info =
1141                                     zfcp_get_fcp_rsp_info_ptr(fcp_rsp);
1142                                 fcp_sns_info =
1143                                     zfcp_get_fcp_sns_info_ptr(fcp_rsp);
1144
1145                                 rec->type.fcp.rsp_validity =
1146                                     fcp_rsp->validity.value;
1147                                 rec->type.fcp.rsp_scsi_status =
1148                                     fcp_rsp->scsi_status;
1149                                 rec->type.fcp.rsp_resid = fcp_rsp->fcp_resid;
1150                                 if (fcp_rsp->validity.bits.fcp_rsp_len_valid)
1151                                         rec->type.fcp.rsp_code =
1152                                             *(fcp_rsp_info + 3);
1153                                 if (fcp_rsp->validity.bits.fcp_sns_len_valid) {
1154                                         buflen = min((int)fcp_rsp->fcp_sns_len,
1155                                                      ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
1156                                         rec->type.fcp.sns_info_len = buflen;
1157                                         memcpy(rec->type.fcp.sns_info,
1158                                                fcp_sns_info,
1159                                                min(buflen,
1160                                                    ZFCP_DBF_SCSI_FCP_SNS_INFO));
1161                                         offset += min(buflen,
1162                                                       ZFCP_DBF_SCSI_FCP_SNS_INFO);
1163                                 }
1164
1165                                 rec->fsf_reqid = (unsigned long)fsf_req;
1166                                 rec->fsf_seqno = fsf_req->seq_no;
1167                                 rec->fsf_issued = fsf_req->issued;
1168                         }
1169                         rec->type.old_fsf_reqid = old_req_id;
1170                 } else {
1171                         strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
1172                         dump->total_size = buflen;
1173                         dump->offset = offset;
1174                         dump->size = min(buflen - offset,
1175                                          (int)sizeof(struct
1176                                                      zfcp_scsi_dbf_record) -
1177                                          (int)sizeof(struct zfcp_dbf_dump));
1178                         memcpy(dump->data, fcp_sns_info + offset, dump->size);
1179                         offset += dump->size;
1180                 }
1181                 debug_event(adapter->scsi_dbf, level,
1182                             rec, sizeof(struct zfcp_scsi_dbf_record));
1183         } while (offset < buflen);
1184         spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags);
1185 }
1186
1187 void
1188 zfcp_scsi_dbf_event_result(const char *tag, int level,
1189                            struct zfcp_adapter *adapter,
1190                            struct scsi_cmnd *scsi_cmnd,
1191                            struct zfcp_fsf_req *fsf_req)
1192 {
1193         _zfcp_scsi_dbf_event_common("rslt", tag, level,
1194                         adapter, scsi_cmnd, fsf_req, 0);
1195 }
1196
1197 void
1198 zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
1199                           struct scsi_cmnd *scsi_cmnd,
1200                           struct zfcp_fsf_req *new_fsf_req,
1201                           unsigned long old_req_id)
1202 {
1203         _zfcp_scsi_dbf_event_common("abrt", tag, 1,
1204                         adapter, scsi_cmnd, new_fsf_req, old_req_id);
1205 }
1206
1207 void
1208 zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
1209                              struct scsi_cmnd *scsi_cmnd)
1210 {
1211         struct zfcp_adapter *adapter = unit->port->adapter;
1212
1213         _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst",
1214                         tag, 1, adapter, scsi_cmnd, NULL, 0);
1215 }
1216
1217 static int
1218 zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view,
1219                           char *out_buf, const char *in_buf)
1220 {
1221         struct zfcp_scsi_dbf_record *rec =
1222             (struct zfcp_scsi_dbf_record *)in_buf;
1223         int len = 0;
1224         struct timespec t;
1225
1226         if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
1227                 return 0;
1228
1229         len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
1230         len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2);
1231         len += zfcp_dbf_view(out_buf + len, "scsi_id", "0x%08x", rec->scsi_id);
1232         len += zfcp_dbf_view(out_buf + len, "scsi_lun", "0x%08x",
1233                              rec->scsi_lun);
1234         len += zfcp_dbf_view(out_buf + len, "scsi_result", "0x%08x",
1235                              rec->scsi_result);
1236         len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx",
1237                              rec->scsi_cmnd);
1238         len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx",
1239                              rec->scsi_serial);
1240         len += zfcp_dbf_view_dump(out_buf + len, "scsi_opcode",
1241                                   rec->scsi_opcode,
1242                                   ZFCP_DBF_SCSI_OPCODE,
1243                                   0, ZFCP_DBF_SCSI_OPCODE);
1244         len += zfcp_dbf_view(out_buf + len, "scsi_retries", "0x%02x",
1245                              rec->scsi_retries);
1246         len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x",
1247                              rec->scsi_allowed);
1248         if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) {
1249                 len += zfcp_dbf_view(out_buf + len, "old_fsf_reqid", "0x%0Lx",
1250                                      rec->type.old_fsf_reqid);
1251         }
1252         len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
1253                              rec->fsf_reqid);
1254         len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
1255                              rec->fsf_seqno);
1256         zfcp_dbf_timestamp(rec->fsf_issued, &t);
1257         len += zfcp_dbf_view(out_buf + len, "fsf_issued", "%011lu:%06lu",
1258                              t.tv_sec, t.tv_nsec);
1259         if (strncmp(rec->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) {
1260                 len +=
1261                     zfcp_dbf_view(out_buf + len, "fcp_rsp_validity", "0x%02x",
1262                                   rec->type.fcp.rsp_validity);
1263                 len +=
1264                     zfcp_dbf_view(out_buf + len, "fcp_rsp_scsi_status",
1265                                   "0x%02x", rec->type.fcp.rsp_scsi_status);
1266                 len +=
1267                     zfcp_dbf_view(out_buf + len, "fcp_rsp_resid", "0x%08x",
1268                                   rec->type.fcp.rsp_resid);
1269                 len +=
1270                     zfcp_dbf_view(out_buf + len, "fcp_rsp_code", "0x%08x",
1271                                   rec->type.fcp.rsp_code);
1272                 len +=
1273                     zfcp_dbf_view(out_buf + len, "fcp_sns_info_len", "0x%08x",
1274                                   rec->type.fcp.sns_info_len);
1275                 len +=
1276                     zfcp_dbf_view_dump(out_buf + len, "fcp_sns_info",
1277                                        rec->type.fcp.sns_info,
1278                                        min((int)rec->type.fcp.sns_info_len,
1279                                            ZFCP_DBF_SCSI_FCP_SNS_INFO), 0,
1280                                        rec->type.fcp.sns_info_len);
1281         }
1282
1283         len += sprintf(out_buf + len, "\n");
1284
1285         return len;
1286 }
1287
1288 static struct debug_view zfcp_scsi_dbf_view = {
1289         "structured",
1290         NULL,
1291         &zfcp_dbf_view_header,
1292         &zfcp_scsi_dbf_view_format,
1293         NULL,
1294         NULL
1295 };
1296
1297 /**
1298  * zfcp_adapter_debug_register - registers debug feature for an adapter
1299  * @adapter: pointer to adapter for which debug features should be registered
1300  * return: -ENOMEM on error, 0 otherwise
1301  */
1302 int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
1303 {
1304         char dbf_name[DEBUG_MAX_NAME_LEN];
1305
1306         /* debug feature area which records recovery activity */
1307         sprintf(dbf_name, "zfcp_%s_rec", zfcp_get_busid_by_adapter(adapter));
1308         adapter->rec_dbf = debug_register(dbf_name, dbfsize, 1,
1309                                           sizeof(struct zfcp_rec_dbf_record));
1310         if (!adapter->rec_dbf)
1311                 goto failed;
1312         debug_register_view(adapter->rec_dbf, &debug_hex_ascii_view);
1313         debug_register_view(adapter->rec_dbf, &zfcp_rec_dbf_view);
1314         debug_set_level(adapter->rec_dbf, 3);
1315
1316         /* debug feature area which records HBA (FSF and QDIO) conditions */
1317         sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter));
1318         adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1,
1319                                           sizeof(struct zfcp_hba_dbf_record));
1320         if (!adapter->hba_dbf)
1321                 goto failed;
1322         debug_register_view(adapter->hba_dbf, &debug_hex_ascii_view);
1323         debug_register_view(adapter->hba_dbf, &zfcp_hba_dbf_view);
1324         debug_set_level(adapter->hba_dbf, 3);
1325
1326         /* debug feature area which records SAN command failures and recovery */
1327         sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter));
1328         adapter->san_dbf = debug_register(dbf_name, dbfsize, 1,
1329                                           sizeof(struct zfcp_san_dbf_record));
1330         if (!adapter->san_dbf)
1331                 goto failed;
1332         debug_register_view(adapter->san_dbf, &debug_hex_ascii_view);
1333         debug_register_view(adapter->san_dbf, &zfcp_san_dbf_view);
1334         debug_set_level(adapter->san_dbf, 6);
1335
1336         /* debug feature area which records SCSI command failures and recovery */
1337         sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter));
1338         adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1,
1339                                            sizeof(struct zfcp_scsi_dbf_record));
1340         if (!adapter->scsi_dbf)
1341                 goto failed;
1342         debug_register_view(adapter->scsi_dbf, &debug_hex_ascii_view);
1343         debug_register_view(adapter->scsi_dbf, &zfcp_scsi_dbf_view);
1344         debug_set_level(adapter->scsi_dbf, 3);
1345
1346         return 0;
1347
1348  failed:
1349         zfcp_adapter_debug_unregister(adapter);
1350
1351         return -ENOMEM;
1352 }
1353
1354 /**
1355  * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
1356  * @adapter: pointer to adapter for which debug features should be unregistered
1357  */
1358 void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)
1359 {
1360         debug_unregister(adapter->scsi_dbf);
1361         debug_unregister(adapter->san_dbf);
1362         debug_unregister(adapter->hba_dbf);
1363         debug_unregister(adapter->rec_dbf);
1364         adapter->scsi_dbf = NULL;
1365         adapter->san_dbf = NULL;
1366         adapter->hba_dbf = NULL;
1367         adapter->rec_dbf = NULL;
1368 }
1369
1370 #undef ZFCP_LOG_AREA