1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for         *
3 * Fibre Channel Host Bus Adapters.                                *
4 * Copyright (C) 2007-2015 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/module.h>
24#include <linux/dma-mapping.h>
25#include <linux/idr.h>
26#include <linux/interrupt.h>
27#include <linux/kthread.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <linux/spinlock.h>
31#include <linux/ctype.h>
32
33#include <scsi/scsi.h>
34#include <scsi/scsi_device.h>
35#include <scsi/scsi_host.h>
36#include <scsi/scsi_transport_fc.h>
37
38#include "lpfc_hw4.h"
39#include "lpfc_hw.h"
40#include "lpfc_sli.h"
41#include "lpfc_sli4.h"
42#include "lpfc_nl.h"
43#include "lpfc_disc.h"
44#include "lpfc_scsi.h"
45#include "lpfc.h"
46#include "lpfc_logmsg.h"
47#include "lpfc_crtn.h"
48#include "lpfc_vport.h"
49#include "lpfc_version.h"
50#include "lpfc_compat.h"
51#include "lpfc_debugfs.h"
52#include "lpfc_bsg.h"
53
54#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
55/*
56 * debugfs interface
57 *
58 * To access this interface the user should:
59 * # mount -t debugfs none /sys/kernel/debug
60 *
61 * The lpfc debugfs directory hierarchy is:
62 * /sys/kernel/debug/lpfc/fnX/vportY
63 * where X is the lpfc hba function unique_id
64 * where Y is the vport VPI on that hba
65 *
66 * Debugging services available per vport:
67 * discovery_trace
68 * This is an ACSII readable file that contains a trace of the last
69 * lpfc_debugfs_max_disc_trc events that happened on a specific vport.
70 * See lpfc_debugfs.h for different categories of  discovery events.
71 * To enable the discovery trace, the following module parameters must be set:
72 * lpfc_debugfs_enable=1         Turns on lpfc debugfs filesystem support
73 * lpfc_debugfs_max_disc_trc=X   Where X is the event trace depth for
74 *                               EACH vport. X MUST also be a power of 2.
75 * lpfc_debugfs_mask_disc_trc=Y  Where Y is an event mask as defined in
76 *                               lpfc_debugfs.h .
77 *
78 * slow_ring_trace
79 * This is an ACSII readable file that contains a trace of the last
80 * lpfc_debugfs_max_slow_ring_trc events that happened on a specific HBA.
81 * To enable the slow ring trace, the following module parameters must be set:
82 * lpfc_debugfs_enable=1         Turns on lpfc debugfs filesystem support
83 * lpfc_debugfs_max_slow_ring_trc=X   Where X is the event trace depth for
84 *                               the HBA. X MUST also be a power of 2.
85 */
86static int lpfc_debugfs_enable = 1;
87module_param(lpfc_debugfs_enable, int, S_IRUGO);
88MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services");
89
90/* This MUST be a power of 2 */
91static int lpfc_debugfs_max_disc_trc;
92module_param(lpfc_debugfs_max_disc_trc, int, S_IRUGO);
93MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc,
94	"Set debugfs discovery trace depth");
95
96/* This MUST be a power of 2 */
97static int lpfc_debugfs_max_slow_ring_trc;
98module_param(lpfc_debugfs_max_slow_ring_trc, int, S_IRUGO);
99MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
100	"Set debugfs slow ring trace depth");
101
102static int lpfc_debugfs_mask_disc_trc;
103module_param(lpfc_debugfs_mask_disc_trc, int, S_IRUGO);
104MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
105	"Set debugfs discovery trace mask");
106
107#include <linux/debugfs.h>
108
109static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
110static unsigned long lpfc_debugfs_start_time = 0L;
111
112/* iDiag */
113static struct lpfc_idiag idiag;
114
115/**
116 * lpfc_debugfs_disc_trc_data - Dump discovery logging to a buffer
117 * @vport: The vport to gather the log info from.
118 * @buf: The buffer to dump log into.
119 * @size: The maximum amount of data to process.
120 *
121 * Description:
122 * This routine gathers the lpfc discovery debugfs data from the @vport and
123 * dumps it to @buf up to @size number of bytes. It will start at the next entry
124 * in the log and process the log until the end of the buffer. Then it will
125 * gather from the beginning of the log and process until the current entry.
126 *
127 * Notes:
128 * Discovery logging will be disabled while while this routine dumps the log.
129 *
130 * Return Value:
131 * This routine returns the amount of bytes that were dumped into @buf and will
132 * not exceed @size.
133 **/
134static int
135lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
136{
137	int i, index, len, enable;
138	uint32_t ms;
139	struct lpfc_debugfs_trc *dtp;
140	char *buffer;
141
142	buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
143	if (!buffer)
144		return 0;
145
146	enable = lpfc_debugfs_enable;
147	lpfc_debugfs_enable = 0;
148
149	len = 0;
150	index = (atomic_read(&vport->disc_trc_cnt) + 1) &
151		(lpfc_debugfs_max_disc_trc - 1);
152	for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
153		dtp = vport->disc_trc + i;
154		if (!dtp->fmt)
155			continue;
156		ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
157		snprintf(buffer,
158			LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
159			dtp->seq_cnt, ms, dtp->fmt);
160		len +=  snprintf(buf+len, size-len, buffer,
161			dtp->data1, dtp->data2, dtp->data3);
162	}
163	for (i = 0; i < index; i++) {
164		dtp = vport->disc_trc + i;
165		if (!dtp->fmt)
166			continue;
167		ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
168		snprintf(buffer,
169			LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
170			dtp->seq_cnt, ms, dtp->fmt);
171		len +=  snprintf(buf+len, size-len, buffer,
172			dtp->data1, dtp->data2, dtp->data3);
173	}
174
175	lpfc_debugfs_enable = enable;
176	kfree(buffer);
177
178	return len;
179}
180
181/**
182 * lpfc_debugfs_slow_ring_trc_data - Dump slow ring logging to a buffer
183 * @phba: The HBA to gather the log info from.
184 * @buf: The buffer to dump log into.
185 * @size: The maximum amount of data to process.
186 *
187 * Description:
188 * This routine gathers the lpfc slow ring debugfs data from the @phba and
189 * dumps it to @buf up to @size number of bytes. It will start at the next entry
190 * in the log and process the log until the end of the buffer. Then it will
191 * gather from the beginning of the log and process until the current entry.
192 *
193 * Notes:
194 * Slow ring logging will be disabled while while this routine dumps the log.
195 *
196 * Return Value:
197 * This routine returns the amount of bytes that were dumped into @buf and will
198 * not exceed @size.
199 **/
200static int
201lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
202{
203	int i, index, len, enable;
204	uint32_t ms;
205	struct lpfc_debugfs_trc *dtp;
206	char *buffer;
207
208	buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
209	if (!buffer)
210		return 0;
211
212	enable = lpfc_debugfs_enable;
213	lpfc_debugfs_enable = 0;
214
215	len = 0;
216	index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
217		(lpfc_debugfs_max_slow_ring_trc - 1);
218	for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
219		dtp = phba->slow_ring_trc + i;
220		if (!dtp->fmt)
221			continue;
222		ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
223		snprintf(buffer,
224			LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
225			dtp->seq_cnt, ms, dtp->fmt);
226		len +=  snprintf(buf+len, size-len, buffer,
227			dtp->data1, dtp->data2, dtp->data3);
228	}
229	for (i = 0; i < index; i++) {
230		dtp = phba->slow_ring_trc + i;
231		if (!dtp->fmt)
232			continue;
233		ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
234		snprintf(buffer,
235			LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
236			dtp->seq_cnt, ms, dtp->fmt);
237		len +=  snprintf(buf+len, size-len, buffer,
238			dtp->data1, dtp->data2, dtp->data3);
239	}
240
241	lpfc_debugfs_enable = enable;
242	kfree(buffer);
243
244	return len;
245}
246
247static int lpfc_debugfs_last_hbq = -1;
248
249/**
250 * lpfc_debugfs_hbqinfo_data - Dump host buffer queue info to a buffer
251 * @phba: The HBA to gather host buffer info from.
252 * @buf: The buffer to dump log into.
253 * @size: The maximum amount of data to process.
254 *
255 * Description:
256 * This routine dumps the host buffer queue info from the @phba to @buf up to
257 * @size number of bytes. A header that describes the current hbq state will be
258 * dumped to @buf first and then info on each hbq entry will be dumped to @buf
259 * until @size bytes have been dumped or all the hbq info has been dumped.
260 *
261 * Notes:
262 * This routine will rotate through each configured HBQ each time called.
263 *
264 * Return Value:
265 * This routine returns the amount of bytes that were dumped into @buf and will
266 * not exceed @size.
267 **/
268static int
269lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
270{
271	int len = 0;
272	int i, j, found, posted, low;
273	uint32_t phys, raw_index, getidx;
274	struct lpfc_hbq_init *hip;
275	struct hbq_s *hbqs;
276	struct lpfc_hbq_entry *hbqe;
277	struct lpfc_dmabuf *d_buf;
278	struct hbq_dmabuf *hbq_buf;
279
280	if (phba->sli_rev != 3)
281		return 0;
282
283	spin_lock_irq(&phba->hbalock);
284
285	/* toggle between multiple hbqs, if any */
286	i = lpfc_sli_hbq_count();
287	if (i > 1) {
288		 lpfc_debugfs_last_hbq++;
289		 if (lpfc_debugfs_last_hbq >= i)
290			lpfc_debugfs_last_hbq = 0;
291	}
292	else
293		lpfc_debugfs_last_hbq = 0;
294
295	i = lpfc_debugfs_last_hbq;
296
297	len +=  snprintf(buf+len, size-len, "HBQ %d Info\n", i);
298
299	hbqs =  &phba->hbqs[i];
300	posted = 0;
301	list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
302		posted++;
303
304	hip =  lpfc_hbq_defs[i];
305	len +=  snprintf(buf+len, size-len,
306		"idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
307		hip->hbq_index, hip->profile, hip->rn,
308		hip->buffer_count, hip->init_count, hip->add_count, posted);
309
310	raw_index = phba->hbq_get[i];
311	getidx = le32_to_cpu(raw_index);
312	len +=  snprintf(buf+len, size-len,
313		"entrys:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
314		hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx,
315		hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx);
316
317	hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
318	for (j=0; j<hbqs->entry_count; j++) {
319		len +=  snprintf(buf+len, size-len,
320			"%03d: %08x %04x %05x ", j,
321			le32_to_cpu(hbqe->bde.addrLow),
322			le32_to_cpu(hbqe->bde.tus.w),
323			le32_to_cpu(hbqe->buffer_tag));
324		i = 0;
325		found = 0;
326
327		/* First calculate if slot has an associated posted buffer */
328		low = hbqs->hbqPutIdx - posted;
329		if (low >= 0) {
330			if ((j >= hbqs->hbqPutIdx) || (j < low)) {
331				len +=  snprintf(buf+len, size-len, "Unused\n");
332				goto skipit;
333			}
334		}
335		else {
336			if ((j >= hbqs->hbqPutIdx) &&
337				(j < (hbqs->entry_count+low))) {
338				len +=  snprintf(buf+len, size-len, "Unused\n");
339				goto skipit;
340			}
341		}
342
343		/* Get the Buffer info for the posted buffer */
344		list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
345			hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
346			phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
347			if (phys == le32_to_cpu(hbqe->bde.addrLow)) {
348				len +=  snprintf(buf+len, size-len,
349					"Buf%d: %p %06x\n", i,
350					hbq_buf->dbuf.virt, hbq_buf->tag);
351				found = 1;
352				break;
353			}
354			i++;
355		}
356		if (!found) {
357			len +=  snprintf(buf+len, size-len, "No DMAinfo?\n");
358		}
359skipit:
360		hbqe++;
361		if (len > LPFC_HBQINFO_SIZE - 54)
362			break;
363	}
364	spin_unlock_irq(&phba->hbalock);
365	return len;
366}
367
368static int lpfc_debugfs_last_hba_slim_off;
369
370/**
371 * lpfc_debugfs_dumpHBASlim_data - Dump HBA SLIM info to a buffer
372 * @phba: The HBA to gather SLIM info from.
373 * @buf: The buffer to dump log into.
374 * @size: The maximum amount of data to process.
375 *
376 * Description:
377 * This routine dumps the current contents of HBA SLIM for the HBA associated
378 * with @phba to @buf up to @size bytes of data. This is the raw HBA SLIM data.
379 *
380 * Notes:
381 * This routine will only dump up to 1024 bytes of data each time called and
382 * should be called multiple times to dump the entire HBA SLIM.
383 *
384 * Return Value:
385 * This routine returns the amount of bytes that were dumped into @buf and will
386 * not exceed @size.
387 **/
388static int
389lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
390{
391	int len = 0;
392	int i, off;
393	uint32_t *ptr;
394	char *buffer;
395
396	buffer = kmalloc(1024, GFP_KERNEL);
397	if (!buffer)
398		return 0;
399
400	off = 0;
401	spin_lock_irq(&phba->hbalock);
402
403	len +=  snprintf(buf+len, size-len, "HBA SLIM\n");
404	lpfc_memcpy_from_slim(buffer,
405		phba->MBslimaddr + lpfc_debugfs_last_hba_slim_off, 1024);
406
407	ptr = (uint32_t *)&buffer[0];
408	off = lpfc_debugfs_last_hba_slim_off;
409
410	/* Set it up for the next time */
411	lpfc_debugfs_last_hba_slim_off += 1024;
412	if (lpfc_debugfs_last_hba_slim_off >= 4096)
413		lpfc_debugfs_last_hba_slim_off = 0;
414
415	i = 1024;
416	while (i > 0) {
417		len +=  snprintf(buf+len, size-len,
418		"%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
419		off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
420		*(ptr+5), *(ptr+6), *(ptr+7));
421		ptr += 8;
422		i -= (8 * sizeof(uint32_t));
423		off += (8 * sizeof(uint32_t));
424	}
425
426	spin_unlock_irq(&phba->hbalock);
427	kfree(buffer);
428
429	return len;
430}
431
432/**
433 * lpfc_debugfs_dumpHostSlim_data - Dump host SLIM info to a buffer
434 * @phba: The HBA to gather Host SLIM info from.
435 * @buf: The buffer to dump log into.
436 * @size: The maximum amount of data to process.
437 *
438 * Description:
439 * This routine dumps the current contents of host SLIM for the host associated
440 * with @phba to @buf up to @size bytes of data. The dump will contain the
441 * Mailbox, PCB, Rings, and Registers that are located in host memory.
442 *
443 * Return Value:
444 * This routine returns the amount of bytes that were dumped into @buf and will
445 * not exceed @size.
446 **/
447static int
448lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
449{
450	int len = 0;
451	int i, off;
452	uint32_t word0, word1, word2, word3;
453	uint32_t *ptr;
454	struct lpfc_pgp *pgpp;
455	struct lpfc_sli *psli = &phba->sli;
456	struct lpfc_sli_ring *pring;
457
458	off = 0;
459	spin_lock_irq(&phba->hbalock);
460
461	len +=  snprintf(buf+len, size-len, "SLIM Mailbox\n");
462	ptr = (uint32_t *)phba->slim2p.virt;
463	i = sizeof(MAILBOX_t);
464	while (i > 0) {
465		len +=  snprintf(buf+len, size-len,
466		"%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
467		off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
468		*(ptr+5), *(ptr+6), *(ptr+7));
469		ptr += 8;
470		i -= (8 * sizeof(uint32_t));
471		off += (8 * sizeof(uint32_t));
472	}
473
474	len +=  snprintf(buf+len, size-len, "SLIM PCB\n");
475	ptr = (uint32_t *)phba->pcb;
476	i = sizeof(PCB_t);
477	while (i > 0) {
478		len +=  snprintf(buf+len, size-len,
479		"%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
480		off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
481		*(ptr+5), *(ptr+6), *(ptr+7));
482		ptr += 8;
483		i -= (8 * sizeof(uint32_t));
484		off += (8 * sizeof(uint32_t));
485	}
486
487	for (i = 0; i < 4; i++) {
488		pgpp = &phba->port_gp[i];
489		pring = &psli->ring[i];
490		len +=  snprintf(buf+len, size-len,
491				 "Ring %d: CMD GetInx:%d (Max:%d Next:%d "
492				 "Local:%d flg:x%x)  RSP PutInx:%d Max:%d\n",
493				 i, pgpp->cmdGetInx, pring->sli.sli3.numCiocb,
494				 pring->sli.sli3.next_cmdidx,
495				 pring->sli.sli3.local_getidx,
496				 pring->flag, pgpp->rspPutInx,
497				 pring->sli.sli3.numRiocb);
498	}
499
500	if (phba->sli_rev <= LPFC_SLI_REV3) {
501		word0 = readl(phba->HAregaddr);
502		word1 = readl(phba->CAregaddr);
503		word2 = readl(phba->HSregaddr);
504		word3 = readl(phba->HCregaddr);
505		len +=  snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x "
506				 "HC:%08x\n", word0, word1, word2, word3);
507	}
508	spin_unlock_irq(&phba->hbalock);
509	return len;
510}
511
512/**
513 * lpfc_debugfs_nodelist_data - Dump target node list to a buffer
514 * @vport: The vport to gather target node info from.
515 * @buf: The buffer to dump log into.
516 * @size: The maximum amount of data to process.
517 *
518 * Description:
519 * This routine dumps the current target node list associated with @vport to
520 * @buf up to @size bytes of data. Each node entry in the dump will contain a
521 * node state, DID, WWPN, WWNN, RPI, flags, type, and other useful fields.
522 *
523 * Return Value:
524 * This routine returns the amount of bytes that were dumped into @buf and will
525 * not exceed @size.
526 **/
527static int
528lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
529{
530	int len = 0;
531	int cnt;
532	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
533	struct lpfc_nodelist *ndlp;
534	unsigned char *statep, *name;
535
536	cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
537
538	spin_lock_irq(shost->host_lock);
539	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
540		if (!cnt) {
541			len +=  snprintf(buf+len, size-len,
542				"Missing Nodelist Entries\n");
543			break;
544		}
545		cnt--;
546		switch (ndlp->nlp_state) {
547		case NLP_STE_UNUSED_NODE:
548			statep = "UNUSED";
549			break;
550		case NLP_STE_PLOGI_ISSUE:
551			statep = "PLOGI ";
552			break;
553		case NLP_STE_ADISC_ISSUE:
554			statep = "ADISC ";
555			break;
556		case NLP_STE_REG_LOGIN_ISSUE:
557			statep = "REGLOG";
558			break;
559		case NLP_STE_PRLI_ISSUE:
560			statep = "PRLI  ";
561			break;
562		case NLP_STE_LOGO_ISSUE:
563			statep = "LOGO  ";
564			break;
565		case NLP_STE_UNMAPPED_NODE:
566			statep = "UNMAP ";
567			break;
568		case NLP_STE_MAPPED_NODE:
569			statep = "MAPPED";
570			break;
571		case NLP_STE_NPR_NODE:
572			statep = "NPR   ";
573			break;
574		default:
575			statep = "UNKNOWN";
576		}
577		len +=  snprintf(buf+len, size-len, "%s DID:x%06x ",
578			statep, ndlp->nlp_DID);
579		name = (unsigned char *)&ndlp->nlp_portname;
580		len +=  snprintf(buf+len, size-len,
581			"WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
582			*name, *(name+1), *(name+2), *(name+3),
583			*(name+4), *(name+5), *(name+6), *(name+7));
584		name = (unsigned char *)&ndlp->nlp_nodename;
585		len +=  snprintf(buf+len, size-len,
586			"WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
587			*name, *(name+1), *(name+2), *(name+3),
588			*(name+4), *(name+5), *(name+6), *(name+7));
589		if (ndlp->nlp_flag & NLP_RPI_REGISTERED)
590			len +=  snprintf(buf+len, size-len, "RPI:%03d ",
591				ndlp->nlp_rpi);
592		else
593			len +=  snprintf(buf+len, size-len, "RPI:none ");
594		len +=  snprintf(buf+len, size-len, "flag:x%08x ",
595			ndlp->nlp_flag);
596		if (!ndlp->nlp_type)
597			len +=  snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
598		if (ndlp->nlp_type & NLP_FC_NODE)
599			len +=  snprintf(buf+len, size-len, "FC_NODE ");
600		if (ndlp->nlp_type & NLP_FABRIC)
601			len +=  snprintf(buf+len, size-len, "FABRIC ");
602		if (ndlp->nlp_type & NLP_FCP_TARGET)
603			len +=  snprintf(buf+len, size-len, "FCP_TGT sid:%d ",
604				ndlp->nlp_sid);
605		if (ndlp->nlp_type & NLP_FCP_INITIATOR)
606			len +=  snprintf(buf+len, size-len, "FCP_INITIATOR ");
607		len += snprintf(buf+len, size-len, "usgmap:%x ",
608			ndlp->nlp_usg_map);
609		len += snprintf(buf+len, size-len, "refcnt:%x",
610			atomic_read(&ndlp->kref.refcount));
611		len +=  snprintf(buf+len, size-len, "\n");
612	}
613	spin_unlock_irq(shost->host_lock);
614	return len;
615}
616#endif
617
618/**
619 * lpfc_debugfs_disc_trc - Store discovery trace log
620 * @vport: The vport to associate this trace string with for retrieval.
621 * @mask: Log entry classification.
622 * @fmt: Format string to be displayed when dumping the log.
623 * @data1: 1st data parameter to be applied to @fmt.
624 * @data2: 2nd data parameter to be applied to @fmt.
625 * @data3: 3rd data parameter to be applied to @fmt.
626 *
627 * Description:
628 * This routine is used by the driver code to add a debugfs log entry to the
629 * discovery trace buffer associated with @vport. Only entries with a @mask that
630 * match the current debugfs discovery mask will be saved. Entries that do not
631 * match will be thrown away. @fmt, @data1, @data2, and @data3 are used like
632 * printf when displaying the log.
633 **/
634inline void
635lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
636	uint32_t data1, uint32_t data2, uint32_t data3)
637{
638#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
639	struct lpfc_debugfs_trc *dtp;
640	int index;
641
642	if (!(lpfc_debugfs_mask_disc_trc & mask))
643		return;
644
645	if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
646		!vport || !vport->disc_trc)
647		return;
648
649	index = atomic_inc_return(&vport->disc_trc_cnt) &
650		(lpfc_debugfs_max_disc_trc - 1);
651	dtp = vport->disc_trc + index;
652	dtp->fmt = fmt;
653	dtp->data1 = data1;
654	dtp->data2 = data2;
655	dtp->data3 = data3;
656	dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
657	dtp->jif = jiffies;
658#endif
659	return;
660}
661
662/**
663 * lpfc_debugfs_slow_ring_trc - Store slow ring trace log
664 * @phba: The phba to associate this trace string with for retrieval.
665 * @fmt: Format string to be displayed when dumping the log.
666 * @data1: 1st data parameter to be applied to @fmt.
667 * @data2: 2nd data parameter to be applied to @fmt.
668 * @data3: 3rd data parameter to be applied to @fmt.
669 *
670 * Description:
671 * This routine is used by the driver code to add a debugfs log entry to the
672 * discovery trace buffer associated with @vport. @fmt, @data1, @data2, and
673 * @data3 are used like printf when displaying the log.
674 **/
675inline void
676lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
677	uint32_t data1, uint32_t data2, uint32_t data3)
678{
679#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
680	struct lpfc_debugfs_trc *dtp;
681	int index;
682
683	if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
684		!phba || !phba->slow_ring_trc)
685		return;
686
687	index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
688		(lpfc_debugfs_max_slow_ring_trc - 1);
689	dtp = phba->slow_ring_trc + index;
690	dtp->fmt = fmt;
691	dtp->data1 = data1;
692	dtp->data2 = data2;
693	dtp->data3 = data3;
694	dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
695	dtp->jif = jiffies;
696#endif
697	return;
698}
699
700#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
701/**
702 * lpfc_debugfs_disc_trc_open - Open the discovery trace log
703 * @inode: The inode pointer that contains a vport pointer.
704 * @file: The file pointer to attach the log output.
705 *
706 * Description:
707 * This routine is the entry point for the debugfs open file operation. It gets
708 * the vport from the i_private field in @inode, allocates the necessary buffer
709 * for the log, fills the buffer from the in-memory log for this vport, and then
710 * returns a pointer to that log in the private_data field in @file.
711 *
712 * Returns:
713 * This function returns zero if successful. On error it will return a negative
714 * error value.
715 **/
716static int
717lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
718{
719	struct lpfc_vport *vport = inode->i_private;
720	struct lpfc_debug *debug;
721	int size;
722	int rc = -ENOMEM;
723
724	if (!lpfc_debugfs_max_disc_trc) {
725		 rc = -ENOSPC;
726		goto out;
727	}
728
729	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
730	if (!debug)
731		goto out;
732
733	/* Round to page boundary */
734	size =  (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
735	size = PAGE_ALIGN(size);
736
737	debug->buffer = kmalloc(size, GFP_KERNEL);
738	if (!debug->buffer) {
739		kfree(debug);
740		goto out;
741	}
742
743	debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
744	file->private_data = debug;
745
746	rc = 0;
747out:
748	return rc;
749}
750
751/**
752 * lpfc_debugfs_slow_ring_trc_open - Open the Slow Ring trace log
753 * @inode: The inode pointer that contains a vport pointer.
754 * @file: The file pointer to attach the log output.
755 *
756 * Description:
757 * This routine is the entry point for the debugfs open file operation. It gets
758 * the vport from the i_private field in @inode, allocates the necessary buffer
759 * for the log, fills the buffer from the in-memory log for this vport, and then
760 * returns a pointer to that log in the private_data field in @file.
761 *
762 * Returns:
763 * This function returns zero if successful. On error it will return a negative
764 * error value.
765 **/
766static int
767lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
768{
769	struct lpfc_hba *phba = inode->i_private;
770	struct lpfc_debug *debug;
771	int size;
772	int rc = -ENOMEM;
773
774	if (!lpfc_debugfs_max_slow_ring_trc) {
775		 rc = -ENOSPC;
776		goto out;
777	}
778
779	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
780	if (!debug)
781		goto out;
782
783	/* Round to page boundary */
784	size =  (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
785	size = PAGE_ALIGN(size);
786
787	debug->buffer = kmalloc(size, GFP_KERNEL);
788	if (!debug->buffer) {
789		kfree(debug);
790		goto out;
791	}
792
793	debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
794	file->private_data = debug;
795
796	rc = 0;
797out:
798	return rc;
799}
800
801/**
802 * lpfc_debugfs_hbqinfo_open - Open the hbqinfo debugfs buffer
803 * @inode: The inode pointer that contains a vport pointer.
804 * @file: The file pointer to attach the log output.
805 *
806 * Description:
807 * This routine is the entry point for the debugfs open file operation. It gets
808 * the vport from the i_private field in @inode, allocates the necessary buffer
809 * for the log, fills the buffer from the in-memory log for this vport, and then
810 * returns a pointer to that log in the private_data field in @file.
811 *
812 * Returns:
813 * This function returns zero if successful. On error it will return a negative
814 * error value.
815 **/
816static int
817lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
818{
819	struct lpfc_hba *phba = inode->i_private;
820	struct lpfc_debug *debug;
821	int rc = -ENOMEM;
822
823	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
824	if (!debug)
825		goto out;
826
827	/* Round to page boundary */
828	debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
829	if (!debug->buffer) {
830		kfree(debug);
831		goto out;
832	}
833
834	debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
835		LPFC_HBQINFO_SIZE);
836	file->private_data = debug;
837
838	rc = 0;
839out:
840	return rc;
841}
842
843/**
844 * lpfc_debugfs_dumpHBASlim_open - Open the Dump HBA SLIM debugfs buffer
845 * @inode: The inode pointer that contains a vport pointer.
846 * @file: The file pointer to attach the log output.
847 *
848 * Description:
849 * This routine is the entry point for the debugfs open file operation. It gets
850 * the vport from the i_private field in @inode, allocates the necessary buffer
851 * for the log, fills the buffer from the in-memory log for this vport, and then
852 * returns a pointer to that log in the private_data field in @file.
853 *
854 * Returns:
855 * This function returns zero if successful. On error it will return a negative
856 * error value.
857 **/
858static int
859lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file)
860{
861	struct lpfc_hba *phba = inode->i_private;
862	struct lpfc_debug *debug;
863	int rc = -ENOMEM;
864
865	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
866	if (!debug)
867		goto out;
868
869	/* Round to page boundary */
870	debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL);
871	if (!debug->buffer) {
872		kfree(debug);
873		goto out;
874	}
875
876	debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer,
877		LPFC_DUMPHBASLIM_SIZE);
878	file->private_data = debug;
879
880	rc = 0;
881out:
882	return rc;
883}
884
885/**
886 * lpfc_debugfs_dumpHostSlim_open - Open the Dump Host SLIM debugfs buffer
887 * @inode: The inode pointer that contains a vport pointer.
888 * @file: The file pointer to attach the log output.
889 *
890 * Description:
891 * This routine is the entry point for the debugfs open file operation. It gets
892 * the vport from the i_private field in @inode, allocates the necessary buffer
893 * for the log, fills the buffer from the in-memory log for this vport, and then
894 * returns a pointer to that log in the private_data field in @file.
895 *
896 * Returns:
897 * This function returns zero if successful. On error it will return a negative
898 * error value.
899 **/
900static int
901lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file)
902{
903	struct lpfc_hba *phba = inode->i_private;
904	struct lpfc_debug *debug;
905	int rc = -ENOMEM;
906
907	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
908	if (!debug)
909		goto out;
910
911	/* Round to page boundary */
912	debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL);
913	if (!debug->buffer) {
914		kfree(debug);
915		goto out;
916	}
917
918	debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer,
919		LPFC_DUMPHOSTSLIM_SIZE);
920	file->private_data = debug;
921
922	rc = 0;
923out:
924	return rc;
925}
926
927static int
928lpfc_debugfs_dumpData_open(struct inode *inode, struct file *file)
929{
930	struct lpfc_debug *debug;
931	int rc = -ENOMEM;
932
933	if (!_dump_buf_data)
934		return -EBUSY;
935
936	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
937	if (!debug)
938		goto out;
939
940	/* Round to page boundary */
941	printk(KERN_ERR "9059 BLKGRD:  %s: _dump_buf_data=0x%p\n",
942			__func__, _dump_buf_data);
943	debug->buffer = _dump_buf_data;
944	if (!debug->buffer) {
945		kfree(debug);
946		goto out;
947	}
948
949	debug->len = (1 << _dump_buf_data_order) << PAGE_SHIFT;
950	file->private_data = debug;
951
952	rc = 0;
953out:
954	return rc;
955}
956
957static int
958lpfc_debugfs_dumpDif_open(struct inode *inode, struct file *file)
959{
960	struct lpfc_debug *debug;
961	int rc = -ENOMEM;
962
963	if (!_dump_buf_dif)
964		return -EBUSY;
965
966	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
967	if (!debug)
968		goto out;
969
970	/* Round to page boundary */
971	printk(KERN_ERR	"9060 BLKGRD: %s: _dump_buf_dif=0x%p file=%pD\n",
972		__func__, _dump_buf_dif, file);
973	debug->buffer = _dump_buf_dif;
974	if (!debug->buffer) {
975		kfree(debug);
976		goto out;
977	}
978
979	debug->len = (1 << _dump_buf_dif_order) << PAGE_SHIFT;
980	file->private_data = debug;
981
982	rc = 0;
983out:
984	return rc;
985}
986
987static ssize_t
988lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf,
989		  size_t nbytes, loff_t *ppos)
990{
991	/*
992	 * The Data/DIF buffers only save one failing IO
993	 * The write op is used as a reset mechanism after an IO has
994	 * already been saved to the next one can be saved
995	 */
996	spin_lock(&_dump_buf_lock);
997
998	memset((void *)_dump_buf_data, 0,
999			((1 << PAGE_SHIFT) << _dump_buf_data_order));
1000	memset((void *)_dump_buf_dif, 0,
1001			((1 << PAGE_SHIFT) << _dump_buf_dif_order));
1002
1003	_dump_buf_done = 0;
1004
1005	spin_unlock(&_dump_buf_lock);
1006
1007	return nbytes;
1008}
1009
1010static ssize_t
1011lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
1012	size_t nbytes, loff_t *ppos)
1013{
1014	struct dentry *dent = file->f_path.dentry;
1015	struct lpfc_hba *phba = file->private_data;
1016	char cbuf[32];
1017	uint64_t tmp = 0;
1018	int cnt = 0;
1019
1020	if (dent == phba->debug_writeGuard)
1021		cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt);
1022	else if (dent == phba->debug_writeApp)
1023		cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt);
1024	else if (dent == phba->debug_writeRef)
1025		cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt);
1026	else if (dent == phba->debug_readGuard)
1027		cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt);
1028	else if (dent == phba->debug_readApp)
1029		cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt);
1030	else if (dent == phba->debug_readRef)
1031		cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt);
1032	else if (dent == phba->debug_InjErrNPortID)
1033		cnt = snprintf(cbuf, 32, "0x%06x\n", phba->lpfc_injerr_nportid);
1034	else if (dent == phba->debug_InjErrWWPN) {
1035		memcpy(&tmp, &phba->lpfc_injerr_wwpn, sizeof(struct lpfc_name));
1036		tmp = cpu_to_be64(tmp);
1037		cnt = snprintf(cbuf, 32, "0x%016llx\n", tmp);
1038	} else if (dent == phba->debug_InjErrLBA) {
1039		if (phba->lpfc_injerr_lba == (sector_t)(-1))
1040			cnt = snprintf(cbuf, 32, "off\n");
1041		else
1042			cnt = snprintf(cbuf, 32, "0x%llx\n",
1043				 (uint64_t) phba->lpfc_injerr_lba);
1044	} else
1045		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1046			 "0547 Unknown debugfs error injection entry\n");
1047
1048	return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt);
1049}
1050
1051static ssize_t
1052lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
1053	size_t nbytes, loff_t *ppos)
1054{
1055	struct dentry *dent = file->f_path.dentry;
1056	struct lpfc_hba *phba = file->private_data;
1057	char dstbuf[32];
1058	uint64_t tmp = 0;
1059	int size;
1060
1061	memset(dstbuf, 0, 32);
1062	size = (nbytes < 32) ? nbytes : 32;
1063	if (copy_from_user(dstbuf, buf, size))
1064		return 0;
1065
1066	if (dent == phba->debug_InjErrLBA) {
1067		if ((buf[0] == 'o') && (buf[1] == 'f') && (buf[2] == 'f'))
1068			tmp = (uint64_t)(-1);
1069	}
1070
1071	if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp)))
1072		return 0;
1073
1074	if (dent == phba->debug_writeGuard)
1075		phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
1076	else if (dent == phba->debug_writeApp)
1077		phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
1078	else if (dent == phba->debug_writeRef)
1079		phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
1080	else if (dent == phba->debug_readGuard)
1081		phba->lpfc_injerr_rgrd_cnt = (uint32_t)tmp;
1082	else if (dent == phba->debug_readApp)
1083		phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
1084	else if (dent == phba->debug_readRef)
1085		phba->lpfc_injerr_rref_cnt = (uint32_t)tmp;
1086	else if (dent == phba->debug_InjErrLBA)
1087		phba->lpfc_injerr_lba = (sector_t)tmp;
1088	else if (dent == phba->debug_InjErrNPortID)
1089		phba->lpfc_injerr_nportid = (uint32_t)(tmp & Mask_DID);
1090	else if (dent == phba->debug_InjErrWWPN) {
1091		tmp = cpu_to_be64(tmp);
1092		memcpy(&phba->lpfc_injerr_wwpn, &tmp, sizeof(struct lpfc_name));
1093	} else
1094		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1095			 "0548 Unknown debugfs error injection entry\n");
1096
1097	return nbytes;
1098}
1099
1100static int
1101lpfc_debugfs_dif_err_release(struct inode *inode, struct file *file)
1102{
1103	return 0;
1104}
1105
1106/**
1107 * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file
1108 * @inode: The inode pointer that contains a vport pointer.
1109 * @file: The file pointer to attach the log output.
1110 *
1111 * Description:
1112 * This routine is the entry point for the debugfs open file operation. It gets
1113 * the vport from the i_private field in @inode, allocates the necessary buffer
1114 * for the log, fills the buffer from the in-memory log for this vport, and then
1115 * returns a pointer to that log in the private_data field in @file.
1116 *
1117 * Returns:
1118 * This function returns zero if successful. On error it will return a negative
1119 * error value.
1120 **/
1121static int
1122lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
1123{
1124	struct lpfc_vport *vport = inode->i_private;
1125	struct lpfc_debug *debug;
1126	int rc = -ENOMEM;
1127
1128	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1129	if (!debug)
1130		goto out;
1131
1132	/* Round to page boundary */
1133	debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
1134	if (!debug->buffer) {
1135		kfree(debug);
1136		goto out;
1137	}
1138
1139	debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
1140		LPFC_NODELIST_SIZE);
1141	file->private_data = debug;
1142
1143	rc = 0;
1144out:
1145	return rc;
1146}
1147
1148/**
1149 * lpfc_debugfs_lseek - Seek through a debugfs file
1150 * @file: The file pointer to seek through.
1151 * @off: The offset to seek to or the amount to seek by.
1152 * @whence: Indicates how to seek.
1153 *
1154 * Description:
1155 * This routine is the entry point for the debugfs lseek file operation. The
1156 * @whence parameter indicates whether @off is the offset to directly seek to,
1157 * or if it is a value to seek forward or reverse by. This function figures out
1158 * what the new offset of the debugfs file will be and assigns that value to the
1159 * f_pos field of @file.
1160 *
1161 * Returns:
1162 * This function returns the new offset if successful and returns a negative
1163 * error if unable to process the seek.
1164 **/
1165static loff_t
1166lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
1167{
1168	struct lpfc_debug *debug = file->private_data;
1169	return fixed_size_llseek(file, off, whence, debug->len);
1170}
1171
1172/**
1173 * lpfc_debugfs_read - Read a debugfs file
1174 * @file: The file pointer to read from.
1175 * @buf: The buffer to copy the data to.
1176 * @nbytes: The number of bytes to read.
1177 * @ppos: The position in the file to start reading from.
1178 *
1179 * Description:
1180 * This routine reads data from from the buffer indicated in the private_data
1181 * field of @file. It will start reading at @ppos and copy up to @nbytes of
1182 * data to @buf.
1183 *
1184 * Returns:
1185 * This function returns the amount of data that was read (this could be less
1186 * than @nbytes if the end of the file was reached) or a negative error value.
1187 **/
1188static ssize_t
1189lpfc_debugfs_read(struct file *file, char __user *buf,
1190		  size_t nbytes, loff_t *ppos)
1191{
1192	struct lpfc_debug *debug = file->private_data;
1193
1194	return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
1195				       debug->len);
1196}
1197
1198/**
1199 * lpfc_debugfs_release - Release the buffer used to store debugfs file data
1200 * @inode: The inode pointer that contains a vport pointer. (unused)
1201 * @file: The file pointer that contains the buffer to release.
1202 *
1203 * Description:
1204 * This routine frees the buffer that was allocated when the debugfs file was
1205 * opened.
1206 *
1207 * Returns:
1208 * This function returns zero.
1209 **/
1210static int
1211lpfc_debugfs_release(struct inode *inode, struct file *file)
1212{
1213	struct lpfc_debug *debug = file->private_data;
1214
1215	kfree(debug->buffer);
1216	kfree(debug);
1217
1218	return 0;
1219}
1220
1221static int
1222lpfc_debugfs_dumpDataDif_release(struct inode *inode, struct file *file)
1223{
1224	struct lpfc_debug *debug = file->private_data;
1225
1226	debug->buffer = NULL;
1227	kfree(debug);
1228
1229	return 0;
1230}
1231
1232/*
1233 * ---------------------------------
1234 * iDiag debugfs file access methods
1235 * ---------------------------------
1236 *
1237 * All access methods are through the proper SLI4 PCI function's debugfs
1238 * iDiag directory:
1239 *
1240 *     /sys/kernel/debug/lpfc/fn<#>/iDiag
1241 */
1242
1243/**
1244 * lpfc_idiag_cmd_get - Get and parse idiag debugfs comands from user space
1245 * @buf: The pointer to the user space buffer.
1246 * @nbytes: The number of bytes in the user space buffer.
1247 * @idiag_cmd: pointer to the idiag command struct.
1248 *
1249 * This routine reads data from debugfs user space buffer and parses the
1250 * buffer for getting the idiag command and arguments. The while space in
1251 * between the set of data is used as the parsing separator.
1252 *
1253 * This routine returns 0 when successful, it returns proper error code
1254 * back to the user space in error conditions.
1255 */
1256static int lpfc_idiag_cmd_get(const char __user *buf, size_t nbytes,
1257			      struct lpfc_idiag_cmd *idiag_cmd)
1258{
1259	char mybuf[64];
1260	char *pbuf, *step_str;
1261	int i;
1262	size_t bsize;
1263
1264	/* Protect copy from user */
1265	if (!access_ok(VERIFY_READ, buf, nbytes))
1266		return -EFAULT;
1267
1268	memset(mybuf, 0, sizeof(mybuf));
1269	memset(idiag_cmd, 0, sizeof(*idiag_cmd));
1270	bsize = min(nbytes, (sizeof(mybuf)-1));
1271
1272	if (copy_from_user(mybuf, buf, bsize))
1273		return -EFAULT;
1274	pbuf = &mybuf[0];
1275	step_str = strsep(&pbuf, "\t ");
1276
1277	/* The opcode must present */
1278	if (!step_str)
1279		return -EINVAL;
1280
1281	idiag_cmd->opcode = simple_strtol(step_str, NULL, 0);
1282	if (idiag_cmd->opcode == 0)
1283		return -EINVAL;
1284
1285	for (i = 0; i < LPFC_IDIAG_CMD_DATA_SIZE; i++) {
1286		step_str = strsep(&pbuf, "\t ");
1287		if (!step_str)
1288			return i;
1289		idiag_cmd->data[i] = simple_strtol(step_str, NULL, 0);
1290	}
1291	return i;
1292}
1293
1294/**
1295 * lpfc_idiag_open - idiag open debugfs
1296 * @inode: The inode pointer that contains a pointer to phba.
1297 * @file: The file pointer to attach the file operation.
1298 *
1299 * Description:
1300 * This routine is the entry point for the debugfs open file operation. It
1301 * gets the reference to phba from the i_private field in @inode, it then
1302 * allocates buffer for the file operation, performs the necessary PCI config
1303 * space read into the allocated buffer according to the idiag user command
1304 * setup, and then returns a pointer to buffer in the private_data field in
1305 * @file.
1306 *
1307 * Returns:
1308 * This function returns zero if successful. On error it will return an
1309 * negative error value.
1310 **/
1311static int
1312lpfc_idiag_open(struct inode *inode, struct file *file)
1313{
1314	struct lpfc_debug *debug;
1315
1316	debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1317	if (!debug)
1318		return -ENOMEM;
1319
1320	debug->i_private = inode->i_private;
1321	debug->buffer = NULL;
1322	file->private_data = debug;
1323
1324	return 0;
1325}
1326
1327/**
1328 * lpfc_idiag_release - Release idiag access file operation
1329 * @inode: The inode pointer that contains a vport pointer. (unused)
1330 * @file: The file pointer that contains the buffer to release.
1331 *
1332 * Description:
1333 * This routine is the generic release routine for the idiag access file
1334 * operation, it frees the buffer that was allocated when the debugfs file
1335 * was opened.
1336 *
1337 * Returns:
1338 * This function returns zero.
1339 **/
1340static int
1341lpfc_idiag_release(struct inode *inode, struct file *file)
1342{
1343	struct lpfc_debug *debug = file->private_data;
1344
1345	/* Free the buffers to the file operation */
1346	kfree(debug->buffer);
1347	kfree(debug);
1348
1349	return 0;
1350}
1351
1352/**
1353 * lpfc_idiag_cmd_release - Release idiag cmd access file operation
1354 * @inode: The inode pointer that contains a vport pointer. (unused)
1355 * @file: The file pointer that contains the buffer to release.
1356 *
1357 * Description:
1358 * This routine frees the buffer that was allocated when the debugfs file
1359 * was opened. It also reset the fields in the idiag command struct in the
1360 * case of command for write operation.
1361 *
1362 * Returns:
1363 * This function returns zero.
1364 **/
1365static int
1366lpfc_idiag_cmd_release(struct inode *inode, struct file *file)
1367{
1368	struct lpfc_debug *debug = file->private_data;
1369
1370	if (debug->op == LPFC_IDIAG_OP_WR) {
1371		switch (idiag.cmd.opcode) {
1372		case LPFC_IDIAG_CMD_PCICFG_WR:
1373		case LPFC_IDIAG_CMD_PCICFG_ST:
1374		case LPFC_IDIAG_CMD_PCICFG_CL:
1375		case LPFC_IDIAG_CMD_QUEACC_WR:
1376		case LPFC_IDIAG_CMD_QUEACC_ST:
1377		case LPFC_IDIAG_CMD_QUEACC_CL:
1378			memset(&idiag, 0, sizeof(idiag));
1379			break;
1380		default:
1381			break;
1382		}
1383	}
1384
1385	/* Free the buffers to the file operation */
1386	kfree(debug->buffer);
1387	kfree(debug);
1388
1389	return 0;
1390}
1391
1392/**
1393 * lpfc_idiag_pcicfg_read - idiag debugfs read pcicfg
1394 * @file: The file pointer to read from.
1395 * @buf: The buffer to copy the data to.
1396 * @nbytes: The number of bytes to read.
1397 * @ppos: The position in the file to start reading from.
1398 *
1399 * Description:
1400 * This routine reads data from the @phba pci config space according to the
1401 * idiag command, and copies to user @buf. Depending on the PCI config space
1402 * read command setup, it does either a single register read of a byte
1403 * (8 bits), a word (16 bits), or a dword (32 bits) or browsing through all
1404 * registers from the 4K extended PCI config space.
1405 *
1406 * Returns:
1407 * This function returns the amount of data that was read (this could be less
1408 * than @nbytes if the end of the file was reached) or a negative error value.
1409 **/
1410static ssize_t
1411lpfc_idiag_pcicfg_read(struct file *file, char __user *buf, size_t nbytes,
1412		       loff_t *ppos)
1413{
1414	struct lpfc_debug *debug = file->private_data;
1415	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1416	int offset_label, offset, len = 0, index = LPFC_PCI_CFG_RD_SIZE;
1417	int where, count;
1418	char *pbuffer;
1419	struct pci_dev *pdev;
1420	uint32_t u32val;
1421	uint16_t u16val;
1422	uint8_t u8val;
1423
1424	pdev = phba->pcidev;
1425	if (!pdev)
1426		return 0;
1427
1428	/* This is a user read operation */
1429	debug->op = LPFC_IDIAG_OP_RD;
1430
1431	if (!debug->buffer)
1432		debug->buffer = kmalloc(LPFC_PCI_CFG_SIZE, GFP_KERNEL);
1433	if (!debug->buffer)
1434		return 0;
1435	pbuffer = debug->buffer;
1436
1437	if (*ppos)
1438		return 0;
1439
1440	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
1441		where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
1442		count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
1443	} else
1444		return 0;
1445
1446	/* Read single PCI config space register */
1447	switch (count) {
1448	case SIZE_U8: /* byte (8 bits) */
1449		pci_read_config_byte(pdev, where, &u8val);
1450		len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1451				"%03x: %02x\n", where, u8val);
1452		break;
1453	case SIZE_U16: /* word (16 bits) */
1454		pci_read_config_word(pdev, where, &u16val);
1455		len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1456				"%03x: %04x\n", where, u16val);
1457		break;
1458	case SIZE_U32: /* double word (32 bits) */
1459		pci_read_config_dword(pdev, where, &u32val);
1460		len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1461				"%03x: %08x\n", where, u32val);
1462		break;
1463	case LPFC_PCI_CFG_BROWSE: /* browse all */
1464		goto pcicfg_browse;
1465		break;
1466	default:
1467		/* illegal count */
1468		len = 0;
1469		break;
1470	}
1471	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1472
1473pcicfg_browse:
1474
1475	/* Browse all PCI config space registers */
1476	offset_label = idiag.offset.last_rd;
1477	offset = offset_label;
1478
1479	/* Read PCI config space */
1480	len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1481			"%03x: ", offset_label);
1482	while (index > 0) {
1483		pci_read_config_dword(pdev, offset, &u32val);
1484		len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1485				"%08x ", u32val);
1486		offset += sizeof(uint32_t);
1487		if (offset >= LPFC_PCI_CFG_SIZE) {
1488			len += snprintf(pbuffer+len,
1489					LPFC_PCI_CFG_SIZE-len, "\n");
1490			break;
1491		}
1492		index -= sizeof(uint32_t);
1493		if (!index)
1494			len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1495					"\n");
1496		else if (!(index % (8 * sizeof(uint32_t)))) {
1497			offset_label += (8 * sizeof(uint32_t));
1498			len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1499					"\n%03x: ", offset_label);
1500		}
1501	}
1502
1503	/* Set up the offset for next portion of pci cfg read */
1504	if (index == 0) {
1505		idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE;
1506		if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE)
1507			idiag.offset.last_rd = 0;
1508	} else
1509		idiag.offset.last_rd = 0;
1510
1511	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1512}
1513
1514/**
1515 * lpfc_idiag_pcicfg_write - Syntax check and set up idiag pcicfg commands
1516 * @file: The file pointer to read from.
1517 * @buf: The buffer to copy the user data from.
1518 * @nbytes: The number of bytes to get.
1519 * @ppos: The position in the file to start reading from.
1520 *
1521 * This routine get the debugfs idiag command struct from user space and
1522 * then perform the syntax check for PCI config space read or write command
1523 * accordingly. In the case of PCI config space read command, it sets up
1524 * the command in the idiag command struct for the debugfs read operation.
1525 * In the case of PCI config space write operation, it executes the write
1526 * operation into the PCI config space accordingly.
1527 *
1528 * It returns the @nbytges passing in from debugfs user space when successful.
1529 * In case of error conditions, it returns proper error code back to the user
1530 * space.
1531 */
1532static ssize_t
1533lpfc_idiag_pcicfg_write(struct file *file, const char __user *buf,
1534			size_t nbytes, loff_t *ppos)
1535{
1536	struct lpfc_debug *debug = file->private_data;
1537	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1538	uint32_t where, value, count;
1539	uint32_t u32val;
1540	uint16_t u16val;
1541	uint8_t u8val;
1542	struct pci_dev *pdev;
1543	int rc;
1544
1545	pdev = phba->pcidev;
1546	if (!pdev)
1547		return -EFAULT;
1548
1549	/* This is a user write operation */
1550	debug->op = LPFC_IDIAG_OP_WR;
1551
1552	rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
1553	if (rc < 0)
1554		return rc;
1555
1556	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
1557		/* Sanity check on PCI config read command line arguments */
1558		if (rc != LPFC_PCI_CFG_RD_CMD_ARG)
1559			goto error_out;
1560		/* Read command from PCI config space, set up command fields */
1561		where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
1562		count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
1563		if (count == LPFC_PCI_CFG_BROWSE) {
1564			if (where % sizeof(uint32_t))
1565				goto error_out;
1566			/* Starting offset to browse */
1567			idiag.offset.last_rd = where;
1568		} else if ((count != sizeof(uint8_t)) &&
1569			   (count != sizeof(uint16_t)) &&
1570			   (count != sizeof(uint32_t)))
1571			goto error_out;
1572		if (count == sizeof(uint8_t)) {
1573			if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
1574				goto error_out;
1575			if (where % sizeof(uint8_t))
1576				goto error_out;
1577		}
1578		if (count == sizeof(uint16_t)) {
1579			if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
1580				goto error_out;
1581			if (where % sizeof(uint16_t))
1582				goto error_out;
1583		}
1584		if (count == sizeof(uint32_t)) {
1585			if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
1586				goto error_out;
1587			if (where % sizeof(uint32_t))
1588				goto error_out;
1589		}
1590	} else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR ||
1591		   idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST ||
1592		   idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1593		/* Sanity check on PCI config write command line arguments */
1594		if (rc != LPFC_PCI_CFG_WR_CMD_ARG)
1595			goto error_out;
1596		/* Write command to PCI config space, read-modify-write */
1597		where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
1598		count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
1599		value = idiag.cmd.data[IDIAG_PCICFG_VALUE_INDX];
1600		/* Sanity checks */
1601		if ((count != sizeof(uint8_t)) &&
1602		    (count != sizeof(uint16_t)) &&
1603		    (count != sizeof(uint32_t)))
1604			goto error_out;
1605		if (count == sizeof(uint8_t)) {
1606			if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
1607				goto error_out;
1608			if (where % sizeof(uint8_t))
1609				goto error_out;
1610			if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
1611				pci_write_config_byte(pdev, where,
1612						      (uint8_t)value);
1613			if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
1614				rc = pci_read_config_byte(pdev, where, &u8val);
1615				if (!rc) {
1616					u8val |= (uint8_t)value;
1617					pci_write_config_byte(pdev, where,
1618							      u8val);
1619				}
1620			}
1621			if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1622				rc = pci_read_config_byte(pdev, where, &u8val);
1623				if (!rc) {
1624					u8val &= (uint8_t)(~value);
1625					pci_write_config_byte(pdev, where,
1626							      u8val);
1627				}
1628			}
1629		}
1630		if (count == sizeof(uint16_t)) {
1631			if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
1632				goto error_out;
1633			if (where % sizeof(uint16_t))
1634				goto error_out;
1635			if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
1636				pci_write_config_word(pdev, where,
1637						      (uint16_t)value);
1638			if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
1639				rc = pci_read_config_word(pdev, where, &u16val);
1640				if (!rc) {
1641					u16val |= (uint16_t)value;
1642					pci_write_config_word(pdev, where,
1643							      u16val);
1644				}
1645			}
1646			if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1647				rc = pci_read_config_word(pdev, where, &u16val);
1648				if (!rc) {
1649					u16val &= (uint16_t)(~value);
1650					pci_write_config_word(pdev, where,
1651							      u16val);
1652				}
1653			}
1654		}
1655		if (count == sizeof(uint32_t)) {
1656			if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
1657				goto error_out;
1658			if (where % sizeof(uint32_t))
1659				goto error_out;
1660			if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
1661				pci_write_config_dword(pdev, where, value);
1662			if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
1663				rc = pci_read_config_dword(pdev, where,
1664							   &u32val);
1665				if (!rc) {
1666					u32val |= value;
1667					pci_write_config_dword(pdev, where,
1668							       u32val);
1669				}
1670			}
1671			if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1672				rc = pci_read_config_dword(pdev, where,
1673							   &u32val);
1674				if (!rc) {
1675					u32val &= ~value;
1676					pci_write_config_dword(pdev, where,
1677							       u32val);
1678				}
1679			}
1680		}
1681	} else
1682		/* All other opecodes are illegal for now */
1683		goto error_out;
1684
1685	return nbytes;
1686error_out:
1687	memset(&idiag, 0, sizeof(idiag));
1688	return -EINVAL;
1689}
1690
1691/**
1692 * lpfc_idiag_baracc_read - idiag debugfs pci bar access read
1693 * @file: The file pointer to read from.
1694 * @buf: The buffer to copy the data to.
1695 * @nbytes: The number of bytes to read.
1696 * @ppos: The position in the file to start reading from.
1697 *
1698 * Description:
1699 * This routine reads data from the @phba pci bar memory mapped space
1700 * according to the idiag command, and copies to user @buf.
1701 *
1702 * Returns:
1703 * This function returns the amount of data that was read (this could be less
1704 * than @nbytes if the end of the file was reached) or a negative error value.
1705 **/
1706static ssize_t
1707lpfc_idiag_baracc_read(struct file *file, char __user *buf, size_t nbytes,
1708		       loff_t *ppos)
1709{
1710	struct lpfc_debug *debug = file->private_data;
1711	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1712	int offset_label, offset, offset_run, len = 0, index;
1713	int bar_num, acc_range, bar_size;
1714	char *pbuffer;
1715	void __iomem *mem_mapped_bar;
1716	uint32_t if_type;
1717	struct pci_dev *pdev;
1718	uint32_t u32val;
1719
1720	pdev = phba->pcidev;
1721	if (!pdev)
1722		return 0;
1723
1724	/* This is a user read operation */
1725	debug->op = LPFC_IDIAG_OP_RD;
1726
1727	if (!debug->buffer)
1728		debug->buffer = kmalloc(LPFC_PCI_BAR_RD_BUF_SIZE, GFP_KERNEL);
1729	if (!debug->buffer)
1730		return 0;
1731	pbuffer = debug->buffer;
1732
1733	if (*ppos)
1734		return 0;
1735
1736	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
1737		bar_num   = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
1738		offset    = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
1739		acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
1740		bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
1741	} else
1742		return 0;
1743
1744	if (acc_range == 0)
1745		return 0;
1746
1747	if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
1748	if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
1749		if (bar_num == IDIAG_BARACC_BAR_0)
1750			mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1751		else if (bar_num == IDIAG_BARACC_BAR_1)
1752			mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
1753		else if (bar_num == IDIAG_BARACC_BAR_2)
1754			mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
1755		else
1756			return 0;
1757	} else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
1758		if (bar_num == IDIAG_BARACC_BAR_0)
1759			mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1760		else
1761			return 0;
1762	} else
1763		return 0;
1764
1765	/* Read single PCI bar space register */
1766	if (acc_range == SINGLE_WORD) {
1767		offset_run = offset;
1768		u32val = readl(mem_mapped_bar + offset_run);
1769		len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
1770				"%05x: %08x\n", offset_run, u32val);
1771	} else
1772		goto baracc_browse;
1773
1774	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1775
1776baracc_browse:
1777
1778	/* Browse all PCI bar space registers */
1779	offset_label = idiag.offset.last_rd;
1780	offset_run = offset_label;
1781
1782	/* Read PCI bar memory mapped space */
1783	len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
1784			"%05x: ", offset_label);
1785	index = LPFC_PCI_BAR_RD_SIZE;
1786	while (index > 0) {
1787		u32val = readl(mem_mapped_bar + offset_run);
1788		len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
1789				"%08x ", u32val);
1790		offset_run += sizeof(uint32_t);
1791		if (acc_range == LPFC_PCI_BAR_BROWSE) {
1792			if (offset_run >= bar_size) {
1793				len += snprintf(pbuffer+len,
1794					LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
1795				break;
1796			}
1797		} else {
1798			if (offset_run >= offset +
1799			    (acc_range * sizeof(uint32_t))) {
1800				len += snprintf(pbuffer+len,
1801					LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
1802				break;
1803			}
1804		}
1805		index -= sizeof(uint32_t);
1806		if (!index)
1807			len += snprintf(pbuffer+len,
1808					LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
1809		else if (!(index % (8 * sizeof(uint32_t)))) {
1810			offset_label += (8 * sizeof(uint32_t));
1811			len += snprintf(pbuffer+len,
1812					LPFC_PCI_BAR_RD_BUF_SIZE-len,
1813					"\n%05x: ", offset_label);
1814		}
1815	}
1816
1817	/* Set up the offset for next portion of pci bar read */
1818	if (index == 0) {
1819		idiag.offset.last_rd += LPFC_PCI_BAR_RD_SIZE;
1820		if (acc_range == LPFC_PCI_BAR_BROWSE) {
1821			if (idiag.offset.last_rd >= bar_size)
1822				idiag.offset.last_rd = 0;
1823		} else {
1824			if (offset_run >= offset +
1825			    (acc_range * sizeof(uint32_t)))
1826				idiag.offset.last_rd = offset;
1827		}
1828	} else {
1829		if (acc_range == LPFC_PCI_BAR_BROWSE)
1830			idiag.offset.last_rd = 0;
1831		else
1832			idiag.offset.last_rd = offset;
1833	}
1834
1835	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1836}
1837
1838/**
1839 * lpfc_idiag_baracc_write - Syntax check and set up idiag bar access commands
1840 * @file: The file pointer to read from.
1841 * @buf: The buffer to copy the user data from.
1842 * @nbytes: The number of bytes to get.
1843 * @ppos: The position in the file to start reading from.
1844 *
1845 * This routine get the debugfs idiag command struct from user space and
1846 * then perform the syntax check for PCI bar memory mapped space read or
1847 * write command accordingly. In the case of PCI bar memory mapped space
1848 * read command, it sets up the command in the idiag command struct for
1849 * the debugfs read operation. In the case of PCI bar memorpy mapped space
1850 * write operation, it executes the write operation into the PCI bar memory
1851 * mapped space accordingly.
1852 *
1853 * It returns the @nbytges passing in from debugfs user space when successful.
1854 * In case of error conditions, it returns proper error code back to the user
1855 * space.
1856 */
1857static ssize_t
1858lpfc_idiag_baracc_write(struct file *file, const char __user *buf,
1859			size_t nbytes, loff_t *ppos)
1860{
1861	struct lpfc_debug *debug = file->private_data;
1862	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1863	uint32_t bar_num, bar_size, offset, value, acc_range;
1864	struct pci_dev *pdev;
1865	void __iomem *mem_mapped_bar;
1866	uint32_t if_type;
1867	uint32_t u32val;
1868	int rc;
1869
1870	pdev = phba->pcidev;
1871	if (!pdev)
1872		return -EFAULT;
1873
1874	/* This is a user write operation */
1875	debug->op = LPFC_IDIAG_OP_WR;
1876
1877	rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
1878	if (rc < 0)
1879		return rc;
1880
1881	if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
1882	bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
1883
1884	if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
1885		if ((bar_num != IDIAG_BARACC_BAR_0) &&
1886		    (bar_num != IDIAG_BARACC_BAR_1) &&
1887		    (bar_num != IDIAG_BARACC_BAR_2))
1888			goto error_out;
1889	} else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
1890		if (bar_num != IDIAG_BARACC_BAR_0)
1891			goto error_out;
1892	} else
1893		goto error_out;
1894
1895	if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
1896		if (bar_num == IDIAG_BARACC_BAR_0) {
1897			idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1898				LPFC_PCI_IF0_BAR0_SIZE;
1899			mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1900		} else if (bar_num == IDIAG_BARACC_BAR_1) {
1901			idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1902				LPFC_PCI_IF0_BAR1_SIZE;
1903			mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
1904		} else if (bar_num == IDIAG_BARACC_BAR_2) {
1905			idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1906				LPFC_PCI_IF0_BAR2_SIZE;
1907			mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
1908		} else
1909			goto error_out;
1910	} else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
1911		if (bar_num == IDIAG_BARACC_BAR_0) {
1912			idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1913				LPFC_PCI_IF2_BAR0_SIZE;
1914			mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1915		} else
1916			goto error_out;
1917	} else
1918		goto error_out;
1919
1920	offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
1921	if (offset % sizeof(uint32_t))
1922		goto error_out;
1923
1924	bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
1925	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
1926		/* Sanity check on PCI config read command line arguments */
1927		if (rc != LPFC_PCI_BAR_RD_CMD_ARG)
1928			goto error_out;
1929		acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
1930		if (acc_range == LPFC_PCI_BAR_BROWSE) {
1931			if (offset > bar_size - sizeof(uint32_t))
1932				goto error_out;
1933			/* Starting offset to browse */
1934			idiag.offset.last_rd = offset;
1935		} else if (acc_range > SINGLE_WORD) {
1936			if (offset + acc_range * sizeof(uint32_t) > bar_size)
1937				goto error_out;
1938			/* Starting offset to browse */
1939			idiag.offset.last_rd = offset;
1940		} else if (acc_range != SINGLE_WORD)
1941			goto error_out;
1942	} else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR ||
1943		   idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST ||
1944		   idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
1945		/* Sanity check on PCI bar write command line arguments */
1946		if (rc != LPFC_PCI_BAR_WR_CMD_ARG)
1947			goto error_out;
1948		/* Write command to PCI bar space, read-modify-write */
1949		acc_range = SINGLE_WORD;
1950		value = idiag.cmd.data[IDIAG_BARACC_REG_VAL_INDX];
1951		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR) {
1952			writel(value, mem_mapped_bar + offset);
1953			readl(mem_mapped_bar + offset);
1954		}
1955		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST) {
1956			u32val = readl(mem_mapped_bar + offset);
1957			u32val |= value;
1958			writel(u32val, mem_mapped_bar + offset);
1959			readl(mem_mapped_bar + offset);
1960		}
1961		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
1962			u32val = readl(mem_mapped_bar + offset);
1963			u32val &= ~value;
1964			writel(u32val, mem_mapped_bar + offset);
1965			readl(mem_mapped_bar + offset);
1966		}
1967	} else
1968		/* All other opecodes are illegal for now */
1969		goto error_out;
1970
1971	return nbytes;
1972error_out:
1973	memset(&idiag, 0, sizeof(idiag));
1974	return -EINVAL;
1975}
1976
1977/**
1978 * lpfc_idiag_queinfo_read - idiag debugfs read queue information
1979 * @file: The file pointer to read from.
1980 * @buf: The buffer to copy the data to.
1981 * @nbytes: The number of bytes to read.
1982 * @ppos: The position in the file to start reading from.
1983 *
1984 * Description:
1985 * This routine reads data from the @phba SLI4 PCI function queue information,
1986 * and copies to user @buf.
1987 *
1988 * Returns:
1989 * This function returns the amount of data that was read (this could be less
1990 * than @nbytes if the end of the file was reached) or a negative error value.
1991 **/
1992static ssize_t
1993lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
1994			loff_t *ppos)
1995{
1996	struct lpfc_debug *debug = file->private_data;
1997	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1998	int len = 0;
1999	char *pbuffer;
2000	int x, cnt;
2001	int max_cnt;
2002	struct lpfc_queue *qp = NULL;
2003
2004
2005	if (!debug->buffer)
2006		debug->buffer = kmalloc(LPFC_QUE_INFO_GET_BUF_SIZE, GFP_KERNEL);
2007	if (!debug->buffer)
2008		return 0;
2009	pbuffer = debug->buffer;
2010	max_cnt = LPFC_QUE_INFO_GET_BUF_SIZE - 128;
2011
2012	if (*ppos)
2013		return 0;
2014
2015	spin_lock_irq(&phba->hbalock);
2016
2017	/* Fast-path event queue */
2018	if (phba->sli4_hba.hba_eq && phba->cfg_fcp_io_channel) {
2019		cnt = phba->cfg_fcp_io_channel;
2020
2021		for (x = 0; x < cnt; x++) {
2022
2023			/* Fast-path EQ */
2024			qp = phba->sli4_hba.hba_eq[x];
2025			if (!qp)
2026				goto proc_cq;
2027
2028			len += snprintf(pbuffer+len,
2029				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2030				"\nHBA EQ info: "
2031				"EQ-STAT[max:x%x noE:x%x "
2032				"bs:x%x proc:x%llx]\n",
2033				qp->q_cnt_1, qp->q_cnt_2,
2034				qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
2035
2036			len += snprintf(pbuffer+len,
2037				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2038				"EQID[%02d], "
2039				"QE-CNT[%04d], QE-SIZE[%04d], "
2040				"HOST-IDX[%04d], PORT-IDX[%04d]",
2041				qp->queue_id,
2042				qp->entry_count,
2043				qp->entry_size,
2044				qp->host_index,
2045				qp->hba_index);
2046
2047
2048			/* Reset max counter */
2049			qp->EQ_max_eqe = 0;
2050
2051			len +=  snprintf(pbuffer+len,
2052				LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2053			if (len >= max_cnt)
2054				goto too_big;
2055proc_cq:
2056			/* Fast-path FCP CQ */
2057			qp = phba->sli4_hba.fcp_cq[x];
2058			len += snprintf(pbuffer+len,
2059				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2060				"\tFCP CQ info: ");
2061			len += snprintf(pbuffer+len,
2062				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2063				"AssocEQID[%02d]: "
2064				"CQ STAT[max:x%x relw:x%x "
2065				"xabt:x%x wq:x%llx]\n",
2066				qp->assoc_qid,
2067				qp->q_cnt_1, qp->q_cnt_2,
2068				qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
2069			len += snprintf(pbuffer+len,
2070				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2071				"\tCQID[%02d], "
2072				"QE-CNT[%04d], QE-SIZE[%04d], "
2073				"HOST-IDX[%04d], PORT-IDX[%04d]",
2074				qp->queue_id, qp->entry_count,
2075				qp->entry_size, qp->host_index,
2076				qp->hba_index);
2077
2078
2079			/* Reset max counter */
2080			qp->CQ_max_cqe = 0;
2081
2082			len +=  snprintf(pbuffer+len,
2083				LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2084			if (len >= max_cnt)
2085				goto too_big;
2086
2087			/* Fast-path FCP WQ */
2088			qp = phba->sli4_hba.fcp_wq[x];
2089
2090			len += snprintf(pbuffer+len,
2091				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2092				"\t\tFCP WQ info: ");
2093			len += snprintf(pbuffer+len,
2094				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2095				"AssocCQID[%02d]: "
2096				"WQ-STAT[oflow:x%x posted:x%llx]\n",
2097				qp->assoc_qid,
2098				qp->q_cnt_1, (unsigned long long)qp->q_cnt_4);
2099			len += snprintf(pbuffer+len,
2100				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2101				"\t\tWQID[%02d], "
2102				"QE-CNT[%04d], QE-SIZE[%04d], "
2103				"HOST-IDX[%04d], PORT-IDX[%04d]",
2104				qp->queue_id,
2105				qp->entry_count,
2106				qp->entry_size,
2107				qp->host_index,
2108				qp->hba_index);
2109
2110			len +=  snprintf(pbuffer+len,
2111				LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2112			if (len >= max_cnt)
2113				goto too_big;
2114
2115			if (x)
2116				continue;
2117
2118			/* Only EQ 0 has slow path CQs configured */
2119
2120			/* Slow-path mailbox CQ */
2121			qp = phba->sli4_hba.mbx_cq;
2122			if (qp) {
2123				len += snprintf(pbuffer+len,
2124					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2125					"\tMBX CQ info: ");
2126				len += snprintf(pbuffer+len,
2127					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2128					"AssocEQID[%02d]: "
2129					"CQ-STAT[mbox:x%x relw:x%x "
2130					"xabt:x%x wq:x%llx]\n",
2131					qp->assoc_qid,
2132					qp->q_cnt_1, qp->q_cnt_2,
2133					qp->q_cnt_3,
2134					(unsigned long long)qp->q_cnt_4);
2135				len += snprintf(pbuffer+len,
2136					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2137					"\tCQID[%02d], "
2138					"QE-CNT[%04d], QE-SIZE[%04d], "
2139					"HOST-IDX[%04d], PORT-IDX[%04d]",
2140					qp->queue_id, qp->entry_count,
2141					qp->entry_size, qp->host_index,
2142					qp->hba_index);
2143
2144				len +=  snprintf(pbuffer+len,
2145					LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2146				if (len >= max_cnt)
2147					goto too_big;
2148			}
2149
2150			/* Slow-path MBOX MQ */
2151			qp = phba->sli4_hba.mbx_wq;
2152			if (qp) {
2153				len += snprintf(pbuffer+len,
2154					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2155					"\t\tMBX MQ info: ");
2156				len += snprintf(pbuffer+len,
2157					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2158					"AssocCQID[%02d]:\n",
2159					phba->sli4_hba.mbx_wq->assoc_qid);
2160				len += snprintf(pbuffer+len,
2161					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2162					"\t\tWQID[%02d], "
2163					"QE-CNT[%04d], QE-SIZE[%04d], "
2164					"HOST-IDX[%04d], PORT-IDX[%04d]",
2165					qp->queue_id, qp->entry_count,
2166					qp->entry_size, qp->host_index,
2167					qp->hba_index);
2168
2169				len +=  snprintf(pbuffer+len,
2170					LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2171				if (len >= max_cnt)
2172					goto too_big;
2173			}
2174
2175			/* Slow-path ELS response CQ */
2176			qp = phba->sli4_hba.els_cq;
2177			if (qp) {
2178				len += snprintf(pbuffer+len,
2179					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2180					"\tELS CQ info: ");
2181				len += snprintf(pbuffer+len,
2182					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2183					"AssocEQID[%02d]: "
2184					"CQ-STAT[max:x%x relw:x%x "
2185					"xabt:x%x wq:x%llx]\n",
2186					qp->assoc_qid,
2187					qp->q_cnt_1, qp->q_cnt_2,
2188					qp->q_cnt_3,
2189					(unsigned long long)qp->q_cnt_4);
2190				len += snprintf(pbuffer+len,
2191					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2192					"\tCQID [%02d], "
2193					"QE-CNT[%04d], QE-SIZE[%04d], "
2194					"HOST-IDX[%04d], PORT-IDX[%04d]",
2195					qp->queue_id, qp->entry_count,
2196					qp->entry_size, qp->host_index,
2197					qp->hba_index);
2198
2199				/* Reset max counter */
2200				qp->CQ_max_cqe = 0;
2201
2202				len +=  snprintf(pbuffer+len,
2203					LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2204				if (len >= max_cnt)
2205					goto too_big;
2206			}
2207
2208			/* Slow-path ELS WQ */
2209			qp = phba->sli4_hba.els_wq;
2210			if (qp) {
2211				len += snprintf(pbuffer+len,
2212					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2213					"\t\tELS WQ info: ");
2214				len += snprintf(pbuffer+len,
2215					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2216					"AssocCQID[%02d]: "
2217					" WQ-STAT[oflow:x%x "
2218					"posted:x%llx]\n",
2219					qp->assoc_qid,
2220					qp->q_cnt_1,
2221					(unsigned long long)qp->q_cnt_4);
2222				len += snprintf(pbuffer+len,
2223					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2224					"\t\tWQID[%02d], "
2225					"QE-CNT[%04d], QE-SIZE[%04d], "
2226					"HOST-IDX[%04d], PORT-IDX[%04d]",
2227					qp->queue_id, qp->entry_count,
2228					qp->entry_size, qp->host_index,
2229					qp->hba_index);
2230
2231				len +=  snprintf(pbuffer+len,
2232					LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2233				if (len >= max_cnt)
2234					goto too_big;
2235			}
2236
2237			if (phba->sli4_hba.hdr_rq && phba->sli4_hba.dat_rq) {
2238				/* Slow-path RQ header */
2239				qp = phba->sli4_hba.hdr_rq;
2240
2241				len += snprintf(pbuffer+len,
2242				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2243					"\t\tRQ info: ");
2244				len += snprintf(pbuffer+len,
2245					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2246					"AssocCQID[%02d]: "
2247					"RQ-STAT[nopost:x%x nobuf:x%x "
2248					"trunc:x%x rcv:x%llx]\n",
2249					qp->assoc_qid,
2250					qp->q_cnt_1, qp->q_cnt_2,
2251					qp->q_cnt_3,
2252					(unsigned long long)qp->q_cnt_4);
2253				len += snprintf(pbuffer+len,
2254					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2255					"\t\tHQID[%02d], "
2256					"QE-CNT[%04d], QE-SIZE[%04d], "
2257					"HOST-IDX[%04d], PORT-IDX[%04d]\n",
2258					qp->queue_id,
2259					qp->entry_count,
2260					qp->entry_size,
2261					qp->host_index,
2262					qp->hba_index);
2263
2264				/* Slow-path RQ data */
2265				qp = phba->sli4_hba.dat_rq;
2266				len += snprintf(pbuffer+len,
2267					LPFC_QUE_INFO_GET_BUF_SIZE-len,
2268					"\t\tDQID[%02d], "
2269					"QE-CNT[%04d], QE-SIZE[%04d], "
2270					"HOST-IDX[%04d], PORT-IDX[%04d]\n",
2271					qp->queue_id,
2272					qp->entry_count,
2273					qp->entry_size,
2274					qp->host_index,
2275					qp->hba_index);
2276
2277				len +=  snprintf(pbuffer+len,
2278					LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2279			}
2280		}
2281	}
2282
2283	if (phba->cfg_fof) {
2284		/* FOF EQ */
2285		qp = phba->sli4_hba.fof_eq;
2286		if (!qp)
2287			goto out;
2288
2289		len += snprintf(pbuffer+len,
2290			LPFC_QUE_INFO_GET_BUF_SIZE-len,
2291			"\nFOF EQ info: "
2292			"EQ-STAT[max:x%x noE:x%x "
2293			"bs:x%x proc:x%llx]\n",
2294			qp->q_cnt_1, qp->q_cnt_2,
2295			qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
2296
2297		len += snprintf(pbuffer+len,
2298			LPFC_QUE_INFO_GET_BUF_SIZE-len,
2299			"EQID[%02d], "
2300			"QE-CNT[%04d], QE-SIZE[%04d], "
2301			"HOST-IDX[%04d], PORT-IDX[%04d]",
2302			qp->queue_id,
2303			qp->entry_count,
2304			qp->entry_size,
2305			qp->host_index,
2306			qp->hba_index);
2307
2308		/* Reset max counter */
2309		qp->EQ_max_eqe = 0;
2310
2311		len +=  snprintf(pbuffer+len,
2312			LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2313		if (len >= max_cnt)
2314			goto too_big;
2315	}
2316
2317	if (phba->cfg_fof) {
2318
2319		/* OAS CQ */
2320		qp = phba->sli4_hba.oas_cq;
2321		if (qp) {
2322			len += snprintf(pbuffer+len,
2323				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2324				"\tOAS CQ info: ");
2325			len += snprintf(pbuffer+len,
2326				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2327				"AssocEQID[%02d]: "
2328				"CQ STAT[max:x%x relw:x%x "
2329				"xabt:x%x wq:x%llx]\n",
2330				qp->assoc_qid,
2331				qp->q_cnt_1, qp->q_cnt_2,
2332				qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
2333			len += snprintf(pbuffer+len,
2334				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2335				"\tCQID[%02d], "
2336				"QE-CNT[%04d], QE-SIZE[%04d], "
2337				"HOST-IDX[%04d], PORT-IDX[%04d]",
2338				qp->queue_id, qp->entry_count,
2339				qp->entry_size, qp->host_index,
2340				qp->hba_index);
2341
2342			/* Reset max counter */
2343			qp->CQ_max_cqe = 0;
2344
2345			len +=  snprintf(pbuffer+len,
2346				LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2347			if (len >= max_cnt)
2348				goto too_big;
2349		}
2350
2351		/* OAS WQ */
2352		qp = phba->sli4_hba.oas_wq;
2353		if (qp) {
2354			len += snprintf(pbuffer+len,
2355				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2356				"\t\tOAS WQ info: ");
2357			len += snprintf(pbuffer+len,
2358				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2359				"AssocCQID[%02d]: "
2360				"WQ-STAT[oflow:x%x posted:x%llx]\n",
2361				qp->assoc_qid,
2362				qp->q_cnt_1, (unsigned long long)qp->q_cnt_4);
2363			len += snprintf(pbuffer+len,
2364				LPFC_QUE_INFO_GET_BUF_SIZE-len,
2365				"\t\tWQID[%02d], "
2366				"QE-CNT[%04d], QE-SIZE[%04d], "
2367				"HOST-IDX[%04d], PORT-IDX[%04d]",
2368				qp->queue_id,
2369				qp->entry_count,
2370				qp->entry_size,
2371				qp->host_index,
2372				qp->hba_index);
2373
2374			len +=  snprintf(pbuffer+len,
2375				LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2376			if (len >= max_cnt)
2377				goto too_big;
2378		}
2379	}
2380out:
2381	spin_unlock_irq(&phba->hbalock);
2382	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2383
2384too_big:
2385	len +=  snprintf(pbuffer+len,
2386		LPFC_QUE_INFO_GET_BUF_SIZE-len, "Truncated ...\n");
2387	spin_unlock_irq(&phba->hbalock);
2388	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2389}
2390
2391/**
2392 * lpfc_idiag_que_param_check - queue access command parameter sanity check
2393 * @q: The pointer to queue structure.
2394 * @index: The index into a queue entry.
2395 * @count: The number of queue entries to access.
2396 *
2397 * Description:
2398 * The routine performs sanity check on device queue access method commands.
2399 *
2400 * Returns:
2401 * This function returns -EINVAL when fails the sanity check, otherwise, it
2402 * returns 0.
2403 **/
2404static int
2405lpfc_idiag_que_param_check(struct lpfc_queue *q, int index, int count)
2406{
2407	/* Only support single entry read or browsing */
2408	if ((count != 1) && (count != LPFC_QUE_ACC_BROWSE))
2409		return -EINVAL;
2410	if (index > q->entry_count - 1)
2411		return -EINVAL;
2412	return 0;
2413}
2414
2415/**
2416 * lpfc_idiag_queacc_read_qe - read a single entry from the given queue index
2417 * @pbuffer: The pointer to buffer to copy the read data into.
2418 * @pque: The pointer to the queue to be read.
2419 * @index: The index into the queue entry.
2420 *
2421 * Description:
2422 * This routine reads out a single entry from the given queue's index location
2423 * and copies it into the buffer provided.
2424 *
2425 * Returns:
2426 * This function returns 0 when it fails, otherwise, it returns the length of
2427 * the data read into the buffer provided.
2428 **/
2429static int
2430lpfc_idiag_queacc_read_qe(char *pbuffer, int len, struct lpfc_queue *pque,
2431			  uint32_t index)
2432{
2433	int offset, esize;
2434	uint32_t *pentry;
2435
2436	if (!pbuffer || !pque)
2437		return 0;
2438
2439	esize = pque->entry_size;
2440	len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
2441			"QE-INDEX[%04d]:\n", index);
2442
2443	offset = 0;
2444	pentry = pque->qe[index].address;
2445	while (esize > 0) {
2446		len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
2447				"%08x ", *pentry);
2448		pentry++;
2449		offset += sizeof(uint32_t);
2450		esize -= sizeof(uint32_t);
2451		if (esize > 0 && !(offset % (4 * sizeof(uint32_t))))
2452			len += snprintf(pbuffer+len,
2453					LPFC_QUE_ACC_BUF_SIZE-len, "\n");
2454	}
2455	len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, "\n");
2456
2457	return len;
2458}
2459
2460/**
2461 * lpfc_idiag_queacc_read - idiag debugfs read port queue
2462 * @file: The file pointer to read from.
2463 * @buf: The buffer to copy the data to.
2464 * @nbytes: The number of bytes to read.
2465 * @ppos: The position in the file to start reading from.
2466 *
2467 * Description:
2468 * This routine reads data from the @phba device queue memory according to the
2469 * idiag command, and copies to user @buf. Depending on the queue dump read
2470 * command setup, it does either a single queue entry read or browing through
2471 * all entries of the queue.
2472 *
2473 * Returns:
2474 * This function returns the amount of data that was read (this could be less
2475 * than @nbytes if the end of the file was reached) or a negative error value.
2476 **/
2477static ssize_t
2478lpfc_idiag_queacc_read(struct file *file, char __user *buf, size_t nbytes,
2479		       loff_t *ppos)
2480{
2481	struct lpfc_debug *debug = file->private_data;
2482	uint32_t last_index, index, count;
2483	struct lpfc_queue *pque = NULL;
2484	char *pbuffer;
2485	int len = 0;
2486
2487	/* This is a user read operation */
2488	debug->op = LPFC_IDIAG_OP_RD;
2489
2490	if (!debug->buffer)
2491		debug->buffer = kmalloc(LPFC_QUE_ACC_BUF_SIZE, GFP_KERNEL);
2492	if (!debug->buffer)
2493		return 0;
2494	pbuffer = debug->buffer;
2495
2496	if (*ppos)
2497		return 0;
2498
2499	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
2500		index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
2501		count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
2502		pque = (struct lpfc_queue *)idiag.ptr_private;
2503	} else
2504		return 0;
2505
2506	/* Browse the queue starting from index */
2507	if (count == LPFC_QUE_ACC_BROWSE)
2508		goto que_browse;
2509
2510	/* Read a single entry from the queue */
2511	len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
2512
2513	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2514
2515que_browse:
2516
2517	/* Browse all entries from the queue */
2518	last_index = idiag.offset.last_rd;
2519	index = last_index;
2520
2521	while (len < LPFC_QUE_ACC_SIZE - pque->entry_size) {
2522		len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
2523		index++;
2524		if (index > pque->entry_count - 1)
2525			break;
2526	}
2527
2528	/* Set up the offset for next portion of pci cfg read */
2529	if (index > pque->entry_count - 1)
2530		index = 0;
2531	idiag.offset.last_rd = index;
2532
2533	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2534}
2535
2536/**
2537 * lpfc_idiag_queacc_write - Syntax check and set up idiag queacc commands
2538 * @file: The file pointer to read from.
2539 * @buf: The buffer to copy the user data from.
2540 * @nbytes: The number of bytes to get.
2541 * @ppos: The position in the file to start reading from.
2542 *
2543 * This routine get the debugfs idiag command struct from user space and then
2544 * perform the syntax check for port queue read (dump) or write (set) command
2545 * accordingly. In the case of port queue read command, it sets up the command
2546 * in the idiag command struct for the following debugfs read operation. In
2547 * the case of port queue write operation, it executes the write operation
2548 * into the port queue entry accordingly.
2549 *
2550 * It returns the @nbytges passing in from debugfs user space when successful.
2551 * In case of error conditions, it returns proper error code back to the user
2552 * space.
2553 **/
2554static ssize_t
2555lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
2556			size_t nbytes, loff_t *ppos)
2557{
2558	struct lpfc_debug *debug = file->private_data;
2559	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2560	uint32_t qidx, quetp, queid, index, count, offset, value;
2561	uint32_t *pentry;
2562	struct lpfc_queue *pque;
2563	int rc;
2564
2565	/* This is a user write operation */
2566	debug->op = LPFC_IDIAG_OP_WR;
2567
2568	rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
2569	if (rc < 0)
2570		return rc;
2571
2572	/* Get and sanity check on command feilds */
2573	quetp  = idiag.cmd.data[IDIAG_QUEACC_QUETP_INDX];
2574	queid  = idiag.cmd.data[IDIAG_QUEACC_QUEID_INDX];
2575	index  = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
2576	count  = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
2577	offset = idiag.cmd.data[IDIAG_QUEACC_OFFST_INDX];
2578	value  = idiag.cmd.data[IDIAG_QUEACC_VALUE_INDX];
2579
2580	/* Sanity check on command line arguments */
2581	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
2582	    idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
2583	    idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
2584		if (rc != LPFC_QUE_ACC_WR_CMD_ARG)
2585			goto error_out;
2586		if (count != 1)
2587			goto error_out;
2588	} else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
2589		if (rc != LPFC_QUE_ACC_RD_CMD_ARG)
2590			goto error_out;
2591	} else
2592		goto error_out;
2593
2594	switch (quetp) {
2595	case LPFC_IDIAG_EQ:
2596		/* HBA event queue */
2597		if (phba->sli4_hba.hba_eq) {
2598			for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
2599				qidx++) {
2600				if (phba->sli4_hba.hba_eq[qidx] &&
2601				    phba->sli4_hba.hba_eq[qidx]->queue_id ==
2602				    queid) {
2603					/* Sanity check */
2604					rc = lpfc_idiag_que_param_check(
2605						phba->sli4_hba.hba_eq[qidx],
2606						index, count);
2607					if (rc)
2608						goto error_out;
2609					idiag.ptr_private =
2610						phba->sli4_hba.hba_eq[qidx];
2611					goto pass_check;
2612				}
2613			}
2614		}
2615		goto error_out;
2616		break;
2617	case LPFC_IDIAG_CQ:
2618		/* MBX complete queue */
2619		if (phba->sli4_hba.mbx_cq &&
2620		    phba->sli4_hba.mbx_cq->queue_id == queid) {
2621			/* Sanity check */
2622			rc = lpfc_idiag_que_param_check(
2623					phba->sli4_hba.mbx_cq, index, count);
2624			if (rc)
2625				goto error_out;
2626			idiag.ptr_private = phba->sli4_hba.mbx_cq;
2627			goto pass_check;
2628		}
2629		/* ELS complete queue */
2630		if (phba->sli4_hba.els_cq &&
2631		    phba->sli4_hba.els_cq->queue_id == queid) {
2632			/* Sanity check */
2633			rc = lpfc_idiag_que_param_check(
2634					phba->sli4_hba.els_cq, index, count);
2635			if (rc)
2636				goto error_out;
2637			idiag.ptr_private = phba->sli4_hba.els_cq;
2638			goto pass_check;
2639		}
2640		/* FCP complete queue */
2641		if (phba->sli4_hba.fcp_cq) {
2642			qidx = 0;
2643			do {
2644				if (phba->sli4_hba.fcp_cq[qidx] &&
2645				    phba->sli4_hba.fcp_cq[qidx]->queue_id ==
2646				    queid) {
2647					/* Sanity check */
2648					rc = lpfc_idiag_que_param_check(
2649						phba->sli4_hba.fcp_cq[qidx],
2650						index, count);
2651					if (rc)
2652						goto error_out;
2653					idiag.ptr_private =
2654						phba->sli4_hba.fcp_cq[qidx];
2655					goto pass_check;
2656				}
2657			} while (++qidx < phba->cfg_fcp_io_channel);
2658		}
2659		goto error_out;
2660		break;
2661	case LPFC_IDIAG_MQ:
2662		/* MBX work queue */
2663		if (phba->sli4_hba.mbx_wq &&
2664		    phba->sli4_hba.mbx_wq->queue_id == queid) {
2665			/* Sanity check */
2666			rc = lpfc_idiag_que_param_check(
2667					phba->sli4_hba.mbx_wq, index, count);
2668			if (rc)
2669				goto error_out;
2670			idiag.ptr_private = phba->sli4_hba.mbx_wq;
2671			goto pass_check;
2672		}
2673		goto error_out;
2674		break;
2675	case LPFC_IDIAG_WQ:
2676		/* ELS work queue */
2677		if (phba->sli4_hba.els_wq &&
2678		    phba->sli4_hba.els_wq->queue_id == queid) {
2679			/* Sanity check */
2680			rc = lpfc_idiag_que_param_check(
2681					phba->sli4_hba.els_wq, index, count);
2682			if (rc)
2683				goto error_out;
2684			idiag.ptr_private = phba->sli4_hba.els_wq;
2685			goto pass_check;
2686		}
2687		/* FCP work queue */
2688		if (phba->sli4_hba.fcp_wq) {
2689			for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
2690				qidx++) {
2691				if (!phba->sli4_hba.fcp_wq[qidx])
2692					continue;
2693				if (phba->sli4_hba.fcp_wq[qidx]->queue_id ==
2694				    queid) {
2695					/* Sanity check */
2696					rc = lpfc_idiag_que_param_check(
2697						phba->sli4_hba.fcp_wq[qidx],
2698						index, count);
2699					if (rc)
2700						goto error_out;
2701					idiag.ptr_private =
2702						phba->sli4_hba.fcp_wq[qidx];
2703					goto pass_check;
2704				}
2705			}
2706		}
2707		goto error_out;
2708		break;
2709	case LPFC_IDIAG_RQ:
2710		/* HDR queue */
2711		if (phba->sli4_hba.hdr_rq &&
2712		    phba->sli4_hba.hdr_rq->queue_id == queid) {
2713			/* Sanity check */
2714			rc = lpfc_idiag_que_param_check(
2715					phba->sli4_hba.hdr_rq, index, count);
2716			if (rc)
2717				goto error_out;
2718			idiag.ptr_private = phba->sli4_hba.hdr_rq;
2719			goto pass_check;
2720		}
2721		/* DAT queue */
2722		if (phba->sli4_hba.dat_rq &&
2723		    phba->sli4_hba.dat_rq->queue_id == queid) {
2724			/* Sanity check */
2725			rc = lpfc_idiag_que_param_check(
2726					phba->sli4_hba.dat_rq, index, count);
2727			if (rc)
2728				goto error_out;
2729			idiag.ptr_private = phba->sli4_hba.dat_rq;
2730			goto pass_check;
2731		}
2732		goto error_out;
2733		break;
2734	default:
2735		goto error_out;
2736		break;
2737	}
2738
2739pass_check:
2740
2741	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
2742		if (count == LPFC_QUE_ACC_BROWSE)
2743			idiag.offset.last_rd = index;
2744	}
2745
2746	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
2747	    idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
2748	    idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
2749		/* Additional sanity checks on write operation */
2750		pque = (struct lpfc_queue *)idiag.ptr_private;
2751		if (offset > pque->entry_size/sizeof(uint32_t) - 1)
2752			goto error_out;
2753		pentry = pque->qe[index].address;
2754		pentry += offset;
2755		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR)
2756			*pentry = value;
2757		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST)
2758			*pentry |= value;
2759		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL)
2760			*pentry &= ~value;
2761	}
2762	return nbytes;
2763
2764error_out:
2765	/* Clean out command structure on command error out */
2766	memset(&idiag, 0, sizeof(idiag));
2767	return -EINVAL;
2768}
2769
2770/**
2771 * lpfc_idiag_drbacc_read_reg - idiag debugfs read a doorbell register
2772 * @phba: The pointer to hba structure.
2773 * @pbuffer: The pointer to the buffer to copy the data to.
2774 * @len: The lenght of bytes to copied.
2775 * @drbregid: The id to doorbell registers.
2776 *
2777 * Description:
2778 * This routine reads a doorbell register and copies its content to the
2779 * user buffer pointed to by @pbuffer.
2780 *
2781 * Returns:
2782 * This function returns the amount of data that was copied into @pbuffer.
2783 **/
2784static int
2785lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
2786			   int len, uint32_t drbregid)
2787{
2788
2789	if (!pbuffer)
2790		return 0;
2791
2792	switch (drbregid) {
2793	case LPFC_DRB_EQCQ:
2794		len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2795				"EQCQ-DRB-REG: 0x%08x\n",
2796				readl(phba->sli4_hba.EQCQDBregaddr));
2797		break;
2798	case LPFC_DRB_MQ:
2799		len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2800				"MQ-DRB-REG:   0x%08x\n",
2801				readl(phba->sli4_hba.MQDBregaddr));
2802		break;
2803	case LPFC_DRB_WQ:
2804		len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2805				"WQ-DRB-REG:   0x%08x\n",
2806				readl(phba->sli4_hba.WQDBregaddr));
2807		break;
2808	case LPFC_DRB_RQ:
2809		len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2810				"RQ-DRB-REG:   0x%08x\n",
2811				readl(phba->sli4_hba.RQDBregaddr));
2812		break;
2813	default:
2814		break;
2815	}
2816
2817	return len;
2818}
2819
2820/**
2821 * lpfc_idiag_drbacc_read - idiag debugfs read port doorbell
2822 * @file: The file pointer to read from.
2823 * @buf: The buffer to copy the data to.
2824 * @nbytes: The number of bytes to read.
2825 * @ppos: The position in the file to start reading from.
2826 *
2827 * Description:
2828 * This routine reads data from the @phba device doorbell register according
2829 * to the idiag command, and copies to user @buf. Depending on the doorbell
2830 * register read command setup, it does either a single doorbell register
2831 * read or dump all doorbell registers.
2832 *
2833 * Returns:
2834 * This function returns the amount of data that was read (this could be less
2835 * than @nbytes if the end of the file was reached) or a negative error value.
2836 **/
2837static ssize_t
2838lpfc_idiag_drbacc_read(struct file *file, char __user *buf, size_t nbytes,
2839		       loff_t *ppos)
2840{
2841	struct lpfc_debug *debug = file->private_data;
2842	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2843	uint32_t drb_reg_id, i;
2844	char *pbuffer;
2845	int len = 0;
2846
2847	/* This is a user read operation */
2848	debug->op = LPFC_IDIAG_OP_RD;
2849
2850	if (!debug->buffer)
2851		debug->buffer = kmalloc(LPFC_DRB_ACC_BUF_SIZE, GFP_KERNEL);
2852	if (!debug->buffer)
2853		return 0;
2854	pbuffer = debug->buffer;
2855
2856	if (*ppos)
2857		return 0;
2858
2859	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD)
2860		drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
2861	else
2862		return 0;
2863
2864	if (drb_reg_id == LPFC_DRB_ACC_ALL)
2865		for (i = 1; i <= LPFC_DRB_MAX; i++)
2866			len = lpfc_idiag_drbacc_read_reg(phba,
2867							 pbuffer, len, i);
2868	else
2869		len = lpfc_idiag_drbacc_read_reg(phba,
2870						 pbuffer, len, drb_reg_id);
2871
2872	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2873}
2874
2875/**
2876 * lpfc_idiag_drbacc_write - Syntax check and set up idiag drbacc commands
2877 * @file: The file pointer to read from.
2878 * @buf: The buffer to copy the user data from.
2879 * @nbytes: The number of bytes to get.
2880 * @ppos: The position in the file to start reading from.
2881 *
2882 * This routine get the debugfs idiag command struct from user space and then
2883 * perform the syntax check for port doorbell register read (dump) or write
2884 * (set) command accordingly. In the case of port queue read command, it sets
2885 * up the command in the idiag command struct for the following debugfs read
2886 * operation. In the case of port doorbell register write operation, it
2887 * executes the write operation into the port doorbell register accordingly.
2888 *
2889 * It returns the @nbytges passing in from debugfs user space when successful.
2890 * In case of error conditions, it returns proper error code back to the user
2891 * space.
2892 **/
2893static ssize_t
2894lpfc_idiag_drbacc_write(struct file *file, const char __user *buf,
2895			size_t nbytes, loff_t *ppos)
2896{
2897	struct lpfc_debug *debug = file->private_data;
2898	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2899	uint32_t drb_reg_id, value, reg_val = 0;
2900	void __iomem *drb_reg;
2901	int rc;
2902
2903	/* This is a user write operation */
2904	debug->op = LPFC_IDIAG_OP_WR;
2905
2906	rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
2907	if (rc < 0)
2908		return rc;
2909
2910	/* Sanity check on command line arguments */
2911	drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
2912	value = idiag.cmd.data[IDIAG_DRBACC_VALUE_INDX];
2913
2914	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
2915	    idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
2916	    idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
2917		if (rc != LPFC_DRB_ACC_WR_CMD_ARG)
2918			goto error_out;
2919		if (drb_reg_id > LPFC_DRB_MAX)
2920			goto error_out;
2921	} else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD) {
2922		if (rc != LPFC_DRB_ACC_RD_CMD_ARG)
2923			goto error_out;
2924		if ((drb_reg_id > LPFC_DRB_MAX) &&
2925		    (drb_reg_id != LPFC_DRB_ACC_ALL))
2926			goto error_out;
2927	} else
2928		goto error_out;
2929
2930	/* Perform the write access operation */
2931	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
2932	    idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
2933	    idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
2934		switch (drb_reg_id) {
2935		case LPFC_DRB_EQCQ:
2936			drb_reg = phba->sli4_hba.EQCQDBregaddr;
2937			break;
2938		case LPFC_DRB_MQ:
2939			drb_reg = phba->sli4_hba.MQDBregaddr;
2940			break;
2941		case LPFC_DRB_WQ:
2942			drb_reg = phba->sli4_hba.WQDBregaddr;
2943			break;
2944		case LPFC_DRB_RQ:
2945			drb_reg = phba->sli4_hba.RQDBregaddr;
2946			break;
2947		default:
2948			goto error_out;
2949		}
2950
2951		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR)
2952			reg_val = value;
2953		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST) {
2954			reg_val = readl(drb_reg);
2955			reg_val |= value;
2956		}
2957		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
2958			reg_val = readl(drb_reg);
2959			reg_val &= ~value;
2960		}
2961		writel(reg_val, drb_reg);
2962		readl(drb_reg); /* flush */
2963	}
2964	return nbytes;
2965
2966error_out:
2967	/* Clean out command structure on command error out */
2968	memset(&idiag, 0, sizeof(idiag));
2969	return -EINVAL;
2970}
2971
2972/**
2973 * lpfc_idiag_ctlacc_read_reg - idiag debugfs read a control registers
2974 * @phba: The pointer to hba structure.
2975 * @pbuffer: The pointer to the buffer to copy the data to.
2976 * @len: The lenght of bytes to copied.
2977 * @drbregid: The id to doorbell registers.
2978 *
2979 * Description:
2980 * This routine reads a control register and copies its content to the
2981 * user buffer pointed to by @pbuffer.
2982 *
2983 * Returns:
2984 * This function returns the amount of data that was copied into @pbuffer.
2985 **/
2986static int
2987lpfc_idiag_ctlacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
2988			   int len, uint32_t ctlregid)
2989{
2990
2991	if (!pbuffer)
2992		return 0;
2993
2994	switch (ctlregid) {
2995	case LPFC_CTL_PORT_SEM:
2996		len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2997				"Port SemReg:   0x%08x\n",
2998				readl(phba->sli4_hba.conf_regs_memmap_p +
2999				      LPFC_CTL_PORT_SEM_OFFSET));
3000		break;
3001	case LPFC_CTL_PORT_STA:
3002		len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
3003				"Port StaReg:   0x%08x\n",
3004				readl(phba->sli4_hba.conf_regs_memmap_p +
3005				      LPFC_CTL_PORT_STA_OFFSET));
3006		break;
3007	case LPFC_CTL_PORT_CTL:
3008		len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
3009				"Port CtlReg:   0x%08x\n",
3010				readl(phba->sli4_hba.conf_regs_memmap_p +
3011				      LPFC_CTL_PORT_CTL_OFFSET));
3012		break;
3013	case LPFC_CTL_PORT_ER1:
3014		len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
3015				"Port Er1Reg:   0x%08x\n",
3016				readl(phba->sli4_hba.conf_regs_memmap_p +
3017				      LPFC_CTL_PORT_ER1_OFFSET));
3018		break;
3019	case LPFC_CTL_PORT_ER2:
3020		len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
3021				"Port Er2Reg:   0x%08x\n",
3022				readl(phba->sli4_hba.conf_regs_memmap_p +
3023				      LPFC_CTL_PORT_ER2_OFFSET));
3024		break;
3025	case LPFC_CTL_PDEV_CTL:
3026		len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
3027				"PDev CtlReg:   0x%08x\n",
3028				readl(phba->sli4_hba.conf_regs_memmap_p +
3029				      LPFC_CTL_PDEV_CTL_OFFSET));
3030		break;
3031	default:
3032		break;
3033	}
3034	return len;
3035}
3036
3037/**
3038 * lpfc_idiag_ctlacc_read - idiag debugfs read port and device control register
3039 * @file: The file pointer to read from.
3040 * @buf: The buffer to copy the data to.
3041 * @nbytes: The number of bytes to read.
3042 * @ppos: The position in the file to start reading from.
3043 *
3044 * Description:
3045 * This routine reads data from the @phba port and device registers according
3046 * to the idiag command, and copies to user @buf.
3047 *
3048 * Returns:
3049 * This function returns the amount of data that was read (this could be less
3050 * than @nbytes if the end of the file was reached) or a negative error value.
3051 **/
3052static ssize_t
3053lpfc_idiag_ctlacc_read(struct file *file, char __user *buf, size_t nbytes,
3054		       loff_t *ppos)
3055{
3056	struct lpfc_debug *debug = file->private_data;
3057	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3058	uint32_t ctl_reg_id, i;
3059	char *pbuffer;
3060	int len = 0;
3061
3062	/* This is a user read operation */
3063	debug->op = LPFC_IDIAG_OP_RD;
3064
3065	if (!debug->buffer)
3066		debug->buffer = kmalloc(LPFC_CTL_ACC_BUF_SIZE, GFP_KERNEL);
3067	if (!debug->buffer)
3068		return 0;
3069	pbuffer = debug->buffer;
3070
3071	if (*ppos)
3072		return 0;
3073
3074	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD)
3075		ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
3076	else
3077		return 0;
3078
3079	if (ctl_reg_id == LPFC_CTL_ACC_ALL)
3080		for (i = 1; i <= LPFC_CTL_MAX; i++)
3081			len = lpfc_idiag_ctlacc_read_reg(phba,
3082							 pbuffer, len, i);
3083	else
3084		len = lpfc_idiag_ctlacc_read_reg(phba,
3085						 pbuffer, len, ctl_reg_id);
3086
3087	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3088}
3089
3090/**
3091 * lpfc_idiag_ctlacc_write - Syntax check and set up idiag ctlacc commands
3092 * @file: The file pointer to read from.
3093 * @buf: The buffer to copy the user data from.
3094 * @nbytes: The number of bytes to get.
3095 * @ppos: The position in the file to start reading from.
3096 *
3097 * This routine get the debugfs idiag command struct from user space and then
3098 * perform the syntax check for port and device control register read (dump)
3099 * or write (set) command accordingly.
3100 *
3101 * It returns the @nbytges passing in from debugfs user space when successful.
3102 * In case of error conditions, it returns proper error code back to the user
3103 * space.
3104 **/
3105static ssize_t
3106lpfc_idiag_ctlacc_write(struct file *file, const char __user *buf,
3107			size_t nbytes, loff_t *ppos)
3108{
3109	struct lpfc_debug *debug = file->private_data;
3110	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3111	uint32_t ctl_reg_id, value, reg_val = 0;
3112	void __iomem *ctl_reg;
3113	int rc;
3114
3115	/* This is a user write operation */
3116	debug->op = LPFC_IDIAG_OP_WR;
3117
3118	rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3119	if (rc < 0)
3120		return rc;
3121
3122	/* Sanity check on command line arguments */
3123	ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
3124	value = idiag.cmd.data[IDIAG_CTLACC_VALUE_INDX];
3125
3126	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
3127	    idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
3128	    idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
3129		if (rc != LPFC_CTL_ACC_WR_CMD_ARG)
3130			goto error_out;
3131		if (ctl_reg_id > LPFC_CTL_MAX)
3132			goto error_out;
3133	} else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD) {
3134		if (rc != LPFC_CTL_ACC_RD_CMD_ARG)
3135			goto error_out;
3136		if ((ctl_reg_id > LPFC_CTL_MAX) &&
3137		    (ctl_reg_id != LPFC_CTL_ACC_ALL))
3138			goto error_out;
3139	} else
3140		goto error_out;
3141
3142	/* Perform the write access operation */
3143	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
3144	    idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
3145	    idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
3146		switch (ctl_reg_id) {
3147		case LPFC_CTL_PORT_SEM:
3148			ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3149					LPFC_CTL_PORT_SEM_OFFSET;
3150			break;
3151		case LPFC_CTL_PORT_STA:
3152			ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3153					LPFC_CTL_PORT_STA_OFFSET;
3154			break;
3155		case LPFC_CTL_PORT_CTL:
3156			ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3157					LPFC_CTL_PORT_CTL_OFFSET;
3158			break;
3159		case LPFC_CTL_PORT_ER1:
3160			ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3161					LPFC_CTL_PORT_ER1_OFFSET;
3162			break;
3163		case LPFC_CTL_PORT_ER2:
3164			ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3165					LPFC_CTL_PORT_ER2_OFFSET;
3166			break;
3167		case LPFC_CTL_PDEV_CTL:
3168			ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3169					LPFC_CTL_PDEV_CTL_OFFSET;
3170			break;
3171		default:
3172			goto error_out;
3173		}
3174
3175		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR)
3176			reg_val = value;
3177		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST) {
3178			reg_val = readl(ctl_reg);
3179			reg_val |= value;
3180		}
3181		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
3182			reg_val = readl(ctl_reg);
3183			reg_val &= ~value;
3184		}
3185		writel(reg_val, ctl_reg);
3186		readl(ctl_reg); /* flush */
3187	}
3188	return nbytes;
3189
3190error_out:
3191	/* Clean out command structure on command error out */
3192	memset(&idiag, 0, sizeof(idiag));
3193	return -EINVAL;
3194}
3195
3196/**
3197 * lpfc_idiag_mbxacc_get_setup - idiag debugfs get mailbox access setup
3198 * @phba: Pointer to HBA context object.
3199 * @pbuffer: Pointer to data buffer.
3200 *
3201 * Description:
3202 * This routine gets the driver mailbox access debugfs setup information.
3203 *
3204 * Returns:
3205 * This function returns the amount of data that was read (this could be less
3206 * than @nbytes if the end of the file was reached) or a negative error value.
3207 **/
3208static int
3209lpfc_idiag_mbxacc_get_setup(struct lpfc_hba *phba, char *pbuffer)
3210{
3211	uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
3212	int len = 0;
3213
3214	mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3215	mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3216	mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3217	mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3218
3219	len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3220			"mbx_dump_map: 0x%08x\n", mbx_dump_map);
3221	len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3222			"mbx_dump_cnt: %04d\n", mbx_dump_cnt);
3223	len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3224			"mbx_word_cnt: %04d\n", mbx_word_cnt);
3225	len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3226			"mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd);
3227
3228	return len;
3229}
3230
3231/**
3232 * lpfc_idiag_mbxacc_read - idiag debugfs read on mailbox access
3233 * @file: The file pointer to read from.
3234 * @buf: The buffer to copy the data to.
3235 * @nbytes: The number of bytes to read.
3236 * @ppos: The position in the file to start reading from.
3237 *
3238 * Description:
3239 * This routine reads data from the @phba driver mailbox access debugfs setup
3240 * information.
3241 *
3242 * Returns:
3243 * This function returns the amount of data that was read (this could be less
3244 * than @nbytes if the end of the file was reached) or a negative error value.
3245 **/
3246static ssize_t
3247lpfc_idiag_mbxacc_read(struct file *file, char __user *buf, size_t nbytes,
3248		       loff_t *ppos)
3249{
3250	struct lpfc_debug *debug = file->private_data;
3251	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3252	char *pbuffer;
3253	int len = 0;
3254
3255	/* This is a user read operation */
3256	debug->op = LPFC_IDIAG_OP_RD;
3257
3258	if (!debug->buffer)
3259		debug->buffer = kmalloc(LPFC_MBX_ACC_BUF_SIZE, GFP_KERNEL);
3260	if (!debug->buffer)
3261		return 0;
3262	pbuffer = debug->buffer;
3263
3264	if (*ppos)
3265		return 0;
3266
3267	if ((idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP) &&
3268	    (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP))
3269		return 0;
3270
3271	len = lpfc_idiag_mbxacc_get_setup(phba, pbuffer);
3272
3273	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3274}
3275
3276/**
3277 * lpfc_idiag_mbxacc_write - Syntax check and set up idiag mbxacc commands
3278 * @file: The file pointer to read from.
3279 * @buf: The buffer to copy the user data from.
3280 * @nbytes: The number of bytes to get.
3281 * @ppos: The position in the file to start reading from.
3282 *
3283 * This routine get the debugfs idiag command struct from user space and then
3284 * perform the syntax check for driver mailbox command (dump) and sets up the
3285 * necessary states in the idiag command struct accordingly.
3286 *
3287 * It returns the @nbytges passing in from debugfs user space when successful.
3288 * In case of error conditions, it returns proper error code back to the user
3289 * space.
3290 **/
3291static ssize_t
3292lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf,
3293			size_t nbytes, loff_t *ppos)
3294{
3295	struct lpfc_debug *debug = file->private_data;
3296	uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
3297	int rc;
3298
3299	/* This is a user write operation */
3300	debug->op = LPFC_IDIAG_OP_WR;
3301
3302	rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3303	if (rc < 0)
3304		return rc;
3305
3306	/* Sanity check on command line arguments */
3307	mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3308	mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3309	mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3310	mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3311
3312	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_MBXACC_DP) {
3313		if (!(mbx_dump_map & LPFC_MBX_DMP_MBX_ALL))
3314			goto error_out;
3315		if ((mbx_dump_map & ~LPFC_MBX_DMP_MBX_ALL) &&
3316		    (mbx_dump_map != LPFC_MBX_DMP_ALL))
3317			goto error_out;
3318		if (mbx_word_cnt > sizeof(MAILBOX_t))
3319			goto error_out;
3320	} else if (idiag.cmd.opcode == LPFC_IDIAG_BSG_MBXACC_DP) {
3321		if (!(mbx_dump_map & LPFC_BSG_DMP_MBX_ALL))
3322			goto error_out;
3323		if ((mbx_dump_map & ~LPFC_BSG_DMP_MBX_ALL) &&
3324		    (mbx_dump_map != LPFC_MBX_DMP_ALL))
3325			goto error_out;
3326		if (mbx_word_cnt > (BSG_MBOX_SIZE)/4)
3327			goto error_out;
3328		if (mbx_mbox_cmd != 0x9b)
3329			goto error_out;
3330	} else
3331		goto error_out;
3332
3333	if (mbx_word_cnt == 0)
3334		goto error_out;
3335	if (rc != LPFC_MBX_DMP_ARG)
3336		goto error_out;
3337	if (mbx_mbox_cmd & ~0xff)
3338		goto error_out;
3339
3340	/* condition for stop mailbox dump */
3341	if (mbx_dump_cnt == 0)
3342		goto reset_out;
3343
3344	return nbytes;
3345
3346reset_out:
3347	/* Clean out command structure on command error out */
3348	memset(&idiag, 0, sizeof(idiag));
3349	return nbytes;
3350
3351error_out:
3352	/* Clean out command structure on command error out */
3353	memset(&idiag, 0, sizeof(idiag));
3354	return -EINVAL;
3355}
3356
3357/**
3358 * lpfc_idiag_extacc_avail_get - get the available extents information
3359 * @phba: pointer to lpfc hba data structure.
3360 * @pbuffer: pointer to internal buffer.
3361 * @len: length into the internal buffer data has been copied.
3362 *
3363 * Description:
3364 * This routine is to get the available extent information.
3365 *
3366 * Returns:
3367 * overall lenth of the data read into the internal buffer.
3368 **/
3369static int
3370lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
3371{
3372	uint16_t ext_cnt, ext_size;
3373
3374	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3375			"\nAvailable Extents Information:\n");
3376
3377	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3378			"\tPort Available VPI extents: ");
3379	lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI,
3380				       &ext_cnt, &ext_size);
3381	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3382			"Count %3d, Size %3d\n", ext_cnt, ext_size);
3383
3384	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3385			"\tPort Available VFI extents: ");
3386	lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI,
3387				       &ext_cnt, &ext_size);
3388	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3389			"Count %3d, Size %3d\n", ext_cnt, ext_size);
3390
3391	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3392			"\tPort Available RPI extents: ");
3393	lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI,
3394				       &ext_cnt, &ext_size);
3395	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3396			"Count %3d, Size %3d\n", ext_cnt, ext_size);
3397
3398	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3399			"\tPort Available XRI extents: ");
3400	lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI,
3401				       &ext_cnt, &ext_size);
3402	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3403			"Count %3d, Size %3d\n", ext_cnt, ext_size);
3404
3405	return len;
3406}
3407
3408/**
3409 * lpfc_idiag_extacc_alloc_get - get the allocated extents information
3410 * @phba: pointer to lpfc hba data structure.
3411 * @pbuffer: pointer to internal buffer.
3412 * @len: length into the internal buffer data has been copied.
3413 *
3414 * Description:
3415 * This routine is to get the allocated extent information.
3416 *
3417 * Returns:
3418 * overall lenth of the data read into the internal buffer.
3419 **/
3420static int
3421lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len)
3422{
3423	uint16_t ext_cnt, ext_size;
3424	int rc;
3425
3426	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3427			"\nAllocated Extents Information:\n");
3428
3429	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3430			"\tHost Allocated VPI extents: ");
3431	rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI,
3432					    &ext_cnt, &ext_size);
3433	if (!rc)
3434		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3435				"Port %d Extent %3d, Size %3d\n",
3436				phba->brd_no, ext_cnt, ext_size);
3437	else
3438		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3439				"N/A\n");
3440
3441	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3442			"\tHost Allocated VFI extents: ");
3443	rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI,
3444					    &ext_cnt, &ext_size);
3445	if (!rc)
3446		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3447				"Port %d Extent %3d, Size %3d\n",
3448				phba->brd_no, ext_cnt, ext_size);
3449	else
3450		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3451				"N/A\n");
3452
3453	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3454			"\tHost Allocated RPI extents: ");
3455	rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI,
3456					    &ext_cnt, &ext_size);
3457	if (!rc)
3458		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3459				"Port %d Extent %3d, Size %3d\n",
3460				phba->brd_no, ext_cnt, ext_size);
3461	else
3462		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3463				"N/A\n");
3464
3465	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3466			"\tHost Allocated XRI extents: ");
3467	rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI,
3468					    &ext_cnt, &ext_size);
3469	if (!rc)
3470		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3471				"Port %d Extent %3d, Size %3d\n",
3472				phba->brd_no, ext_cnt, ext_size);
3473	else
3474		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3475				"N/A\n");
3476
3477	return len;
3478}
3479
3480/**
3481 * lpfc_idiag_extacc_drivr_get - get driver extent information
3482 * @phba: pointer to lpfc hba data structure.
3483 * @pbuffer: pointer to internal buffer.
3484 * @len: length into the internal buffer data has been copied.
3485 *
3486 * Description:
3487 * This routine is to get the driver extent information.
3488 *
3489 * Returns:
3490 * overall lenth of the data read into the internal buffer.
3491 **/
3492static int
3493lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len)
3494{
3495	struct lpfc_rsrc_blks *rsrc_blks;
3496	int index;
3497
3498	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3499			"\nDriver Extents Information:\n");
3500
3501	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3502			"\tVPI extents:\n");
3503	index = 0;
3504	list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) {
3505		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3506				"\t\tBlock %3d: Start %4d, Count %4d\n",
3507				index, rsrc_blks->rsrc_start,
3508				rsrc_blks->rsrc_size);
3509		index++;
3510	}
3511	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3512			"\tVFI extents:\n");
3513	index = 0;
3514	list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list,
3515			    list) {
3516		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3517				"\t\tBlock %3d: Start %4d, Count %4d\n",
3518				index, rsrc_blks->rsrc_start,
3519				rsrc_blks->rsrc_size);
3520		index++;
3521	}
3522
3523	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3524			"\tRPI extents:\n");
3525	index = 0;
3526	list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list,
3527			    list) {
3528		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3529				"\t\tBlock %3d: Start %4d, Count %4d\n",
3530				index, rsrc_blks->rsrc_start,
3531				rsrc_blks->rsrc_size);
3532		index++;
3533	}
3534
3535	len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3536			"\tXRI extents:\n");
3537	index = 0;
3538	list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list,
3539			    list) {
3540		len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3541				"\t\tBlock %3d: Start %4d, Count %4d\n",
3542				index, rsrc_blks->rsrc_start,
3543				rsrc_blks->rsrc_size);
3544		index++;
3545	}
3546
3547	return len;
3548}
3549
3550/**
3551 * lpfc_idiag_extacc_write - Syntax check and set up idiag extacc commands
3552 * @file: The file pointer to read from.
3553 * @buf: The buffer to copy the user data from.
3554 * @nbytes: The number of bytes to get.
3555 * @ppos: The position in the file to start reading from.
3556 *
3557 * This routine get the debugfs idiag command struct from user space and then
3558 * perform the syntax check for extent information access commands and sets
3559 * up the necessary states in the idiag command struct accordingly.
3560 *
3561 * It returns the @nbytges passing in from debugfs user space when successful.
3562 * In case of error conditions, it returns proper error code back to the user
3563 * space.
3564 **/
3565static ssize_t
3566lpfc_idiag_extacc_write(struct file *file, const char __user *buf,
3567			size_t nbytes, loff_t *ppos)
3568{
3569	struct lpfc_debug *debug = file->private_data;
3570	uint32_t ext_map;
3571	int rc;
3572
3573	/* This is a user write operation */
3574	debug->op = LPFC_IDIAG_OP_WR;
3575
3576	rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3577	if (rc < 0)
3578		return rc;
3579
3580	ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
3581
3582	if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
3583		goto error_out;
3584	if (rc != LPFC_EXT_ACC_CMD_ARG)
3585		goto error_out;
3586	if (!(ext_map & LPFC_EXT_ACC_ALL))
3587		goto error_out;
3588
3589	return nbytes;
3590error_out:
3591	/* Clean out command structure on command error out */
3592	memset(&idiag, 0, sizeof(idiag));
3593	return -EINVAL;
3594}
3595
3596/**
3597 * lpfc_idiag_extacc_read - idiag debugfs read access to extent information
3598 * @file: The file pointer to read from.
3599 * @buf: The buffer to copy the data to.
3600 * @nbytes: The number of bytes to read.
3601 * @ppos: The position in the file to start reading from.
3602 *
3603 * Description:
3604 * This routine reads data from the proper extent information according to
3605 * the idiag command, and copies to user @buf.
3606 *
3607 * Returns:
3608 * This function returns the amount of data that was read (this could be less
3609 * than @nbytes if the end of the file was reached) or a negative error value.
3610 **/
3611static ssize_t
3612lpfc_idiag_extacc_read(struct file *file, char __user *buf, size_t nbytes,
3613		       loff_t *ppos)
3614{
3615	struct lpfc_debug *debug = file->private_data;
3616	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3617	char *pbuffer;
3618	uint32_t ext_map;
3619	int len = 0;
3620
3621	/* This is a user read operation */
3622	debug->op = LPFC_IDIAG_OP_RD;
3623
3624	if (!debug->buffer)
3625		debug->buffer = kmalloc(LPFC_EXT_ACC_BUF_SIZE, GFP_KERNEL);
3626	if (!debug->buffer)
3627		return 0;
3628	pbuffer = debug->buffer;
3629	if (*ppos)
3630		return 0;
3631	if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
3632		return 0;
3633
3634	ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
3635	if (ext_map & LPFC_EXT_ACC_AVAIL)
3636		len = lpfc_idiag_extacc_avail_get(phba, pbuffer, len);
3637	if (ext_map & LPFC_EXT_ACC_ALLOC)
3638		len = lpfc_idiag_extacc_alloc_get(phba, pbuffer, len);
3639	if (ext_map & LPFC_EXT_ACC_DRIVR)
3640		len = lpfc_idiag_extacc_drivr_get(phba, pbuffer, len);
3641
3642	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3643}
3644
3645#undef lpfc_debugfs_op_disc_trc
3646static const struct file_operations lpfc_debugfs_op_disc_trc = {
3647	.owner =        THIS_MODULE,
3648	.open =         lpfc_debugfs_disc_trc_open,
3649	.llseek =       lpfc_debugfs_lseek,
3650	.read =         lpfc_debugfs_read,
3651	.release =      lpfc_debugfs_release,
3652};
3653
3654#undef lpfc_debugfs_op_nodelist
3655static const struct file_operations lpfc_debugfs_op_nodelist = {
3656	.owner =        THIS_MODULE,
3657	.open =         lpfc_debugfs_nodelist_open,
3658	.llseek =       lpfc_debugfs_lseek,
3659	.read =         lpfc_debugfs_read,
3660	.release =      lpfc_debugfs_release,
3661};
3662
3663#undef lpfc_debugfs_op_hbqinfo
3664static const struct file_operations lpfc_debugfs_op_hbqinfo = {
3665	.owner =        THIS_MODULE,
3666	.open =         lpfc_debugfs_hbqinfo_open,
3667	.llseek =       lpfc_debugfs_lseek,
3668	.read =         lpfc_debugfs_read,
3669	.release =      lpfc_debugfs_release,
3670};
3671
3672#undef lpfc_debugfs_op_dumpHBASlim
3673static const struct file_operations lpfc_debugfs_op_dumpHBASlim = {
3674	.owner =        THIS_MODULE,
3675	.open =         lpfc_debugfs_dumpHBASlim_open,
3676	.llseek =       lpfc_debugfs_lseek,
3677	.read =         lpfc_debugfs_read,
3678	.release =      lpfc_debugfs_release,
3679};
3680
3681#undef lpfc_debugfs_op_dumpHostSlim
3682static const struct file_operations lpfc_debugfs_op_dumpHostSlim = {
3683	.owner =        THIS_MODULE,
3684	.open =         lpfc_debugfs_dumpHostSlim_open,
3685	.llseek =       lpfc_debugfs_lseek,
3686	.read =         lpfc_debugfs_read,
3687	.release =      lpfc_debugfs_release,
3688};
3689
3690#undef lpfc_debugfs_op_dumpData
3691static const struct file_operations lpfc_debugfs_op_dumpData = {
3692	.owner =        THIS_MODULE,
3693	.open =         lpfc_debugfs_dumpData_open,
3694	.llseek =       lpfc_debugfs_lseek,
3695	.read =         lpfc_debugfs_read,
3696	.write =	lpfc_debugfs_dumpDataDif_write,
3697	.release =      lpfc_debugfs_dumpDataDif_release,
3698};
3699
3700#undef lpfc_debugfs_op_dumpDif
3701static const struct file_operations lpfc_debugfs_op_dumpDif = {
3702	.owner =        THIS_MODULE,
3703	.open =         lpfc_debugfs_dumpDif_open,
3704	.llseek =       lpfc_debugfs_lseek,
3705	.read =         lpfc_debugfs_read,
3706	.write =	lpfc_debugfs_dumpDataDif_write,
3707	.release =      lpfc_debugfs_dumpDataDif_release,
3708};
3709
3710#undef lpfc_debugfs_op_dif_err
3711static const struct file_operations lpfc_debugfs_op_dif_err = {
3712	.owner =	THIS_MODULE,
3713	.open =		simple_open,
3714	.llseek =	lpfc_debugfs_lseek,
3715	.read =		lpfc_debugfs_dif_err_read,
3716	.write =	lpfc_debugfs_dif_err_write,
3717	.release =	lpfc_debugfs_dif_err_release,
3718};
3719
3720#undef lpfc_debugfs_op_slow_ring_trc
3721static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
3722	.owner =        THIS_MODULE,
3723	.open =         lpfc_debugfs_slow_ring_trc_open,
3724	.llseek =       lpfc_debugfs_lseek,
3725	.read =         lpfc_debugfs_read,
3726	.release =      lpfc_debugfs_release,
3727};
3728
3729static struct dentry *lpfc_debugfs_root = NULL;
3730static atomic_t lpfc_debugfs_hba_count;
3731
3732/*
3733 * File operations for the iDiag debugfs
3734 */
3735#undef lpfc_idiag_op_pciCfg
3736static const struct file_operations lpfc_idiag_op_pciCfg = {
3737	.owner =        THIS_MODULE,
3738	.open =         lpfc_idiag_open,
3739	.llseek =       lpfc_debugfs_lseek,
3740	.read =         lpfc_idiag_pcicfg_read,
3741	.write =        lpfc_idiag_pcicfg_write,
3742	.release =      lpfc_idiag_cmd_release,
3743};
3744
3745#undef lpfc_idiag_op_barAcc
3746static const struct file_operations lpfc_idiag_op_barAcc = {
3747	.owner =        THIS_MODULE,
3748	.open =         lpfc_idiag_open,
3749	.llseek =       lpfc_debugfs_lseek,
3750	.read =         lpfc_idiag_baracc_read,
3751	.write =        lpfc_idiag_baracc_write,
3752	.release =      lpfc_idiag_cmd_release,
3753};
3754
3755#undef lpfc_idiag_op_queInfo
3756static const struct file_operations lpfc_idiag_op_queInfo = {
3757	.owner =        THIS_MODULE,
3758	.open =         lpfc_idiag_open,
3759	.read =         lpfc_idiag_queinfo_read,
3760	.release =      lpfc_idiag_release,
3761};
3762
3763#undef lpfc_idiag_op_queAcc
3764static const struct file_operations lpfc_idiag_op_queAcc = {
3765	.owner =        THIS_MODULE,
3766	.open =         lpfc_idiag_open,
3767	.llseek =       lpfc_debugfs_lseek,
3768	.read =         lpfc_idiag_queacc_read,
3769	.write =        lpfc_idiag_queacc_write,
3770	.release =      lpfc_idiag_cmd_release,
3771};
3772
3773#undef lpfc_idiag_op_drbAcc
3774static const struct file_operations lpfc_idiag_op_drbAcc = {
3775	.owner =        THIS_MODULE,
3776	.open =         lpfc_idiag_open,
3777	.llseek =       lpfc_debugfs_lseek,
3778	.read =         lpfc_idiag_drbacc_read,
3779	.write =        lpfc_idiag_drbacc_write,
3780	.release =      lpfc_idiag_cmd_release,
3781};
3782
3783#undef lpfc_idiag_op_ctlAcc
3784static const struct file_operations lpfc_idiag_op_ctlAcc = {
3785	.owner =        THIS_MODULE,
3786	.open =         lpfc_idiag_open,
3787	.llseek =       lpfc_debugfs_lseek,
3788	.read =         lpfc_idiag_ctlacc_read,
3789	.write =        lpfc_idiag_ctlacc_write,
3790	.release =      lpfc_idiag_cmd_release,
3791};
3792
3793#undef lpfc_idiag_op_mbxAcc
3794static const struct file_operations lpfc_idiag_op_mbxAcc = {
3795	.owner =        THIS_MODULE,
3796	.open =         lpfc_idiag_open,
3797	.llseek =       lpfc_debugfs_lseek,
3798	.read =         lpfc_idiag_mbxacc_read,
3799	.write =        lpfc_idiag_mbxacc_write,
3800	.release =      lpfc_idiag_cmd_release,
3801};
3802
3803#undef lpfc_idiag_op_extAcc
3804static const struct file_operations lpfc_idiag_op_extAcc = {
3805	.owner =        THIS_MODULE,
3806	.open =         lpfc_idiag_open,
3807	.llseek =       lpfc_debugfs_lseek,
3808	.read =         lpfc_idiag_extacc_read,
3809	.write =        lpfc_idiag_extacc_write,
3810	.release =      lpfc_idiag_cmd_release,
3811};
3812
3813#endif
3814
3815/* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command
3816 * @phba: Pointer to HBA context object.
3817 * @dmabuf: Pointer to a DMA buffer descriptor.
3818 *
3819 * Description:
3820 * This routine dump a bsg pass-through non-embedded mailbox command with
3821 * external buffer.
3822 **/
3823void
3824lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *phba, enum nemb_type nemb_tp,
3825				enum mbox_type mbox_tp, enum dma_type dma_tp,
3826				enum sta_type sta_tp,
3827				struct lpfc_dmabuf *dmabuf, uint32_t ext_buf)
3828{
3829#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
3830	uint32_t *mbx_mbox_cmd, *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt;
3831	char line_buf[LPFC_MBX_ACC_LBUF_SZ];
3832	int len = 0;
3833	uint32_t do_dump = 0;
3834	uint32_t *pword;
3835	uint32_t i;
3836
3837	if (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP)
3838		return;
3839
3840	mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3841	mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3842	mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3843	mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3844
3845	if (!(*mbx_dump_map & LPFC_MBX_DMP_ALL) ||
3846	    (*mbx_dump_cnt == 0) ||
3847	    (*mbx_word_cnt == 0))
3848		return;
3849
3850	if (*mbx_mbox_cmd != 0x9B)
3851		return;
3852
3853	if ((mbox_tp == mbox_rd) && (dma_tp == dma_mbox)) {
3854		if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_MBX) {
3855			do_dump |= LPFC_BSG_DMP_MBX_RD_MBX;
3856			printk(KERN_ERR "\nRead mbox command (x%x), "
3857			       "nemb:0x%x, extbuf_cnt:%d:\n",
3858			       sta_tp, nemb_tp, ext_buf);
3859		}
3860	}
3861	if ((mbox_tp == mbox_rd) && (dma_tp == dma_ebuf)) {
3862		if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_BUF) {
3863			do_dump |= LPFC_BSG_DMP_MBX_RD_BUF;
3864			printk(KERN_ERR "\nRead mbox buffer (x%x), "
3865			       "nemb:0x%x, extbuf_seq:%d:\n",
3866			       sta_tp, nemb_tp, ext_buf);
3867		}
3868	}
3869	if ((mbox_tp == mbox_wr) && (dma_tp == dma_mbox)) {
3870		if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_MBX) {
3871			do_dump |= LPFC_BSG_DMP_MBX_WR_MBX;
3872			printk(KERN_ERR "\nWrite mbox command (x%x), "
3873			       "nemb:0x%x, extbuf_cnt:%d:\n",
3874			       sta_tp, nemb_tp, ext_buf);
3875		}
3876	}
3877	if ((mbox_tp == mbox_wr) && (dma_tp == dma_ebuf)) {
3878		if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_BUF) {
3879			do_dump |= LPFC_BSG_DMP_MBX_WR_BUF;
3880			printk(KERN_ERR "\nWrite mbox buffer (x%x), "
3881			       "nemb:0x%x, extbuf_seq:%d:\n",
3882			       sta_tp, nemb_tp, ext_buf);
3883		}
3884	}
3885
3886	/* dump buffer content */
3887	if (do_dump) {
3888		pword = (uint32_t *)dmabuf->virt;
3889		for (i = 0; i < *mbx_word_cnt; i++) {
3890			if (!(i % 8)) {
3891				if (i != 0)
3892					printk(KERN_ERR "%s\n", line_buf);
3893				len = 0;
3894				len += snprintf(line_buf+len,
3895						LPFC_MBX_ACC_LBUF_SZ-len,
3896						"%03d: ", i);
3897			}
3898			len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
3899					"%08x ", (uint32_t)*pword);
3900			pword++;
3901		}
3902		if ((i - 1) % 8)
3903			printk(KERN_ERR "%s\n", line_buf);
3904		(*mbx_dump_cnt)--;
3905	}
3906
3907	/* Clean out command structure on reaching dump count */
3908	if (*mbx_dump_cnt == 0)
3909		memset(&idiag, 0, sizeof(idiag));
3910	return;
3911#endif
3912}
3913
3914/* lpfc_idiag_mbxacc_dump_issue_mbox - idiag debugfs dump issue mailbox command
3915 * @phba: Pointer to HBA context object.
3916 * @dmabuf: Pointer to a DMA buffer descriptor.
3917 *
3918 * Description:
3919 * This routine dump a pass-through non-embedded mailbox command from issue
3920 * mailbox command.
3921 **/
3922void
3923lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox)
3924{
3925#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
3926	uint32_t *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt, *mbx_mbox_cmd;
3927	char line_buf[LPFC_MBX_ACC_LBUF_SZ];
3928	int len = 0;
3929	uint32_t *pword;
3930	uint8_t *pbyte;
3931	uint32_t i, j;
3932
3933	if (idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP)
3934		return;
3935
3936	mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3937	mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3938	mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3939	mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3940
3941	if (!(*mbx_dump_map & LPFC_MBX_DMP_MBX_ALL) ||
3942	    (*mbx_dump_cnt == 0) ||
3943	    (*mbx_word_cnt == 0))
3944		return;
3945
3946	if ((*mbx_mbox_cmd != LPFC_MBX_ALL_CMD) &&
3947	    (*mbx_mbox_cmd != pmbox->mbxCommand))
3948		return;
3949
3950	/* dump buffer content */
3951	if (*mbx_dump_map & LPFC_MBX_DMP_MBX_WORD) {
3952		printk(KERN_ERR "Mailbox command:0x%x dump by word:\n",
3953		       pmbox->mbxCommand);
3954		pword = (uint32_t *)pmbox;
3955		for (i = 0; i < *mbx_word_cnt; i++) {
3956			if (!(i % 8)) {
3957				if (i != 0)
3958					printk(KERN_ERR "%s\n", line_buf);
3959				len = 0;
3960				memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
3961				len += snprintf(line_buf+len,
3962						LPFC_MBX_ACC_LBUF_SZ-len,
3963						"%03d: ", i);
3964			}
3965			len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
3966					"%08x ",
3967					((uint32_t)*pword) & 0xffffffff);
3968			pword++;
3969		}
3970		if ((i - 1) % 8)
3971			printk(KERN_ERR "%s\n", line_buf);
3972		printk(KERN_ERR "\n");
3973	}
3974	if (*mbx_dump_map & LPFC_MBX_DMP_MBX_BYTE) {
3975		printk(KERN_ERR "Mailbox command:0x%x dump by byte:\n",
3976		       pmbox->mbxCommand);
3977		pbyte = (uint8_t *)pmbox;
3978		for (i = 0; i < *mbx_word_cnt; i++) {
3979			if (!(i % 8)) {
3980				if (i != 0)
3981					printk(KERN_ERR "%s\n", line_buf);
3982				len = 0;
3983				memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
3984				len += snprintf(line_buf+len,
3985						LPFC_MBX_ACC_LBUF_SZ-len,
3986						"%03d: ", i);
3987			}
3988			for (j = 0; j < 4; j++) {
3989				len += snprintf(line_buf+len,
3990						LPFC_MBX_ACC_LBUF_SZ-len,
3991						"%02x",
3992						((uint8_t)*pbyte) & 0xff);
3993				pbyte++;
3994			}
3995			len += snprintf(line_buf+len,
3996					LPFC_MBX_ACC_LBUF_SZ-len, " ");
3997		}
3998		if ((i - 1) % 8)
3999			printk(KERN_ERR "%s\n", line_buf);
4000		printk(KERN_ERR "\n");
4001	}
4002	(*mbx_dump_cnt)--;
4003
4004	/* Clean out command structure on reaching dump count */
4005	if (*mbx_dump_cnt == 0)
4006		memset(&idiag, 0, sizeof(idiag));
4007	return;
4008#endif
4009}
4010
4011/**
4012 * lpfc_debugfs_initialize - Initialize debugfs for a vport
4013 * @vport: The vport pointer to initialize.
4014 *
4015 * Description:
4016 * When Debugfs is configured this routine sets up the lpfc debugfs file system.
4017 * If not already created, this routine will create the lpfc directory, and
4018 * lpfcX directory (for this HBA), and vportX directory for this vport. It will
4019 * also create each file used to access lpfc specific debugfs information.
4020 **/
4021inline void
4022lpfc_debugfs_initialize(struct lpfc_vport *vport)
4023{
4024#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
4025	struct lpfc_hba   *phba = vport->phba;
4026	char name[64];
4027	uint32_t num, i;
4028	bool pport_setup = false;
4029
4030	if (!lpfc_debugfs_enable)
4031		return;
4032
4033	/* Setup lpfc root directory */
4034	if (!lpfc_debugfs_root) {
4035		lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
4036		atomic_set(&lpfc_debugfs_hba_count, 0);
4037		if (!lpfc_debugfs_root) {
4038			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4039					 "0408 Cannot create debugfs root\n");
4040			goto debug_failed;
4041		}
4042	}
4043	if (!lpfc_debugfs_start_time)
4044		lpfc_debugfs_start_time = jiffies;
4045
4046	/* Setup funcX directory for specific HBA PCI function */
4047	snprintf(name, sizeof(name), "fn%d", phba->brd_no);
4048	if (!phba->hba_debugfs_root) {
4049		pport_setup = true;
4050		phba->hba_debugfs_root =
4051			debugfs_create_dir(name, lpfc_debugfs_root);
4052		if (!phba->hba_debugfs_root) {
4053			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4054					 "0412 Cannot create debugfs hba\n");
4055			goto debug_failed;
4056		}
4057		atomic_inc(&lpfc_debugfs_hba_count);
4058		atomic_set(&phba->debugfs_vport_count, 0);
4059
4060		/* Setup hbqinfo */
4061		snprintf(name, sizeof(name), "hbqinfo");
4062		phba->debug_hbqinfo =
4063			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4064				 phba->hba_debugfs_root,
4065				 phba, &lpfc_debugfs_op_hbqinfo);
4066		if (!phba->debug_hbqinfo) {
4067			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4068				"0411 Cannot create debugfs hbqinfo\n");
4069			goto debug_failed;
4070		}
4071
4072		/* Setup dumpHBASlim */
4073		if (phba->sli_rev < LPFC_SLI_REV4) {
4074			snprintf(name, sizeof(name), "dumpHBASlim");
4075			phba->debug_dumpHBASlim =
4076				debugfs_create_file(name,
4077					S_IFREG|S_IRUGO|S_IWUSR,
4078					phba->hba_debugfs_root,
4079					phba, &lpfc_debugfs_op_dumpHBASlim);
4080			if (!phba->debug_dumpHBASlim) {
4081				lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4082						 "0413 Cannot create debugfs "
4083						"dumpHBASlim\n");
4084				goto debug_failed;
4085			}
4086		} else
4087			phba->debug_dumpHBASlim = NULL;
4088
4089		/* Setup dumpHostSlim */
4090		if (phba->sli_rev < LPFC_SLI_REV4) {
4091			snprintf(name, sizeof(name), "dumpHostSlim");
4092			phba->debug_dumpHostSlim =
4093				debugfs_create_file(name,
4094					S_IFREG|S_IRUGO|S_IWUSR,
4095					phba->hba_debugfs_root,
4096					phba, &lpfc_debugfs_op_dumpHostSlim);
4097			if (!phba->debug_dumpHostSlim) {
4098				lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4099						 "0414 Cannot create debugfs "
4100						 "dumpHostSlim\n");
4101				goto debug_failed;
4102			}
4103		} else
4104			phba->debug_dumpHostSlim = NULL;
4105
4106		/* Setup dumpData */
4107		snprintf(name, sizeof(name), "dumpData");
4108		phba->debug_dumpData =
4109			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4110				 phba->hba_debugfs_root,
4111				 phba, &lpfc_debugfs_op_dumpData);
4112		if (!phba->debug_dumpData) {
4113			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4114				"0800 Cannot create debugfs dumpData\n");
4115			goto debug_failed;
4116		}
4117
4118		/* Setup dumpDif */
4119		snprintf(name, sizeof(name), "dumpDif");
4120		phba->debug_dumpDif =
4121			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4122				 phba->hba_debugfs_root,
4123				 phba, &lpfc_debugfs_op_dumpDif);
4124		if (!phba->debug_dumpDif) {
4125			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4126				"0801 Cannot create debugfs dumpDif\n");
4127			goto debug_failed;
4128		}
4129
4130		/* Setup DIF Error Injections */
4131		snprintf(name, sizeof(name), "InjErrLBA");
4132		phba->debug_InjErrLBA =
4133			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4134			phba->hba_debugfs_root,
4135			phba, &lpfc_debugfs_op_dif_err);
4136		if (!phba->debug_InjErrLBA) {
4137			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4138				"0807 Cannot create debugfs InjErrLBA\n");
4139			goto debug_failed;
4140		}
4141		phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
4142
4143		snprintf(name, sizeof(name), "InjErrNPortID");
4144		phba->debug_InjErrNPortID =
4145			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4146			phba->hba_debugfs_root,
4147			phba, &lpfc_debugfs_op_dif_err);
4148		if (!phba->debug_InjErrNPortID) {
4149			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4150				"0809 Cannot create debugfs InjErrNPortID\n");
4151			goto debug_failed;
4152		}
4153
4154		snprintf(name, sizeof(name), "InjErrWWPN");
4155		phba->debug_InjErrWWPN =
4156			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4157			phba->hba_debugfs_root,
4158			phba, &lpfc_debugfs_op_dif_err);
4159		if (!phba->debug_InjErrWWPN) {
4160			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4161				"0810 Cannot create debugfs InjErrWWPN\n");
4162			goto debug_failed;
4163		}
4164
4165		snprintf(name, sizeof(name), "writeGuardInjErr");
4166		phba->debug_writeGuard =
4167			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4168			phba->hba_debugfs_root,
4169			phba, &lpfc_debugfs_op_dif_err);
4170		if (!phba->debug_writeGuard) {
4171			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4172				"0802 Cannot create debugfs writeGuard\n");
4173			goto debug_failed;
4174		}
4175
4176		snprintf(name, sizeof(name), "writeAppInjErr");
4177		phba->debug_writeApp =
4178			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4179			phba->hba_debugfs_root,
4180			phba, &lpfc_debugfs_op_dif_err);
4181		if (!phba->debug_writeApp) {
4182			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4183				"0803 Cannot create debugfs writeApp\n");
4184			goto debug_failed;
4185		}
4186
4187		snprintf(name, sizeof(name), "writeRefInjErr");
4188		phba->debug_writeRef =
4189			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4190			phba->hba_debugfs_root,
4191			phba, &lpfc_debugfs_op_dif_err);
4192		if (!phba->debug_writeRef) {
4193			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4194				"0804 Cannot create debugfs writeRef\n");
4195			goto debug_failed;
4196		}
4197
4198		snprintf(name, sizeof(name), "readGuardInjErr");
4199		phba->debug_readGuard =
4200			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4201			phba->hba_debugfs_root,
4202			phba, &lpfc_debugfs_op_dif_err);
4203		if (!phba->debug_readGuard) {
4204			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4205				"0808 Cannot create debugfs readGuard\n");
4206			goto debug_failed;
4207		}
4208
4209		snprintf(name, sizeof(name), "readAppInjErr");
4210		phba->debug_readApp =
4211			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4212			phba->hba_debugfs_root,
4213			phba, &lpfc_debugfs_op_dif_err);
4214		if (!phba->debug_readApp) {
4215			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4216				"0805 Cannot create debugfs readApp\n");
4217			goto debug_failed;
4218		}
4219
4220		snprintf(name, sizeof(name), "readRefInjErr");
4221		phba->debug_readRef =
4222			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4223			phba->hba_debugfs_root,
4224			phba, &lpfc_debugfs_op_dif_err);
4225		if (!phba->debug_readRef) {
4226			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4227				"0806 Cannot create debugfs readApp\n");
4228			goto debug_failed;
4229		}
4230
4231		/* Setup slow ring trace */
4232		if (lpfc_debugfs_max_slow_ring_trc) {
4233			num = lpfc_debugfs_max_slow_ring_trc - 1;
4234			if (num & lpfc_debugfs_max_slow_ring_trc) {
4235				/* Change to be a power of 2 */
4236				num = lpfc_debugfs_max_slow_ring_trc;
4237				i = 0;
4238				while (num > 1) {
4239					num = num >> 1;
4240					i++;
4241				}
4242				lpfc_debugfs_max_slow_ring_trc = (1 << i);
4243				printk(KERN_ERR
4244				       "lpfc_debugfs_max_disc_trc changed to "
4245				       "%d\n", lpfc_debugfs_max_disc_trc);
4246			}
4247		}
4248
4249		snprintf(name, sizeof(name), "slow_ring_trace");
4250		phba->debug_slow_ring_trc =
4251			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4252				 phba->hba_debugfs_root,
4253				 phba, &lpfc_debugfs_op_slow_ring_trc);
4254		if (!phba->debug_slow_ring_trc) {
4255			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4256					 "0415 Cannot create debugfs "
4257					 "slow_ring_trace\n");
4258			goto debug_failed;
4259		}
4260		if (!phba->slow_ring_trc) {
4261			phba->slow_ring_trc = kmalloc(
4262				(sizeof(struct lpfc_debugfs_trc) *
4263				lpfc_debugfs_max_slow_ring_trc),
4264				GFP_KERNEL);
4265			if (!phba->slow_ring_trc) {
4266				lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4267						 "0416 Cannot create debugfs "
4268						 "slow_ring buffer\n");
4269				goto debug_failed;
4270			}
4271			atomic_set(&phba->slow_ring_trc_cnt, 0);
4272			memset(phba->slow_ring_trc, 0,
4273				(sizeof(struct lpfc_debugfs_trc) *
4274				lpfc_debugfs_max_slow_ring_trc));
4275		}
4276	}
4277
4278	snprintf(name, sizeof(name), "vport%d", vport->vpi);
4279	if (!vport->vport_debugfs_root) {
4280		vport->vport_debugfs_root =
4281			debugfs_create_dir(name, phba->hba_debugfs_root);
4282		if (!vport->vport_debugfs_root) {
4283			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4284					 "0417 Can't create debugfs\n");
4285			goto debug_failed;
4286		}
4287		atomic_inc(&phba->debugfs_vport_count);
4288	}
4289
4290	if (lpfc_debugfs_max_disc_trc) {
4291		num = lpfc_debugfs_max_disc_trc - 1;
4292		if (num & lpfc_debugfs_max_disc_trc) {
4293			/* Change to be a power of 2 */
4294			num = lpfc_debugfs_max_disc_trc;
4295			i = 0;
4296			while (num > 1) {
4297				num = num >> 1;
4298				i++;
4299			}
4300			lpfc_debugfs_max_disc_trc = (1 << i);
4301			printk(KERN_ERR
4302			       "lpfc_debugfs_max_disc_trc changed to %d\n",
4303			       lpfc_debugfs_max_disc_trc);
4304		}
4305	}
4306
4307	vport->disc_trc = kzalloc(
4308		(sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
4309		GFP_KERNEL);
4310
4311	if (!vport->disc_trc) {
4312		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4313				 "0418 Cannot create debugfs disc trace "
4314				 "buffer\n");
4315		goto debug_failed;
4316	}
4317	atomic_set(&vport->disc_trc_cnt, 0);
4318
4319	snprintf(name, sizeof(name), "discovery_trace");
4320	vport->debug_disc_trc =
4321		debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4322				 vport->vport_debugfs_root,
4323				 vport, &lpfc_debugfs_op_disc_trc);
4324	if (!vport->debug_disc_trc) {
4325		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4326				 "0419 Cannot create debugfs "
4327				 "discovery_trace\n");
4328		goto debug_failed;
4329	}
4330	snprintf(name, sizeof(name), "nodelist");
4331	vport->debug_nodelist =
4332		debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4333				 vport->vport_debugfs_root,
4334				 vport, &lpfc_debugfs_op_nodelist);
4335	if (!vport->debug_nodelist) {
4336		lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4337				 "2985 Can't create debugfs nodelist\n");
4338		goto debug_failed;
4339	}
4340
4341	/*
4342	 * The following section is for additional directories/files for the
4343	 * physical port.
4344	 */
4345
4346	if (!pport_setup)
4347		goto debug_failed;
4348
4349	/*
4350	 * iDiag debugfs root entry points for SLI4 device only
4351	 */
4352	if (phba->sli_rev < LPFC_SLI_REV4)
4353		goto debug_failed;
4354
4355	snprintf(name, sizeof(name), "iDiag");
4356	if (!phba->idiag_root) {
4357		phba->idiag_root =
4358			debugfs_create_dir(name, phba->hba_debugfs_root);
4359		if (!phba->idiag_root) {
4360			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4361					 "2922 Can't create idiag debugfs\n");
4362			goto debug_failed;
4363		}
4364		/* Initialize iDiag data structure */
4365		memset(&idiag, 0, sizeof(idiag));
4366	}
4367
4368	/* iDiag read PCI config space */
4369	snprintf(name, sizeof(name), "pciCfg");
4370	if (!phba->idiag_pci_cfg) {
4371		phba->idiag_pci_cfg =
4372			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4373				phba->idiag_root, phba, &lpfc_idiag_op_pciCfg);
4374		if (!phba->idiag_pci_cfg) {
4375			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4376					 "2923 Can't create idiag debugfs\n");
4377			goto debug_failed;
4378		}
4379		idiag.offset.last_rd = 0;
4380	}
4381
4382	/* iDiag PCI BAR access */
4383	snprintf(name, sizeof(name), "barAcc");
4384	if (!phba->idiag_bar_acc) {
4385		phba->idiag_bar_acc =
4386			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4387				phba->idiag_root, phba, &lpfc_idiag_op_barAcc);
4388		if (!phba->idiag_bar_acc) {
4389			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4390					"3056 Can't create idiag debugfs\n");
4391			goto debug_failed;
4392		}
4393		idiag.offset.last_rd = 0;
4394	}
4395
4396	/* iDiag get PCI function queue information */
4397	snprintf(name, sizeof(name), "queInfo");
4398	if (!phba->idiag_que_info) {
4399		phba->idiag_que_info =
4400			debugfs_create_file(name, S_IFREG|S_IRUGO,
4401			phba->idiag_root, phba, &lpfc_idiag_op_queInfo);
4402		if (!phba->idiag_que_info) {
4403			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4404					 "2924 Can't create idiag debugfs\n");
4405			goto debug_failed;
4406		}
4407	}
4408
4409	/* iDiag access PCI function queue */
4410	snprintf(name, sizeof(name), "queAcc");
4411	if (!phba->idiag_que_acc) {
4412		phba->idiag_que_acc =
4413			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4414				phba->idiag_root, phba, &lpfc_idiag_op_queAcc);
4415		if (!phba->idiag_que_acc) {
4416			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4417					 "2926 Can't create idiag debugfs\n");
4418			goto debug_failed;
4419		}
4420	}
4421
4422	/* iDiag access PCI function doorbell registers */
4423	snprintf(name, sizeof(name), "drbAcc");
4424	if (!phba->idiag_drb_acc) {
4425		phba->idiag_drb_acc =
4426			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4427				phba->idiag_root, phba, &lpfc_idiag_op_drbAcc);
4428		if (!phba->idiag_drb_acc) {
4429			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4430					 "2927 Can't create idiag debugfs\n");
4431			goto debug_failed;
4432		}
4433	}
4434
4435	/* iDiag access PCI function control registers */
4436	snprintf(name, sizeof(name), "ctlAcc");
4437	if (!phba->idiag_ctl_acc) {
4438		phba->idiag_ctl_acc =
4439			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4440				phba->idiag_root, phba, &lpfc_idiag_op_ctlAcc);
4441		if (!phba->idiag_ctl_acc) {
4442			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4443					 "2981 Can't create idiag debugfs\n");
4444			goto debug_failed;
4445		}
4446	}
4447
4448	/* iDiag access mbox commands */
4449	snprintf(name, sizeof(name), "mbxAcc");
4450	if (!phba->idiag_mbx_acc) {
4451		phba->idiag_mbx_acc =
4452			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4453				phba->idiag_root, phba, &lpfc_idiag_op_mbxAcc);
4454		if (!phba->idiag_mbx_acc) {
4455			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4456					"2980 Can't create idiag debugfs\n");
4457			goto debug_failed;
4458		}
4459	}
4460
4461	/* iDiag extents access commands */
4462	if (phba->sli4_hba.extents_in_use) {
4463		snprintf(name, sizeof(name), "extAcc");
4464		if (!phba->idiag_ext_acc) {
4465			phba->idiag_ext_acc =
4466				debugfs_create_file(name,
4467						    S_IFREG|S_IRUGO|S_IWUSR,
4468						    phba->idiag_root, phba,
4469						    &lpfc_idiag_op_extAcc);
4470			if (!phba->idiag_ext_acc) {
4471				lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4472						"2986 Cant create "
4473						"idiag debugfs\n");
4474				goto debug_failed;
4475			}
4476		}
4477	}
4478
4479debug_failed:
4480	return;
4481#endif
4482}
4483
4484/**
4485 * lpfc_debugfs_terminate -  Tear down debugfs infrastructure for this vport
4486 * @vport: The vport pointer to remove from debugfs.
4487 *
4488 * Description:
4489 * When Debugfs is configured this routine removes debugfs file system elements
4490 * that are specific to this vport. It also checks to see if there are any
4491 * users left for the debugfs directories associated with the HBA and driver. If
4492 * this is the last user of the HBA directory or driver directory then it will
4493 * remove those from the debugfs infrastructure as well.
4494 **/
4495inline void
4496lpfc_debugfs_terminate(struct lpfc_vport *vport)
4497{
4498#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
4499	struct lpfc_hba   *phba = vport->phba;
4500
4501	if (vport->disc_trc) {
4502		kfree(vport->disc_trc);
4503		vport->disc_trc = NULL;
4504	}
4505	if (vport->debug_disc_trc) {
4506		debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
4507		vport->debug_disc_trc = NULL;
4508	}
4509	if (vport->debug_nodelist) {
4510		debugfs_remove(vport->debug_nodelist); /* nodelist */
4511		vport->debug_nodelist = NULL;
4512	}
4513	if (vport->vport_debugfs_root) {
4514		debugfs_remove(vport->vport_debugfs_root); /* vportX */
4515		vport->vport_debugfs_root = NULL;
4516		atomic_dec(&phba->debugfs_vport_count);
4517	}
4518	if (atomic_read(&phba->debugfs_vport_count) == 0) {
4519
4520		if (phba->debug_hbqinfo) {
4521			debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
4522			phba->debug_hbqinfo = NULL;
4523		}
4524		if (phba->debug_dumpHBASlim) {
4525			debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */
4526			phba->debug_dumpHBASlim = NULL;
4527		}
4528		if (phba->debug_dumpHostSlim) {
4529			debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */
4530			phba->debug_dumpHostSlim = NULL;
4531		}
4532		if (phba->debug_dumpData) {
4533			debugfs_remove(phba->debug_dumpData); /* dumpData */
4534			phba->debug_dumpData = NULL;
4535		}
4536
4537		if (phba->debug_dumpDif) {
4538			debugfs_remove(phba->debug_dumpDif); /* dumpDif */
4539			phba->debug_dumpDif = NULL;
4540		}
4541		if (phba->debug_InjErrLBA) {
4542			debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */
4543			phba->debug_InjErrLBA = NULL;
4544		}
4545		if (phba->debug_InjErrNPortID) {	 /* InjErrNPortID */
4546			debugfs_remove(phba->debug_InjErrNPortID);
4547			phba->debug_InjErrNPortID = NULL;
4548		}
4549		if (phba->debug_InjErrWWPN) {
4550			debugfs_remove(phba->debug_InjErrWWPN); /* InjErrWWPN */
4551			phba->debug_InjErrWWPN = NULL;
4552		}
4553		if (phba->debug_writeGuard) {
4554			debugfs_remove(phba->debug_writeGuard); /* writeGuard */
4555			phba->debug_writeGuard = NULL;
4556		}
4557		if (phba->debug_writeApp) {
4558			debugfs_remove(phba->debug_writeApp); /* writeApp */
4559			phba->debug_writeApp = NULL;
4560		}
4561		if (phba->debug_writeRef) {
4562			debugfs_remove(phba->debug_writeRef); /* writeRef */
4563			phba->debug_writeRef = NULL;
4564		}
4565		if (phba->debug_readGuard) {
4566			debugfs_remove(phba->debug_readGuard); /* readGuard */
4567			phba->debug_readGuard = NULL;
4568		}
4569		if (phba->debug_readApp) {
4570			debugfs_remove(phba->debug_readApp); /* readApp */
4571			phba->debug_readApp = NULL;
4572		}
4573		if (phba->debug_readRef) {
4574			debugfs_remove(phba->debug_readRef); /* readRef */
4575			phba->debug_readRef = NULL;
4576		}
4577
4578		if (phba->slow_ring_trc) {
4579			kfree(phba->slow_ring_trc);
4580			phba->slow_ring_trc = NULL;
4581		}
4582		if (phba->debug_slow_ring_trc) {
4583			/* slow_ring_trace */
4584			debugfs_remove(phba->debug_slow_ring_trc);
4585			phba->debug_slow_ring_trc = NULL;
4586		}
4587
4588		/*
4589		 * iDiag release
4590		 */
4591		if (phba->sli_rev == LPFC_SLI_REV4) {
4592			if (phba->idiag_ext_acc) {
4593				/* iDiag extAcc */
4594				debugfs_remove(phba->idiag_ext_acc);
4595				phba->idiag_ext_acc = NULL;
4596			}
4597			if (phba->idiag_mbx_acc) {
4598				/* iDiag mbxAcc */
4599				debugfs_remove(phba->idiag_mbx_acc);
4600				phba->idiag_mbx_acc = NULL;
4601			}
4602			if (phba->idiag_ctl_acc) {
4603				/* iDiag ctlAcc */
4604				debugfs_remove(phba->idiag_ctl_acc);
4605				phba->idiag_ctl_acc = NULL;
4606			}
4607			if (phba->idiag_drb_acc) {
4608				/* iDiag drbAcc */
4609				debugfs_remove(phba->idiag_drb_acc);
4610				phba->idiag_drb_acc = NULL;
4611			}
4612			if (phba->idiag_que_acc) {
4613				/* iDiag queAcc */
4614				debugfs_remove(phba->idiag_que_acc);
4615				phba->idiag_que_acc = NULL;
4616			}
4617			if (phba->idiag_que_info) {
4618				/* iDiag queInfo */
4619				debugfs_remove(phba->idiag_que_info);
4620				phba->idiag_que_info = NULL;
4621			}
4622			if (phba->idiag_bar_acc) {
4623				/* iDiag barAcc */
4624				debugfs_remove(phba->idiag_bar_acc);
4625				phba->idiag_bar_acc = NULL;
4626			}
4627			if (phba->idiag_pci_cfg) {
4628				/* iDiag pciCfg */
4629				debugfs_remove(phba->idiag_pci_cfg);
4630				phba->idiag_pci_cfg = NULL;
4631			}
4632
4633			/* Finally remove the iDiag debugfs root */
4634			if (phba->idiag_root) {
4635				/* iDiag root */
4636				debugfs_remove(phba->idiag_root);
4637				phba->idiag_root = NULL;
4638			}
4639		}
4640
4641		if (phba->hba_debugfs_root) {
4642			debugfs_remove(phba->hba_debugfs_root); /* fnX */
4643			phba->hba_debugfs_root = NULL;
4644			atomic_dec(&lpfc_debugfs_hba_count);
4645		}
4646
4647		if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
4648			debugfs_remove(lpfc_debugfs_root); /* lpfc */
4649			lpfc_debugfs_root = NULL;
4650		}
4651	}
4652#endif
4653	return;
4654}
4655
4656/*
4657 * Driver debug utility routines outside of debugfs. The debug utility
4658 * routines implemented here is intended to be used in the instrumented
4659 * debug driver for debugging host or port issues.
4660 */
4661
4662/**
4663 * lpfc_debug_dump_all_queues - dump all the queues with a hba
4664 * @phba: Pointer to HBA context object.
4665 *
4666 * This function dumps entries of all the queues asociated with the @phba.
4667 **/
4668void
4669lpfc_debug_dump_all_queues(struct lpfc_hba *phba)
4670{
4671	int fcp_wqidx;
4672
4673	/*
4674	 * Dump Work Queues (WQs)
4675	 */
4676	lpfc_debug_dump_mbx_wq(phba);
4677	lpfc_debug_dump_els_wq(phba);
4678
4679	for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
4680		lpfc_debug_dump_fcp_wq(phba, fcp_wqidx);
4681
4682	lpfc_debug_dump_hdr_rq(phba);
4683	lpfc_debug_dump_dat_rq(phba);
4684	/*
4685	 * Dump Complete Queues (CQs)
4686	 */
4687	lpfc_debug_dump_mbx_cq(phba);
4688	lpfc_debug_dump_els_cq(phba);
4689
4690	for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
4691		lpfc_debug_dump_fcp_cq(phba, fcp_wqidx);
4692
4693	/*
4694	 * Dump Event Queues (EQs)
4695	 */
4696	for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
4697		lpfc_debug_dump_hba_eq(phba, fcp_wqidx);
4698}
4699