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 static atomic_t lpfc_debugfs_seq_trc_cnt
= ATOMIC_INIT(0);
116 static unsigned long lpfc_debugfs_start_time
= 0L;
119 lpfc_debugfs_disc_trc_data(struct lpfc_vport
*vport
, char *buf
, int size
)
121 int i
, index
, len
, enable
;
123 struct lpfc_debugfs_trc
*dtp
;
124 char buffer
[LPFC_DEBUG_TRC_ENTRY_SIZE
];
127 enable
= lpfc_debugfs_enable
;
128 lpfc_debugfs_enable
= 0;
131 index
= (atomic_read(&vport
->disc_trc_cnt
) + 1) &
132 (lpfc_debugfs_max_disc_trc
- 1);
133 for (i
= index
; i
< lpfc_debugfs_max_disc_trc
; i
++) {
134 dtp
= vport
->disc_trc
+ i
;
137 ms
= jiffies_to_msecs(dtp
->jif
- lpfc_debugfs_start_time
);
139 LPFC_DEBUG_TRC_ENTRY_SIZE
, "%010d:%010d ms:%s\n",
140 dtp
->seq_cnt
, ms
, dtp
->fmt
);
141 len
+= snprintf(buf
+len
, size
-len
, buffer
,
142 dtp
->data1
, dtp
->data2
, dtp
->data3
);
144 for (i
= 0; i
< index
; i
++) {
145 dtp
= vport
->disc_trc
+ i
;
148 ms
= jiffies_to_msecs(dtp
->jif
- lpfc_debugfs_start_time
);
150 LPFC_DEBUG_TRC_ENTRY_SIZE
, "%010d:%010d ms:%s\n",
151 dtp
->seq_cnt
, ms
, dtp
->fmt
);
152 len
+= snprintf(buf
+len
, size
-len
, buffer
,
153 dtp
->data1
, dtp
->data2
, dtp
->data3
);
156 lpfc_debugfs_enable
= enable
;
161 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba
*phba
, char *buf
, int size
)
163 int i
, index
, len
, enable
;
165 struct lpfc_debugfs_trc
*dtp
;
166 char buffer
[LPFC_DEBUG_TRC_ENTRY_SIZE
];
169 enable
= lpfc_debugfs_enable
;
170 lpfc_debugfs_enable
= 0;
173 index
= (atomic_read(&phba
->slow_ring_trc_cnt
) + 1) &
174 (lpfc_debugfs_max_slow_ring_trc
- 1);
175 for (i
= index
; i
< lpfc_debugfs_max_slow_ring_trc
; i
++) {
176 dtp
= phba
->slow_ring_trc
+ i
;
179 ms
= jiffies_to_msecs(dtp
->jif
- lpfc_debugfs_start_time
);
181 LPFC_DEBUG_TRC_ENTRY_SIZE
, "%010d:%010d ms:%s\n",
182 dtp
->seq_cnt
, ms
, dtp
->fmt
);
183 len
+= snprintf(buf
+len
, size
-len
, buffer
,
184 dtp
->data1
, dtp
->data2
, dtp
->data3
);
186 for (i
= 0; i
< index
; i
++) {
187 dtp
= phba
->slow_ring_trc
+ i
;
190 ms
= jiffies_to_msecs(dtp
->jif
- lpfc_debugfs_start_time
);
192 LPFC_DEBUG_TRC_ENTRY_SIZE
, "%010d:%010d ms:%s\n",
193 dtp
->seq_cnt
, ms
, dtp
->fmt
);
194 len
+= snprintf(buf
+len
, size
-len
, buffer
,
195 dtp
->data1
, dtp
->data2
, dtp
->data3
);
198 lpfc_debugfs_enable
= enable
;
202 static int lpfc_debugfs_last_hbq
= -1;
205 lpfc_debugfs_hbqinfo_data(struct lpfc_hba
*phba
, char *buf
, int size
)
208 int cnt
, i
, j
, found
, posted
, low
;
209 uint32_t phys
, raw_index
, getidx
;
210 struct lpfc_hbq_init
*hip
;
212 struct lpfc_hbq_entry
*hbqe
;
213 struct lpfc_dmabuf
*d_buf
;
214 struct hbq_dmabuf
*hbq_buf
;
216 cnt
= LPFC_HBQINFO_SIZE
;
217 spin_lock_irq(&phba
->hbalock
);
219 /* toggle between multiple hbqs, if any */
220 i
= lpfc_sli_hbq_count();
222 lpfc_debugfs_last_hbq
++;
223 if (lpfc_debugfs_last_hbq
>= i
)
224 lpfc_debugfs_last_hbq
= 0;
227 lpfc_debugfs_last_hbq
= 0;
229 i
= lpfc_debugfs_last_hbq
;
231 len
+= snprintf(buf
+len
, size
-len
, "HBQ %d Info\n", i
);
233 hbqs
= &phba
->hbqs
[i
];
235 list_for_each_entry(d_buf
, &hbqs
->hbq_buffer_list
, list
)
238 hip
= lpfc_hbq_defs
[i
];
239 len
+= snprintf(buf
+len
, size
-len
,
240 "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
241 hip
->hbq_index
, hip
->profile
, hip
->rn
,
242 hip
->buffer_count
, hip
->init_count
, hip
->add_count
, posted
);
244 raw_index
= phba
->hbq_get
[i
];
245 getidx
= le32_to_cpu(raw_index
);
246 len
+= snprintf(buf
+len
, size
-len
,
247 "entrys:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
248 hbqs
->entry_count
, hbqs
->hbqPutIdx
, hbqs
->next_hbqPutIdx
,
249 hbqs
->local_hbqGetIdx
, getidx
);
251 hbqe
= (struct lpfc_hbq_entry
*) phba
->hbqs
[i
].hbq_virt
;
252 for (j
=0; j
<hbqs
->entry_count
; j
++) {
253 len
+= snprintf(buf
+len
, size
-len
,
254 "%03d: %08x %04x %05x ", j
,
255 hbqe
->bde
.addrLow
, hbqe
->bde
.tus
.w
, hbqe
->buffer_tag
);
260 /* First calculate if slot has an associated posted buffer */
261 low
= hbqs
->hbqPutIdx
- posted
;
263 if ((j
>= hbqs
->hbqPutIdx
) || (j
< low
)) {
264 len
+= snprintf(buf
+len
, size
-len
, "Unused\n");
269 if ((j
>= hbqs
->hbqPutIdx
) &&
270 (j
< (hbqs
->entry_count
+low
))) {
271 len
+= snprintf(buf
+len
, size
-len
, "Unused\n");
276 /* Get the Buffer info for the posted buffer */
277 list_for_each_entry(d_buf
, &hbqs
->hbq_buffer_list
, list
) {
278 hbq_buf
= container_of(d_buf
, struct hbq_dmabuf
, dbuf
);
279 phys
= ((uint64_t)hbq_buf
->dbuf
.phys
& 0xffffffff);
280 if (phys
== hbqe
->bde
.addrLow
) {
281 len
+= snprintf(buf
+len
, size
-len
,
282 "Buf%d: %p %06x\n", i
,
283 hbq_buf
->dbuf
.virt
, hbq_buf
->tag
);
290 len
+= snprintf(buf
+len
, size
-len
, "No DMAinfo?\n");
294 if (len
> LPFC_HBQINFO_SIZE
- 54)
297 spin_unlock_irq(&phba
->hbalock
);
302 lpfc_debugfs_dumpslim_data(struct lpfc_hba
*phba
, char *buf
, int size
)
306 uint32_t word0
, word1
, word2
, word3
;
308 struct lpfc_pgp
*pgpp
;
309 struct lpfc_sli
*psli
= &phba
->sli
;
310 struct lpfc_sli_ring
*pring
;
312 cnt
= LPFC_DUMPSLIM_SIZE
;
314 spin_lock_irq(&phba
->hbalock
);
316 len
+= snprintf(buf
+len
, size
-len
, "SLIM Mailbox\n");
317 ptr
= (uint32_t *)phba
->slim2p
;
318 i
= sizeof(MAILBOX_t
);
320 len
+= snprintf(buf
+len
, size
-len
,
321 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
322 off
, *ptr
, *(ptr
+1), *(ptr
+2), *(ptr
+3), *(ptr
+4),
323 *(ptr
+5), *(ptr
+6), *(ptr
+7));
325 i
-= (8 * sizeof(uint32_t));
326 off
+= (8 * sizeof(uint32_t));
329 len
+= snprintf(buf
+len
, size
-len
, "SLIM PCB\n");
330 ptr
= (uint32_t *)&phba
->slim2p
->pcb
;
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));
338 i
-= (8 * sizeof(uint32_t));
339 off
+= (8 * sizeof(uint32_t));
342 pgpp
= (struct lpfc_pgp
*)&phba
->slim2p
->mbx
.us
.s3_pgp
.port
;
343 pring
= &psli
->ring
[0];
344 len
+= snprintf(buf
+len
, size
-len
,
345 "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
346 "RSP PutInx:%d Max:%d\n",
347 pgpp
->cmdGetInx
, pring
->numCiocb
,
348 pring
->next_cmdidx
, pring
->local_getidx
, pring
->flag
,
349 pgpp
->rspPutInx
, pring
->numRiocb
);
352 pring
= &psli
->ring
[1];
353 len
+= snprintf(buf
+len
, size
-len
,
354 "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
355 "RSP PutInx:%d Max:%d\n",
356 pgpp
->cmdGetInx
, pring
->numCiocb
,
357 pring
->next_cmdidx
, pring
->local_getidx
, pring
->flag
,
358 pgpp
->rspPutInx
, pring
->numRiocb
);
361 pring
= &psli
->ring
[2];
362 len
+= snprintf(buf
+len
, size
-len
,
363 "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
364 "RSP PutInx:%d Max:%d\n",
365 pgpp
->cmdGetInx
, pring
->numCiocb
,
366 pring
->next_cmdidx
, pring
->local_getidx
, pring
->flag
,
367 pgpp
->rspPutInx
, pring
->numRiocb
);
370 pring
= &psli
->ring
[3];
371 len
+= snprintf(buf
+len
, size
-len
,
372 "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
373 "RSP PutInx:%d Max:%d\n",
374 pgpp
->cmdGetInx
, pring
->numCiocb
,
375 pring
->next_cmdidx
, pring
->local_getidx
, pring
->flag
,
376 pgpp
->rspPutInx
, pring
->numRiocb
);
379 ptr
= (uint32_t *)&phba
->slim2p
->mbx
.us
.s3_pgp
.hbq_get
;
380 word0
= readl(phba
->HAregaddr
);
381 word1
= readl(phba
->CAregaddr
);
382 word2
= readl(phba
->HSregaddr
);
383 word3
= readl(phba
->HCregaddr
);
384 len
+= snprintf(buf
+len
, size
-len
, "HA:%08x CA:%08x HS:%08x HC:%08x\n",
385 word0
, word1
, word2
, word3
);
386 spin_unlock_irq(&phba
->hbalock
);
391 lpfc_debugfs_nodelist_data(struct lpfc_vport
*vport
, char *buf
, int size
)
395 struct Scsi_Host
*shost
= lpfc_shost_from_vport(vport
);
396 struct lpfc_nodelist
*ndlp
;
397 unsigned char *statep
, *name
;
399 cnt
= (LPFC_NODELIST_SIZE
/ LPFC_NODELIST_ENTRY_SIZE
);
401 spin_lock_irq(shost
->host_lock
);
402 list_for_each_entry(ndlp
, &vport
->fc_nodes
, nlp_listp
) {
404 len
+= snprintf(buf
+len
, size
-len
,
405 "Missing Nodelist Entries\n");
409 switch (ndlp
->nlp_state
) {
410 case NLP_STE_UNUSED_NODE
:
413 case NLP_STE_PLOGI_ISSUE
:
416 case NLP_STE_ADISC_ISSUE
:
419 case NLP_STE_REG_LOGIN_ISSUE
:
422 case NLP_STE_PRLI_ISSUE
:
425 case NLP_STE_UNMAPPED_NODE
:
428 case NLP_STE_MAPPED_NODE
:
431 case NLP_STE_NPR_NODE
:
437 len
+= snprintf(buf
+len
, size
-len
, "%s DID:x%06x ",
438 statep
, ndlp
->nlp_DID
);
439 name
= (unsigned char *)&ndlp
->nlp_portname
;
440 len
+= snprintf(buf
+len
, size
-len
,
441 "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
442 *name
, *(name
+1), *(name
+2), *(name
+3),
443 *(name
+4), *(name
+5), *(name
+6), *(name
+7));
444 name
= (unsigned char *)&ndlp
->nlp_nodename
;
445 len
+= snprintf(buf
+len
, size
-len
,
446 "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
447 *name
, *(name
+1), *(name
+2), *(name
+3),
448 *(name
+4), *(name
+5), *(name
+6), *(name
+7));
449 len
+= snprintf(buf
+len
, size
-len
, "RPI:%03d flag:x%08x ",
450 ndlp
->nlp_rpi
, ndlp
->nlp_flag
);
452 len
+= snprintf(buf
+len
, size
-len
, "UNKNOWN_TYPE ");
453 if (ndlp
->nlp_type
& NLP_FC_NODE
)
454 len
+= snprintf(buf
+len
, size
-len
, "FC_NODE ");
455 if (ndlp
->nlp_type
& NLP_FABRIC
)
456 len
+= snprintf(buf
+len
, size
-len
, "FABRIC ");
457 if (ndlp
->nlp_type
& NLP_FCP_TARGET
)
458 len
+= snprintf(buf
+len
, size
-len
, "FCP_TGT sid:%d ",
460 if (ndlp
->nlp_type
& NLP_FCP_INITIATOR
)
461 len
+= snprintf(buf
+len
, size
-len
, "FCP_INITIATOR ");
462 len
+= snprintf(buf
+len
, size
-len
, "refcnt:%x",
463 atomic_read(&ndlp
->kref
.refcount
));
464 len
+= snprintf(buf
+len
, size
-len
, "\n");
466 spin_unlock_irq(shost
->host_lock
);
473 lpfc_debugfs_disc_trc(struct lpfc_vport
*vport
, int mask
, char *fmt
,
474 uint32_t data1
, uint32_t data2
, uint32_t data3
)
476 #ifdef CONFIG_LPFC_DEBUG_FS
477 struct lpfc_debugfs_trc
*dtp
;
480 if (!(lpfc_debugfs_mask_disc_trc
& mask
))
483 if (!lpfc_debugfs_enable
|| !lpfc_debugfs_max_disc_trc
||
484 !vport
|| !vport
->disc_trc
)
487 index
= atomic_inc_return(&vport
->disc_trc_cnt
) &
488 (lpfc_debugfs_max_disc_trc
- 1);
489 dtp
= vport
->disc_trc
+ index
;
494 dtp
->seq_cnt
= atomic_inc_return(&lpfc_debugfs_seq_trc_cnt
);
501 lpfc_debugfs_slow_ring_trc(struct lpfc_hba
*phba
, char *fmt
,
502 uint32_t data1
, uint32_t data2
, uint32_t data3
)
504 #ifdef CONFIG_LPFC_DEBUG_FS
505 struct lpfc_debugfs_trc
*dtp
;
508 if (!lpfc_debugfs_enable
|| !lpfc_debugfs_max_slow_ring_trc
||
509 !phba
|| !phba
->slow_ring_trc
)
512 index
= atomic_inc_return(&phba
->slow_ring_trc_cnt
) &
513 (lpfc_debugfs_max_slow_ring_trc
- 1);
514 dtp
= phba
->slow_ring_trc
+ index
;
519 dtp
->seq_cnt
= atomic_inc_return(&lpfc_debugfs_seq_trc_cnt
);
525 #ifdef CONFIG_LPFC_DEBUG_FS
527 lpfc_debugfs_disc_trc_open(struct inode
*inode
, struct file
*file
)
529 struct lpfc_vport
*vport
= inode
->i_private
;
530 struct lpfc_debug
*debug
;
534 if (!lpfc_debugfs_max_disc_trc
) {
539 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
543 /* Round to page boundry */
544 size
= (lpfc_debugfs_max_disc_trc
* LPFC_DEBUG_TRC_ENTRY_SIZE
);
545 size
= PAGE_ALIGN(size
);
547 debug
->buffer
= kmalloc(size
, GFP_KERNEL
);
548 if (!debug
->buffer
) {
553 debug
->len
= lpfc_debugfs_disc_trc_data(vport
, debug
->buffer
, size
);
554 file
->private_data
= debug
;
562 lpfc_debugfs_slow_ring_trc_open(struct inode
*inode
, struct file
*file
)
564 struct lpfc_hba
*phba
= inode
->i_private
;
565 struct lpfc_debug
*debug
;
569 if (!lpfc_debugfs_max_slow_ring_trc
) {
574 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
578 /* Round to page boundry */
579 size
= (lpfc_debugfs_max_slow_ring_trc
* LPFC_DEBUG_TRC_ENTRY_SIZE
);
580 size
= PAGE_ALIGN(size
);
582 debug
->buffer
= kmalloc(size
, GFP_KERNEL
);
583 if (!debug
->buffer
) {
588 debug
->len
= lpfc_debugfs_slow_ring_trc_data(phba
, debug
->buffer
, size
);
589 file
->private_data
= debug
;
597 lpfc_debugfs_hbqinfo_open(struct inode
*inode
, struct file
*file
)
599 struct lpfc_hba
*phba
= inode
->i_private
;
600 struct lpfc_debug
*debug
;
603 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
607 /* Round to page boundry */
608 debug
->buffer
= kmalloc(LPFC_HBQINFO_SIZE
, GFP_KERNEL
);
609 if (!debug
->buffer
) {
614 debug
->len
= lpfc_debugfs_hbqinfo_data(phba
, debug
->buffer
,
616 file
->private_data
= debug
;
624 lpfc_debugfs_dumpslim_open(struct inode
*inode
, struct file
*file
)
626 struct lpfc_hba
*phba
= inode
->i_private
;
627 struct lpfc_debug
*debug
;
630 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
634 /* Round to page boundry */
635 debug
->buffer
= kmalloc(LPFC_DUMPSLIM_SIZE
, GFP_KERNEL
);
636 if (!debug
->buffer
) {
641 debug
->len
= lpfc_debugfs_dumpslim_data(phba
, debug
->buffer
,
643 file
->private_data
= debug
;
651 lpfc_debugfs_nodelist_open(struct inode
*inode
, struct file
*file
)
653 struct lpfc_vport
*vport
= inode
->i_private
;
654 struct lpfc_debug
*debug
;
657 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
661 /* Round to page boundry */
662 debug
->buffer
= kmalloc(LPFC_NODELIST_SIZE
, GFP_KERNEL
);
663 if (!debug
->buffer
) {
668 debug
->len
= lpfc_debugfs_nodelist_data(vport
, debug
->buffer
,
670 file
->private_data
= debug
;
678 lpfc_debugfs_lseek(struct file
*file
, loff_t off
, int whence
)
680 struct lpfc_debug
*debug
;
683 debug
= file
->private_data
;
690 pos
= file
->f_pos
+ off
;
693 pos
= debug
->len
- off
;
695 return (pos
< 0 || pos
> debug
->len
) ? -EINVAL
: (file
->f_pos
= pos
);
699 lpfc_debugfs_read(struct file
*file
, char __user
*buf
,
700 size_t nbytes
, loff_t
*ppos
)
702 struct lpfc_debug
*debug
= file
->private_data
;
703 return simple_read_from_buffer(buf
, nbytes
, ppos
, debug
->buffer
,
708 lpfc_debugfs_release(struct inode
*inode
, struct file
*file
)
710 struct lpfc_debug
*debug
= file
->private_data
;
712 kfree(debug
->buffer
);
718 #undef lpfc_debugfs_op_disc_trc
719 static struct file_operations lpfc_debugfs_op_disc_trc
= {
720 .owner
= THIS_MODULE
,
721 .open
= lpfc_debugfs_disc_trc_open
,
722 .llseek
= lpfc_debugfs_lseek
,
723 .read
= lpfc_debugfs_read
,
724 .release
= lpfc_debugfs_release
,
727 #undef lpfc_debugfs_op_nodelist
728 static struct file_operations lpfc_debugfs_op_nodelist
= {
729 .owner
= THIS_MODULE
,
730 .open
= lpfc_debugfs_nodelist_open
,
731 .llseek
= lpfc_debugfs_lseek
,
732 .read
= lpfc_debugfs_read
,
733 .release
= lpfc_debugfs_release
,
736 #undef lpfc_debugfs_op_hbqinfo
737 static struct file_operations lpfc_debugfs_op_hbqinfo
= {
738 .owner
= THIS_MODULE
,
739 .open
= lpfc_debugfs_hbqinfo_open
,
740 .llseek
= lpfc_debugfs_lseek
,
741 .read
= lpfc_debugfs_read
,
742 .release
= lpfc_debugfs_release
,
745 #undef lpfc_debugfs_op_dumpslim
746 static struct file_operations lpfc_debugfs_op_dumpslim
= {
747 .owner
= THIS_MODULE
,
748 .open
= lpfc_debugfs_dumpslim_open
,
749 .llseek
= lpfc_debugfs_lseek
,
750 .read
= lpfc_debugfs_read
,
751 .release
= lpfc_debugfs_release
,
754 #undef lpfc_debugfs_op_slow_ring_trc
755 static struct file_operations lpfc_debugfs_op_slow_ring_trc
= {
756 .owner
= THIS_MODULE
,
757 .open
= lpfc_debugfs_slow_ring_trc_open
,
758 .llseek
= lpfc_debugfs_lseek
,
759 .read
= lpfc_debugfs_read
,
760 .release
= lpfc_debugfs_release
,
763 static struct dentry
*lpfc_debugfs_root
= NULL
;
764 static atomic_t lpfc_debugfs_hba_count
;
768 lpfc_debugfs_initialize(struct lpfc_vport
*vport
)
770 #ifdef CONFIG_LPFC_DEBUG_FS
771 struct lpfc_hba
*phba
= vport
->phba
;
775 if (!lpfc_debugfs_enable
)
778 /* Setup lpfc root directory */
779 if (!lpfc_debugfs_root
) {
780 lpfc_debugfs_root
= debugfs_create_dir("lpfc", NULL
);
781 atomic_set(&lpfc_debugfs_hba_count
, 0);
782 if (!lpfc_debugfs_root
) {
783 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
784 "0409 Cannot create debugfs root\n");
788 if (!lpfc_debugfs_start_time
)
789 lpfc_debugfs_start_time
= jiffies
;
791 /* Setup lpfcX directory for specific HBA */
792 snprintf(name
, sizeof(name
), "lpfc%d", phba
->brd_no
);
793 if (!phba
->hba_debugfs_root
) {
794 phba
->hba_debugfs_root
=
795 debugfs_create_dir(name
, lpfc_debugfs_root
);
796 if (!phba
->hba_debugfs_root
) {
797 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
798 "0409 Cannot create debugfs hba\n");
801 atomic_inc(&lpfc_debugfs_hba_count
);
802 atomic_set(&phba
->debugfs_vport_count
, 0);
805 snprintf(name
, sizeof(name
), "hbqinfo");
806 phba
->debug_hbqinfo
=
807 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
808 phba
->hba_debugfs_root
,
809 phba
, &lpfc_debugfs_op_hbqinfo
);
810 if (!phba
->debug_hbqinfo
) {
811 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
812 "0409 Cannot create debugfs hbqinfo\n");
817 snprintf(name
, sizeof(name
), "dumpslim");
818 phba
->debug_dumpslim
=
819 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
820 phba
->hba_debugfs_root
,
821 phba
, &lpfc_debugfs_op_dumpslim
);
822 if (!phba
->debug_dumpslim
) {
823 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
824 "0409 Cannot create debugfs dumpslim\n");
828 /* Setup slow ring trace */
829 if (lpfc_debugfs_max_slow_ring_trc
) {
830 num
= lpfc_debugfs_max_slow_ring_trc
- 1;
831 if (num
& lpfc_debugfs_max_slow_ring_trc
) {
832 /* Change to be a power of 2 */
833 num
= lpfc_debugfs_max_slow_ring_trc
;
839 lpfc_debugfs_max_slow_ring_trc
= (1 << i
);
841 "lpfc_debugfs_max_disc_trc changed to "
842 "%d\n", lpfc_debugfs_max_disc_trc
);
847 snprintf(name
, sizeof(name
), "slow_ring_trace");
848 phba
->debug_slow_ring_trc
=
849 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
850 phba
->hba_debugfs_root
,
851 phba
, &lpfc_debugfs_op_slow_ring_trc
);
852 if (!phba
->debug_slow_ring_trc
) {
853 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
854 "0409 Cannot create debugfs "
855 "slow_ring_trace\n");
858 if (!phba
->slow_ring_trc
) {
859 phba
->slow_ring_trc
= kmalloc(
860 (sizeof(struct lpfc_debugfs_trc
) *
861 lpfc_debugfs_max_slow_ring_trc
),
863 if (!phba
->slow_ring_trc
) {
864 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
865 "0409 Cannot create debugfs "
866 "slow_ring buffer\n");
869 atomic_set(&phba
->slow_ring_trc_cnt
, 0);
870 memset(phba
->slow_ring_trc
, 0,
871 (sizeof(struct lpfc_debugfs_trc
) *
872 lpfc_debugfs_max_slow_ring_trc
));
876 snprintf(name
, sizeof(name
), "vport%d", vport
->vpi
);
877 if (!vport
->vport_debugfs_root
) {
878 vport
->vport_debugfs_root
=
879 debugfs_create_dir(name
, phba
->hba_debugfs_root
);
880 if (!vport
->vport_debugfs_root
) {
881 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
882 "0409 Cant create debugfs");
885 atomic_inc(&phba
->debugfs_vport_count
);
888 if (lpfc_debugfs_max_disc_trc
) {
889 num
= lpfc_debugfs_max_disc_trc
- 1;
890 if (num
& lpfc_debugfs_max_disc_trc
) {
891 /* Change to be a power of 2 */
892 num
= lpfc_debugfs_max_disc_trc
;
898 lpfc_debugfs_max_disc_trc
= (1 << i
);
900 "lpfc_debugfs_max_disc_trc changed to %d\n",
901 lpfc_debugfs_max_disc_trc
);
905 vport
->disc_trc
= kmalloc(
906 (sizeof(struct lpfc_debugfs_trc
) * lpfc_debugfs_max_disc_trc
),
909 if (!vport
->disc_trc
) {
910 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
911 "0409 Cannot create debugfs disc trace "
915 atomic_set(&vport
->disc_trc_cnt
, 0);
916 memset(vport
->disc_trc
, 0,
917 (sizeof(struct lpfc_debugfs_trc
) * lpfc_debugfs_max_disc_trc
));
919 snprintf(name
, sizeof(name
), "discovery_trace");
920 vport
->debug_disc_trc
=
921 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
922 vport
->vport_debugfs_root
,
923 vport
, &lpfc_debugfs_op_disc_trc
);
924 if (!vport
->debug_disc_trc
) {
925 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
926 "0409 Cannot create debugfs "
927 "discovery_trace\n");
930 snprintf(name
, sizeof(name
), "nodelist");
931 vport
->debug_nodelist
=
932 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
933 vport
->vport_debugfs_root
,
934 vport
, &lpfc_debugfs_op_nodelist
);
935 if (!vport
->debug_nodelist
) {
936 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
937 "0409 Cant create debugfs nodelist");
947 lpfc_debugfs_terminate(struct lpfc_vport
*vport
)
949 #ifdef CONFIG_LPFC_DEBUG_FS
950 struct lpfc_hba
*phba
= vport
->phba
;
952 if (vport
->disc_trc
) {
953 kfree(vport
->disc_trc
);
954 vport
->disc_trc
= NULL
;
956 if (vport
->debug_disc_trc
) {
957 debugfs_remove(vport
->debug_disc_trc
); /* discovery_trace */
958 vport
->debug_disc_trc
= NULL
;
960 if (vport
->debug_nodelist
) {
961 debugfs_remove(vport
->debug_nodelist
); /* nodelist */
962 vport
->debug_nodelist
= NULL
;
965 if (vport
->vport_debugfs_root
) {
966 debugfs_remove(vport
->vport_debugfs_root
); /* vportX */
967 vport
->vport_debugfs_root
= NULL
;
968 atomic_dec(&phba
->debugfs_vport_count
);
970 if (atomic_read(&phba
->debugfs_vport_count
) == 0) {
972 if (phba
->debug_hbqinfo
) {
973 debugfs_remove(phba
->debug_hbqinfo
); /* hbqinfo */
974 phba
->debug_hbqinfo
= NULL
;
976 if (phba
->debug_dumpslim
) {
977 debugfs_remove(phba
->debug_dumpslim
); /* dumpslim */
978 phba
->debug_dumpslim
= NULL
;
980 if (phba
->slow_ring_trc
) {
981 kfree(phba
->slow_ring_trc
);
982 phba
->slow_ring_trc
= NULL
;
984 if (phba
->debug_slow_ring_trc
) {
985 /* slow_ring_trace */
986 debugfs_remove(phba
->debug_slow_ring_trc
);
987 phba
->debug_slow_ring_trc
= NULL
;
990 if (phba
->hba_debugfs_root
) {
991 debugfs_remove(phba
->hba_debugfs_root
); /* lpfcX */
992 phba
->hba_debugfs_root
= NULL
;
993 atomic_dec(&lpfc_debugfs_hba_count
);
996 if (atomic_read(&lpfc_debugfs_hba_count
) == 0) {
997 debugfs_remove(lpfc_debugfs_root
); /* lpfc */
998 lpfc_debugfs_root
= NULL
;