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