xref: /linux/drivers/scsi/lpfc/lpfc_debugfs.c (revision 42fda66387daa53538ae13a2c858396aaf037158)
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 = kmzlloc(
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 
1003