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