xref: /linux/drivers/scsi/lpfc/lpfc_debugfs.c (revision ed3174d93c342b8b2eeba6bbd124707d55304a7b)
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, "refcnt:%x",
507 			atomic_read(&ndlp->kref.refcount));
508 		len +=  snprintf(buf+len, size-len, "\n");
509 	}
510 	spin_unlock_irq(shost->host_lock);
511 	return len;
512 }
513 #endif
514 
515 
516 inline void
517 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
518 	uint32_t data1, uint32_t data2, uint32_t data3)
519 {
520 #ifdef CONFIG_LPFC_DEBUG_FS
521 	struct lpfc_debugfs_trc *dtp;
522 	int index;
523 
524 	if (!(lpfc_debugfs_mask_disc_trc & mask))
525 		return;
526 
527 	if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
528 		!vport || !vport->disc_trc)
529 		return;
530 
531 	index = atomic_inc_return(&vport->disc_trc_cnt) &
532 		(lpfc_debugfs_max_disc_trc - 1);
533 	dtp = vport->disc_trc + index;
534 	dtp->fmt = fmt;
535 	dtp->data1 = data1;
536 	dtp->data2 = data2;
537 	dtp->data3 = data3;
538 	dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
539 	dtp->jif = jiffies;
540 #endif
541 	return;
542 }
543 
544 inline void
545 lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
546 	uint32_t data1, uint32_t data2, uint32_t data3)
547 {
548 #ifdef CONFIG_LPFC_DEBUG_FS
549 	struct lpfc_debugfs_trc *dtp;
550 	int index;
551 
552 	if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
553 		!phba || !phba->slow_ring_trc)
554 		return;
555 
556 	index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
557 		(lpfc_debugfs_max_slow_ring_trc - 1);
558 	dtp = phba->slow_ring_trc + index;
559 	dtp->fmt = fmt;
560 	dtp->data1 = data1;
561 	dtp->data2 = data2;
562 	dtp->data3 = data3;
563 	dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
564 	dtp->jif = jiffies;
565 #endif
566 	return;
567 }
568 
569 #ifdef CONFIG_LPFC_DEBUG_FS
570 static int
571 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
572 {
573 	struct lpfc_vport *vport = inode->i_private;
574 	struct lpfc_debug *debug;
575 	int size;
576 	int rc = -ENOMEM;
577 
578 	if (!lpfc_debugfs_max_disc_trc) {
579 		 rc = -ENOSPC;
580 		goto out;
581 	}
582 
583 	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
584 	if (!debug)
585 		goto out;
586 
587 	/* Round to page boundry */
588 	size =  (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
589 	size = PAGE_ALIGN(size);
590 
591 	debug->buffer = kmalloc(size, GFP_KERNEL);
592 	if (!debug->buffer) {
593 		kfree(debug);
594 		goto out;
595 	}
596 
597 	debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
598 	file->private_data = debug;
599 
600 	rc = 0;
601 out:
602 	return rc;
603 }
604 
605 static int
606 lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
607 {
608 	struct lpfc_hba *phba = inode->i_private;
609 	struct lpfc_debug *debug;
610 	int size;
611 	int rc = -ENOMEM;
612 
613 	if (!lpfc_debugfs_max_slow_ring_trc) {
614 		 rc = -ENOSPC;
615 		goto out;
616 	}
617 
618 	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
619 	if (!debug)
620 		goto out;
621 
622 	/* Round to page boundry */
623 	size =  (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
624 	size = PAGE_ALIGN(size);
625 
626 	debug->buffer = kmalloc(size, GFP_KERNEL);
627 	if (!debug->buffer) {
628 		kfree(debug);
629 		goto out;
630 	}
631 
632 	debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
633 	file->private_data = debug;
634 
635 	rc = 0;
636 out:
637 	return rc;
638 }
639 
640 static int
641 lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
642 {
643 	struct lpfc_hba *phba = inode->i_private;
644 	struct lpfc_debug *debug;
645 	int rc = -ENOMEM;
646 
647 	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
648 	if (!debug)
649 		goto out;
650 
651 	/* Round to page boundry */
652 	debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
653 	if (!debug->buffer) {
654 		kfree(debug);
655 		goto out;
656 	}
657 
658 	debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
659 		LPFC_HBQINFO_SIZE);
660 	file->private_data = debug;
661 
662 	rc = 0;
663 out:
664 	return rc;
665 }
666 
667 static int
668 lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file)
669 {
670 	struct lpfc_hba *phba = inode->i_private;
671 	struct lpfc_debug *debug;
672 	int rc = -ENOMEM;
673 
674 	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
675 	if (!debug)
676 		goto out;
677 
678 	/* Round to page boundry */
679 	debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL);
680 	if (!debug->buffer) {
681 		kfree(debug);
682 		goto out;
683 	}
684 
685 	debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer,
686 		LPFC_DUMPHBASLIM_SIZE);
687 	file->private_data = debug;
688 
689 	rc = 0;
690 out:
691 	return rc;
692 }
693 
694 static int
695 lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file)
696 {
697 	struct lpfc_hba *phba = inode->i_private;
698 	struct lpfc_debug *debug;
699 	int rc = -ENOMEM;
700 
701 	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
702 	if (!debug)
703 		goto out;
704 
705 	/* Round to page boundry */
706 	debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL);
707 	if (!debug->buffer) {
708 		kfree(debug);
709 		goto out;
710 	}
711 
712 	debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer,
713 		LPFC_DUMPHOSTSLIM_SIZE);
714 	file->private_data = debug;
715 
716 	rc = 0;
717 out:
718 	return rc;
719 }
720 
721 static int
722 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
723 {
724 	struct lpfc_vport *vport = inode->i_private;
725 	struct lpfc_debug *debug;
726 	int rc = -ENOMEM;
727 
728 	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
729 	if (!debug)
730 		goto out;
731 
732 	/* Round to page boundry */
733 	debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
734 	if (!debug->buffer) {
735 		kfree(debug);
736 		goto out;
737 	}
738 
739 	debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
740 		LPFC_NODELIST_SIZE);
741 	file->private_data = debug;
742 
743 	rc = 0;
744 out:
745 	return rc;
746 }
747 
748 static loff_t
749 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
750 {
751 	struct lpfc_debug *debug;
752 	loff_t pos = -1;
753 
754 	debug = file->private_data;
755 
756 	switch (whence) {
757 	case 0:
758 		pos = off;
759 		break;
760 	case 1:
761 		pos = file->f_pos + off;
762 		break;
763 	case 2:
764 		pos = debug->len - off;
765 	}
766 	return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos);
767 }
768 
769 static ssize_t
770 lpfc_debugfs_read(struct file *file, char __user *buf,
771 		  size_t nbytes, loff_t *ppos)
772 {
773 	struct lpfc_debug *debug = file->private_data;
774 	return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
775 				       debug->len);
776 }
777 
778 static int
779 lpfc_debugfs_release(struct inode *inode, struct file *file)
780 {
781 	struct lpfc_debug *debug = file->private_data;
782 
783 	kfree(debug->buffer);
784 	kfree(debug);
785 
786 	return 0;
787 }
788 
789 #undef lpfc_debugfs_op_disc_trc
790 static struct file_operations lpfc_debugfs_op_disc_trc = {
791 	.owner =        THIS_MODULE,
792 	.open =         lpfc_debugfs_disc_trc_open,
793 	.llseek =       lpfc_debugfs_lseek,
794 	.read =         lpfc_debugfs_read,
795 	.release =      lpfc_debugfs_release,
796 };
797 
798 #undef lpfc_debugfs_op_nodelist
799 static struct file_operations lpfc_debugfs_op_nodelist = {
800 	.owner =        THIS_MODULE,
801 	.open =         lpfc_debugfs_nodelist_open,
802 	.llseek =       lpfc_debugfs_lseek,
803 	.read =         lpfc_debugfs_read,
804 	.release =      lpfc_debugfs_release,
805 };
806 
807 #undef lpfc_debugfs_op_hbqinfo
808 static struct file_operations lpfc_debugfs_op_hbqinfo = {
809 	.owner =        THIS_MODULE,
810 	.open =         lpfc_debugfs_hbqinfo_open,
811 	.llseek =       lpfc_debugfs_lseek,
812 	.read =         lpfc_debugfs_read,
813 	.release =      lpfc_debugfs_release,
814 };
815 
816 #undef lpfc_debugfs_op_dumpHBASlim
817 static struct file_operations lpfc_debugfs_op_dumpHBASlim = {
818 	.owner =        THIS_MODULE,
819 	.open =         lpfc_debugfs_dumpHBASlim_open,
820 	.llseek =       lpfc_debugfs_lseek,
821 	.read =         lpfc_debugfs_read,
822 	.release =      lpfc_debugfs_release,
823 };
824 
825 #undef lpfc_debugfs_op_dumpHostSlim
826 static struct file_operations lpfc_debugfs_op_dumpHostSlim = {
827 	.owner =        THIS_MODULE,
828 	.open =         lpfc_debugfs_dumpHostSlim_open,
829 	.llseek =       lpfc_debugfs_lseek,
830 	.read =         lpfc_debugfs_read,
831 	.release =      lpfc_debugfs_release,
832 };
833 
834 #undef lpfc_debugfs_op_slow_ring_trc
835 static struct file_operations lpfc_debugfs_op_slow_ring_trc = {
836 	.owner =        THIS_MODULE,
837 	.open =         lpfc_debugfs_slow_ring_trc_open,
838 	.llseek =       lpfc_debugfs_lseek,
839 	.read =         lpfc_debugfs_read,
840 	.release =      lpfc_debugfs_release,
841 };
842 
843 static struct dentry *lpfc_debugfs_root = NULL;
844 static atomic_t lpfc_debugfs_hba_count;
845 #endif
846 
847 inline void
848 lpfc_debugfs_initialize(struct lpfc_vport *vport)
849 {
850 #ifdef CONFIG_LPFC_DEBUG_FS
851 	struct lpfc_hba   *phba = vport->phba;
852 	char name[64];
853 	uint32_t num, i;
854 
855 	if (!lpfc_debugfs_enable)
856 		return;
857 
858 	/* Setup lpfc root directory */
859 	if (!lpfc_debugfs_root) {
860 		lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
861 		atomic_set(&lpfc_debugfs_hba_count, 0);
862 		if (!lpfc_debugfs_root) {
863 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
864 					 "0409 Cannot create debugfs root\n");
865 			goto debug_failed;
866 		}
867 	}
868 	if (!lpfc_debugfs_start_time)
869 		lpfc_debugfs_start_time = jiffies;
870 
871 	/* Setup lpfcX directory for specific HBA */
872 	snprintf(name, sizeof(name), "lpfc%d", phba->brd_no);
873 	if (!phba->hba_debugfs_root) {
874 		phba->hba_debugfs_root =
875 			debugfs_create_dir(name, lpfc_debugfs_root);
876 		if (!phba->hba_debugfs_root) {
877 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
878 					 "0409 Cannot create debugfs hba\n");
879 			goto debug_failed;
880 		}
881 		atomic_inc(&lpfc_debugfs_hba_count);
882 		atomic_set(&phba->debugfs_vport_count, 0);
883 
884 		/* Setup hbqinfo */
885 		snprintf(name, sizeof(name), "hbqinfo");
886 		phba->debug_hbqinfo =
887 			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
888 				 phba->hba_debugfs_root,
889 				 phba, &lpfc_debugfs_op_hbqinfo);
890 		if (!phba->debug_hbqinfo) {
891 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
892 				"0409 Cannot create debugfs hbqinfo\n");
893 			goto debug_failed;
894 		}
895 
896 		/* Setup dumpHBASlim */
897 		snprintf(name, sizeof(name), "dumpHBASlim");
898 		phba->debug_dumpHBASlim =
899 			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
900 				 phba->hba_debugfs_root,
901 				 phba, &lpfc_debugfs_op_dumpHBASlim);
902 		if (!phba->debug_dumpHBASlim) {
903 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
904 				"0409 Cannot create debugfs dumpHBASlim\n");
905 			goto debug_failed;
906 		}
907 
908 		/* Setup dumpHostSlim */
909 		snprintf(name, sizeof(name), "dumpHostSlim");
910 		phba->debug_dumpHostSlim =
911 			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
912 				 phba->hba_debugfs_root,
913 				 phba, &lpfc_debugfs_op_dumpHostSlim);
914 		if (!phba->debug_dumpHostSlim) {
915 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
916 				"0409 Cannot create debugfs dumpHostSlim\n");
917 			goto debug_failed;
918 		}
919 
920 		/* Setup slow ring trace */
921 		if (lpfc_debugfs_max_slow_ring_trc) {
922 			num = lpfc_debugfs_max_slow_ring_trc - 1;
923 			if (num & lpfc_debugfs_max_slow_ring_trc) {
924 				/* Change to be a power of 2 */
925 				num = lpfc_debugfs_max_slow_ring_trc;
926 				i = 0;
927 				while (num > 1) {
928 					num = num >> 1;
929 					i++;
930 				}
931 				lpfc_debugfs_max_slow_ring_trc = (1 << i);
932 				printk(KERN_ERR
933 				       "lpfc_debugfs_max_disc_trc changed to "
934 				       "%d\n", lpfc_debugfs_max_disc_trc);
935 			}
936 		}
937 
938 
939 		snprintf(name, sizeof(name), "slow_ring_trace");
940 		phba->debug_slow_ring_trc =
941 			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
942 				 phba->hba_debugfs_root,
943 				 phba, &lpfc_debugfs_op_slow_ring_trc);
944 		if (!phba->debug_slow_ring_trc) {
945 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
946 					 "0409 Cannot create debugfs "
947 					 "slow_ring_trace\n");
948 			goto debug_failed;
949 		}
950 		if (!phba->slow_ring_trc) {
951 			phba->slow_ring_trc = kmalloc(
952 				(sizeof(struct lpfc_debugfs_trc) *
953 				lpfc_debugfs_max_slow_ring_trc),
954 				GFP_KERNEL);
955 			if (!phba->slow_ring_trc) {
956 				lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
957 						 "0409 Cannot create debugfs "
958 						 "slow_ring buffer\n");
959 				goto debug_failed;
960 			}
961 			atomic_set(&phba->slow_ring_trc_cnt, 0);
962 			memset(phba->slow_ring_trc, 0,
963 				(sizeof(struct lpfc_debugfs_trc) *
964 				lpfc_debugfs_max_slow_ring_trc));
965 		}
966 	}
967 
968 	snprintf(name, sizeof(name), "vport%d", vport->vpi);
969 	if (!vport->vport_debugfs_root) {
970 		vport->vport_debugfs_root =
971 			debugfs_create_dir(name, phba->hba_debugfs_root);
972 		if (!vport->vport_debugfs_root) {
973 			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
974 					 "0409 Cant create debugfs");
975 			goto debug_failed;
976 		}
977 		atomic_inc(&phba->debugfs_vport_count);
978 	}
979 
980 	if (lpfc_debugfs_max_disc_trc) {
981 		num = lpfc_debugfs_max_disc_trc - 1;
982 		if (num & lpfc_debugfs_max_disc_trc) {
983 			/* Change to be a power of 2 */
984 			num = lpfc_debugfs_max_disc_trc;
985 			i = 0;
986 			while (num > 1) {
987 				num = num >> 1;
988 				i++;
989 			}
990 			lpfc_debugfs_max_disc_trc = (1 << i);
991 			printk(KERN_ERR
992 			       "lpfc_debugfs_max_disc_trc changed to %d\n",
993 			       lpfc_debugfs_max_disc_trc);
994 		}
995 	}
996 
997 	vport->disc_trc = kzalloc(
998 		(sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
999 		GFP_KERNEL);
1000 
1001 	if (!vport->disc_trc) {
1002 		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1003 				 "0409 Cannot create debugfs disc trace "
1004 				 "buffer\n");
1005 		goto debug_failed;
1006 	}
1007 	atomic_set(&vport->disc_trc_cnt, 0);
1008 
1009 	snprintf(name, sizeof(name), "discovery_trace");
1010 	vport->debug_disc_trc =
1011 		debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
1012 				 vport->vport_debugfs_root,
1013 				 vport, &lpfc_debugfs_op_disc_trc);
1014 	if (!vport->debug_disc_trc) {
1015 		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1016 				 "0409 Cannot create debugfs "
1017 				 "discovery_trace\n");
1018 		goto debug_failed;
1019 	}
1020 	snprintf(name, sizeof(name), "nodelist");
1021 	vport->debug_nodelist =
1022 		debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
1023 				 vport->vport_debugfs_root,
1024 				 vport, &lpfc_debugfs_op_nodelist);
1025 	if (!vport->debug_nodelist) {
1026 		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1027 				 "0409 Cant create debugfs nodelist");
1028 		goto debug_failed;
1029 	}
1030 debug_failed:
1031 	return;
1032 #endif
1033 }
1034 
1035 
1036 inline void
1037 lpfc_debugfs_terminate(struct lpfc_vport *vport)
1038 {
1039 #ifdef CONFIG_LPFC_DEBUG_FS
1040 	struct lpfc_hba   *phba = vport->phba;
1041 
1042 	if (vport->disc_trc) {
1043 		kfree(vport->disc_trc);
1044 		vport->disc_trc = NULL;
1045 	}
1046 	if (vport->debug_disc_trc) {
1047 		debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
1048 		vport->debug_disc_trc = NULL;
1049 	}
1050 	if (vport->debug_nodelist) {
1051 		debugfs_remove(vport->debug_nodelist); /* nodelist */
1052 		vport->debug_nodelist = NULL;
1053 	}
1054 
1055 	if (vport->vport_debugfs_root) {
1056 		debugfs_remove(vport->vport_debugfs_root); /* vportX */
1057 		vport->vport_debugfs_root = NULL;
1058 		atomic_dec(&phba->debugfs_vport_count);
1059 	}
1060 	if (atomic_read(&phba->debugfs_vport_count) == 0) {
1061 
1062 		if (phba->debug_hbqinfo) {
1063 			debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
1064 			phba->debug_hbqinfo = NULL;
1065 		}
1066 		if (phba->debug_dumpHBASlim) {
1067 			debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */
1068 			phba->debug_dumpHBASlim = NULL;
1069 		}
1070 		if (phba->debug_dumpHostSlim) {
1071 			debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */
1072 			phba->debug_dumpHostSlim = NULL;
1073 		}
1074 		if (phba->slow_ring_trc) {
1075 			kfree(phba->slow_ring_trc);
1076 			phba->slow_ring_trc = NULL;
1077 		}
1078 		if (phba->debug_slow_ring_trc) {
1079 			/* slow_ring_trace */
1080 			debugfs_remove(phba->debug_slow_ring_trc);
1081 			phba->debug_slow_ring_trc = NULL;
1082 		}
1083 
1084 		if (phba->hba_debugfs_root) {
1085 			debugfs_remove(phba->hba_debugfs_root); /* lpfcX */
1086 			phba->hba_debugfs_root = NULL;
1087 			atomic_dec(&lpfc_debugfs_hba_count);
1088 		}
1089 
1090 		if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
1091 			debugfs_remove(lpfc_debugfs_root); /* lpfc */
1092 			lpfc_debugfs_root = NULL;
1093 		}
1094 	}
1095 #endif
1096 	return;
1097 }
1098 
1099 
1100