]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/scsi/lpfc/lpfc_debugfs.c
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux...
[linux-2.6-omap-h63xx.git] / drivers / scsi / lpfc / lpfc_debugfs.c
1 /*******************************************************************
2  * This file is part of the Emulex Linux Device Driver for         *
3  * Fibre Channel Host Bus Adapters.                                *
4  * Copyright (C) 2007 Emulex.  All rights reserved.                *
5  * EMULEX and SLI are trademarks of Emulex.                        *
6  * www.emulex.com                                                  *
7  *                                                                 *
8  * This program is free software; you can redistribute it and/or   *
9  * modify it under the terms of version 2 of the GNU General       *
10  * Public License as published by the Free Software Foundation.    *
11  * This program is distributed in the hope that it will be useful. *
12  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
13  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
14  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
15  * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
16  * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
17  * more details, a copy of which can be found in the file COPYING  *
18  * included with this package.                                     *
19  *******************************************************************/
20
21 #include <linux/blkdev.h>
22 #include <linux/delay.h>
23 #include <linux/dma-mapping.h>
24 #include <linux/idr.h>
25 #include <linux/interrupt.h>
26 #include <linux/kthread.h>
27 #include <linux/pci.h>
28 #include <linux/spinlock.h>
29 #include <linux/ctype.h>
30 #include <linux/version.h>
31
32 #include <scsi/scsi.h>
33 #include <scsi/scsi_device.h>
34 #include <scsi/scsi_host.h>
35 #include <scsi/scsi_transport_fc.h>
36
37 #include "lpfc_hw.h"
38 #include "lpfc_sli.h"
39 #include "lpfc_disc.h"
40 #include "lpfc_scsi.h"
41 #include "lpfc.h"
42 #include "lpfc_logmsg.h"
43 #include "lpfc_crtn.h"
44 #include "lpfc_vport.h"
45 #include "lpfc_version.h"
46 #include "lpfc_compat.h"
47 #include "lpfc_debugfs.h"
48
49 #ifdef CONFIG_LPFC_DEBUG_FS
50 /* debugfs interface
51  *
52  * To access this interface the user should:
53  * # mkdir /debug
54  * # mount -t debugfs none /debug
55  *
56  * The lpfc debugfs directory hierachy is:
57  * lpfc/lpfcX/vportY
58  * where X is the lpfc hba unique_id
59  * where Y is the vport VPI on that hba
60  *
61  * Debugging services available per vport:
62  * discovery_trace
63  * This is an ACSII readable file that contains a trace of the last
64  * lpfc_debugfs_max_disc_trc events that happened on a specific vport.
65  * See lpfc_debugfs.h for different categories of
66  * discovery events. To enable the discovery trace, the following
67  * module parameters must be set:
68  * lpfc_debugfs_enable=1         Turns on lpfc debugfs filesystem support
69  * lpfc_debugfs_max_disc_trc=X   Where X is the event trace depth for
70  *                               EACH vport. X MUST also be a power of 2.
71  * lpfc_debugfs_mask_disc_trc=Y  Where Y is an event mask as defined in
72  *                               lpfc_debugfs.h .
73  */
74 static int lpfc_debugfs_enable = 1;
75 module_param(lpfc_debugfs_enable, int, 0);
76 MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services");
77
78 /* This MUST be a power of 2 */
79 static int lpfc_debugfs_max_disc_trc;
80 module_param(lpfc_debugfs_max_disc_trc, int, 0);
81 MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc,
82         "Set debugfs discovery trace depth");
83
84 /* This MUST be a power of 2 */
85 static int lpfc_debugfs_max_slow_ring_trc;
86 module_param(lpfc_debugfs_max_slow_ring_trc, int, 0);
87 MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
88         "Set debugfs slow ring trace depth");
89
90 int lpfc_debugfs_mask_disc_trc;
91 module_param(lpfc_debugfs_mask_disc_trc, int, 0);
92 MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
93         "Set debugfs discovery trace mask");
94
95 #include <linux/debugfs.h>
96
97 /* size of output line, for discovery_trace and slow_ring_trace */
98 #define LPFC_DEBUG_TRC_ENTRY_SIZE 100
99
100 /* nodelist output buffer size */
101 #define LPFC_NODELIST_SIZE 8192
102 #define LPFC_NODELIST_ENTRY_SIZE 120
103
104 /* dumpHBASlim output buffer size */
105 #define LPFC_DUMPHBASLIM_SIZE 4096
106
107 /* dumpHostSlim output buffer size */
108 #define LPFC_DUMPHOSTSLIM_SIZE 4096
109
110 /* hbqinfo output buffer size */
111 #define LPFC_HBQINFO_SIZE 8192
112
113 struct lpfc_debug {
114         char *buffer;
115         int  len;
116 };
117
118 static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
119 static unsigned long lpfc_debugfs_start_time = 0L;
120
121 static int
122 lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
123 {
124         int i, index, len, enable;
125         uint32_t ms;
126         struct lpfc_debugfs_trc *dtp;
127         char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
128
129
130         enable = lpfc_debugfs_enable;
131         lpfc_debugfs_enable = 0;
132
133         len = 0;
134         index = (atomic_read(&vport->disc_trc_cnt) + 1) &
135                 (lpfc_debugfs_max_disc_trc - 1);
136         for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
137                 dtp = vport->disc_trc + i;
138                 if (!dtp->fmt)
139                         continue;
140                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
141                 snprintf(buffer,
142                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
143                         dtp->seq_cnt, ms, dtp->fmt);
144                 len +=  snprintf(buf+len, size-len, buffer,
145                         dtp->data1, dtp->data2, dtp->data3);
146         }
147         for (i = 0; i < index; i++) {
148                 dtp = vport->disc_trc + i;
149                 if (!dtp->fmt)
150                         continue;
151                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
152                 snprintf(buffer,
153                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
154                         dtp->seq_cnt, ms, dtp->fmt);
155                 len +=  snprintf(buf+len, size-len, buffer,
156                         dtp->data1, dtp->data2, dtp->data3);
157         }
158
159         lpfc_debugfs_enable = enable;
160         return len;
161 }
162
163 static int
164 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
165 {
166         int i, index, len, enable;
167         uint32_t ms;
168         struct lpfc_debugfs_trc *dtp;
169         char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
170
171
172         enable = lpfc_debugfs_enable;
173         lpfc_debugfs_enable = 0;
174
175         len = 0;
176         index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
177                 (lpfc_debugfs_max_slow_ring_trc - 1);
178         for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
179                 dtp = phba->slow_ring_trc + i;
180                 if (!dtp->fmt)
181                         continue;
182                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
183                 snprintf(buffer,
184                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
185                         dtp->seq_cnt, ms, dtp->fmt);
186                 len +=  snprintf(buf+len, size-len, buffer,
187                         dtp->data1, dtp->data2, dtp->data3);
188         }
189         for (i = 0; i < index; i++) {
190                 dtp = phba->slow_ring_trc + i;
191                 if (!dtp->fmt)
192                         continue;
193                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
194                 snprintf(buffer,
195                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
196                         dtp->seq_cnt, ms, dtp->fmt);
197                 len +=  snprintf(buf+len, size-len, buffer,
198                         dtp->data1, dtp->data2, dtp->data3);
199         }
200
201         lpfc_debugfs_enable = enable;
202         return len;
203 }
204
205 static int lpfc_debugfs_last_hbq = -1;
206
207 static int
208 lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
209 {
210         int len = 0;
211         int cnt, i, j, found, posted, low;
212         uint32_t phys, raw_index, getidx;
213         struct lpfc_hbq_init *hip;
214         struct hbq_s *hbqs;
215         struct lpfc_hbq_entry *hbqe;
216         struct lpfc_dmabuf *d_buf;
217         struct hbq_dmabuf *hbq_buf;
218
219         cnt = LPFC_HBQINFO_SIZE;
220         spin_lock_irq(&phba->hbalock);
221
222         /* toggle between multiple hbqs, if any */
223         i = lpfc_sli_hbq_count();
224         if (i > 1) {
225                  lpfc_debugfs_last_hbq++;
226                  if (lpfc_debugfs_last_hbq >= i)
227                         lpfc_debugfs_last_hbq = 0;
228         }
229         else
230                 lpfc_debugfs_last_hbq = 0;
231
232         i = lpfc_debugfs_last_hbq;
233
234         len +=  snprintf(buf+len, size-len, "HBQ %d Info\n", i);
235
236         hbqs =  &phba->hbqs[i];
237         posted = 0;
238         list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
239                 posted++;
240
241         hip =  lpfc_hbq_defs[i];
242         len +=  snprintf(buf+len, size-len,
243                 "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
244                 hip->hbq_index, hip->profile, hip->rn,
245                 hip->buffer_count, hip->init_count, hip->add_count, posted);
246
247         raw_index = phba->hbq_get[i];
248         getidx = le32_to_cpu(raw_index);
249         len +=  snprintf(buf+len, size-len,
250                 "entrys:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
251                 hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx,
252                 hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx);
253
254         hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
255         for (j=0; j<hbqs->entry_count; j++) {
256                 len +=  snprintf(buf+len, size-len,
257                         "%03d: %08x %04x %05x ", j,
258                         le32_to_cpu(hbqe->bde.addrLow),
259                         le32_to_cpu(hbqe->bde.tus.w),
260                         le32_to_cpu(hbqe->buffer_tag));
261                 i = 0;
262                 found = 0;
263
264                 /* First calculate if slot has an associated posted buffer */
265                 low = hbqs->hbqPutIdx - posted;
266                 if (low >= 0) {
267                         if ((j >= hbqs->hbqPutIdx) || (j < low)) {
268                                 len +=  snprintf(buf+len, size-len, "Unused\n");
269                                 goto skipit;
270                         }
271                 }
272                 else {
273                         if ((j >= hbqs->hbqPutIdx) &&
274                                 (j < (hbqs->entry_count+low))) {
275                                 len +=  snprintf(buf+len, size-len, "Unused\n");
276                                 goto skipit;
277                         }
278                 }
279
280                 /* Get the Buffer info for the posted buffer */
281                 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
282                         hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
283                         phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
284                         if (phys == le32_to_cpu(hbqe->bde.addrLow)) {
285                                 len +=  snprintf(buf+len, size-len,
286                                         "Buf%d: %p %06x\n", i,
287                                         hbq_buf->dbuf.virt, hbq_buf->tag);
288                                 found = 1;
289                                 break;
290                         }
291                         i++;
292                 }
293                 if (!found) {
294                         len +=  snprintf(buf+len, size-len, "No DMAinfo?\n");
295                 }
296 skipit:
297                 hbqe++;
298                 if (len > LPFC_HBQINFO_SIZE - 54)
299                         break;
300         }
301         spin_unlock_irq(&phba->hbalock);
302         return len;
303 }
304
305 static int lpfc_debugfs_last_hba_slim_off;
306
307 static int
308 lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
309 {
310         int len = 0;
311         int i, off;
312         uint32_t *ptr;
313         char buffer[1024];
314
315         off = 0;
316         spin_lock_irq(&phba->hbalock);
317
318         len +=  snprintf(buf+len, size-len, "HBA SLIM\n");
319         lpfc_memcpy_from_slim(buffer,
320                 ((uint8_t *)phba->MBslimaddr) + lpfc_debugfs_last_hba_slim_off,
321                 1024);
322
323         ptr = (uint32_t *)&buffer[0];
324         off = lpfc_debugfs_last_hba_slim_off;
325
326         /* Set it up for the next time */
327         lpfc_debugfs_last_hba_slim_off += 1024;
328         if (lpfc_debugfs_last_hba_slim_off >= 4096)
329                 lpfc_debugfs_last_hba_slim_off = 0;
330
331         i = 1024;
332         while (i > 0) {
333                 len +=  snprintf(buf+len, size-len,
334                 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
335                 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
336                 *(ptr+5), *(ptr+6), *(ptr+7));
337                 ptr += 8;
338                 i -= (8 * sizeof(uint32_t));
339                 off += (8 * sizeof(uint32_t));
340         }
341
342         spin_unlock_irq(&phba->hbalock);
343         return len;
344 }
345
346 static int
347 lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
348 {
349         int len = 0;
350         int i, off;
351         uint32_t word0, word1, word2, word3;
352         uint32_t *ptr;
353         struct lpfc_pgp *pgpp;
354         struct lpfc_sli *psli = &phba->sli;
355         struct lpfc_sli_ring *pring;
356
357         off = 0;
358         spin_lock_irq(&phba->hbalock);
359
360         len +=  snprintf(buf+len, size-len, "SLIM Mailbox\n");
361         ptr = (uint32_t *)phba->slim2p;
362         i = sizeof(MAILBOX_t);
363         while (i > 0) {
364                 len +=  snprintf(buf+len, size-len,
365                 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
366                 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
367                 *(ptr+5), *(ptr+6), *(ptr+7));
368                 ptr += 8;
369                 i -= (8 * sizeof(uint32_t));
370                 off += (8 * sizeof(uint32_t));
371         }
372
373         len +=  snprintf(buf+len, size-len, "SLIM PCB\n");
374         ptr = (uint32_t *)&phba->slim2p->pcb;
375         i = sizeof(PCB_t);
376         while (i > 0) {
377                 len +=  snprintf(buf+len, size-len,
378                 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
379                 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
380                 *(ptr+5), *(ptr+6), *(ptr+7));
381                 ptr += 8;
382                 i -= (8 * sizeof(uint32_t));
383                 off += (8 * sizeof(uint32_t));
384         }
385
386         pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port;
387         pring = &psli->ring[0];
388         len +=  snprintf(buf+len, size-len,
389                 "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x)  "
390                 "RSP PutInx:%d Max:%d\n",
391                 pgpp->cmdGetInx, pring->numCiocb,
392                 pring->next_cmdidx, pring->local_getidx, pring->flag,
393                 pgpp->rspPutInx, pring->numRiocb);
394         pgpp++;
395
396         pring = &psli->ring[1];
397         len +=  snprintf(buf+len, size-len,
398                 "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x)  "
399                 "RSP PutInx:%d Max:%d\n",
400                 pgpp->cmdGetInx, pring->numCiocb,
401                 pring->next_cmdidx, pring->local_getidx, pring->flag,
402                 pgpp->rspPutInx, pring->numRiocb);
403         pgpp++;
404
405         pring = &psli->ring[2];
406         len +=  snprintf(buf+len, size-len,
407                 "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x)  "
408                 "RSP PutInx:%d Max:%d\n",
409                 pgpp->cmdGetInx, pring->numCiocb,
410                 pring->next_cmdidx, pring->local_getidx, pring->flag,
411                 pgpp->rspPutInx, pring->numRiocb);
412         pgpp++;
413
414         pring = &psli->ring[3];
415         len +=  snprintf(buf+len, size-len,
416                 "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x)  "
417                 "RSP PutInx:%d Max:%d\n",
418                 pgpp->cmdGetInx, pring->numCiocb,
419                 pring->next_cmdidx, pring->local_getidx, pring->flag,
420                 pgpp->rspPutInx, pring->numRiocb);
421
422
423         ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get;
424         word0 = readl(phba->HAregaddr);
425         word1 = readl(phba->CAregaddr);
426         word2 = readl(phba->HSregaddr);
427         word3 = readl(phba->HCregaddr);
428         len +=  snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x HC:%08x\n",
429         word0, word1, word2, word3);
430         spin_unlock_irq(&phba->hbalock);
431         return len;
432 }
433
434 static int
435 lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
436 {
437         int len = 0;
438         int cnt;
439         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
440         struct lpfc_nodelist *ndlp;
441         unsigned char *statep, *name;
442
443         cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
444
445         spin_lock_irq(shost->host_lock);
446         list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
447                 if (!cnt) {
448                         len +=  snprintf(buf+len, size-len,
449                                 "Missing Nodelist Entries\n");
450                         break;
451                 }
452                 cnt--;
453                 switch (ndlp->nlp_state) {
454                 case NLP_STE_UNUSED_NODE:
455                         statep = "UNUSED";
456                         break;
457                 case NLP_STE_PLOGI_ISSUE:
458                         statep = "PLOGI ";
459                         break;
460                 case NLP_STE_ADISC_ISSUE:
461                         statep = "ADISC ";
462                         break;
463                 case NLP_STE_REG_LOGIN_ISSUE:
464                         statep = "REGLOG";
465                         break;
466                 case NLP_STE_PRLI_ISSUE:
467                         statep = "PRLI  ";
468                         break;
469                 case NLP_STE_UNMAPPED_NODE:
470                         statep = "UNMAP ";
471                         break;
472                 case NLP_STE_MAPPED_NODE:
473                         statep = "MAPPED";
474                         break;
475                 case NLP_STE_NPR_NODE:
476                         statep = "NPR   ";
477                         break;
478                 default:
479                         statep = "UNKNOWN";
480                 }
481                 len +=  snprintf(buf+len, size-len, "%s DID:x%06x ",
482                         statep, ndlp->nlp_DID);
483                 name = (unsigned char *)&ndlp->nlp_portname;
484                 len +=  snprintf(buf+len, size-len,
485                         "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
486                         *name, *(name+1), *(name+2), *(name+3),
487                         *(name+4), *(name+5), *(name+6), *(name+7));
488                 name = (unsigned char *)&ndlp->nlp_nodename;
489                 len +=  snprintf(buf+len, size-len,
490                         "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
491                         *name, *(name+1), *(name+2), *(name+3),
492                         *(name+4), *(name+5), *(name+6), *(name+7));
493                 len +=  snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ",
494                         ndlp->nlp_rpi, ndlp->nlp_flag);
495                 if (!ndlp->nlp_type)
496                         len +=  snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
497                 if (ndlp->nlp_type & NLP_FC_NODE)
498                         len +=  snprintf(buf+len, size-len, "FC_NODE ");
499                 if (ndlp->nlp_type & NLP_FABRIC)
500                         len +=  snprintf(buf+len, size-len, "FABRIC ");
501                 if (ndlp->nlp_type & NLP_FCP_TARGET)
502                         len +=  snprintf(buf+len, size-len, "FCP_TGT sid:%d ",
503                                 ndlp->nlp_sid);
504                 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
505                         len +=  snprintf(buf+len, size-len, "FCP_INITIATOR ");
506                 len += snprintf(buf+len, size-len, "usgmap:%x ",
507                         ndlp->nlp_usg_map);
508                 len += snprintf(buf+len, size-len, "refcnt:%x",
509                         atomic_read(&ndlp->kref.refcount));
510                 len +=  snprintf(buf+len, size-len, "\n");
511         }
512         spin_unlock_irq(shost->host_lock);
513         return len;
514 }
515 #endif
516
517
518 inline void
519 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
520         uint32_t data1, uint32_t data2, uint32_t data3)
521 {
522 #ifdef CONFIG_LPFC_DEBUG_FS
523         struct lpfc_debugfs_trc *dtp;
524         int index;
525
526         if (!(lpfc_debugfs_mask_disc_trc & mask))
527                 return;
528
529         if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
530                 !vport || !vport->disc_trc)
531                 return;
532
533         index = atomic_inc_return(&vport->disc_trc_cnt) &
534                 (lpfc_debugfs_max_disc_trc - 1);
535         dtp = vport->disc_trc + index;
536         dtp->fmt = fmt;
537         dtp->data1 = data1;
538         dtp->data2 = data2;
539         dtp->data3 = data3;
540         dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
541         dtp->jif = jiffies;
542 #endif
543         return;
544 }
545
546 inline void
547 lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
548         uint32_t data1, uint32_t data2, uint32_t data3)
549 {
550 #ifdef CONFIG_LPFC_DEBUG_FS
551         struct lpfc_debugfs_trc *dtp;
552         int index;
553
554         if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
555                 !phba || !phba->slow_ring_trc)
556                 return;
557
558         index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
559                 (lpfc_debugfs_max_slow_ring_trc - 1);
560         dtp = phba->slow_ring_trc + index;
561         dtp->fmt = fmt;
562         dtp->data1 = data1;
563         dtp->data2 = data2;
564         dtp->data3 = data3;
565         dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
566         dtp->jif = jiffies;
567 #endif
568         return;
569 }
570
571 #ifdef CONFIG_LPFC_DEBUG_FS
572 static int
573 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
574 {
575         struct lpfc_vport *vport = inode->i_private;
576         struct lpfc_debug *debug;
577         int size;
578         int rc = -ENOMEM;
579
580         if (!lpfc_debugfs_max_disc_trc) {
581                  rc = -ENOSPC;
582                 goto out;
583         }
584
585         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
586         if (!debug)
587                 goto out;
588
589         /* Round to page boundry */
590         size =  (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
591         size = PAGE_ALIGN(size);
592
593         debug->buffer = kmalloc(size, GFP_KERNEL);
594         if (!debug->buffer) {
595                 kfree(debug);
596                 goto out;
597         }
598
599         debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
600         file->private_data = debug;
601
602         rc = 0;
603 out:
604         return rc;
605 }
606
607 static int
608 lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
609 {
610         struct lpfc_hba *phba = inode->i_private;
611         struct lpfc_debug *debug;
612         int size;
613         int rc = -ENOMEM;
614
615         if (!lpfc_debugfs_max_slow_ring_trc) {
616                  rc = -ENOSPC;
617                 goto out;
618         }
619
620         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
621         if (!debug)
622                 goto out;
623
624         /* Round to page boundry */
625         size =  (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
626         size = PAGE_ALIGN(size);
627
628         debug->buffer = kmalloc(size, GFP_KERNEL);
629         if (!debug->buffer) {
630                 kfree(debug);
631                 goto out;
632         }
633
634         debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
635         file->private_data = debug;
636
637         rc = 0;
638 out:
639         return rc;
640 }
641
642 static int
643 lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
644 {
645         struct lpfc_hba *phba = inode->i_private;
646         struct lpfc_debug *debug;
647         int rc = -ENOMEM;
648
649         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
650         if (!debug)
651                 goto out;
652
653         /* Round to page boundry */
654         debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
655         if (!debug->buffer) {
656                 kfree(debug);
657                 goto out;
658         }
659
660         debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
661                 LPFC_HBQINFO_SIZE);
662         file->private_data = debug;
663
664         rc = 0;
665 out:
666         return rc;
667 }
668
669 static int
670 lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file)
671 {
672         struct lpfc_hba *phba = inode->i_private;
673         struct lpfc_debug *debug;
674         int rc = -ENOMEM;
675
676         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
677         if (!debug)
678                 goto out;
679
680         /* Round to page boundry */
681         debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL);
682         if (!debug->buffer) {
683                 kfree(debug);
684                 goto out;
685         }
686
687         debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer,
688                 LPFC_DUMPHBASLIM_SIZE);
689         file->private_data = debug;
690
691         rc = 0;
692 out:
693         return rc;
694 }
695
696 static int
697 lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file)
698 {
699         struct lpfc_hba *phba = inode->i_private;
700         struct lpfc_debug *debug;
701         int rc = -ENOMEM;
702
703         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
704         if (!debug)
705                 goto out;
706
707         /* Round to page boundry */
708         debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL);
709         if (!debug->buffer) {
710                 kfree(debug);
711                 goto out;
712         }
713
714         debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer,
715                 LPFC_DUMPHOSTSLIM_SIZE);
716         file->private_data = debug;
717
718         rc = 0;
719 out:
720         return rc;
721 }
722
723 static int
724 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
725 {
726         struct lpfc_vport *vport = inode->i_private;
727         struct lpfc_debug *debug;
728         int rc = -ENOMEM;
729
730         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
731         if (!debug)
732                 goto out;
733
734         /* Round to page boundry */
735         debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
736         if (!debug->buffer) {
737                 kfree(debug);
738                 goto out;
739         }
740
741         debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
742                 LPFC_NODELIST_SIZE);
743         file->private_data = debug;
744
745         rc = 0;
746 out:
747         return rc;
748 }
749
750 static loff_t
751 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
752 {
753         struct lpfc_debug *debug;
754         loff_t pos = -1;
755
756         debug = file->private_data;
757
758         switch (whence) {
759         case 0:
760                 pos = off;
761                 break;
762         case 1:
763                 pos = file->f_pos + off;
764                 break;
765         case 2:
766                 pos = debug->len - off;
767         }
768         return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos);
769 }
770
771 static ssize_t
772 lpfc_debugfs_read(struct file *file, char __user *buf,
773                   size_t nbytes, loff_t *ppos)
774 {
775         struct lpfc_debug *debug = file->private_data;
776         return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
777                                        debug->len);
778 }
779
780 static int
781 lpfc_debugfs_release(struct inode *inode, struct file *file)
782 {
783         struct lpfc_debug *debug = file->private_data;
784
785         kfree(debug->buffer);
786         kfree(debug);
787
788         return 0;
789 }
790
791 #undef lpfc_debugfs_op_disc_trc
792 static struct file_operations lpfc_debugfs_op_disc_trc = {
793         .owner =        THIS_MODULE,
794         .open =         lpfc_debugfs_disc_trc_open,
795         .llseek =       lpfc_debugfs_lseek,
796         .read =         lpfc_debugfs_read,
797         .release =      lpfc_debugfs_release,
798 };
799
800 #undef lpfc_debugfs_op_nodelist
801 static struct file_operations lpfc_debugfs_op_nodelist = {
802         .owner =        THIS_MODULE,
803         .open =         lpfc_debugfs_nodelist_open,
804         .llseek =       lpfc_debugfs_lseek,
805         .read =         lpfc_debugfs_read,
806         .release =      lpfc_debugfs_release,
807 };
808
809 #undef lpfc_debugfs_op_hbqinfo
810 static struct file_operations lpfc_debugfs_op_hbqinfo = {
811         .owner =        THIS_MODULE,
812         .open =         lpfc_debugfs_hbqinfo_open,
813         .llseek =       lpfc_debugfs_lseek,
814         .read =         lpfc_debugfs_read,
815         .release =      lpfc_debugfs_release,
816 };
817
818 #undef lpfc_debugfs_op_dumpHBASlim
819 static struct file_operations lpfc_debugfs_op_dumpHBASlim = {
820         .owner =        THIS_MODULE,
821         .open =         lpfc_debugfs_dumpHBASlim_open,
822         .llseek =       lpfc_debugfs_lseek,
823         .read =         lpfc_debugfs_read,
824         .release =      lpfc_debugfs_release,
825 };
826
827 #undef lpfc_debugfs_op_dumpHostSlim
828 static struct file_operations lpfc_debugfs_op_dumpHostSlim = {
829         .owner =        THIS_MODULE,
830         .open =         lpfc_debugfs_dumpHostSlim_open,
831         .llseek =       lpfc_debugfs_lseek,
832         .read =         lpfc_debugfs_read,
833         .release =      lpfc_debugfs_release,
834 };
835
836 #undef lpfc_debugfs_op_slow_ring_trc
837 static struct file_operations lpfc_debugfs_op_slow_ring_trc = {
838         .owner =        THIS_MODULE,
839         .open =         lpfc_debugfs_slow_ring_trc_open,
840         .llseek =       lpfc_debugfs_lseek,
841         .read =         lpfc_debugfs_read,
842         .release =      lpfc_debugfs_release,
843 };
844
845 static struct dentry *lpfc_debugfs_root = NULL;
846 static atomic_t lpfc_debugfs_hba_count;
847 #endif
848
849 inline void
850 lpfc_debugfs_initialize(struct lpfc_vport *vport)
851 {
852 #ifdef CONFIG_LPFC_DEBUG_FS
853         struct lpfc_hba   *phba = vport->phba;
854         char name[64];
855         uint32_t num, i;
856
857         if (!lpfc_debugfs_enable)
858                 return;
859
860         /* Setup lpfc root directory */
861         if (!lpfc_debugfs_root) {
862                 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
863                 atomic_set(&lpfc_debugfs_hba_count, 0);
864                 if (!lpfc_debugfs_root) {
865                         lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
866                                          "0409 Cannot create debugfs root\n");
867                         goto debug_failed;
868                 }
869         }
870         if (!lpfc_debugfs_start_time)
871                 lpfc_debugfs_start_time = jiffies;
872
873         /* Setup lpfcX directory for specific HBA */
874         snprintf(name, sizeof(name), "lpfc%d", phba->brd_no);
875         if (!phba->hba_debugfs_root) {
876                 phba->hba_debugfs_root =
877                         debugfs_create_dir(name, lpfc_debugfs_root);
878                 if (!phba->hba_debugfs_root) {
879                         lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
880                                          "0409 Cannot create debugfs hba\n");
881                         goto debug_failed;
882                 }
883                 atomic_inc(&lpfc_debugfs_hba_count);
884                 atomic_set(&phba->debugfs_vport_count, 0);
885
886                 /* Setup hbqinfo */
887                 snprintf(name, sizeof(name), "hbqinfo");
888                 phba->debug_hbqinfo =
889                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
890                                  phba->hba_debugfs_root,
891                                  phba, &lpfc_debugfs_op_hbqinfo);
892                 if (!phba->debug_hbqinfo) {
893                         lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
894                                 "0409 Cannot create debugfs hbqinfo\n");
895                         goto debug_failed;
896                 }
897
898                 /* Setup dumpHBASlim */
899                 snprintf(name, sizeof(name), "dumpHBASlim");
900                 phba->debug_dumpHBASlim =
901                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
902                                  phba->hba_debugfs_root,
903                                  phba, &lpfc_debugfs_op_dumpHBASlim);
904                 if (!phba->debug_dumpHBASlim) {
905                         lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
906                                 "0409 Cannot create debugfs dumpHBASlim\n");
907                         goto debug_failed;
908                 }
909
910                 /* Setup dumpHostSlim */
911                 snprintf(name, sizeof(name), "dumpHostSlim");
912                 phba->debug_dumpHostSlim =
913                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
914                                  phba->hba_debugfs_root,
915                                  phba, &lpfc_debugfs_op_dumpHostSlim);
916                 if (!phba->debug_dumpHostSlim) {
917                         lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
918                                 "0409 Cannot create debugfs dumpHostSlim\n");
919                         goto debug_failed;
920                 }
921
922                 /* Setup slow ring trace */
923                 if (lpfc_debugfs_max_slow_ring_trc) {
924                         num = lpfc_debugfs_max_slow_ring_trc - 1;
925                         if (num & lpfc_debugfs_max_slow_ring_trc) {
926                                 /* Change to be a power of 2 */
927                                 num = lpfc_debugfs_max_slow_ring_trc;
928                                 i = 0;
929                                 while (num > 1) {
930                                         num = num >> 1;
931                                         i++;
932                                 }
933                                 lpfc_debugfs_max_slow_ring_trc = (1 << i);
934                                 printk(KERN_ERR
935                                        "lpfc_debugfs_max_disc_trc changed to "
936                                        "%d\n", lpfc_debugfs_max_disc_trc);
937                         }
938                 }
939
940
941                 snprintf(name, sizeof(name), "slow_ring_trace");
942                 phba->debug_slow_ring_trc =
943                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
944                                  phba->hba_debugfs_root,
945                                  phba, &lpfc_debugfs_op_slow_ring_trc);
946                 if (!phba->debug_slow_ring_trc) {
947                         lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
948                                          "0409 Cannot create debugfs "
949                                          "slow_ring_trace\n");
950                         goto debug_failed;
951                 }
952                 if (!phba->slow_ring_trc) {
953                         phba->slow_ring_trc = kmalloc(
954                                 (sizeof(struct lpfc_debugfs_trc) *
955                                 lpfc_debugfs_max_slow_ring_trc),
956                                 GFP_KERNEL);
957                         if (!phba->slow_ring_trc) {
958                                 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
959                                                  "0409 Cannot create debugfs "
960                                                  "slow_ring buffer\n");
961                                 goto debug_failed;
962                         }
963                         atomic_set(&phba->slow_ring_trc_cnt, 0);
964                         memset(phba->slow_ring_trc, 0,
965                                 (sizeof(struct lpfc_debugfs_trc) *
966                                 lpfc_debugfs_max_slow_ring_trc));
967                 }
968         }
969
970         snprintf(name, sizeof(name), "vport%d", vport->vpi);
971         if (!vport->vport_debugfs_root) {
972                 vport->vport_debugfs_root =
973                         debugfs_create_dir(name, phba->hba_debugfs_root);
974                 if (!vport->vport_debugfs_root) {
975                         lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
976                                          "0409 Cant create debugfs");
977                         goto debug_failed;
978                 }
979                 atomic_inc(&phba->debugfs_vport_count);
980         }
981
982         if (lpfc_debugfs_max_disc_trc) {
983                 num = lpfc_debugfs_max_disc_trc - 1;
984                 if (num & lpfc_debugfs_max_disc_trc) {
985                         /* Change to be a power of 2 */
986                         num = lpfc_debugfs_max_disc_trc;
987                         i = 0;
988                         while (num > 1) {
989                                 num = num >> 1;
990                                 i++;
991                         }
992                         lpfc_debugfs_max_disc_trc = (1 << i);
993                         printk(KERN_ERR
994                                "lpfc_debugfs_max_disc_trc changed to %d\n",
995                                lpfc_debugfs_max_disc_trc);
996                 }
997         }
998
999         vport->disc_trc = kzalloc(
1000                 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
1001                 GFP_KERNEL);
1002
1003         if (!vport->disc_trc) {
1004                 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1005                                  "0409 Cannot create debugfs disc trace "
1006                                  "buffer\n");
1007                 goto debug_failed;
1008         }
1009         atomic_set(&vport->disc_trc_cnt, 0);
1010
1011         snprintf(name, sizeof(name), "discovery_trace");
1012         vport->debug_disc_trc =
1013                 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
1014                                  vport->vport_debugfs_root,
1015                                  vport, &lpfc_debugfs_op_disc_trc);
1016         if (!vport->debug_disc_trc) {
1017                 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1018                                  "0409 Cannot create debugfs "
1019                                  "discovery_trace\n");
1020                 goto debug_failed;
1021         }
1022         snprintf(name, sizeof(name), "nodelist");
1023         vport->debug_nodelist =
1024                 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
1025                                  vport->vport_debugfs_root,
1026                                  vport, &lpfc_debugfs_op_nodelist);
1027         if (!vport->debug_nodelist) {
1028                 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1029                                  "0409 Cant create debugfs nodelist");
1030                 goto debug_failed;
1031         }
1032 debug_failed:
1033         return;
1034 #endif
1035 }
1036
1037
1038 inline void
1039 lpfc_debugfs_terminate(struct lpfc_vport *vport)
1040 {
1041 #ifdef CONFIG_LPFC_DEBUG_FS
1042         struct lpfc_hba   *phba = vport->phba;
1043
1044         if (vport->disc_trc) {
1045                 kfree(vport->disc_trc);
1046                 vport->disc_trc = NULL;
1047         }
1048         if (vport->debug_disc_trc) {
1049                 debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
1050                 vport->debug_disc_trc = NULL;
1051         }
1052         if (vport->debug_nodelist) {
1053                 debugfs_remove(vport->debug_nodelist); /* nodelist */
1054                 vport->debug_nodelist = NULL;
1055         }
1056
1057         if (vport->vport_debugfs_root) {
1058                 debugfs_remove(vport->vport_debugfs_root); /* vportX */
1059                 vport->vport_debugfs_root = NULL;
1060                 atomic_dec(&phba->debugfs_vport_count);
1061         }
1062         if (atomic_read(&phba->debugfs_vport_count) == 0) {
1063
1064                 if (phba->debug_hbqinfo) {
1065                         debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
1066                         phba->debug_hbqinfo = NULL;
1067                 }
1068                 if (phba->debug_dumpHBASlim) {
1069                         debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */
1070                         phba->debug_dumpHBASlim = NULL;
1071                 }
1072                 if (phba->debug_dumpHostSlim) {
1073                         debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */
1074                         phba->debug_dumpHostSlim = NULL;
1075                 }
1076                 if (phba->slow_ring_trc) {
1077                         kfree(phba->slow_ring_trc);
1078                         phba->slow_ring_trc = NULL;
1079                 }
1080                 if (phba->debug_slow_ring_trc) {
1081                         /* slow_ring_trace */
1082                         debugfs_remove(phba->debug_slow_ring_trc);
1083                         phba->debug_slow_ring_trc = NULL;
1084                 }
1085
1086                 if (phba->hba_debugfs_root) {
1087                         debugfs_remove(phba->hba_debugfs_root); /* lpfcX */
1088                         phba->hba_debugfs_root = NULL;
1089                         atomic_dec(&lpfc_debugfs_hba_count);
1090                 }
1091
1092                 if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
1093                         debugfs_remove(lpfc_debugfs_root); /* lpfc */
1094                         lpfc_debugfs_root = NULL;
1095                 }
1096         }
1097 #endif
1098         return;
1099 }
1100
1101