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. *
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 *******************************************************************/
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>
32 #include <scsi/scsi.h>
33 #include <scsi/scsi_device.h>
34 #include <scsi/scsi_host.h>
35 #include <scsi/scsi_transport_fc.h>
39 #include "lpfc_disc.h"
40 #include "lpfc_scsi.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"
49 #ifdef CONFIG_LPFC_DEBUG_FS
52 * To access this interface the user should:
54 * # mount -t debugfs none /debug
56 * The lpfc debugfs directory hierachy is:
58 * where X is the lpfc hba unique_id
59 * where Y is the vport VPI on that hba
61 * Debugging services available per vport:
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
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");
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");
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");
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");
95 #include <linux/debugfs.h>
97 /* size of output line, for discovery_trace and slow_ring_trace */
98 #define LPFC_DEBUG_TRC_ENTRY_SIZE 100
100 /* nodelist output buffer size */
101 #define LPFC_NODELIST_SIZE 8192
102 #define LPFC_NODELIST_ENTRY_SIZE 120
104 /* dumpslim output buffer size */
105 #define LPFC_DUMPSLIM_SIZE 4096
107 /* hbqinfo output buffer size */
108 #define LPFC_HBQINFO_SIZE 8192
115 extern struct lpfc_hbq_init *lpfc_hbq_defs[];
117 atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
118 unsigned long lpfc_debugfs_start_time = 0L;
121 lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
123 int i, index, len, enable;
125 struct lpfc_debugfs_trc *dtp;
126 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
129 enable = lpfc_debugfs_enable;
130 lpfc_debugfs_enable = 0;
133 index = (atomic_read(&vport->disc_trc_cnt) + 1) &
134 (lpfc_debugfs_max_disc_trc - 1);
135 for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
136 dtp = vport->disc_trc + i;
139 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
141 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
142 dtp->seq_cnt, ms, dtp->fmt);
143 len += snprintf(buf+len, size-len, buffer,
144 dtp->data1, dtp->data2, dtp->data3);
146 for (i = 0; i < index; i++) {
147 dtp = vport->disc_trc + i;
150 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
152 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
153 dtp->seq_cnt, ms, dtp->fmt);
154 len += snprintf(buf+len, size-len, buffer,
155 dtp->data1, dtp->data2, dtp->data3);
158 lpfc_debugfs_enable = enable;
163 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
165 int i, index, len, enable;
167 struct lpfc_debugfs_trc *dtp;
168 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
171 enable = lpfc_debugfs_enable;
172 lpfc_debugfs_enable = 0;
175 index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
176 (lpfc_debugfs_max_slow_ring_trc - 1);
177 for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
178 dtp = phba->slow_ring_trc + i;
181 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
183 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
184 dtp->seq_cnt, ms, dtp->fmt);
185 len += snprintf(buf+len, size-len, buffer,
186 dtp->data1, dtp->data2, dtp->data3);
188 for (i = 0; i < index; i++) {
189 dtp = phba->slow_ring_trc + i;
192 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
194 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
195 dtp->seq_cnt, ms, dtp->fmt);
196 len += snprintf(buf+len, size-len, buffer,
197 dtp->data1, dtp->data2, dtp->data3);
200 lpfc_debugfs_enable = enable;
204 int lpfc_debugfs_last_hbq = -1;
207 lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
210 int cnt, i, j, found, posted, low;
211 uint32_t phys, raw_index, getidx;
212 struct lpfc_hbq_init *hip;
214 struct lpfc_hbq_entry *hbqe;
215 struct lpfc_dmabuf *d_buf;
216 struct hbq_dmabuf *hbq_buf;
218 cnt = LPFC_HBQINFO_SIZE;
219 spin_lock_irq(&phba->hbalock);
221 /* toggle between multiple hbqs, if any */
222 i = lpfc_sli_hbq_count();
224 lpfc_debugfs_last_hbq++;
225 if (lpfc_debugfs_last_hbq >= i)
226 lpfc_debugfs_last_hbq = 0;
229 lpfc_debugfs_last_hbq = 0;
231 i = lpfc_debugfs_last_hbq;
233 len += snprintf(buf+len, size-len, "HBQ %d Info\n", i);
235 hbqs = &phba->hbqs[i];
237 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
240 hip = lpfc_hbq_defs[i];
241 len += snprintf(buf+len, size-len,
242 "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
243 hip->hbq_index, hip->profile, hip->rn,
244 hip->buffer_count, hip->init_count, hip->add_count, posted);
246 raw_index = phba->hbq_get[i];
247 getidx = le32_to_cpu(raw_index);
248 len += snprintf(buf+len, size-len,
249 "entrys:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
250 hbqs->entry_count, hbqs->hbqPutIdx, hbqs->next_hbqPutIdx,
251 hbqs->local_hbqGetIdx, getidx);
253 hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
254 for (j=0; j<hbqs->entry_count; j++) {
255 len += snprintf(buf+len, size-len,
256 "%03d: %08x %04x %05x ", j,
257 hbqe->bde.addrLow, hbqe->bde.tus.w, hbqe->buffer_tag);
262 /* First calculate if slot has an associated posted buffer */
263 low = hbqs->hbqPutIdx - posted;
265 if ((j >= hbqs->hbqPutIdx) || (j < low)) {
266 len += snprintf(buf+len, size-len, "Unused\n");
271 if ((j >= hbqs->hbqPutIdx) &&
272 (j < (hbqs->entry_count+low))) {
273 len += snprintf(buf+len, size-len, "Unused\n");
278 /* Get the Buffer info for the posted buffer */
279 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
280 hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
281 phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
282 if (phys == hbqe->bde.addrLow) {
283 len += snprintf(buf+len, size-len,
284 "Buf%d: %p %06x\n", i,
285 hbq_buf->dbuf.virt, hbq_buf->tag);
292 len += snprintf(buf+len, size-len, "No DMAinfo?\n");
296 if (len > LPFC_HBQINFO_SIZE - 54)
299 spin_unlock_irq(&phba->hbalock);
304 lpfc_debugfs_dumpslim_data(struct lpfc_hba *phba, char *buf, int size)
308 uint32_t word0, word1, word2, word3;
310 struct lpfc_pgp *pgpp;
311 struct lpfc_sli *psli = &phba->sli;
312 struct lpfc_sli_ring *pring;
314 cnt = LPFC_DUMPSLIM_SIZE;
316 spin_lock_irq(&phba->hbalock);
318 len += snprintf(buf+len, size-len, "SLIM Mailbox\n");
319 ptr = (uint32_t *)phba->slim2p;
320 i = sizeof(MAILBOX_t);
322 len += snprintf(buf+len, size-len,
323 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
324 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
325 *(ptr+5), *(ptr+6), *(ptr+7));
327 i -= (8 * sizeof(uint32_t));
328 off += (8 * sizeof(uint32_t));
331 len += snprintf(buf+len, size-len, "SLIM PCB\n");
332 ptr = (uint32_t *)&phba->slim2p->pcb;
335 len += snprintf(buf+len, size-len,
336 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
337 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
338 *(ptr+5), *(ptr+6), *(ptr+7));
340 i -= (8 * sizeof(uint32_t));
341 off += (8 * sizeof(uint32_t));
344 pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port;
345 pring = &psli->ring[0];
346 len += snprintf(buf+len, size-len,
347 "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
348 "RSP PutInx:%d Max:%d\n",
349 pgpp->cmdGetInx, pring->numCiocb,
350 pring->next_cmdidx, pring->local_getidx, pring->flag,
351 pgpp->rspPutInx, pring->numRiocb);
354 pring = &psli->ring[1];
355 len += snprintf(buf+len, size-len,
356 "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
357 "RSP PutInx:%d Max:%d\n",
358 pgpp->cmdGetInx, pring->numCiocb,
359 pring->next_cmdidx, pring->local_getidx, pring->flag,
360 pgpp->rspPutInx, pring->numRiocb);
363 pring = &psli->ring[2];
364 len += snprintf(buf+len, size-len,
365 "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
366 "RSP PutInx:%d Max:%d\n",
367 pgpp->cmdGetInx, pring->numCiocb,
368 pring->next_cmdidx, pring->local_getidx, pring->flag,
369 pgpp->rspPutInx, pring->numRiocb);
372 pring = &psli->ring[3];
373 len += snprintf(buf+len, size-len,
374 "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
375 "RSP PutInx:%d Max:%d\n",
376 pgpp->cmdGetInx, pring->numCiocb,
377 pring->next_cmdidx, pring->local_getidx, pring->flag,
378 pgpp->rspPutInx, pring->numRiocb);
381 ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get;
382 word0 = readl(phba->HAregaddr);
383 word1 = readl(phba->CAregaddr);
384 word2 = readl(phba->HSregaddr);
385 word3 = readl(phba->HCregaddr);
386 len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x HC:%08x\n",
387 word0, word1, word2, word3);
388 spin_unlock_irq(&phba->hbalock);
393 lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
397 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
398 struct lpfc_nodelist *ndlp;
399 unsigned char *statep, *name;
401 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
403 spin_lock_irq(shost->host_lock);
404 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
406 len += snprintf(buf+len, size-len,
407 "Missing Nodelist Entries\n");
411 switch (ndlp->nlp_state) {
412 case NLP_STE_UNUSED_NODE:
415 case NLP_STE_PLOGI_ISSUE:
418 case NLP_STE_ADISC_ISSUE:
421 case NLP_STE_REG_LOGIN_ISSUE:
424 case NLP_STE_PRLI_ISSUE:
427 case NLP_STE_UNMAPPED_NODE:
430 case NLP_STE_MAPPED_NODE:
433 case NLP_STE_NPR_NODE:
439 len += snprintf(buf+len, size-len, "%s DID:x%06x ",
440 statep, ndlp->nlp_DID);
441 name = (unsigned char *)&ndlp->nlp_portname;
442 len += snprintf(buf+len, size-len,
443 "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
444 *name, *(name+1), *(name+2), *(name+3),
445 *(name+4), *(name+5), *(name+6), *(name+7));
446 name = (unsigned char *)&ndlp->nlp_nodename;
447 len += snprintf(buf+len, size-len,
448 "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
449 *name, *(name+1), *(name+2), *(name+3),
450 *(name+4), *(name+5), *(name+6), *(name+7));
451 len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ",
452 ndlp->nlp_rpi, ndlp->nlp_flag);
454 len += snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
455 if (ndlp->nlp_type & NLP_FC_NODE)
456 len += snprintf(buf+len, size-len, "FC_NODE ");
457 if (ndlp->nlp_type & NLP_FABRIC)
458 len += snprintf(buf+len, size-len, "FABRIC ");
459 if (ndlp->nlp_type & NLP_FCP_TARGET)
460 len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ",
462 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
463 len += snprintf(buf+len, size-len, "FCP_INITIATOR ");
464 len += snprintf(buf+len, size-len, "refcnt:%x",
465 atomic_read(&ndlp->kref.refcount));
466 len += snprintf(buf+len, size-len, "\n");
468 spin_unlock_irq(shost->host_lock);
475 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
476 uint32_t data1, uint32_t data2, uint32_t data3)
478 #ifdef CONFIG_LPFC_DEBUG_FS
479 struct lpfc_debugfs_trc *dtp;
482 if (!(lpfc_debugfs_mask_disc_trc & mask))
485 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
486 !vport || !vport->disc_trc)
489 index = atomic_inc_return(&vport->disc_trc_cnt) &
490 (lpfc_debugfs_max_disc_trc - 1);
491 dtp = vport->disc_trc + index;
496 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
503 lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
504 uint32_t data1, uint32_t data2, uint32_t data3)
506 #ifdef CONFIG_LPFC_DEBUG_FS
507 struct lpfc_debugfs_trc *dtp;
510 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
511 !phba || !phba->slow_ring_trc)
514 index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
515 (lpfc_debugfs_max_slow_ring_trc - 1);
516 dtp = phba->slow_ring_trc + index;
521 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
527 #ifdef CONFIG_LPFC_DEBUG_FS
529 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
531 struct lpfc_vport *vport = inode->i_private;
532 struct lpfc_debug *debug;
536 if (!lpfc_debugfs_max_disc_trc) {
541 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
545 /* Round to page boundry */
546 size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
547 size = PAGE_ALIGN(size);
549 debug->buffer = kmalloc(size, GFP_KERNEL);
550 if (!debug->buffer) {
555 debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
556 file->private_data = debug;
564 lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
566 struct lpfc_hba *phba = inode->i_private;
567 struct lpfc_debug *debug;
571 if (!lpfc_debugfs_max_slow_ring_trc) {
576 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
580 /* Round to page boundry */
581 size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
582 size = PAGE_ALIGN(size);
584 debug->buffer = kmalloc(size, GFP_KERNEL);
585 if (!debug->buffer) {
590 debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
591 file->private_data = debug;
599 lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
601 struct lpfc_hba *phba = inode->i_private;
602 struct lpfc_debug *debug;
605 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
609 /* Round to page boundry */
610 debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
611 if (!debug->buffer) {
616 debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
618 file->private_data = debug;
626 lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file)
628 struct lpfc_hba *phba = inode->i_private;
629 struct lpfc_debug *debug;
632 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
636 /* Round to page boundry */
637 debug->buffer = kmalloc(LPFC_DUMPSLIM_SIZE, GFP_KERNEL);
638 if (!debug->buffer) {
643 debug->len = lpfc_debugfs_dumpslim_data(phba, debug->buffer,
645 file->private_data = debug;
653 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
655 struct lpfc_vport *vport = inode->i_private;
656 struct lpfc_debug *debug;
659 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
663 /* Round to page boundry */
664 debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
665 if (!debug->buffer) {
670 debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
672 file->private_data = debug;
680 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
682 struct lpfc_debug *debug;
685 debug = file->private_data;
692 pos = file->f_pos + off;
695 pos = debug->len - off;
697 return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos);
701 lpfc_debugfs_read(struct file *file, char __user *buf,
702 size_t nbytes, loff_t *ppos)
704 struct lpfc_debug *debug = file->private_data;
705 return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
710 lpfc_debugfs_release(struct inode *inode, struct file *file)
712 struct lpfc_debug *debug = file->private_data;
714 kfree(debug->buffer);
720 #undef lpfc_debugfs_op_disc_trc
721 static struct file_operations lpfc_debugfs_op_disc_trc = {
722 .owner = THIS_MODULE,
723 .open = lpfc_debugfs_disc_trc_open,
724 .llseek = lpfc_debugfs_lseek,
725 .read = lpfc_debugfs_read,
726 .release = lpfc_debugfs_release,
729 #undef lpfc_debugfs_op_nodelist
730 static struct file_operations lpfc_debugfs_op_nodelist = {
731 .owner = THIS_MODULE,
732 .open = lpfc_debugfs_nodelist_open,
733 .llseek = lpfc_debugfs_lseek,
734 .read = lpfc_debugfs_read,
735 .release = lpfc_debugfs_release,
738 #undef lpfc_debugfs_op_hbqinfo
739 static struct file_operations lpfc_debugfs_op_hbqinfo = {
740 .owner = THIS_MODULE,
741 .open = lpfc_debugfs_hbqinfo_open,
742 .llseek = lpfc_debugfs_lseek,
743 .read = lpfc_debugfs_read,
744 .release = lpfc_debugfs_release,
747 #undef lpfc_debugfs_op_dumpslim
748 static struct file_operations lpfc_debugfs_op_dumpslim = {
749 .owner = THIS_MODULE,
750 .open = lpfc_debugfs_dumpslim_open,
751 .llseek = lpfc_debugfs_lseek,
752 .read = lpfc_debugfs_read,
753 .release = lpfc_debugfs_release,
756 #undef lpfc_debugfs_op_slow_ring_trc
757 static struct file_operations lpfc_debugfs_op_slow_ring_trc = {
758 .owner = THIS_MODULE,
759 .open = lpfc_debugfs_slow_ring_trc_open,
760 .llseek = lpfc_debugfs_lseek,
761 .read = lpfc_debugfs_read,
762 .release = lpfc_debugfs_release,
765 static struct dentry *lpfc_debugfs_root = NULL;
766 static atomic_t lpfc_debugfs_hba_count;
770 lpfc_debugfs_initialize(struct lpfc_vport *vport)
772 #ifdef CONFIG_LPFC_DEBUG_FS
773 struct lpfc_hba *phba = vport->phba;
777 if (!lpfc_debugfs_enable)
780 /* Setup lpfc root directory */
781 if (!lpfc_debugfs_root) {
782 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
783 atomic_set(&lpfc_debugfs_hba_count, 0);
784 if (!lpfc_debugfs_root) {
785 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
786 "0409 Cannot create debugfs root\n");
790 if (!lpfc_debugfs_start_time)
791 lpfc_debugfs_start_time = jiffies;
793 /* Setup lpfcX directory for specific HBA */
794 snprintf(name, sizeof(name), "lpfc%d", phba->brd_no);
795 if (!phba->hba_debugfs_root) {
796 phba->hba_debugfs_root =
797 debugfs_create_dir(name, lpfc_debugfs_root);
798 if (!phba->hba_debugfs_root) {
799 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
800 "0409 Cannot create debugfs hba\n");
803 atomic_inc(&lpfc_debugfs_hba_count);
804 atomic_set(&phba->debugfs_vport_count, 0);
807 snprintf(name, sizeof(name), "hbqinfo");
808 phba->debug_hbqinfo =
809 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
810 phba->hba_debugfs_root,
811 phba, &lpfc_debugfs_op_hbqinfo);
812 if (!phba->debug_hbqinfo) {
813 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
814 "0409 Cannot create debugfs hbqinfo\n");
819 snprintf(name, sizeof(name), "dumpslim");
820 phba->debug_dumpslim =
821 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
822 phba->hba_debugfs_root,
823 phba, &lpfc_debugfs_op_dumpslim);
824 if (!phba->debug_dumpslim) {
825 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
826 "0409 Cannot create debugfs dumpslim\n");
830 /* Setup slow ring trace */
831 if (lpfc_debugfs_max_slow_ring_trc) {
832 num = lpfc_debugfs_max_slow_ring_trc - 1;
833 if (num & lpfc_debugfs_max_slow_ring_trc) {
834 /* Change to be a power of 2 */
835 num = lpfc_debugfs_max_slow_ring_trc;
841 lpfc_debugfs_max_slow_ring_trc = (1 << i);
843 "lpfc_debugfs_max_disc_trc changed to "
844 "%d\n", lpfc_debugfs_max_disc_trc);
849 snprintf(name, sizeof(name), "slow_ring_trace");
850 phba->debug_slow_ring_trc =
851 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
852 phba->hba_debugfs_root,
853 phba, &lpfc_debugfs_op_slow_ring_trc);
854 if (!phba->debug_slow_ring_trc) {
855 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
856 "0409 Cannot create debugfs "
857 "slow_ring_trace\n");
860 if (!phba->slow_ring_trc) {
861 phba->slow_ring_trc = kmalloc(
862 (sizeof(struct lpfc_debugfs_trc) *
863 lpfc_debugfs_max_slow_ring_trc),
865 if (!phba->slow_ring_trc) {
866 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
867 "0409 Cannot create debugfs "
868 "slow_ring buffer\n");
871 atomic_set(&phba->slow_ring_trc_cnt, 0);
872 memset(phba->slow_ring_trc, 0,
873 (sizeof(struct lpfc_debugfs_trc) *
874 lpfc_debugfs_max_slow_ring_trc));
878 snprintf(name, sizeof(name), "vport%d", vport->vpi);
879 if (!vport->vport_debugfs_root) {
880 vport->vport_debugfs_root =
881 debugfs_create_dir(name, phba->hba_debugfs_root);
882 if (!vport->vport_debugfs_root) {
883 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
884 "0409 Cant create debugfs");
887 atomic_inc(&phba->debugfs_vport_count);
890 if (lpfc_debugfs_max_disc_trc) {
891 num = lpfc_debugfs_max_disc_trc - 1;
892 if (num & lpfc_debugfs_max_disc_trc) {
893 /* Change to be a power of 2 */
894 num = lpfc_debugfs_max_disc_trc;
900 lpfc_debugfs_max_disc_trc = (1 << i);
902 "lpfc_debugfs_max_disc_trc changed to %d\n",
903 lpfc_debugfs_max_disc_trc);
907 vport->disc_trc = kmalloc(
908 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
911 if (!vport->disc_trc) {
912 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
913 "0409 Cannot create debugfs disc trace "
917 atomic_set(&vport->disc_trc_cnt, 0);
918 memset(vport->disc_trc, 0,
919 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc));
921 snprintf(name, sizeof(name), "discovery_trace");
922 vport->debug_disc_trc =
923 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
924 vport->vport_debugfs_root,
925 vport, &lpfc_debugfs_op_disc_trc);
926 if (!vport->debug_disc_trc) {
927 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
928 "0409 Cannot create debugfs "
929 "discovery_trace\n");
932 snprintf(name, sizeof(name), "nodelist");
933 vport->debug_nodelist =
934 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
935 vport->vport_debugfs_root,
936 vport, &lpfc_debugfs_op_nodelist);
937 if (!vport->debug_nodelist) {
938 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
939 "0409 Cant create debugfs nodelist");
949 lpfc_debugfs_terminate(struct lpfc_vport *vport)
951 #ifdef CONFIG_LPFC_DEBUG_FS
952 struct lpfc_hba *phba = vport->phba;
954 if (vport->disc_trc) {
955 kfree(vport->disc_trc);
956 vport->disc_trc = NULL;
958 if (vport->debug_disc_trc) {
959 debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
960 vport->debug_disc_trc = NULL;
962 if (vport->debug_nodelist) {
963 debugfs_remove(vport->debug_nodelist); /* nodelist */
964 vport->debug_nodelist = NULL;
967 if (vport->vport_debugfs_root) {
968 debugfs_remove(vport->vport_debugfs_root); /* vportX */
969 vport->vport_debugfs_root = NULL;
970 atomic_dec(&phba->debugfs_vport_count);
972 if (atomic_read(&phba->debugfs_vport_count) == 0) {
974 if (phba->debug_hbqinfo) {
975 debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
976 phba->debug_hbqinfo = NULL;
978 if (phba->debug_dumpslim) {
979 debugfs_remove(phba->debug_dumpslim); /* dumpslim */
980 phba->debug_dumpslim = NULL;
982 if (phba->slow_ring_trc) {
983 kfree(phba->slow_ring_trc);
984 phba->slow_ring_trc = NULL;
986 if (phba->debug_slow_ring_trc) {
987 /* slow_ring_trace */
988 debugfs_remove(phba->debug_slow_ring_trc);
989 phba->debug_slow_ring_trc = NULL;
992 if (phba->hba_debugfs_root) {
993 debugfs_remove(phba->hba_debugfs_root); /* lpfcX */
994 phba->hba_debugfs_root = NULL;
995 atomic_dec(&lpfc_debugfs_hba_count);
998 if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
999 debugfs_remove(lpfc_debugfs_root); /* lpfc */
1000 lpfc_debugfs_root = NULL;