[SCSI] lpfc 8.2.2 : Miscellaneous Bug Fixes
[linux-2.6/linux-2.6-openrd.git] / drivers / scsi / lpfc / lpfc_debugfs.c
blob697a09dccb6f051cfaa3a50f453bb60094539589
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 *******************************************************************/
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>
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"
49 #ifdef CONFIG_LPFC_DEBUG_FS
50 /* debugfs interface
52 * To access this interface the user should:
53 * # mkdir /debug
54 * # mount -t debugfs none /debug
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
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 .
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
110 struct lpfc_debug {
111 char *buffer;
112 int len;
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;
120 static int
121 lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
123 int i, index, len, enable;
124 uint32_t ms;
125 struct lpfc_debugfs_trc *dtp;
126 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
129 enable = lpfc_debugfs_enable;
130 lpfc_debugfs_enable = 0;
132 len = 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;
137 if (!dtp->fmt)
138 continue;
139 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
140 snprintf(buffer,
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;
148 if (!dtp->fmt)
149 continue;
150 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
151 snprintf(buffer,
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;
159 return len;
162 static int
163 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
165 int i, index, len, enable;
166 uint32_t ms;
167 struct lpfc_debugfs_trc *dtp;
168 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
171 enable = lpfc_debugfs_enable;
172 lpfc_debugfs_enable = 0;
174 len = 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;
179 if (!dtp->fmt)
180 continue;
181 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
182 snprintf(buffer,
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;
190 if (!dtp->fmt)
191 continue;
192 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
193 snprintf(buffer,
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;
201 return len;
204 int lpfc_debugfs_last_hbq = -1;
206 static int
207 lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
209 int len = 0;
210 int cnt, i, j, found, posted, low;
211 uint32_t phys, raw_index, getidx;
212 struct lpfc_hbq_init *hip;
213 struct hbq_s *hbqs;
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();
223 if (i > 1) {
224 lpfc_debugfs_last_hbq++;
225 if (lpfc_debugfs_last_hbq >= i)
226 lpfc_debugfs_last_hbq = 0;
228 else
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];
236 posted = 0;
237 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
238 posted++;
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);
259 i = 0;
260 found = 0;
262 /* First calculate if slot has an associated posted buffer */
263 low = hbqs->hbqPutIdx - posted;
264 if (low >= 0) {
265 if ((j >= hbqs->hbqPutIdx) || (j < low)) {
266 len += snprintf(buf+len, size-len, "Unused\n");
267 goto skipit;
270 else {
271 if ((j >= hbqs->hbqPutIdx) &&
272 (j < (hbqs->entry_count+low))) {
273 len += snprintf(buf+len, size-len, "Unused\n");
274 goto skipit;
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);
286 found = 1;
287 break;
289 i++;
291 if (!found) {
292 len += snprintf(buf+len, size-len, "No DMAinfo?\n");
294 skipit:
295 hbqe++;
296 if (len > LPFC_HBQINFO_SIZE - 54)
297 break;
299 spin_unlock_irq(&phba->hbalock);
300 return len;
303 static int
304 lpfc_debugfs_dumpslim_data(struct lpfc_hba *phba, char *buf, int size)
306 int len = 0;
307 int cnt, i, off;
308 uint32_t word0, word1, word2, word3;
309 uint32_t *ptr;
310 struct lpfc_pgp *pgpp;
311 struct lpfc_sli *psli = &phba->sli;
312 struct lpfc_sli_ring *pring;
314 cnt = LPFC_DUMPSLIM_SIZE;
315 off = 0;
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);
321 while (i > 0) {
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));
326 ptr += 8;
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;
333 i = sizeof(PCB_t);
334 while (i > 0) {
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));
339 ptr += 8;
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);
352 pgpp++;
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);
361 pgpp++;
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);
370 pgpp++;
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);
389 return len;
392 static int
393 lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
395 int len = 0;
396 int cnt;
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) {
405 if (!cnt) {
406 len += snprintf(buf+len, size-len,
407 "Missing Nodelist Entries\n");
408 break;
410 cnt--;
411 switch (ndlp->nlp_state) {
412 case NLP_STE_UNUSED_NODE:
413 statep = "UNUSED";
414 break;
415 case NLP_STE_PLOGI_ISSUE:
416 statep = "PLOGI ";
417 break;
418 case NLP_STE_ADISC_ISSUE:
419 statep = "ADISC ";
420 break;
421 case NLP_STE_REG_LOGIN_ISSUE:
422 statep = "REGLOG";
423 break;
424 case NLP_STE_PRLI_ISSUE:
425 statep = "PRLI ";
426 break;
427 case NLP_STE_UNMAPPED_NODE:
428 statep = "UNMAP ";
429 break;
430 case NLP_STE_MAPPED_NODE:
431 statep = "MAPPED";
432 break;
433 case NLP_STE_NPR_NODE:
434 statep = "NPR ";
435 break;
436 default:
437 statep = "UNKNOWN";
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);
453 if (!ndlp->nlp_type)
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 ",
461 ndlp->nlp_sid);
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);
469 return len;
471 #endif
474 inline void
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;
480 int index;
482 if (!(lpfc_debugfs_mask_disc_trc & mask))
483 return;
485 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
486 !vport || !vport->disc_trc)
487 return;
489 index = atomic_inc_return(&vport->disc_trc_cnt) &
490 (lpfc_debugfs_max_disc_trc - 1);
491 dtp = vport->disc_trc + index;
492 dtp->fmt = fmt;
493 dtp->data1 = data1;
494 dtp->data2 = data2;
495 dtp->data3 = data3;
496 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
497 dtp->jif = jiffies;
498 #endif
499 return;
502 inline void
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;
508 int index;
510 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
511 !phba || !phba->slow_ring_trc)
512 return;
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;
517 dtp->fmt = fmt;
518 dtp->data1 = data1;
519 dtp->data2 = data2;
520 dtp->data3 = data3;
521 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
522 dtp->jif = jiffies;
523 #endif
524 return;
527 #ifdef CONFIG_LPFC_DEBUG_FS
528 static int
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;
533 int size;
534 int rc = -ENOMEM;
536 if (!lpfc_debugfs_max_disc_trc) {
537 rc = -ENOSPC;
538 goto out;
541 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
542 if (!debug)
543 goto out;
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) {
551 kfree(debug);
552 goto out;
555 debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
556 file->private_data = debug;
558 rc = 0;
559 out:
560 return rc;
563 static int
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;
568 int size;
569 int rc = -ENOMEM;
571 if (!lpfc_debugfs_max_slow_ring_trc) {
572 rc = -ENOSPC;
573 goto out;
576 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
577 if (!debug)
578 goto out;
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) {
586 kfree(debug);
587 goto out;
590 debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
591 file->private_data = debug;
593 rc = 0;
594 out:
595 return rc;
598 static int
599 lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
601 struct lpfc_hba *phba = inode->i_private;
602 struct lpfc_debug *debug;
603 int rc = -ENOMEM;
605 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
606 if (!debug)
607 goto out;
609 /* Round to page boundry */
610 debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
611 if (!debug->buffer) {
612 kfree(debug);
613 goto out;
616 debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
617 LPFC_HBQINFO_SIZE);
618 file->private_data = debug;
620 rc = 0;
621 out:
622 return rc;
625 static int
626 lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file)
628 struct lpfc_hba *phba = inode->i_private;
629 struct lpfc_debug *debug;
630 int rc = -ENOMEM;
632 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
633 if (!debug)
634 goto out;
636 /* Round to page boundry */
637 debug->buffer = kmalloc(LPFC_DUMPSLIM_SIZE, GFP_KERNEL);
638 if (!debug->buffer) {
639 kfree(debug);
640 goto out;
643 debug->len = lpfc_debugfs_dumpslim_data(phba, debug->buffer,
644 LPFC_DUMPSLIM_SIZE);
645 file->private_data = debug;
647 rc = 0;
648 out:
649 return rc;
652 static int
653 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
655 struct lpfc_vport *vport = inode->i_private;
656 struct lpfc_debug *debug;
657 int rc = -ENOMEM;
659 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
660 if (!debug)
661 goto out;
663 /* Round to page boundry */
664 debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
665 if (!debug->buffer) {
666 kfree(debug);
667 goto out;
670 debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
671 LPFC_NODELIST_SIZE);
672 file->private_data = debug;
674 rc = 0;
675 out:
676 return rc;
679 static loff_t
680 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
682 struct lpfc_debug *debug;
683 loff_t pos = -1;
685 debug = file->private_data;
687 switch (whence) {
688 case 0:
689 pos = off;
690 break;
691 case 1:
692 pos = file->f_pos + off;
693 break;
694 case 2:
695 pos = debug->len - off;
697 return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos);
700 static ssize_t
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,
706 debug->len);
709 static int
710 lpfc_debugfs_release(struct inode *inode, struct file *file)
712 struct lpfc_debug *debug = file->private_data;
714 kfree(debug->buffer);
715 kfree(debug);
717 return 0;
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;
767 #endif
769 inline void
770 lpfc_debugfs_initialize(struct lpfc_vport *vport)
772 #ifdef CONFIG_LPFC_DEBUG_FS
773 struct lpfc_hba *phba = vport->phba;
774 char name[64];
775 uint32_t num, i;
777 if (!lpfc_debugfs_enable)
778 return;
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");
787 goto debug_failed;
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");
801 goto debug_failed;
803 atomic_inc(&lpfc_debugfs_hba_count);
804 atomic_set(&phba->debugfs_vport_count, 0);
806 /* Setup hbqinfo */
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");
815 goto debug_failed;
818 /* Setup dumpslim */
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");
827 goto debug_failed;
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;
836 i = 0;
837 while (num > 1) {
838 num = num >> 1;
839 i++;
841 lpfc_debugfs_max_slow_ring_trc = (1 << i);
842 printk(KERN_ERR
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");
858 goto debug_failed;
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),
864 GFP_KERNEL);
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");
869 goto debug_failed;
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");
885 goto debug_failed;
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;
895 i = 0;
896 while (num > 1) {
897 num = num >> 1;
898 i++;
900 lpfc_debugfs_max_disc_trc = (1 << i);
901 printk(KERN_ERR
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),
909 GFP_KERNEL);
911 if (!vport->disc_trc) {
912 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
913 "0409 Cannot create debugfs disc trace "
914 "buffer\n");
915 goto debug_failed;
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");
930 goto debug_failed;
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");
940 goto debug_failed;
942 debug_failed:
943 return;
944 #endif
948 inline void
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;
1003 #endif
1004 return;