[SCSI] lpfc 8.2.2 : Error messages and debugfs updates
[linux-2.6.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_vport.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 = 0;
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 = 0;
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 = 0;
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 static int lpfc_debugfs_mask_disc_trc = 0;
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 /* dump_slim output buffer size */
105 #define LPFC_DUMPSLIM_SIZE 4096
106
107 struct lpfc_debug {
108         char *buffer;
109         int  len;
110 };
111
112 atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
113 unsigned long lpfc_debugfs_start_time = 0L;
114
115 static int
116 lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
117 {
118         int i, index, len, enable;
119         uint32_t ms;
120         struct lpfc_debugfs_trc *dtp;
121         char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
122
123
124         enable = lpfc_debugfs_enable;
125         lpfc_debugfs_enable = 0;
126
127         len = 0;
128         index = (atomic_read(&vport->disc_trc_cnt) + 1) &
129                 (lpfc_debugfs_max_disc_trc - 1);
130         for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
131                 dtp = vport->disc_trc + i;
132                 if (!dtp->fmt)
133                         continue;
134                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
135                 snprintf(buffer,
136                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
137                         dtp->seq_cnt, ms, dtp->fmt);
138                 len +=  snprintf(buf+len, size-len, buffer,
139                         dtp->data1, dtp->data2, dtp->data3);
140         }
141         for (i = 0; i < index; i++) {
142                 dtp = vport->disc_trc + i;
143                 if (!dtp->fmt)
144                         continue;
145                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
146                 snprintf(buffer,
147                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
148                         dtp->seq_cnt, ms, dtp->fmt);
149                 len +=  snprintf(buf+len, size-len, buffer,
150                         dtp->data1, dtp->data2, dtp->data3);
151         }
152
153         lpfc_debugfs_enable = enable;
154         return len;
155 }
156
157 static int
158 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
159 {
160         int i, index, len, enable;
161         uint32_t ms;
162         struct lpfc_debugfs_trc *dtp;
163         char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
164
165
166         enable = lpfc_debugfs_enable;
167         lpfc_debugfs_enable = 0;
168
169         len = 0;
170         index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
171                 (lpfc_debugfs_max_slow_ring_trc - 1);
172         for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
173                 dtp = phba->slow_ring_trc + i;
174                 if (!dtp->fmt)
175                         continue;
176                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
177                 snprintf(buffer,
178                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
179                         dtp->seq_cnt, ms, dtp->fmt);
180                 len +=  snprintf(buf+len, size-len, buffer,
181                         dtp->data1, dtp->data2, dtp->data3);
182         }
183         for (i = 0; i < index; i++) {
184                 dtp = phba->slow_ring_trc + i;
185                 if (!dtp->fmt)
186                         continue;
187                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
188                 snprintf(buffer,
189                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
190                         dtp->seq_cnt, ms, dtp->fmt);
191                 len +=  snprintf(buf+len, size-len, buffer,
192                         dtp->data1, dtp->data2, dtp->data3);
193         }
194
195         lpfc_debugfs_enable = enable;
196         return len;
197 }
198
199 static int
200 lpfc_debugfs_dumpslim_data(struct lpfc_hba *phba, char *buf, int size)
201 {
202         int len = 0;
203         int cnt, i, off;
204         uint32_t word0, word1, word2, word3;
205         uint32_t *ptr;
206         struct lpfc_pgp *pgpp;
207         struct lpfc_sli *psli = &phba->sli;
208         struct lpfc_sli_ring *pring;
209
210         cnt = LPFC_DUMPSLIM_SIZE;
211         off = 0;
212         spin_lock_irq(&phba->hbalock);
213
214         len +=  snprintf(buf+len, size-len, "SLIM Mailbox\n");
215         ptr = (uint32_t *)phba->slim2p;
216         i = sizeof(MAILBOX_t);
217         while (i > 0) {
218                 len +=  snprintf(buf+len, size-len,
219                 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
220                 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
221                 *(ptr+5), *(ptr+6), *(ptr+7));
222                 ptr += 8;
223                 i -= (8 * sizeof(uint32_t));
224                 off += (8 * sizeof(uint32_t));
225         }
226
227         len +=  snprintf(buf+len, size-len, "SLIM PCB\n");
228         ptr = (uint32_t *)&phba->slim2p->pcb;
229         i = sizeof(PCB_t);
230         while (i > 0) {
231                 len +=  snprintf(buf+len, size-len,
232                 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
233                 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
234                 *(ptr+5), *(ptr+6), *(ptr+7));
235                 ptr += 8;
236                 i -= (8 * sizeof(uint32_t));
237                 off += (8 * sizeof(uint32_t));
238         }
239
240         pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port;
241         pring = &psli->ring[0];
242         len +=  snprintf(buf+len, size-len,
243                 "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x)  "
244                 "RSP PutInx:%d Max:%d\n",
245                 pgpp->cmdGetInx, pring->numCiocb,
246                 pring->next_cmdidx, pring->local_getidx, pring->flag,
247                 pgpp->rspPutInx, pring->numRiocb);
248         pgpp++;
249
250         pring = &psli->ring[1];
251         len +=  snprintf(buf+len, size-len,
252                 "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x)  "
253                 "RSP PutInx:%d Max:%d\n",
254                 pgpp->cmdGetInx, pring->numCiocb,
255                 pring->next_cmdidx, pring->local_getidx, pring->flag,
256                 pgpp->rspPutInx, pring->numRiocb);
257         pgpp++;
258
259         pring = &psli->ring[2];
260         len +=  snprintf(buf+len, size-len,
261                 "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x)  "
262                 "RSP PutInx:%d Max:%d\n",
263                 pgpp->cmdGetInx, pring->numCiocb,
264                 pring->next_cmdidx, pring->local_getidx, pring->flag,
265                 pgpp->rspPutInx, pring->numRiocb);
266         pgpp++;
267
268         pring = &psli->ring[3];
269         len +=  snprintf(buf+len, size-len,
270                 "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x)  "
271                 "RSP PutInx:%d Max:%d\n",
272                 pgpp->cmdGetInx, pring->numCiocb,
273                 pring->next_cmdidx, pring->local_getidx, pring->flag,
274                 pgpp->rspPutInx, pring->numRiocb);
275
276
277         ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get;
278         word0 = readl(phba->HAregaddr);
279         word1 = readl(phba->CAregaddr);
280         word2 = readl(phba->HSregaddr);
281         word3 = readl(phba->HCregaddr);
282         len +=  snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x HC:%08x\n",
283         word0, word1, word2, word3);
284         spin_unlock_irq(&phba->hbalock);
285         return len;
286 }
287
288 static int
289 lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
290 {
291         int len = 0;
292         int cnt;
293         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
294         struct lpfc_nodelist *ndlp;
295         unsigned char *statep, *name;
296
297         cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
298
299         spin_lock_irq(shost->host_lock);
300         list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
301                 if (!cnt) {
302                         len +=  snprintf(buf+len, size-len,
303                                 "Missing Nodelist Entries\n");
304                         break;
305                 }
306                 cnt--;
307                 switch (ndlp->nlp_state) {
308                 case NLP_STE_UNUSED_NODE:
309                         statep = "UNUSED";
310                         break;
311                 case NLP_STE_PLOGI_ISSUE:
312                         statep = "PLOGI ";
313                         break;
314                 case NLP_STE_ADISC_ISSUE:
315                         statep = "ADISC ";
316                         break;
317                 case NLP_STE_REG_LOGIN_ISSUE:
318                         statep = "REGLOG";
319                         break;
320                 case NLP_STE_PRLI_ISSUE:
321                         statep = "PRLI  ";
322                         break;
323                 case NLP_STE_UNMAPPED_NODE:
324                         statep = "UNMAP ";
325                         break;
326                 case NLP_STE_MAPPED_NODE:
327                         statep = "MAPPED";
328                         break;
329                 case NLP_STE_NPR_NODE:
330                         statep = "NPR   ";
331                         break;
332                 default:
333                         statep = "UNKNOWN";
334                 }
335                 len +=  snprintf(buf+len, size-len, "%s DID:x%06x ",
336                         statep, ndlp->nlp_DID);
337                 name = (unsigned char *)&ndlp->nlp_portname;
338                 len +=  snprintf(buf+len, size-len,
339                         "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
340                         *name, *(name+1), *(name+2), *(name+3),
341                         *(name+4), *(name+5), *(name+6), *(name+7));
342                 name = (unsigned char *)&ndlp->nlp_nodename;
343                 len +=  snprintf(buf+len, size-len,
344                         "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
345                         *name, *(name+1), *(name+2), *(name+3),
346                         *(name+4), *(name+5), *(name+6), *(name+7));
347                 len +=  snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ",
348                         ndlp->nlp_rpi, ndlp->nlp_flag);
349                 if (!ndlp->nlp_type)
350                         len +=  snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
351                 if (ndlp->nlp_type & NLP_FC_NODE)
352                         len +=  snprintf(buf+len, size-len, "FC_NODE ");
353                 if (ndlp->nlp_type & NLP_FABRIC)
354                         len +=  snprintf(buf+len, size-len, "FABRIC ");
355                 if (ndlp->nlp_type & NLP_FCP_TARGET)
356                         len +=  snprintf(buf+len, size-len, "FCP_TGT sid:%d ",
357                                 ndlp->nlp_sid);
358                 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
359                         len +=  snprintf(buf+len, size-len, "FCP_INITIATOR ");
360                 len += snprintf(buf+len, size-len, "refcnt:%x",
361                         atomic_read(&ndlp->kref.refcount));
362                 len +=  snprintf(buf+len, size-len, "\n");
363         }
364         spin_unlock_irq(shost->host_lock);
365         return len;
366 }
367 #endif
368
369
370 inline void
371 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
372         uint32_t data1, uint32_t data2, uint32_t data3)
373 {
374 #ifdef CONFIG_LPFC_DEBUG_FS
375         struct lpfc_debugfs_trc *dtp;
376         int index;
377
378         if (!(lpfc_debugfs_mask_disc_trc & mask))
379                 return;
380
381         if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
382                 !vport || !vport->disc_trc)
383                 return;
384
385         index = atomic_inc_return(&vport->disc_trc_cnt) &
386                 (lpfc_debugfs_max_disc_trc - 1);
387         dtp = vport->disc_trc + index;
388         dtp->fmt = fmt;
389         dtp->data1 = data1;
390         dtp->data2 = data2;
391         dtp->data3 = data3;
392         dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
393         dtp->jif = jiffies;
394 #endif
395         return;
396 }
397
398 inline void
399 lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
400         uint32_t data1, uint32_t data2, uint32_t data3)
401 {
402 #ifdef CONFIG_LPFC_DEBUG_FS
403         struct lpfc_debugfs_trc *dtp;
404         int index;
405
406         if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
407                 !phba || !phba->slow_ring_trc)
408                 return;
409
410         index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
411                 (lpfc_debugfs_max_slow_ring_trc - 1);
412         dtp = phba->slow_ring_trc + index;
413         dtp->fmt = fmt;
414         dtp->data1 = data1;
415         dtp->data2 = data2;
416         dtp->data3 = data3;
417         dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
418         dtp->jif = jiffies;
419 #endif
420         return;
421 }
422
423 #ifdef CONFIG_LPFC_DEBUG_FS
424 static int
425 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
426 {
427         struct lpfc_vport *vport = inode->i_private;
428         struct lpfc_debug *debug;
429         int size;
430         int rc = -ENOMEM;
431
432         if (!lpfc_debugfs_max_disc_trc) {
433                  rc = -ENOSPC;
434                 goto out;
435         }
436
437         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
438         if (!debug)
439                 goto out;
440
441         /* Round to page boundry */
442         size =  (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
443         size = PAGE_ALIGN(size);
444
445         debug->buffer = kmalloc(size, GFP_KERNEL);
446         if (!debug->buffer) {
447                 kfree(debug);
448                 goto out;
449         }
450
451         debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
452         file->private_data = debug;
453
454         rc = 0;
455 out:
456         return rc;
457 }
458
459 static int
460 lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
461 {
462         struct lpfc_hba *phba = inode->i_private;
463         struct lpfc_debug *debug;
464         int size;
465         int rc = -ENOMEM;
466
467         if (!lpfc_debugfs_max_slow_ring_trc) {
468                  rc = -ENOSPC;
469                 goto out;
470         }
471
472         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
473         if (!debug)
474                 goto out;
475
476         /* Round to page boundry */
477         size =  (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
478         size = PAGE_ALIGN(size);
479
480         debug->buffer = kmalloc(size, GFP_KERNEL);
481         if (!debug->buffer) {
482                 kfree(debug);
483                 goto out;
484         }
485
486         debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
487         file->private_data = debug;
488
489         rc = 0;
490 out:
491         return rc;
492 }
493
494 static int
495 lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file)
496 {
497         struct lpfc_hba *phba = inode->i_private;
498         struct lpfc_debug *debug;
499         int rc = -ENOMEM;
500
501         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
502         if (!debug)
503                 goto out;
504
505         /* Round to page boundry */
506         debug->buffer = kmalloc(LPFC_DUMPSLIM_SIZE, GFP_KERNEL);
507         if (!debug->buffer) {
508                 kfree(debug);
509                 goto out;
510         }
511
512         debug->len = lpfc_debugfs_dumpslim_data(phba, debug->buffer,
513                 LPFC_DUMPSLIM_SIZE);
514         file->private_data = debug;
515
516         rc = 0;
517 out:
518         return rc;
519 }
520
521 static int
522 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
523 {
524         struct lpfc_vport *vport = inode->i_private;
525         struct lpfc_debug *debug;
526         int rc = -ENOMEM;
527
528         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
529         if (!debug)
530                 goto out;
531
532         /* Round to page boundry */
533         debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
534         if (!debug->buffer) {
535                 kfree(debug);
536                 goto out;
537         }
538
539         debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
540                 LPFC_NODELIST_SIZE);
541         file->private_data = debug;
542
543         rc = 0;
544 out:
545         return rc;
546 }
547
548 static loff_t
549 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
550 {
551         struct lpfc_debug *debug;
552         loff_t pos = -1;
553
554         debug = file->private_data;
555
556         switch (whence) {
557         case 0:
558                 pos = off;
559                 break;
560         case 1:
561                 pos = file->f_pos + off;
562                 break;
563         case 2:
564                 pos = debug->len - off;
565         }
566         return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos);
567 }
568
569 static ssize_t
570 lpfc_debugfs_read(struct file *file, char __user *buf,
571                   size_t nbytes, loff_t *ppos)
572 {
573         struct lpfc_debug *debug = file->private_data;
574         return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
575                                        debug->len);
576 }
577
578 static int
579 lpfc_debugfs_release(struct inode *inode, struct file *file)
580 {
581         struct lpfc_debug *debug = file->private_data;
582
583         kfree(debug->buffer);
584         kfree(debug);
585
586         return 0;
587 }
588
589 #undef lpfc_debugfs_op_disc_trc
590 static struct file_operations lpfc_debugfs_op_disc_trc = {
591         .owner =        THIS_MODULE,
592         .open =         lpfc_debugfs_disc_trc_open,
593         .llseek =       lpfc_debugfs_lseek,
594         .read =         lpfc_debugfs_read,
595         .release =      lpfc_debugfs_release,
596 };
597
598 #undef lpfc_debugfs_op_nodelist
599 static struct file_operations lpfc_debugfs_op_nodelist = {
600         .owner =        THIS_MODULE,
601         .open =         lpfc_debugfs_nodelist_open,
602         .llseek =       lpfc_debugfs_lseek,
603         .read =         lpfc_debugfs_read,
604         .release =      lpfc_debugfs_release,
605 };
606
607 #undef lpfc_debugfs_op_dumpslim
608 static struct file_operations lpfc_debugfs_op_dumpslim = {
609         .owner =        THIS_MODULE,
610         .open =         lpfc_debugfs_dumpslim_open,
611         .llseek =       lpfc_debugfs_lseek,
612         .read =         lpfc_debugfs_read,
613         .release =      lpfc_debugfs_release,
614 };
615
616 #undef lpfc_debugfs_op_slow_ring_trc
617 static struct file_operations lpfc_debugfs_op_slow_ring_trc = {
618         .owner =        THIS_MODULE,
619         .open =         lpfc_debugfs_slow_ring_trc_open,
620         .llseek =       lpfc_debugfs_lseek,
621         .read =         lpfc_debugfs_read,
622         .release =      lpfc_debugfs_release,
623 };
624
625 static struct dentry *lpfc_debugfs_root = NULL;
626 static atomic_t lpfc_debugfs_hba_count;
627 #endif
628
629 inline void
630 lpfc_debugfs_initialize(struct lpfc_vport *vport)
631 {
632 #ifdef CONFIG_LPFC_DEBUG_FS
633         struct lpfc_hba   *phba = vport->phba;
634         char name[64];
635         uint32_t num, i;
636
637         if (!lpfc_debugfs_enable)
638                 return;
639
640         /* Setup lpfc root directory */
641         if (!lpfc_debugfs_root) {
642                 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
643                 atomic_set(&lpfc_debugfs_hba_count, 0);
644                 if (!lpfc_debugfs_root) {
645                         lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
646                                 "%d:0409 Cannot create debugfs root (lpfc)",
647                                 phba->brd_no);
648                         goto debug_failed;
649                 }
650         }
651
652         if (!lpfc_debugfs_start_time)
653                 lpfc_debugfs_start_time = jiffies;
654
655         /* Setup lpfcX directory for specific HBA */
656         snprintf(name, sizeof(name), "lpfc%d", phba->brd_no);
657         if (!phba->hba_debugfs_root) {
658                 phba->hba_debugfs_root =
659                         debugfs_create_dir(name, lpfc_debugfs_root);
660                 if (!phba->hba_debugfs_root) {
661                         lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
662                                 "%d:0409 Cannot create debugfs hba (lpfc%d)",
663                                 phba->brd_no, phba->brd_no);
664                         goto debug_failed;
665                 }
666                 atomic_inc(&lpfc_debugfs_hba_count);
667                 atomic_set(&phba->debugfs_vport_count, 0);
668
669                 /* Setup dumpslim */
670                 snprintf(name, sizeof(name), "dumpslim");
671                 phba->debug_dumpslim =
672                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
673                                  phba->hba_debugfs_root,
674                                  phba, &lpfc_debugfs_op_dumpslim);
675                 if (!phba->debug_dumpslim) {
676                         lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
677                         "%d:0409 Cannot create debugfs dumpslim (lpfc%d)",
678                                 phba->brd_no, phba->brd_no);
679                         goto debug_failed;
680                 }
681
682                 /* Setup slow ring trace */
683                 if (lpfc_debugfs_max_slow_ring_trc) {
684                         num = lpfc_debugfs_max_slow_ring_trc - 1;
685                         if (num & lpfc_debugfs_max_slow_ring_trc) {
686                                 /* Change to be a power of 2 */
687                                 num = lpfc_debugfs_max_slow_ring_trc;
688                                 i = 0;
689                                 while (num > 1) {
690                                         num = num >> 1;
691                                         i++;
692                                 }
693                                 lpfc_debugfs_max_slow_ring_trc = (1 << i);
694                                 printk(KERN_ERR
695                                 "lpfc_debugfs_max_slow_ring_trc change to %d\n",
696                                         lpfc_debugfs_max_slow_ring_trc);
697                         }
698                 }
699
700
701                 snprintf(name, sizeof(name), "slow_ring_trace");
702                 phba->debug_slow_ring_trc =
703                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
704                                  phba->hba_debugfs_root,
705                                  phba, &lpfc_debugfs_op_slow_ring_trc);
706                 if (!phba->debug_slow_ring_trc) {
707                         lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
708                                 "%d:0409 Cannot create debugfs "
709                                 "slow_ring_trace (lpfc%d)",
710                                 phba->brd_no, phba->brd_no);
711                         goto debug_failed;
712                 }
713                 if (!phba->slow_ring_trc) {
714                         phba->slow_ring_trc = kmalloc(
715                                 (sizeof(struct lpfc_debugfs_trc) *
716                                 lpfc_debugfs_max_slow_ring_trc),
717                                 GFP_KERNEL);
718                         if (!phba->slow_ring_trc) {
719                                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
720                                 "%d:0409 Cannot create debugfs "
721                                 "slow_ring buffer (lpfc%d)",
722                                 phba->brd_no, phba->brd_no);
723                                 goto debug_failed;
724                         }
725                         atomic_set(&phba->slow_ring_trc_cnt, 0);
726                         memset(phba->slow_ring_trc, 0,
727                                 (sizeof(struct lpfc_debugfs_trc) *
728                                 lpfc_debugfs_max_slow_ring_trc));
729                 }
730         }
731
732         snprintf(name, sizeof(name), "vport%d", vport->vpi);
733         if (!vport->vport_debugfs_root) {
734                 vport->vport_debugfs_root =
735                         debugfs_create_dir(name, phba->hba_debugfs_root);
736                 if (!vport->vport_debugfs_root) {
737                         lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
738                                 "%d:0409 Cant create debugfs vport%d (lpfc%d)",
739                                 phba->brd_no, vport->vpi, phba->brd_no);
740                         goto debug_failed;
741                 }
742                 atomic_inc(&phba->debugfs_vport_count);
743         }
744
745         if (lpfc_debugfs_max_disc_trc) {
746                 num = lpfc_debugfs_max_disc_trc - 1;
747                 if (num & lpfc_debugfs_max_disc_trc) {
748                         /* Change to be a power of 2 */
749                         num = lpfc_debugfs_max_disc_trc;
750                         i = 0;
751                         while (num > 1) {
752                                 num = num >> 1;
753                                 i++;
754                         }
755                         lpfc_debugfs_max_disc_trc = (1 << i);
756                         printk(KERN_ERR
757                                 "lpfc_debugfs_max_disc_trc changed to %d\n",
758                                 lpfc_debugfs_max_disc_trc);
759                 }
760         }
761
762         vport->disc_trc = kmalloc(
763                 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
764                 GFP_KERNEL);
765
766         if (!vport->disc_trc) {
767                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
768                         "%d:0409 Cannot create debugfs "
769                         "vport%d disc trace buffer (lpfc%d)",
770                         phba->brd_no, vport->vpi, phba->brd_no);
771                 goto debug_failed;
772         }
773         atomic_set(&vport->disc_trc_cnt, 0);
774         memset(vport->disc_trc, 0,
775                 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc));
776
777         snprintf(name, sizeof(name), "discovery_trace");
778         vport->debug_disc_trc =
779                 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
780                                  vport->vport_debugfs_root,
781                                  vport, &lpfc_debugfs_op_disc_trc);
782         if (!vport->debug_disc_trc) {
783                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
784                         "%d:0409 Cannot create debugfs "
785                         "vport%d discovery_trace (lpfc%d)",
786                         phba->brd_no, vport->vpi, phba->brd_no);
787                 goto debug_failed;
788         }
789         snprintf(name, sizeof(name), "nodelist");
790         vport->debug_nodelist =
791                 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
792                                  vport->vport_debugfs_root,
793                                  vport, &lpfc_debugfs_op_nodelist);
794         if (!vport->debug_nodelist) {
795                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
796                         "%d:0409 Cant create debugfs vport%d nodelist (lpfc%d)",
797                         phba->brd_no, vport->vpi, phba->brd_no);
798                 goto debug_failed;
799         }
800 debug_failed:
801         return;
802 #endif
803 }
804
805
806 inline void
807 lpfc_debugfs_terminate(struct lpfc_vport *vport)
808 {
809 #ifdef CONFIG_LPFC_DEBUG_FS
810         struct lpfc_hba   *phba = vport->phba;
811
812         if (vport->disc_trc) {
813                 kfree(vport->disc_trc);
814                 vport->disc_trc = NULL;
815         }
816         if (vport->debug_disc_trc) {
817                 debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
818                 vport->debug_disc_trc = NULL;
819         }
820         if (vport->debug_nodelist) {
821                 debugfs_remove(vport->debug_nodelist); /* nodelist */
822                 vport->debug_nodelist = NULL;
823         }
824
825         if (vport->vport_debugfs_root) {
826                 debugfs_remove(vport->vport_debugfs_root); /* vportX */
827                 vport->vport_debugfs_root = NULL;
828                 atomic_dec(&phba->debugfs_vport_count);
829         }
830         if (atomic_read(&phba->debugfs_vport_count) == 0) {
831
832                 if (phba->debug_dumpslim) {
833                         debugfs_remove(phba->debug_dumpslim); /* dumpslim */
834                         phba->debug_dumpslim = NULL;
835                 }
836                 if (phba->slow_ring_trc) {
837                         kfree(phba->slow_ring_trc);
838                         phba->slow_ring_trc = NULL;
839                 }
840                 if (phba->debug_slow_ring_trc) {
841                         /* slow_ring_trace */
842                         debugfs_remove(phba->debug_slow_ring_trc);
843                         phba->debug_slow_ring_trc = NULL;
844                 }
845
846                 if (phba->hba_debugfs_root) {
847                         debugfs_remove(phba->hba_debugfs_root); /* lpfcX */
848                         phba->hba_debugfs_root = NULL;
849                         atomic_dec(&lpfc_debugfs_hba_count);
850                 }
851
852                 if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
853                         debugfs_remove(lpfc_debugfs_root); /* lpfc */
854                         lpfc_debugfs_root = NULL;
855                 }
856         }
857 #endif
858         return;
859 }
860
861