]> Git Repo - linux.git/blob - drivers/scsi/lpfc/lpfc_debugfs.c
ARM: dts: imx7s: Enable SNVS power key according to board design
[linux.git] / drivers / scsi / lpfc / lpfc_debugfs.c
1 /*******************************************************************
2  * This file is part of the Emulex Linux Device Driver for         *
3  * Fibre Channel Host Bus Adapters.                                *
4  * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term *
5  * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.  *
6  * Copyright (C) 2007-2015 Emulex.  All rights reserved.           *
7  * EMULEX and SLI are trademarks of Emulex.                        *
8  * www.broadcom.com                                                *
9  *                                                                 *
10  * This program is free software; you can redistribute it and/or   *
11  * modify it under the terms of version 2 of the GNU General       *
12  * Public License as published by the Free Software Foundation.    *
13  * This program is distributed in the hope that it will be useful. *
14  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
15  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
16  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
17  * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
18  * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
19  * more details, a copy of which can be found in the file COPYING  *
20  * included with this package.                                     *
21  *******************************************************************/
22
23 #include <linux/blkdev.h>
24 #include <linux/delay.h>
25 #include <linux/module.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/idr.h>
28 #include <linux/interrupt.h>
29 #include <linux/kthread.h>
30 #include <linux/slab.h>
31 #include <linux/pci.h>
32 #include <linux/spinlock.h>
33 #include <linux/ctype.h>
34
35 #include <scsi/scsi.h>
36 #include <scsi/scsi_device.h>
37 #include <scsi/scsi_host.h>
38 #include <scsi/scsi_transport_fc.h>
39 #include <scsi/fc/fc_fs.h>
40
41 #include <linux/nvme-fc-driver.h>
42
43 #include "lpfc_hw4.h"
44 #include "lpfc_hw.h"
45 #include "lpfc_sli.h"
46 #include "lpfc_sli4.h"
47 #include "lpfc_nl.h"
48 #include "lpfc_disc.h"
49 #include "lpfc.h"
50 #include "lpfc_scsi.h"
51 #include "lpfc_nvme.h"
52 #include "lpfc_nvmet.h"
53 #include "lpfc_logmsg.h"
54 #include "lpfc_crtn.h"
55 #include "lpfc_vport.h"
56 #include "lpfc_version.h"
57 #include "lpfc_compat.h"
58 #include "lpfc_debugfs.h"
59 #include "lpfc_bsg.h"
60
61 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
62 /*
63  * debugfs interface
64  *
65  * To access this interface the user should:
66  * # mount -t debugfs none /sys/kernel/debug
67  *
68  * The lpfc debugfs directory hierarchy is:
69  * /sys/kernel/debug/lpfc/fnX/vportY
70  * where X is the lpfc hba function unique_id
71  * where Y is the vport VPI on that hba
72  *
73  * Debugging services available per vport:
74  * discovery_trace
75  * This is an ACSII readable file that contains a trace of the last
76  * lpfc_debugfs_max_disc_trc events that happened on a specific vport.
77  * See lpfc_debugfs.h for different categories of  discovery events.
78  * To enable the discovery trace, the following module parameters must be set:
79  * lpfc_debugfs_enable=1         Turns on lpfc debugfs filesystem support
80  * lpfc_debugfs_max_disc_trc=X   Where X is the event trace depth for
81  *                               EACH vport. X MUST also be a power of 2.
82  * lpfc_debugfs_mask_disc_trc=Y  Where Y is an event mask as defined in
83  *                               lpfc_debugfs.h .
84  *
85  * slow_ring_trace
86  * This is an ACSII readable file that contains a trace of the last
87  * lpfc_debugfs_max_slow_ring_trc events that happened on a specific HBA.
88  * To enable the slow ring trace, the following module parameters must be set:
89  * lpfc_debugfs_enable=1         Turns on lpfc debugfs filesystem support
90  * lpfc_debugfs_max_slow_ring_trc=X   Where X is the event trace depth for
91  *                               the HBA. X MUST also be a power of 2.
92  */
93 static int lpfc_debugfs_enable = 1;
94 module_param(lpfc_debugfs_enable, int, S_IRUGO);
95 MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services");
96
97 /* This MUST be a power of 2 */
98 static int lpfc_debugfs_max_disc_trc;
99 module_param(lpfc_debugfs_max_disc_trc, int, S_IRUGO);
100 MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc,
101         "Set debugfs discovery trace depth");
102
103 /* This MUST be a power of 2 */
104 static int lpfc_debugfs_max_slow_ring_trc;
105 module_param(lpfc_debugfs_max_slow_ring_trc, int, S_IRUGO);
106 MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
107         "Set debugfs slow ring trace depth");
108
109 /* This MUST be a power of 2 */
110 static int lpfc_debugfs_max_nvmeio_trc;
111 module_param(lpfc_debugfs_max_nvmeio_trc, int, 0444);
112 MODULE_PARM_DESC(lpfc_debugfs_max_nvmeio_trc,
113                  "Set debugfs NVME IO trace depth");
114
115 static int lpfc_debugfs_mask_disc_trc;
116 module_param(lpfc_debugfs_mask_disc_trc, int, S_IRUGO);
117 MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
118         "Set debugfs discovery trace mask");
119
120 #include <linux/debugfs.h>
121
122 static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
123 static unsigned long lpfc_debugfs_start_time = 0L;
124
125 /* iDiag */
126 static struct lpfc_idiag idiag;
127
128 /**
129  * lpfc_debugfs_disc_trc_data - Dump discovery logging to a buffer
130  * @vport: The vport to gather the log info from.
131  * @buf: The buffer to dump log into.
132  * @size: The maximum amount of data to process.
133  *
134  * Description:
135  * This routine gathers the lpfc discovery debugfs data from the @vport and
136  * dumps it to @buf up to @size number of bytes. It will start at the next entry
137  * in the log and process the log until the end of the buffer. Then it will
138  * gather from the beginning of the log and process until the current entry.
139  *
140  * Notes:
141  * Discovery logging will be disabled while while this routine dumps the log.
142  *
143  * Return Value:
144  * This routine returns the amount of bytes that were dumped into @buf and will
145  * not exceed @size.
146  **/
147 static int
148 lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
149 {
150         int i, index, len, enable;
151         uint32_t ms;
152         struct lpfc_debugfs_trc *dtp;
153         char *buffer;
154
155         buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
156         if (!buffer)
157                 return 0;
158
159         enable = lpfc_debugfs_enable;
160         lpfc_debugfs_enable = 0;
161
162         len = 0;
163         index = (atomic_read(&vport->disc_trc_cnt) + 1) &
164                 (lpfc_debugfs_max_disc_trc - 1);
165         for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
166                 dtp = vport->disc_trc + i;
167                 if (!dtp->fmt)
168                         continue;
169                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
170                 snprintf(buffer,
171                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
172                         dtp->seq_cnt, ms, dtp->fmt);
173                 len +=  scnprintf(buf+len, size-len, buffer,
174                         dtp->data1, dtp->data2, dtp->data3);
175         }
176         for (i = 0; i < index; i++) {
177                 dtp = vport->disc_trc + i;
178                 if (!dtp->fmt)
179                         continue;
180                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
181                 snprintf(buffer,
182                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
183                         dtp->seq_cnt, ms, dtp->fmt);
184                 len +=  scnprintf(buf+len, size-len, buffer,
185                         dtp->data1, dtp->data2, dtp->data3);
186         }
187
188         lpfc_debugfs_enable = enable;
189         kfree(buffer);
190
191         return len;
192 }
193
194 /**
195  * lpfc_debugfs_slow_ring_trc_data - Dump slow ring logging to a buffer
196  * @phba: The HBA to gather the log info from.
197  * @buf: The buffer to dump log into.
198  * @size: The maximum amount of data to process.
199  *
200  * Description:
201  * This routine gathers the lpfc slow ring debugfs data from the @phba and
202  * dumps it to @buf up to @size number of bytes. It will start at the next entry
203  * in the log and process the log until the end of the buffer. Then it will
204  * gather from the beginning of the log and process until the current entry.
205  *
206  * Notes:
207  * Slow ring logging will be disabled while while this routine dumps the log.
208  *
209  * Return Value:
210  * This routine returns the amount of bytes that were dumped into @buf and will
211  * not exceed @size.
212  **/
213 static int
214 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
215 {
216         int i, index, len, enable;
217         uint32_t ms;
218         struct lpfc_debugfs_trc *dtp;
219         char *buffer;
220
221         buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
222         if (!buffer)
223                 return 0;
224
225         enable = lpfc_debugfs_enable;
226         lpfc_debugfs_enable = 0;
227
228         len = 0;
229         index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
230                 (lpfc_debugfs_max_slow_ring_trc - 1);
231         for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
232                 dtp = phba->slow_ring_trc + i;
233                 if (!dtp->fmt)
234                         continue;
235                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
236                 snprintf(buffer,
237                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
238                         dtp->seq_cnt, ms, dtp->fmt);
239                 len +=  scnprintf(buf+len, size-len, buffer,
240                         dtp->data1, dtp->data2, dtp->data3);
241         }
242         for (i = 0; i < index; i++) {
243                 dtp = phba->slow_ring_trc + i;
244                 if (!dtp->fmt)
245                         continue;
246                 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
247                 snprintf(buffer,
248                         LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
249                         dtp->seq_cnt, ms, dtp->fmt);
250                 len +=  scnprintf(buf+len, size-len, buffer,
251                         dtp->data1, dtp->data2, dtp->data3);
252         }
253
254         lpfc_debugfs_enable = enable;
255         kfree(buffer);
256
257         return len;
258 }
259
260 static int lpfc_debugfs_last_hbq = -1;
261
262 /**
263  * lpfc_debugfs_hbqinfo_data - Dump host buffer queue info to a buffer
264  * @phba: The HBA to gather host buffer info from.
265  * @buf: The buffer to dump log into.
266  * @size: The maximum amount of data to process.
267  *
268  * Description:
269  * This routine dumps the host buffer queue info from the @phba to @buf up to
270  * @size number of bytes. A header that describes the current hbq state will be
271  * dumped to @buf first and then info on each hbq entry will be dumped to @buf
272  * until @size bytes have been dumped or all the hbq info has been dumped.
273  *
274  * Notes:
275  * This routine will rotate through each configured HBQ each time called.
276  *
277  * Return Value:
278  * This routine returns the amount of bytes that were dumped into @buf and will
279  * not exceed @size.
280  **/
281 static int
282 lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
283 {
284         int len = 0;
285         int i, j, found, posted, low;
286         uint32_t phys, raw_index, getidx;
287         struct lpfc_hbq_init *hip;
288         struct hbq_s *hbqs;
289         struct lpfc_hbq_entry *hbqe;
290         struct lpfc_dmabuf *d_buf;
291         struct hbq_dmabuf *hbq_buf;
292
293         if (phba->sli_rev != 3)
294                 return 0;
295
296         spin_lock_irq(&phba->hbalock);
297
298         /* toggle between multiple hbqs, if any */
299         i = lpfc_sli_hbq_count();
300         if (i > 1) {
301                  lpfc_debugfs_last_hbq++;
302                  if (lpfc_debugfs_last_hbq >= i)
303                         lpfc_debugfs_last_hbq = 0;
304         }
305         else
306                 lpfc_debugfs_last_hbq = 0;
307
308         i = lpfc_debugfs_last_hbq;
309
310         len +=  scnprintf(buf+len, size-len, "HBQ %d Info\n", i);
311
312         hbqs =  &phba->hbqs[i];
313         posted = 0;
314         list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
315                 posted++;
316
317         hip =  lpfc_hbq_defs[i];
318         len +=  scnprintf(buf+len, size-len,
319                 "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
320                 hip->hbq_index, hip->profile, hip->rn,
321                 hip->buffer_count, hip->init_count, hip->add_count, posted);
322
323         raw_index = phba->hbq_get[i];
324         getidx = le32_to_cpu(raw_index);
325         len +=  scnprintf(buf+len, size-len,
326                 "entries:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
327                 hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx,
328                 hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx);
329
330         hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
331         for (j=0; j<hbqs->entry_count; j++) {
332                 len +=  scnprintf(buf+len, size-len,
333                         "%03d: %08x %04x %05x ", j,
334                         le32_to_cpu(hbqe->bde.addrLow),
335                         le32_to_cpu(hbqe->bde.tus.w),
336                         le32_to_cpu(hbqe->buffer_tag));
337                 i = 0;
338                 found = 0;
339
340                 /* First calculate if slot has an associated posted buffer */
341                 low = hbqs->hbqPutIdx - posted;
342                 if (low >= 0) {
343                         if ((j >= hbqs->hbqPutIdx) || (j < low)) {
344                                 len +=  scnprintf(buf + len, size - len,
345                                                 "Unused\n");
346                                 goto skipit;
347                         }
348                 }
349                 else {
350                         if ((j >= hbqs->hbqPutIdx) &&
351                                 (j < (hbqs->entry_count+low))) {
352                                 len +=  scnprintf(buf + len, size - len,
353                                                 "Unused\n");
354                                 goto skipit;
355                         }
356                 }
357
358                 /* Get the Buffer info for the posted buffer */
359                 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
360                         hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
361                         phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
362                         if (phys == le32_to_cpu(hbqe->bde.addrLow)) {
363                                 len +=  scnprintf(buf+len, size-len,
364                                         "Buf%d: %p %06x\n", i,
365                                         hbq_buf->dbuf.virt, hbq_buf->tag);
366                                 found = 1;
367                                 break;
368                         }
369                         i++;
370                 }
371                 if (!found) {
372                         len +=  scnprintf(buf+len, size-len, "No DMAinfo?\n");
373                 }
374 skipit:
375                 hbqe++;
376                 if (len > LPFC_HBQINFO_SIZE - 54)
377                         break;
378         }
379         spin_unlock_irq(&phba->hbalock);
380         return len;
381 }
382
383 static int lpfc_debugfs_last_xripool;
384
385 /**
386  * lpfc_debugfs_common_xri_data - Dump Hardware Queue info to a buffer
387  * @phba: The HBA to gather host buffer info from.
388  * @buf: The buffer to dump log into.
389  * @size: The maximum amount of data to process.
390  *
391  * Description:
392  * This routine dumps the Hardware Queue info from the @phba to @buf up to
393  * @size number of bytes. A header that describes the current hdwq state will be
394  * dumped to @buf first and then info on each hdwq entry will be dumped to @buf
395  * until @size bytes have been dumped or all the hdwq info has been dumped.
396  *
397  * Notes:
398  * This routine will rotate through each configured Hardware Queue each
399  * time called.
400  *
401  * Return Value:
402  * This routine returns the amount of bytes that were dumped into @buf and will
403  * not exceed @size.
404  **/
405 static int
406 lpfc_debugfs_commonxripools_data(struct lpfc_hba *phba, char *buf, int size)
407 {
408         struct lpfc_sli4_hdw_queue *qp;
409         int len = 0;
410         int i, out;
411         unsigned long iflag;
412
413         for (i = 0; i < phba->cfg_hdw_queue; i++) {
414                 if (len > (LPFC_DUMP_MULTIXRIPOOL_SIZE - 80))
415                         break;
416                 qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_xripool];
417
418                 len += scnprintf(buf + len, size - len, "HdwQ %d Info ", i);
419                 spin_lock_irqsave(&qp->abts_scsi_buf_list_lock, iflag);
420                 spin_lock(&qp->abts_nvme_buf_list_lock);
421                 spin_lock(&qp->io_buf_list_get_lock);
422                 spin_lock(&qp->io_buf_list_put_lock);
423                 out = qp->total_io_bufs - (qp->get_io_bufs + qp->put_io_bufs +
424                         qp->abts_scsi_io_bufs + qp->abts_nvme_io_bufs);
425                 len += scnprintf(buf + len, size - len,
426                                  "tot:%d get:%d put:%d mt:%d "
427                                  "ABTS scsi:%d nvme:%d Out:%d\n",
428                         qp->total_io_bufs, qp->get_io_bufs, qp->put_io_bufs,
429                         qp->empty_io_bufs, qp->abts_scsi_io_bufs,
430                         qp->abts_nvme_io_bufs, out);
431                 spin_unlock(&qp->io_buf_list_put_lock);
432                 spin_unlock(&qp->io_buf_list_get_lock);
433                 spin_unlock(&qp->abts_nvme_buf_list_lock);
434                 spin_unlock_irqrestore(&qp->abts_scsi_buf_list_lock, iflag);
435
436                 lpfc_debugfs_last_xripool++;
437                 if (lpfc_debugfs_last_xripool >= phba->cfg_hdw_queue)
438                         lpfc_debugfs_last_xripool = 0;
439         }
440
441         return len;
442 }
443
444 /**
445  * lpfc_debugfs_multixripools_data - Display multi-XRI pools information
446  * @phba: The HBA to gather host buffer info from.
447  * @buf: The buffer to dump log into.
448  * @size: The maximum amount of data to process.
449  *
450  * Description:
451  * This routine displays current multi-XRI pools information including XRI
452  * count in public, private and txcmplq. It also displays current high and
453  * low watermark.
454  *
455  * Return Value:
456  * This routine returns the amount of bytes that were dumped into @buf and will
457  * not exceed @size.
458  **/
459 static int
460 lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size)
461 {
462         u32 i;
463         u32 hwq_count;
464         struct lpfc_sli4_hdw_queue *qp;
465         struct lpfc_multixri_pool *multixri_pool;
466         struct lpfc_pvt_pool *pvt_pool;
467         struct lpfc_pbl_pool *pbl_pool;
468         u32 txcmplq_cnt;
469         char tmp[LPFC_DEBUG_OUT_LINE_SZ] = {0};
470
471         if (phba->sli_rev != LPFC_SLI_REV4)
472                 return 0;
473
474         if (!phba->sli4_hba.hdwq)
475                 return 0;
476
477         if (!phba->cfg_xri_rebalancing) {
478                 i = lpfc_debugfs_commonxripools_data(phba, buf, size);
479                 return i;
480         }
481
482         /*
483          * Pbl: Current number of free XRIs in public pool
484          * Pvt: Current number of free XRIs in private pool
485          * Busy: Current number of outstanding XRIs
486          * HWM: Current high watermark
487          * pvt_empty: Incremented by 1 when IO submission fails (no xri)
488          * pbl_empty: Incremented by 1 when all pbl_pool are empty during
489          *            IO submission
490          */
491         scnprintf(tmp, sizeof(tmp),
492                   "HWQ:  Pbl  Pvt Busy  HWM |  pvt_empty  pbl_empty ");
493         if (strlcat(buf, tmp, size) >= size)
494                 return strnlen(buf, size);
495
496 #ifdef LPFC_MXP_STAT
497         /*
498          * MAXH: Max high watermark seen so far
499          * above_lmt: Incremented by 1 if xri_owned > xri_limit during
500          *            IO submission
501          * below_lmt: Incremented by 1 if xri_owned <= xri_limit  during
502          *            IO submission
503          * locPbl_hit: Incremented by 1 if successfully get a batch of XRI from
504          *             local pbl_pool
505          * othPbl_hit: Incremented by 1 if successfully get a batch of XRI from
506          *             other pbl_pool
507          */
508         scnprintf(tmp, sizeof(tmp),
509                   "MAXH  above_lmt  below_lmt locPbl_hit othPbl_hit");
510         if (strlcat(buf, tmp, size) >= size)
511                 return strnlen(buf, size);
512
513         /*
514          * sPbl: snapshot of Pbl 15 sec after stat gets cleared
515          * sPvt: snapshot of Pvt 15 sec after stat gets cleared
516          * sBusy: snapshot of Busy 15 sec after stat gets cleared
517          */
518         scnprintf(tmp, sizeof(tmp),
519                   " | sPbl sPvt sBusy");
520         if (strlcat(buf, tmp, size) >= size)
521                 return strnlen(buf, size);
522 #endif
523
524         scnprintf(tmp, sizeof(tmp), "\n");
525         if (strlcat(buf, tmp, size) >= size)
526                 return strnlen(buf, size);
527
528         hwq_count = phba->cfg_hdw_queue;
529         for (i = 0; i < hwq_count; i++) {
530                 qp = &phba->sli4_hba.hdwq[i];
531                 multixri_pool = qp->p_multixri_pool;
532                 if (!multixri_pool)
533                         continue;
534                 pbl_pool = &multixri_pool->pbl_pool;
535                 pvt_pool = &multixri_pool->pvt_pool;
536                 txcmplq_cnt = qp->fcp_wq->pring->txcmplq_cnt;
537                 if (qp->nvme_wq)
538                         txcmplq_cnt += qp->nvme_wq->pring->txcmplq_cnt;
539
540                 scnprintf(tmp, sizeof(tmp),
541                           "%03d: %4d %4d %4d %4d | %10d %10d ",
542                           i, pbl_pool->count, pvt_pool->count,
543                           txcmplq_cnt, pvt_pool->high_watermark,
544                           qp->empty_io_bufs, multixri_pool->pbl_empty_count);
545                 if (strlcat(buf, tmp, size) >= size)
546                         break;
547
548 #ifdef LPFC_MXP_STAT
549                 scnprintf(tmp, sizeof(tmp),
550                           "%4d %10d %10d %10d %10d",
551                           multixri_pool->stat_max_hwm,
552                           multixri_pool->above_limit_count,
553                           multixri_pool->below_limit_count,
554                           multixri_pool->local_pbl_hit_count,
555                           multixri_pool->other_pbl_hit_count);
556                 if (strlcat(buf, tmp, size) >= size)
557                         break;
558
559                 scnprintf(tmp, sizeof(tmp),
560                           " | %4d %4d %5d",
561                           multixri_pool->stat_pbl_count,
562                           multixri_pool->stat_pvt_count,
563                           multixri_pool->stat_busy_count);
564                 if (strlcat(buf, tmp, size) >= size)
565                         break;
566 #endif
567
568                 scnprintf(tmp, sizeof(tmp), "\n");
569                 if (strlcat(buf, tmp, size) >= size)
570                         break;
571         }
572         return strnlen(buf, size);
573 }
574
575
576 #ifdef LPFC_HDWQ_LOCK_STAT
577 static int lpfc_debugfs_last_lock;
578
579 /**
580  * lpfc_debugfs_lockstat_data - Dump Hardware Queue info to a buffer
581  * @phba: The HBA to gather host buffer info from.
582  * @buf: The buffer to dump log into.
583  * @size: The maximum amount of data to process.
584  *
585  * Description:
586  * This routine dumps the Hardware Queue info from the @phba to @buf up to
587  * @size number of bytes. A header that describes the current hdwq state will be
588  * dumped to @buf first and then info on each hdwq entry will be dumped to @buf
589  * until @size bytes have been dumped or all the hdwq info has been dumped.
590  *
591  * Notes:
592  * This routine will rotate through each configured Hardware Queue each
593  * time called.
594  *
595  * Return Value:
596  * This routine returns the amount of bytes that were dumped into @buf and will
597  * not exceed @size.
598  **/
599 static int
600 lpfc_debugfs_lockstat_data(struct lpfc_hba *phba, char *buf, int size)
601 {
602         struct lpfc_sli4_hdw_queue *qp;
603         int len = 0;
604         int i;
605
606         if (phba->sli_rev != LPFC_SLI_REV4)
607                 return 0;
608
609         if (!phba->sli4_hba.hdwq)
610                 return 0;
611
612         for (i = 0; i < phba->cfg_hdw_queue; i++) {
613                 if (len > (LPFC_HDWQINFO_SIZE - 100))
614                         break;
615                 qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_lock];
616
617                 len += scnprintf(buf + len, size - len, "HdwQ %03d Lock ", i);
618                 if (phba->cfg_xri_rebalancing) {
619                         len += scnprintf(buf + len, size - len,
620                                          "get_pvt:%d mv_pvt:%d "
621                                          "mv2pub:%d mv2pvt:%d "
622                                          "put_pvt:%d put_pub:%d wq:%d\n",
623                                          qp->lock_conflict.alloc_pvt_pool,
624                                          qp->lock_conflict.mv_from_pvt_pool,
625                                          qp->lock_conflict.mv_to_pub_pool,
626                                          qp->lock_conflict.mv_to_pvt_pool,
627                                          qp->lock_conflict.free_pvt_pool,
628                                          qp->lock_conflict.free_pub_pool,
629                                          qp->lock_conflict.wq_access);
630                 } else {
631                         len += scnprintf(buf + len, size - len,
632                                          "get:%d put:%d free:%d wq:%d\n",
633                                          qp->lock_conflict.alloc_xri_get,
634                                          qp->lock_conflict.alloc_xri_put,
635                                          qp->lock_conflict.free_xri,
636                                          qp->lock_conflict.wq_access);
637                 }
638
639                 lpfc_debugfs_last_lock++;
640                 if (lpfc_debugfs_last_lock >= phba->cfg_hdw_queue)
641                         lpfc_debugfs_last_lock = 0;
642         }
643
644         return len;
645 }
646 #endif
647
648 static int lpfc_debugfs_last_hba_slim_off;
649
650 /**
651  * lpfc_debugfs_dumpHBASlim_data - Dump HBA SLIM info to a buffer
652  * @phba: The HBA to gather SLIM info from.
653  * @buf: The buffer to dump log into.
654  * @size: The maximum amount of data to process.
655  *
656  * Description:
657  * This routine dumps the current contents of HBA SLIM for the HBA associated
658  * with @phba to @buf up to @size bytes of data. This is the raw HBA SLIM data.
659  *
660  * Notes:
661  * This routine will only dump up to 1024 bytes of data each time called and
662  * should be called multiple times to dump the entire HBA SLIM.
663  *
664  * Return Value:
665  * This routine returns the amount of bytes that were dumped into @buf and will
666  * not exceed @size.
667  **/
668 static int
669 lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
670 {
671         int len = 0;
672         int i, off;
673         uint32_t *ptr;
674         char *buffer;
675
676         buffer = kmalloc(1024, GFP_KERNEL);
677         if (!buffer)
678                 return 0;
679
680         off = 0;
681         spin_lock_irq(&phba->hbalock);
682
683         len +=  scnprintf(buf+len, size-len, "HBA SLIM\n");
684         lpfc_memcpy_from_slim(buffer,
685                 phba->MBslimaddr + lpfc_debugfs_last_hba_slim_off, 1024);
686
687         ptr = (uint32_t *)&buffer[0];
688         off = lpfc_debugfs_last_hba_slim_off;
689
690         /* Set it up for the next time */
691         lpfc_debugfs_last_hba_slim_off += 1024;
692         if (lpfc_debugfs_last_hba_slim_off >= 4096)
693                 lpfc_debugfs_last_hba_slim_off = 0;
694
695         i = 1024;
696         while (i > 0) {
697                 len +=  scnprintf(buf+len, size-len,
698                 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
699                 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
700                 *(ptr+5), *(ptr+6), *(ptr+7));
701                 ptr += 8;
702                 i -= (8 * sizeof(uint32_t));
703                 off += (8 * sizeof(uint32_t));
704         }
705
706         spin_unlock_irq(&phba->hbalock);
707         kfree(buffer);
708
709         return len;
710 }
711
712 /**
713  * lpfc_debugfs_dumpHostSlim_data - Dump host SLIM info to a buffer
714  * @phba: The HBA to gather Host SLIM info from.
715  * @buf: The buffer to dump log into.
716  * @size: The maximum amount of data to process.
717  *
718  * Description:
719  * This routine dumps the current contents of host SLIM for the host associated
720  * with @phba to @buf up to @size bytes of data. The dump will contain the
721  * Mailbox, PCB, Rings, and Registers that are located in host memory.
722  *
723  * Return Value:
724  * This routine returns the amount of bytes that were dumped into @buf and will
725  * not exceed @size.
726  **/
727 static int
728 lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
729 {
730         int len = 0;
731         int i, off;
732         uint32_t word0, word1, word2, word3;
733         uint32_t *ptr;
734         struct lpfc_pgp *pgpp;
735         struct lpfc_sli *psli = &phba->sli;
736         struct lpfc_sli_ring *pring;
737
738         off = 0;
739         spin_lock_irq(&phba->hbalock);
740
741         len +=  scnprintf(buf+len, size-len, "SLIM Mailbox\n");
742         ptr = (uint32_t *)phba->slim2p.virt;
743         i = sizeof(MAILBOX_t);
744         while (i > 0) {
745                 len +=  scnprintf(buf+len, size-len,
746                 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
747                 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
748                 *(ptr+5), *(ptr+6), *(ptr+7));
749                 ptr += 8;
750                 i -= (8 * sizeof(uint32_t));
751                 off += (8 * sizeof(uint32_t));
752         }
753
754         len +=  scnprintf(buf+len, size-len, "SLIM PCB\n");
755         ptr = (uint32_t *)phba->pcb;
756         i = sizeof(PCB_t);
757         while (i > 0) {
758                 len +=  scnprintf(buf+len, size-len,
759                 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
760                 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
761                 *(ptr+5), *(ptr+6), *(ptr+7));
762                 ptr += 8;
763                 i -= (8 * sizeof(uint32_t));
764                 off += (8 * sizeof(uint32_t));
765         }
766
767         if (phba->sli_rev <= LPFC_SLI_REV3) {
768                 for (i = 0; i < 4; i++) {
769                         pgpp = &phba->port_gp[i];
770                         pring = &psli->sli3_ring[i];
771                         len +=  scnprintf(buf+len, size-len,
772                                          "Ring %d: CMD GetInx:%d "
773                                          "(Max:%d Next:%d "
774                                          "Local:%d flg:x%x)  "
775                                          "RSP PutInx:%d Max:%d\n",
776                                          i, pgpp->cmdGetInx,
777                                          pring->sli.sli3.numCiocb,
778                                          pring->sli.sli3.next_cmdidx,
779                                          pring->sli.sli3.local_getidx,
780                                          pring->flag, pgpp->rspPutInx,
781                                          pring->sli.sli3.numRiocb);
782                 }
783
784                 word0 = readl(phba->HAregaddr);
785                 word1 = readl(phba->CAregaddr);
786                 word2 = readl(phba->HSregaddr);
787                 word3 = readl(phba->HCregaddr);
788                 len +=  scnprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x "
789                                  "HC:%08x\n", word0, word1, word2, word3);
790         }
791         spin_unlock_irq(&phba->hbalock);
792         return len;
793 }
794
795 /**
796  * lpfc_debugfs_nodelist_data - Dump target node list to a buffer
797  * @vport: The vport to gather target node info from.
798  * @buf: The buffer to dump log into.
799  * @size: The maximum amount of data to process.
800  *
801  * Description:
802  * This routine dumps the current target node list associated with @vport to
803  * @buf up to @size bytes of data. Each node entry in the dump will contain a
804  * node state, DID, WWPN, WWNN, RPI, flags, type, and other useful fields.
805  *
806  * Return Value:
807  * This routine returns the amount of bytes that were dumped into @buf and will
808  * not exceed @size.
809  **/
810 static int
811 lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
812 {
813         int len = 0;
814         int i, iocnt, outio, cnt;
815         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
816         struct lpfc_hba  *phba = vport->phba;
817         struct lpfc_nodelist *ndlp;
818         unsigned char *statep;
819         struct nvme_fc_local_port *localport;
820         struct nvme_fc_remote_port *nrport = NULL;
821         struct lpfc_nvme_rport *rport;
822
823         cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
824         outio = 0;
825
826         len += scnprintf(buf+len, size-len, "\nFCP Nodelist Entries ...\n");
827         spin_lock_irq(shost->host_lock);
828         list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
829                 iocnt = 0;
830                 if (!cnt) {
831                         len +=  scnprintf(buf+len, size-len,
832                                 "Missing Nodelist Entries\n");
833                         break;
834                 }
835                 cnt--;
836                 switch (ndlp->nlp_state) {
837                 case NLP_STE_UNUSED_NODE:
838                         statep = "UNUSED";
839                         break;
840                 case NLP_STE_PLOGI_ISSUE:
841                         statep = "PLOGI ";
842                         break;
843                 case NLP_STE_ADISC_ISSUE:
844                         statep = "ADISC ";
845                         break;
846                 case NLP_STE_REG_LOGIN_ISSUE:
847                         statep = "REGLOG";
848                         break;
849                 case NLP_STE_PRLI_ISSUE:
850                         statep = "PRLI  ";
851                         break;
852                 case NLP_STE_LOGO_ISSUE:
853                         statep = "LOGO  ";
854                         break;
855                 case NLP_STE_UNMAPPED_NODE:
856                         statep = "UNMAP ";
857                         iocnt = 1;
858                         break;
859                 case NLP_STE_MAPPED_NODE:
860                         statep = "MAPPED";
861                         iocnt = 1;
862                         break;
863                 case NLP_STE_NPR_NODE:
864                         statep = "NPR   ";
865                         break;
866                 default:
867                         statep = "UNKNOWN";
868                 }
869                 len += scnprintf(buf+len, size-len, "%s DID:x%06x ",
870                                 statep, ndlp->nlp_DID);
871                 len += scnprintf(buf+len, size-len,
872                                 "WWPN x%llx ",
873                                 wwn_to_u64(ndlp->nlp_portname.u.wwn));
874                 len += scnprintf(buf+len, size-len,
875                                 "WWNN x%llx ",
876                                 wwn_to_u64(ndlp->nlp_nodename.u.wwn));
877                 if (ndlp->nlp_flag & NLP_RPI_REGISTERED)
878                         len += scnprintf(buf+len, size-len, "RPI:%03d ",
879                                         ndlp->nlp_rpi);
880                 else
881                         len += scnprintf(buf+len, size-len, "RPI:none ");
882                 len +=  scnprintf(buf+len, size-len, "flag:x%08x ",
883                         ndlp->nlp_flag);
884                 if (!ndlp->nlp_type)
885                         len += scnprintf(buf+len, size-len, "UNKNOWN_TYPE ");
886                 if (ndlp->nlp_type & NLP_FC_NODE)
887                         len += scnprintf(buf+len, size-len, "FC_NODE ");
888                 if (ndlp->nlp_type & NLP_FABRIC) {
889                         len += scnprintf(buf+len, size-len, "FABRIC ");
890                         iocnt = 0;
891                 }
892                 if (ndlp->nlp_type & NLP_FCP_TARGET)
893                         len += scnprintf(buf+len, size-len, "FCP_TGT sid:%d ",
894                                 ndlp->nlp_sid);
895                 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
896                         len += scnprintf(buf+len, size-len, "FCP_INITIATOR ");
897                 if (ndlp->nlp_type & NLP_NVME_TARGET)
898                         len += scnprintf(buf + len,
899                                         size - len, "NVME_TGT sid:%d ",
900                                         NLP_NO_SID);
901                 if (ndlp->nlp_type & NLP_NVME_INITIATOR)
902                         len += scnprintf(buf + len,
903                                         size - len, "NVME_INITIATOR ");
904                 len += scnprintf(buf+len, size-len, "usgmap:%x ",
905                         ndlp->nlp_usg_map);
906                 len += scnprintf(buf+len, size-len, "refcnt:%x",
907                         kref_read(&ndlp->kref));
908                 if (iocnt) {
909                         i = atomic_read(&ndlp->cmd_pending);
910                         len += scnprintf(buf + len, size - len,
911                                         " OutIO:x%x Qdepth x%x",
912                                         i, ndlp->cmd_qdepth);
913                         outio += i;
914                 }
915                 len += scnprintf(buf + len, size - len, "defer:%x ",
916                         ndlp->nlp_defer_did);
917                 len +=  scnprintf(buf+len, size-len, "\n");
918         }
919         spin_unlock_irq(shost->host_lock);
920
921         len += scnprintf(buf + len, size - len,
922                         "\nOutstanding IO x%x\n",  outio);
923
924         if (phba->nvmet_support && phba->targetport && (vport == phba->pport)) {
925                 len += scnprintf(buf + len, size - len,
926                                 "\nNVME Targetport Entry ...\n");
927
928                 /* Port state is only one of two values for now. */
929                 if (phba->targetport->port_id)
930                         statep = "REGISTERED";
931                 else
932                         statep = "INIT";
933                 len += scnprintf(buf + len, size - len,
934                                 "TGT WWNN x%llx WWPN x%llx State %s\n",
935                                 wwn_to_u64(vport->fc_nodename.u.wwn),
936                                 wwn_to_u64(vport->fc_portname.u.wwn),
937                                 statep);
938                 len += scnprintf(buf + len, size - len,
939                                 "    Targetport DID x%06x\n",
940                                 phba->targetport->port_id);
941                 goto out_exit;
942         }
943
944         len += scnprintf(buf + len, size - len,
945                                 "\nNVME Lport/Rport Entries ...\n");
946
947         localport = vport->localport;
948         if (!localport)
949                 goto out_exit;
950
951         spin_lock_irq(shost->host_lock);
952
953         /* Port state is only one of two values for now. */
954         if (localport->port_id)
955                 statep = "ONLINE";
956         else
957                 statep = "UNKNOWN ";
958
959         len += scnprintf(buf + len, size - len,
960                         "Lport DID x%06x PortState %s\n",
961                         localport->port_id, statep);
962
963         len += scnprintf(buf + len, size - len, "\tRport List:\n");
964         list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
965                 /* local short-hand pointer. */
966                 spin_lock(&phba->hbalock);
967                 rport = lpfc_ndlp_get_nrport(ndlp);
968                 if (rport)
969                         nrport = rport->remoteport;
970                 else
971                         nrport = NULL;
972                 spin_unlock(&phba->hbalock);
973                 if (!nrport)
974                         continue;
975
976                 /* Port state is only one of two values for now. */
977                 switch (nrport->port_state) {
978                 case FC_OBJSTATE_ONLINE:
979                         statep = "ONLINE";
980                         break;
981                 case FC_OBJSTATE_UNKNOWN:
982                         statep = "UNKNOWN ";
983                         break;
984                 default:
985                         statep = "UNSUPPORTED";
986                         break;
987                 }
988
989                 /* Tab in to show lport ownership. */
990                 len += scnprintf(buf + len, size - len,
991                                 "\t%s Port ID:x%06x ",
992                                 statep, nrport->port_id);
993                 len += scnprintf(buf + len, size - len, "WWPN x%llx ",
994                                 nrport->port_name);
995                 len += scnprintf(buf + len, size - len, "WWNN x%llx ",
996                                 nrport->node_name);
997
998                 /* An NVME rport can have multiple roles. */
999                 if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR)
1000                         len +=  scnprintf(buf + len, size - len,
1001                                          "INITIATOR ");
1002                 if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET)
1003                         len +=  scnprintf(buf + len, size - len,
1004                                          "TARGET ");
1005                 if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY)
1006                         len +=  scnprintf(buf + len, size - len,
1007                                          "DISCSRVC ");
1008                 if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
1009                                           FC_PORT_ROLE_NVME_TARGET |
1010                                           FC_PORT_ROLE_NVME_DISCOVERY))
1011                         len +=  scnprintf(buf + len, size - len,
1012                                          "UNKNOWN ROLE x%x",
1013                                          nrport->port_role);
1014                 /* Terminate the string. */
1015                 len +=  scnprintf(buf + len, size - len, "\n");
1016         }
1017
1018         spin_unlock_irq(shost->host_lock);
1019  out_exit:
1020         return len;
1021 }
1022
1023 /**
1024  * lpfc_debugfs_nvmestat_data - Dump target node list to a buffer
1025  * @vport: The vport to gather target node info from.
1026  * @buf: The buffer to dump log into.
1027  * @size: The maximum amount of data to process.
1028  *
1029  * Description:
1030  * This routine dumps the NVME statistics associated with @vport
1031  *
1032  * Return Value:
1033  * This routine returns the amount of bytes that were dumped into @buf and will
1034  * not exceed @size.
1035  **/
1036 static int
1037 lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size)
1038 {
1039         struct lpfc_hba   *phba = vport->phba;
1040         struct lpfc_nvmet_tgtport *tgtp;
1041         struct lpfc_nvmet_rcv_ctx *ctxp, *next_ctxp;
1042         struct nvme_fc_local_port *localport;
1043         struct lpfc_fc4_ctrl_stat *cstat;
1044         struct lpfc_nvme_lport *lport;
1045         uint64_t data1, data2, data3;
1046         uint64_t tot, totin, totout;
1047         int cnt, i;
1048         int len = 0;
1049
1050         if (phba->nvmet_support) {
1051                 if (!phba->targetport)
1052                         return len;
1053                 tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
1054                 len += scnprintf(buf + len, size - len,
1055                                 "\nNVME Targetport Statistics\n");
1056
1057                 len += scnprintf(buf + len, size - len,
1058                                 "LS: Rcv %08x Drop %08x Abort %08x\n",
1059                                 atomic_read(&tgtp->rcv_ls_req_in),
1060                                 atomic_read(&tgtp->rcv_ls_req_drop),
1061                                 atomic_read(&tgtp->xmt_ls_abort));
1062                 if (atomic_read(&tgtp->rcv_ls_req_in) !=
1063                     atomic_read(&tgtp->rcv_ls_req_out)) {
1064                         len += scnprintf(buf + len, size - len,
1065                                         "Rcv LS: in %08x != out %08x\n",
1066                                         atomic_read(&tgtp->rcv_ls_req_in),
1067                                         atomic_read(&tgtp->rcv_ls_req_out));
1068                 }
1069
1070                 len += scnprintf(buf + len, size - len,
1071                                 "LS: Xmt %08x Drop %08x Cmpl %08x\n",
1072                                 atomic_read(&tgtp->xmt_ls_rsp),
1073                                 atomic_read(&tgtp->xmt_ls_drop),
1074                                 atomic_read(&tgtp->xmt_ls_rsp_cmpl));
1075
1076                 len += scnprintf(buf + len, size - len,
1077                                 "LS: RSP Abort %08x xb %08x Err %08x\n",
1078                                 atomic_read(&tgtp->xmt_ls_rsp_aborted),
1079                                 atomic_read(&tgtp->xmt_ls_rsp_xb_set),
1080                                 atomic_read(&tgtp->xmt_ls_rsp_error));
1081
1082                 len += scnprintf(buf + len, size - len,
1083                                 "FCP: Rcv %08x Defer %08x Release %08x "
1084                                 "Drop %08x\n",
1085                                 atomic_read(&tgtp->rcv_fcp_cmd_in),
1086                                 atomic_read(&tgtp->rcv_fcp_cmd_defer),
1087                                 atomic_read(&tgtp->xmt_fcp_release),
1088                                 atomic_read(&tgtp->rcv_fcp_cmd_drop));
1089
1090                 if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
1091                     atomic_read(&tgtp->rcv_fcp_cmd_out)) {
1092                         len += scnprintf(buf + len, size - len,
1093                                         "Rcv FCP: in %08x != out %08x\n",
1094                                         atomic_read(&tgtp->rcv_fcp_cmd_in),
1095                                         atomic_read(&tgtp->rcv_fcp_cmd_out));
1096                 }
1097
1098                 len += scnprintf(buf + len, size - len,
1099                                 "FCP Rsp: read %08x readrsp %08x "
1100                                 "write %08x rsp %08x\n",
1101                                 atomic_read(&tgtp->xmt_fcp_read),
1102                                 atomic_read(&tgtp->xmt_fcp_read_rsp),
1103                                 atomic_read(&tgtp->xmt_fcp_write),
1104                                 atomic_read(&tgtp->xmt_fcp_rsp));
1105
1106                 len += scnprintf(buf + len, size - len,
1107                                 "FCP Rsp Cmpl: %08x err %08x drop %08x\n",
1108                                 atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
1109                                 atomic_read(&tgtp->xmt_fcp_rsp_error),
1110                                 atomic_read(&tgtp->xmt_fcp_rsp_drop));
1111
1112                 len += scnprintf(buf + len, size - len,
1113                                 "FCP Rsp Abort: %08x xb %08x xricqe  %08x\n",
1114                                 atomic_read(&tgtp->xmt_fcp_rsp_aborted),
1115                                 atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
1116                                 atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
1117
1118                 len += scnprintf(buf + len, size - len,
1119                                 "ABORT: Xmt %08x Cmpl %08x\n",
1120                                 atomic_read(&tgtp->xmt_fcp_abort),
1121                                 atomic_read(&tgtp->xmt_fcp_abort_cmpl));
1122
1123                 len += scnprintf(buf + len, size - len,
1124                                 "ABORT: Sol %08x  Usol %08x Err %08x Cmpl %08x",
1125                                 atomic_read(&tgtp->xmt_abort_sol),
1126                                 atomic_read(&tgtp->xmt_abort_unsol),
1127                                 atomic_read(&tgtp->xmt_abort_rsp),
1128                                 atomic_read(&tgtp->xmt_abort_rsp_error));
1129
1130                 len +=  scnprintf(buf + len, size - len, "\n");
1131
1132                 cnt = 0;
1133                 spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1134                 list_for_each_entry_safe(ctxp, next_ctxp,
1135                                 &phba->sli4_hba.lpfc_abts_nvmet_ctx_list,
1136                                 list) {
1137                         cnt++;
1138                 }
1139                 spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1140                 if (cnt) {
1141                         len += scnprintf(buf + len, size - len,
1142                                         "ABORT: %d ctx entries\n", cnt);
1143                         spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1144                         list_for_each_entry_safe(ctxp, next_ctxp,
1145                                     &phba->sli4_hba.lpfc_abts_nvmet_ctx_list,
1146                                     list) {
1147                                 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ))
1148                                         break;
1149                                 len += scnprintf(buf + len, size - len,
1150                                                 "Entry: oxid %x state %x "
1151                                                 "flag %x\n",
1152                                                 ctxp->oxid, ctxp->state,
1153                                                 ctxp->flag);
1154                         }
1155                         spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1156                 }
1157
1158                 /* Calculate outstanding IOs */
1159                 tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
1160                 tot += atomic_read(&tgtp->xmt_fcp_release);
1161                 tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot;
1162
1163                 len += scnprintf(buf + len, size - len,
1164                                 "IO_CTX: %08x  WAIT: cur %08x tot %08x\n"
1165                                 "CTX Outstanding %08llx\n",
1166                                 phba->sli4_hba.nvmet_xri_cnt,
1167                                 phba->sli4_hba.nvmet_io_wait_cnt,
1168                                 phba->sli4_hba.nvmet_io_wait_total,
1169                                 tot);
1170         } else {
1171                 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME))
1172                         return len;
1173
1174                 localport = vport->localport;
1175                 if (!localport)
1176                         return len;
1177                 lport = (struct lpfc_nvme_lport *)localport->private;
1178                 if (!lport)
1179                         return len;
1180
1181                 len += scnprintf(buf + len, size - len,
1182                                 "\nNVME HDWQ Statistics\n");
1183
1184                 len += scnprintf(buf + len, size - len,
1185                                 "LS: Xmt %016x Cmpl %016x\n",
1186                                 atomic_read(&lport->fc4NvmeLsRequests),
1187                                 atomic_read(&lport->fc4NvmeLsCmpls));
1188
1189                 totin = 0;
1190                 totout = 0;
1191                 for (i = 0; i < phba->cfg_hdw_queue; i++) {
1192                         cstat = &phba->sli4_hba.hdwq[i].nvme_cstat;
1193                         tot = cstat->io_cmpls;
1194                         totin += tot;
1195                         data1 = cstat->input_requests;
1196                         data2 = cstat->output_requests;
1197                         data3 = cstat->control_requests;
1198                         totout += (data1 + data2 + data3);
1199
1200                         /* Limit to 32, debugfs display buffer limitation */
1201                         if (i >= 32)
1202                                 continue;
1203
1204                         len += scnprintf(buf + len, PAGE_SIZE - len,
1205                                         "HDWQ (%d): Rd %016llx Wr %016llx "
1206                                         "IO %016llx ",
1207                                         i, data1, data2, data3);
1208                         len += scnprintf(buf + len, PAGE_SIZE - len,
1209                                         "Cmpl %016llx OutIO %016llx\n",
1210                                         tot, ((data1 + data2 + data3) - tot));
1211                 }
1212                 len += scnprintf(buf + len, PAGE_SIZE - len,
1213                                 "Total FCP Cmpl %016llx Issue %016llx "
1214                                 "OutIO %016llx\n",
1215                                 totin, totout, totout - totin);
1216
1217                 len += scnprintf(buf + len, size - len,
1218                                 "LS Xmt Err: Abrt %08x Err %08x  "
1219                                 "Cmpl Err: xb %08x Err %08x\n",
1220                                 atomic_read(&lport->xmt_ls_abort),
1221                                 atomic_read(&lport->xmt_ls_err),
1222                                 atomic_read(&lport->cmpl_ls_xb),
1223                                 atomic_read(&lport->cmpl_ls_err));
1224
1225                 len += scnprintf(buf + len, size - len,
1226                                 "FCP Xmt Err: noxri %06x nondlp %06x "
1227                                 "qdepth %06x wqerr %06x err %06x Abrt %06x\n",
1228                                 atomic_read(&lport->xmt_fcp_noxri),
1229                                 atomic_read(&lport->xmt_fcp_bad_ndlp),
1230                                 atomic_read(&lport->xmt_fcp_qdepth),
1231                                 atomic_read(&lport->xmt_fcp_wqerr),
1232                                 atomic_read(&lport->xmt_fcp_err),
1233                                 atomic_read(&lport->xmt_fcp_abort));
1234
1235                 len += scnprintf(buf + len, size - len,
1236                                 "FCP Cmpl Err: xb %08x Err %08x\n",
1237                                 atomic_read(&lport->cmpl_fcp_xb),
1238                                 atomic_read(&lport->cmpl_fcp_err));
1239
1240         }
1241
1242         return len;
1243 }
1244
1245 /**
1246  * lpfc_debugfs_scsistat_data - Dump target node list to a buffer
1247  * @vport: The vport to gather target node info from.
1248  * @buf: The buffer to dump log into.
1249  * @size: The maximum amount of data to process.
1250  *
1251  * Description:
1252  * This routine dumps the SCSI statistics associated with @vport
1253  *
1254  * Return Value:
1255  * This routine returns the amount of bytes that were dumped into @buf and will
1256  * not exceed @size.
1257  **/
1258 static int
1259 lpfc_debugfs_scsistat_data(struct lpfc_vport *vport, char *buf, int size)
1260 {
1261         int len;
1262         struct lpfc_hba *phba = vport->phba;
1263         struct lpfc_fc4_ctrl_stat *cstat;
1264         u64 data1, data2, data3;
1265         u64 tot, totin, totout;
1266         int i;
1267         char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
1268
1269         if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
1270             (phba->sli_rev != LPFC_SLI_REV4))
1271                 return 0;
1272
1273         scnprintf(buf, size, "SCSI HDWQ Statistics\n");
1274
1275         totin = 0;
1276         totout = 0;
1277         for (i = 0; i < phba->cfg_hdw_queue; i++) {
1278                 cstat = &phba->sli4_hba.hdwq[i].scsi_cstat;
1279                 tot = cstat->io_cmpls;
1280                 totin += tot;
1281                 data1 = cstat->input_requests;
1282                 data2 = cstat->output_requests;
1283                 data3 = cstat->control_requests;
1284                 totout += (data1 + data2 + data3);
1285
1286                 scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx "
1287                           "IO %016llx ", i, data1, data2, data3);
1288                 if (strlcat(buf, tmp, size) >= size)
1289                         goto buffer_done;
1290
1291                 scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n",
1292                           tot, ((data1 + data2 + data3) - tot));
1293                 if (strlcat(buf, tmp, size) >= size)
1294                         goto buffer_done;
1295         }
1296         scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx "
1297                   "OutIO %016llx\n", totin, totout, totout - totin);
1298         strlcat(buf, tmp, size);
1299
1300 buffer_done:
1301         len = strnlen(buf, size);
1302
1303         return len;
1304 }
1305
1306 /**
1307  * lpfc_debugfs_nvmektime_data - Dump target node list to a buffer
1308  * @vport: The vport to gather target node info from.
1309  * @buf: The buffer to dump log into.
1310  * @size: The maximum amount of data to process.
1311  *
1312  * Description:
1313  * This routine dumps the NVME statistics associated with @vport
1314  *
1315  * Return Value:
1316  * This routine returns the amount of bytes that were dumped into @buf and will
1317  * not exceed @size.
1318  **/
1319 static int
1320 lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size)
1321 {
1322         struct lpfc_hba   *phba = vport->phba;
1323         int len = 0;
1324
1325         if (phba->nvmet_support == 0) {
1326                 /* NVME Initiator */
1327                 len += scnprintf(buf + len, PAGE_SIZE - len,
1328                                 "ktime %s: Total Samples: %lld\n",
1329                                 (phba->ktime_on ?  "Enabled" : "Disabled"),
1330                                 phba->ktime_data_samples);
1331                 if (phba->ktime_data_samples == 0)
1332                         return len;
1333
1334                 len += scnprintf(
1335                         buf + len, PAGE_SIZE - len,
1336                         "Segment 1: Last NVME Cmd cmpl "
1337                         "done -to- Start of next NVME cnd (in driver)\n");
1338                 len += scnprintf(
1339                         buf + len, PAGE_SIZE - len,
1340                         "avg:%08lld min:%08lld max %08lld\n",
1341                         div_u64(phba->ktime_seg1_total,
1342                                 phba->ktime_data_samples),
1343                         phba->ktime_seg1_min,
1344                         phba->ktime_seg1_max);
1345                 len += scnprintf(
1346                         buf + len, PAGE_SIZE - len,
1347                         "Segment 2: Driver start of NVME cmd "
1348                         "-to- Firmware WQ doorbell\n");
1349                 len += scnprintf(
1350                         buf + len, PAGE_SIZE - len,
1351                         "avg:%08lld min:%08lld max %08lld\n",
1352                         div_u64(phba->ktime_seg2_total,
1353                                 phba->ktime_data_samples),
1354                         phba->ktime_seg2_min,
1355                         phba->ktime_seg2_max);
1356                 len += scnprintf(
1357                         buf + len, PAGE_SIZE - len,
1358                         "Segment 3: Firmware WQ doorbell -to- "
1359                         "MSI-X ISR cmpl\n");
1360                 len += scnprintf(
1361                         buf + len, PAGE_SIZE - len,
1362                         "avg:%08lld min:%08lld max %08lld\n",
1363                         div_u64(phba->ktime_seg3_total,
1364                                 phba->ktime_data_samples),
1365                         phba->ktime_seg3_min,
1366                         phba->ktime_seg3_max);
1367                 len += scnprintf(
1368                         buf + len, PAGE_SIZE - len,
1369                         "Segment 4: MSI-X ISR cmpl -to- "
1370                         "NVME cmpl done\n");
1371                 len += scnprintf(
1372                         buf + len, PAGE_SIZE - len,
1373                         "avg:%08lld min:%08lld max %08lld\n",
1374                         div_u64(phba->ktime_seg4_total,
1375                                 phba->ktime_data_samples),
1376                         phba->ktime_seg4_min,
1377                         phba->ktime_seg4_max);
1378                 len += scnprintf(
1379                         buf + len, PAGE_SIZE - len,
1380                         "Total IO avg time: %08lld\n",
1381                         div_u64(phba->ktime_seg1_total +
1382                         phba->ktime_seg2_total  +
1383                         phba->ktime_seg3_total +
1384                         phba->ktime_seg4_total,
1385                         phba->ktime_data_samples));
1386                 return len;
1387         }
1388
1389         /* NVME Target */
1390         len += scnprintf(buf + len, PAGE_SIZE-len,
1391                         "ktime %s: Total Samples: %lld %lld\n",
1392                         (phba->ktime_on ? "Enabled" : "Disabled"),
1393                         phba->ktime_data_samples,
1394                         phba->ktime_status_samples);
1395         if (phba->ktime_data_samples == 0)
1396                 return len;
1397
1398         len += scnprintf(buf + len, PAGE_SIZE-len,
1399                         "Segment 1: MSI-X ISR Rcv cmd -to- "
1400                         "cmd pass to NVME Layer\n");
1401         len += scnprintf(buf + len, PAGE_SIZE-len,
1402                         "avg:%08lld min:%08lld max %08lld\n",
1403                         div_u64(phba->ktime_seg1_total,
1404                                 phba->ktime_data_samples),
1405                         phba->ktime_seg1_min,
1406                         phba->ktime_seg1_max);
1407         len += scnprintf(buf + len, PAGE_SIZE-len,
1408                         "Segment 2: cmd pass to NVME Layer- "
1409                         "-to- Driver rcv cmd OP (action)\n");
1410         len += scnprintf(buf + len, PAGE_SIZE-len,
1411                         "avg:%08lld min:%08lld max %08lld\n",
1412                         div_u64(phba->ktime_seg2_total,
1413                                 phba->ktime_data_samples),
1414                         phba->ktime_seg2_min,
1415                         phba->ktime_seg2_max);
1416         len += scnprintf(buf + len, PAGE_SIZE-len,
1417                         "Segment 3: Driver rcv cmd OP -to- "
1418                         "Firmware WQ doorbell: cmd\n");
1419         len += scnprintf(buf + len, PAGE_SIZE-len,
1420                         "avg:%08lld min:%08lld max %08lld\n",
1421                         div_u64(phba->ktime_seg3_total,
1422                                 phba->ktime_data_samples),
1423                         phba->ktime_seg3_min,
1424                         phba->ktime_seg3_max);
1425         len += scnprintf(buf + len, PAGE_SIZE-len,
1426                         "Segment 4: Firmware WQ doorbell: cmd "
1427                         "-to- MSI-X ISR for cmd cmpl\n");
1428         len += scnprintf(buf + len, PAGE_SIZE-len,
1429                         "avg:%08lld min:%08lld max %08lld\n",
1430                         div_u64(phba->ktime_seg4_total,
1431                                 phba->ktime_data_samples),
1432                         phba->ktime_seg4_min,
1433                         phba->ktime_seg4_max);
1434         len += scnprintf(buf + len, PAGE_SIZE-len,
1435                         "Segment 5: MSI-X ISR for cmd cmpl "
1436                         "-to- NVME layer passed cmd done\n");
1437         len += scnprintf(buf + len, PAGE_SIZE-len,
1438                         "avg:%08lld min:%08lld max %08lld\n",
1439                         div_u64(phba->ktime_seg5_total,
1440                                 phba->ktime_data_samples),
1441                         phba->ktime_seg5_min,
1442                         phba->ktime_seg5_max);
1443
1444         if (phba->ktime_status_samples == 0) {
1445                 len += scnprintf(buf + len, PAGE_SIZE-len,
1446                                 "Total: cmd received by MSI-X ISR "
1447                                 "-to- cmd completed on wire\n");
1448                 len += scnprintf(buf + len, PAGE_SIZE-len,
1449                                 "avg:%08lld min:%08lld "
1450                                 "max %08lld\n",
1451                                 div_u64(phba->ktime_seg10_total,
1452                                         phba->ktime_data_samples),
1453                                 phba->ktime_seg10_min,
1454                                 phba->ktime_seg10_max);
1455                 return len;
1456         }
1457
1458         len += scnprintf(buf + len, PAGE_SIZE-len,
1459                         "Segment 6: NVME layer passed cmd done "
1460                         "-to- Driver rcv rsp status OP\n");
1461         len += scnprintf(buf + len, PAGE_SIZE-len,
1462                         "avg:%08lld min:%08lld max %08lld\n",
1463                         div_u64(phba->ktime_seg6_total,
1464                                 phba->ktime_status_samples),
1465                         phba->ktime_seg6_min,
1466                         phba->ktime_seg6_max);
1467         len += scnprintf(buf + len, PAGE_SIZE-len,
1468                         "Segment 7: Driver rcv rsp status OP "
1469                         "-to- Firmware WQ doorbell: status\n");
1470         len += scnprintf(buf + len, PAGE_SIZE-len,
1471                         "avg:%08lld min:%08lld max %08lld\n",
1472                         div_u64(phba->ktime_seg7_total,
1473                                 phba->ktime_status_samples),
1474                         phba->ktime_seg7_min,
1475                         phba->ktime_seg7_max);
1476         len += scnprintf(buf + len, PAGE_SIZE-len,
1477                         "Segment 8: Firmware WQ doorbell: status"
1478                         " -to- MSI-X ISR for status cmpl\n");
1479         len += scnprintf(buf + len, PAGE_SIZE-len,
1480                         "avg:%08lld min:%08lld max %08lld\n",
1481                         div_u64(phba->ktime_seg8_total,
1482                                 phba->ktime_status_samples),
1483                         phba->ktime_seg8_min,
1484                         phba->ktime_seg8_max);
1485         len += scnprintf(buf + len, PAGE_SIZE-len,
1486                         "Segment 9: MSI-X ISR for status cmpl  "
1487                         "-to- NVME layer passed status done\n");
1488         len += scnprintf(buf + len, PAGE_SIZE-len,
1489                         "avg:%08lld min:%08lld max %08lld\n",
1490                         div_u64(phba->ktime_seg9_total,
1491                                 phba->ktime_status_samples),
1492                         phba->ktime_seg9_min,
1493                         phba->ktime_seg9_max);
1494         len += scnprintf(buf + len, PAGE_SIZE-len,
1495                         "Total: cmd received by MSI-X ISR -to- "
1496                         "cmd completed on wire\n");
1497         len += scnprintf(buf + len, PAGE_SIZE-len,
1498                         "avg:%08lld min:%08lld max %08lld\n",
1499                         div_u64(phba->ktime_seg10_total,
1500                                 phba->ktime_status_samples),
1501                         phba->ktime_seg10_min,
1502                         phba->ktime_seg10_max);
1503         return len;
1504 }
1505
1506 /**
1507  * lpfc_debugfs_nvmeio_trc_data - Dump NVME IO trace list to a buffer
1508  * @phba: The phba to gather target node info from.
1509  * @buf: The buffer to dump log into.
1510  * @size: The maximum amount of data to process.
1511  *
1512  * Description:
1513  * This routine dumps the NVME IO trace associated with @phba
1514  *
1515  * Return Value:
1516  * This routine returns the amount of bytes that were dumped into @buf and will
1517  * not exceed @size.
1518  **/
1519 static int
1520 lpfc_debugfs_nvmeio_trc_data(struct lpfc_hba *phba, char *buf, int size)
1521 {
1522         struct lpfc_debugfs_nvmeio_trc *dtp;
1523         int i, state, index, skip;
1524         int len = 0;
1525
1526         state = phba->nvmeio_trc_on;
1527
1528         index = (atomic_read(&phba->nvmeio_trc_cnt) + 1) &
1529                 (phba->nvmeio_trc_size - 1);
1530         skip = phba->nvmeio_trc_output_idx;
1531
1532         len += scnprintf(buf + len, size - len,
1533                         "%s IO Trace %s: next_idx %d skip %d size %d\n",
1534                         (phba->nvmet_support ? "NVME" : "NVMET"),
1535                         (state ? "Enabled" : "Disabled"),
1536                         index, skip, phba->nvmeio_trc_size);
1537
1538         if (!phba->nvmeio_trc || state)
1539                 return len;
1540
1541         /* trace MUST bhe off to continue */
1542
1543         for (i = index; i < phba->nvmeio_trc_size; i++) {
1544                 if (skip) {
1545                         skip--;
1546                         continue;
1547                 }
1548                 dtp = phba->nvmeio_trc + i;
1549                 phba->nvmeio_trc_output_idx++;
1550
1551                 if (!dtp->fmt)
1552                         continue;
1553
1554                 len +=  scnprintf(buf + len, size - len, dtp->fmt,
1555                         dtp->data1, dtp->data2, dtp->data3);
1556
1557                 if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) {
1558                         phba->nvmeio_trc_output_idx = 0;
1559                         len += scnprintf(buf + len, size - len,
1560                                         "Trace Complete\n");
1561                         goto out;
1562                 }
1563
1564                 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) {
1565                         len += scnprintf(buf + len, size - len,
1566                                         "Trace Continue (%d of %d)\n",
1567                                         phba->nvmeio_trc_output_idx,
1568                                         phba->nvmeio_trc_size);
1569                         goto out;
1570                 }
1571         }
1572         for (i = 0; i < index; i++) {
1573                 if (skip) {
1574                         skip--;
1575                         continue;
1576                 }
1577                 dtp = phba->nvmeio_trc + i;
1578                 phba->nvmeio_trc_output_idx++;
1579
1580                 if (!dtp->fmt)
1581                         continue;
1582
1583                 len +=  scnprintf(buf + len, size - len, dtp->fmt,
1584                         dtp->data1, dtp->data2, dtp->data3);
1585
1586                 if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) {
1587                         phba->nvmeio_trc_output_idx = 0;
1588                         len += scnprintf(buf + len, size - len,
1589                                         "Trace Complete\n");
1590                         goto out;
1591                 }
1592
1593                 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) {
1594                         len += scnprintf(buf + len, size - len,
1595                                         "Trace Continue (%d of %d)\n",
1596                                         phba->nvmeio_trc_output_idx,
1597                                         phba->nvmeio_trc_size);
1598                         goto out;
1599                 }
1600         }
1601
1602         len += scnprintf(buf + len, size - len,
1603                         "Trace Done\n");
1604 out:
1605         return len;
1606 }
1607
1608 /**
1609  * lpfc_debugfs_cpucheck_data - Dump target node list to a buffer
1610  * @vport: The vport to gather target node info from.
1611  * @buf: The buffer to dump log into.
1612  * @size: The maximum amount of data to process.
1613  *
1614  * Description:
1615  * This routine dumps the NVME statistics associated with @vport
1616  *
1617  * Return Value:
1618  * This routine returns the amount of bytes that were dumped into @buf and will
1619  * not exceed @size.
1620  **/
1621 static int
1622 lpfc_debugfs_cpucheck_data(struct lpfc_vport *vport, char *buf, int size)
1623 {
1624         struct lpfc_hba   *phba = vport->phba;
1625         struct lpfc_sli4_hdw_queue *qp;
1626         int i, j, max_cnt;
1627         int len = 0;
1628         uint32_t tot_xmt;
1629         uint32_t tot_rcv;
1630         uint32_t tot_cmpl;
1631
1632         len += scnprintf(buf + len, PAGE_SIZE - len,
1633                         "CPUcheck %s ",
1634                         (phba->cpucheck_on & LPFC_CHECK_NVME_IO ?
1635                                 "Enabled" : "Disabled"));
1636         if (phba->nvmet_support) {
1637                 len += scnprintf(buf + len, PAGE_SIZE - len,
1638                                 "%s\n",
1639                                 (phba->cpucheck_on & LPFC_CHECK_NVMET_RCV ?
1640                                         "Rcv Enabled\n" : "Rcv Disabled\n"));
1641         } else {
1642                 len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
1643         }
1644         max_cnt = size - LPFC_DEBUG_OUT_LINE_SZ;
1645
1646         for (i = 0; i < phba->cfg_hdw_queue; i++) {
1647                 qp = &phba->sli4_hba.hdwq[i];
1648
1649                 tot_rcv = 0;
1650                 tot_xmt = 0;
1651                 tot_cmpl = 0;
1652                 for (j = 0; j < LPFC_CHECK_CPU_CNT; j++) {
1653                         tot_xmt += qp->cpucheck_xmt_io[j];
1654                         tot_cmpl += qp->cpucheck_cmpl_io[j];
1655                         if (phba->nvmet_support)
1656                                 tot_rcv += qp->cpucheck_rcv_io[j];
1657                 }
1658
1659                 /* Only display Hardware Qs with something */
1660                 if (!tot_xmt && !tot_cmpl && !tot_rcv)
1661                         continue;
1662
1663                 len += scnprintf(buf + len, PAGE_SIZE - len,
1664                                 "HDWQ %03d: ", i);
1665                 for (j = 0; j < LPFC_CHECK_CPU_CNT; j++) {
1666                         /* Only display non-zero counters */
1667                         if (!qp->cpucheck_xmt_io[j] &&
1668                             !qp->cpucheck_cmpl_io[j] &&
1669                             !qp->cpucheck_rcv_io[j])
1670                                 continue;
1671                         if (phba->nvmet_support) {
1672                                 len += scnprintf(buf + len, PAGE_SIZE - len,
1673                                                 "CPU %03d: %x/%x/%x ", j,
1674                                                 qp->cpucheck_rcv_io[j],
1675                                                 qp->cpucheck_xmt_io[j],
1676                                                 qp->cpucheck_cmpl_io[j]);
1677                         } else {
1678                                 len += scnprintf(buf + len, PAGE_SIZE - len,
1679                                                 "CPU %03d: %x/%x ", j,
1680                                                 qp->cpucheck_xmt_io[j],
1681                                                 qp->cpucheck_cmpl_io[j]);
1682                         }
1683                 }
1684                 len += scnprintf(buf + len, PAGE_SIZE - len,
1685                                 "Total: %x\n", tot_xmt);
1686                 if (len >= max_cnt) {
1687                         len += scnprintf(buf + len, PAGE_SIZE - len,
1688                                         "Truncated ...\n");
1689                         return len;
1690                 }
1691         }
1692         return len;
1693 }
1694
1695 #endif
1696
1697 /**
1698  * lpfc_debugfs_disc_trc - Store discovery trace log
1699  * @vport: The vport to associate this trace string with for retrieval.
1700  * @mask: Log entry classification.
1701  * @fmt: Format string to be displayed when dumping the log.
1702  * @data1: 1st data parameter to be applied to @fmt.
1703  * @data2: 2nd data parameter to be applied to @fmt.
1704  * @data3: 3rd data parameter to be applied to @fmt.
1705  *
1706  * Description:
1707  * This routine is used by the driver code to add a debugfs log entry to the
1708  * discovery trace buffer associated with @vport. Only entries with a @mask that
1709  * match the current debugfs discovery mask will be saved. Entries that do not
1710  * match will be thrown away. @fmt, @data1, @data2, and @data3 are used like
1711  * printf when displaying the log.
1712  **/
1713 inline void
1714 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
1715         uint32_t data1, uint32_t data2, uint32_t data3)
1716 {
1717 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1718         struct lpfc_debugfs_trc *dtp;
1719         int index;
1720
1721         if (!(lpfc_debugfs_mask_disc_trc & mask))
1722                 return;
1723
1724         if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
1725                 !vport || !vport->disc_trc)
1726                 return;
1727
1728         index = atomic_inc_return(&vport->disc_trc_cnt) &
1729                 (lpfc_debugfs_max_disc_trc - 1);
1730         dtp = vport->disc_trc + index;
1731         dtp->fmt = fmt;
1732         dtp->data1 = data1;
1733         dtp->data2 = data2;
1734         dtp->data3 = data3;
1735         dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
1736         dtp->jif = jiffies;
1737 #endif
1738         return;
1739 }
1740
1741 /**
1742  * lpfc_debugfs_slow_ring_trc - Store slow ring trace log
1743  * @phba: The phba to associate this trace string with for retrieval.
1744  * @fmt: Format string to be displayed when dumping the log.
1745  * @data1: 1st data parameter to be applied to @fmt.
1746  * @data2: 2nd data parameter to be applied to @fmt.
1747  * @data3: 3rd data parameter to be applied to @fmt.
1748  *
1749  * Description:
1750  * This routine is used by the driver code to add a debugfs log entry to the
1751  * discovery trace buffer associated with @vport. @fmt, @data1, @data2, and
1752  * @data3 are used like printf when displaying the log.
1753  **/
1754 inline void
1755 lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
1756         uint32_t data1, uint32_t data2, uint32_t data3)
1757 {
1758 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1759         struct lpfc_debugfs_trc *dtp;
1760         int index;
1761
1762         if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
1763                 !phba || !phba->slow_ring_trc)
1764                 return;
1765
1766         index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
1767                 (lpfc_debugfs_max_slow_ring_trc - 1);
1768         dtp = phba->slow_ring_trc + index;
1769         dtp->fmt = fmt;
1770         dtp->data1 = data1;
1771         dtp->data2 = data2;
1772         dtp->data3 = data3;
1773         dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
1774         dtp->jif = jiffies;
1775 #endif
1776         return;
1777 }
1778
1779 /**
1780  * lpfc_debugfs_nvme_trc - Store NVME/NVMET trace log
1781  * @phba: The phba to associate this trace string with for retrieval.
1782  * @fmt: Format string to be displayed when dumping the log.
1783  * @data1: 1st data parameter to be applied to @fmt.
1784  * @data2: 2nd data parameter to be applied to @fmt.
1785  * @data3: 3rd data parameter to be applied to @fmt.
1786  *
1787  * Description:
1788  * This routine is used by the driver code to add a debugfs log entry to the
1789  * nvme trace buffer associated with @phba. @fmt, @data1, @data2, and
1790  * @data3 are used like printf when displaying the log.
1791  **/
1792 inline void
1793 lpfc_debugfs_nvme_trc(struct lpfc_hba *phba, char *fmt,
1794                       uint16_t data1, uint16_t data2, uint32_t data3)
1795 {
1796 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1797         struct lpfc_debugfs_nvmeio_trc *dtp;
1798         int index;
1799
1800         if (!phba->nvmeio_trc_on || !phba->nvmeio_trc)
1801                 return;
1802
1803         index = atomic_inc_return(&phba->nvmeio_trc_cnt) &
1804                 (phba->nvmeio_trc_size - 1);
1805         dtp = phba->nvmeio_trc + index;
1806         dtp->fmt = fmt;
1807         dtp->data1 = data1;
1808         dtp->data2 = data2;
1809         dtp->data3 = data3;
1810 #endif
1811 }
1812
1813 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1814 /**
1815  * lpfc_debugfs_disc_trc_open - Open the discovery trace log
1816  * @inode: The inode pointer that contains a vport pointer.
1817  * @file: The file pointer to attach the log output.
1818  *
1819  * Description:
1820  * This routine is the entry point for the debugfs open file operation. It gets
1821  * the vport from the i_private field in @inode, allocates the necessary buffer
1822  * for the log, fills the buffer from the in-memory log for this vport, and then
1823  * returns a pointer to that log in the private_data field in @file.
1824  *
1825  * Returns:
1826  * This function returns zero if successful. On error it will return a negative
1827  * error value.
1828  **/
1829 static int
1830 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
1831 {
1832         struct lpfc_vport *vport = inode->i_private;
1833         struct lpfc_debug *debug;
1834         int size;
1835         int rc = -ENOMEM;
1836
1837         if (!lpfc_debugfs_max_disc_trc) {
1838                 rc = -ENOSPC;
1839                 goto out;
1840         }
1841
1842         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1843         if (!debug)
1844                 goto out;
1845
1846         /* Round to page boundary */
1847         size =  (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
1848         size = PAGE_ALIGN(size);
1849
1850         debug->buffer = kmalloc(size, GFP_KERNEL);
1851         if (!debug->buffer) {
1852                 kfree(debug);
1853                 goto out;
1854         }
1855
1856         debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
1857         file->private_data = debug;
1858
1859         rc = 0;
1860 out:
1861         return rc;
1862 }
1863
1864 /**
1865  * lpfc_debugfs_slow_ring_trc_open - Open the Slow Ring trace log
1866  * @inode: The inode pointer that contains a vport pointer.
1867  * @file: The file pointer to attach the log output.
1868  *
1869  * Description:
1870  * This routine is the entry point for the debugfs open file operation. It gets
1871  * the vport from the i_private field in @inode, allocates the necessary buffer
1872  * for the log, fills the buffer from the in-memory log for this vport, and then
1873  * returns a pointer to that log in the private_data field in @file.
1874  *
1875  * Returns:
1876  * This function returns zero if successful. On error it will return a negative
1877  * error value.
1878  **/
1879 static int
1880 lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
1881 {
1882         struct lpfc_hba *phba = inode->i_private;
1883         struct lpfc_debug *debug;
1884         int size;
1885         int rc = -ENOMEM;
1886
1887         if (!lpfc_debugfs_max_slow_ring_trc) {
1888                 rc = -ENOSPC;
1889                 goto out;
1890         }
1891
1892         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1893         if (!debug)
1894                 goto out;
1895
1896         /* Round to page boundary */
1897         size =  (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
1898         size = PAGE_ALIGN(size);
1899
1900         debug->buffer = kmalloc(size, GFP_KERNEL);
1901         if (!debug->buffer) {
1902                 kfree(debug);
1903                 goto out;
1904         }
1905
1906         debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
1907         file->private_data = debug;
1908
1909         rc = 0;
1910 out:
1911         return rc;
1912 }
1913
1914 /**
1915  * lpfc_debugfs_hbqinfo_open - Open the hbqinfo debugfs buffer
1916  * @inode: The inode pointer that contains a vport pointer.
1917  * @file: The file pointer to attach the log output.
1918  *
1919  * Description:
1920  * This routine is the entry point for the debugfs open file operation. It gets
1921  * the vport from the i_private field in @inode, allocates the necessary buffer
1922  * for the log, fills the buffer from the in-memory log for this vport, and then
1923  * returns a pointer to that log in the private_data field in @file.
1924  *
1925  * Returns:
1926  * This function returns zero if successful. On error it will return a negative
1927  * error value.
1928  **/
1929 static int
1930 lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
1931 {
1932         struct lpfc_hba *phba = inode->i_private;
1933         struct lpfc_debug *debug;
1934         int rc = -ENOMEM;
1935
1936         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1937         if (!debug)
1938                 goto out;
1939
1940         /* Round to page boundary */
1941         debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
1942         if (!debug->buffer) {
1943                 kfree(debug);
1944                 goto out;
1945         }
1946
1947         debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
1948                 LPFC_HBQINFO_SIZE);
1949         file->private_data = debug;
1950
1951         rc = 0;
1952 out:
1953         return rc;
1954 }
1955
1956 /**
1957  * lpfc_debugfs_multixripools_open - Open the multixripool debugfs buffer
1958  * @inode: The inode pointer that contains a hba pointer.
1959  * @file: The file pointer to attach the log output.
1960  *
1961  * Description:
1962  * This routine is the entry point for the debugfs open file operation. It gets
1963  * the hba from the i_private field in @inode, allocates the necessary buffer
1964  * for the log, fills the buffer from the in-memory log for this hba, and then
1965  * returns a pointer to that log in the private_data field in @file.
1966  *
1967  * Returns:
1968  * This function returns zero if successful. On error it will return a negative
1969  * error value.
1970  **/
1971 static int
1972 lpfc_debugfs_multixripools_open(struct inode *inode, struct file *file)
1973 {
1974         struct lpfc_hba *phba = inode->i_private;
1975         struct lpfc_debug *debug;
1976         int rc = -ENOMEM;
1977
1978         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1979         if (!debug)
1980                 goto out;
1981
1982         /* Round to page boundary */
1983         debug->buffer = kzalloc(LPFC_DUMP_MULTIXRIPOOL_SIZE, GFP_KERNEL);
1984         if (!debug->buffer) {
1985                 kfree(debug);
1986                 goto out;
1987         }
1988
1989         debug->len = lpfc_debugfs_multixripools_data(
1990                 phba, debug->buffer, LPFC_DUMP_MULTIXRIPOOL_SIZE);
1991
1992         debug->i_private = inode->i_private;
1993         file->private_data = debug;
1994
1995         rc = 0;
1996 out:
1997         return rc;
1998 }
1999
2000 #ifdef LPFC_HDWQ_LOCK_STAT
2001 /**
2002  * lpfc_debugfs_lockstat_open - Open the lockstat debugfs buffer
2003  * @inode: The inode pointer that contains a vport pointer.
2004  * @file: The file pointer to attach the log output.
2005  *
2006  * Description:
2007  * This routine is the entry point for the debugfs open file operation. It gets
2008  * the vport from the i_private field in @inode, allocates the necessary buffer
2009  * for the log, fills the buffer from the in-memory log for this vport, and then
2010  * returns a pointer to that log in the private_data field in @file.
2011  *
2012  * Returns:
2013  * This function returns zero if successful. On error it will return a negative
2014  * error value.
2015  **/
2016 static int
2017 lpfc_debugfs_lockstat_open(struct inode *inode, struct file *file)
2018 {
2019         struct lpfc_hba *phba = inode->i_private;
2020         struct lpfc_debug *debug;
2021         int rc = -ENOMEM;
2022
2023         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2024         if (!debug)
2025                 goto out;
2026
2027         /* Round to page boundary */
2028         debug->buffer = kmalloc(LPFC_HDWQINFO_SIZE, GFP_KERNEL);
2029         if (!debug->buffer) {
2030                 kfree(debug);
2031                 goto out;
2032         }
2033
2034         debug->len = lpfc_debugfs_lockstat_data(phba, debug->buffer,
2035                 LPFC_HBQINFO_SIZE);
2036         file->private_data = debug;
2037
2038         rc = 0;
2039 out:
2040         return rc;
2041 }
2042
2043 static ssize_t
2044 lpfc_debugfs_lockstat_write(struct file *file, const char __user *buf,
2045                             size_t nbytes, loff_t *ppos)
2046 {
2047         struct lpfc_debug *debug = file->private_data;
2048         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2049         struct lpfc_sli4_hdw_queue *qp;
2050         char mybuf[64];
2051         char *pbuf;
2052         int i;
2053
2054         /* Protect copy from user */
2055         if (!access_ok(buf, nbytes))
2056                 return -EFAULT;
2057
2058         memset(mybuf, 0, sizeof(mybuf));
2059
2060         if (copy_from_user(mybuf, buf, nbytes))
2061                 return -EFAULT;
2062         pbuf = &mybuf[0];
2063
2064         if ((strncmp(pbuf, "reset", strlen("reset")) == 0) ||
2065             (strncmp(pbuf, "zero", strlen("zero")) == 0)) {
2066                 for (i = 0; i < phba->cfg_hdw_queue; i++) {
2067                         qp = &phba->sli4_hba.hdwq[i];
2068                         qp->lock_conflict.alloc_xri_get = 0;
2069                         qp->lock_conflict.alloc_xri_put = 0;
2070                         qp->lock_conflict.free_xri = 0;
2071                         qp->lock_conflict.wq_access = 0;
2072                         qp->lock_conflict.alloc_pvt_pool = 0;
2073                         qp->lock_conflict.mv_from_pvt_pool = 0;
2074                         qp->lock_conflict.mv_to_pub_pool = 0;
2075                         qp->lock_conflict.mv_to_pvt_pool = 0;
2076                         qp->lock_conflict.free_pvt_pool = 0;
2077                         qp->lock_conflict.free_pub_pool = 0;
2078                         qp->lock_conflict.wq_access = 0;
2079                 }
2080         }
2081         return nbytes;
2082 }
2083 #endif
2084
2085 /**
2086  * lpfc_debugfs_dumpHBASlim_open - Open the Dump HBA SLIM debugfs buffer
2087  * @inode: The inode pointer that contains a vport pointer.
2088  * @file: The file pointer to attach the log output.
2089  *
2090  * Description:
2091  * This routine is the entry point for the debugfs open file operation. It gets
2092  * the vport from the i_private field in @inode, allocates the necessary buffer
2093  * for the log, fills the buffer from the in-memory log for this vport, and then
2094  * returns a pointer to that log in the private_data field in @file.
2095  *
2096  * Returns:
2097  * This function returns zero if successful. On error it will return a negative
2098  * error value.
2099  **/
2100 static int
2101 lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file)
2102 {
2103         struct lpfc_hba *phba = inode->i_private;
2104         struct lpfc_debug *debug;
2105         int rc = -ENOMEM;
2106
2107         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2108         if (!debug)
2109                 goto out;
2110
2111         /* Round to page boundary */
2112         debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL);
2113         if (!debug->buffer) {
2114                 kfree(debug);
2115                 goto out;
2116         }
2117
2118         debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer,
2119                 LPFC_DUMPHBASLIM_SIZE);
2120         file->private_data = debug;
2121
2122         rc = 0;
2123 out:
2124         return rc;
2125 }
2126
2127 /**
2128  * lpfc_debugfs_dumpHostSlim_open - Open the Dump Host SLIM debugfs buffer
2129  * @inode: The inode pointer that contains a vport pointer.
2130  * @file: The file pointer to attach the log output.
2131  *
2132  * Description:
2133  * This routine is the entry point for the debugfs open file operation. It gets
2134  * the vport from the i_private field in @inode, allocates the necessary buffer
2135  * for the log, fills the buffer from the in-memory log for this vport, and then
2136  * returns a pointer to that log in the private_data field in @file.
2137  *
2138  * Returns:
2139  * This function returns zero if successful. On error it will return a negative
2140  * error value.
2141  **/
2142 static int
2143 lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file)
2144 {
2145         struct lpfc_hba *phba = inode->i_private;
2146         struct lpfc_debug *debug;
2147         int rc = -ENOMEM;
2148
2149         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2150         if (!debug)
2151                 goto out;
2152
2153         /* Round to page boundary */
2154         debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL);
2155         if (!debug->buffer) {
2156                 kfree(debug);
2157                 goto out;
2158         }
2159
2160         debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer,
2161                 LPFC_DUMPHOSTSLIM_SIZE);
2162         file->private_data = debug;
2163
2164         rc = 0;
2165 out:
2166         return rc;
2167 }
2168
2169 static int
2170 lpfc_debugfs_dumpData_open(struct inode *inode, struct file *file)
2171 {
2172         struct lpfc_debug *debug;
2173         int rc = -ENOMEM;
2174
2175         if (!_dump_buf_data)
2176                 return -EBUSY;
2177
2178         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2179         if (!debug)
2180                 goto out;
2181
2182         /* Round to page boundary */
2183         pr_err("9059 BLKGRD:  %s: _dump_buf_data=0x%p\n",
2184                         __func__, _dump_buf_data);
2185         debug->buffer = _dump_buf_data;
2186         if (!debug->buffer) {
2187                 kfree(debug);
2188                 goto out;
2189         }
2190
2191         debug->len = (1 << _dump_buf_data_order) << PAGE_SHIFT;
2192         file->private_data = debug;
2193
2194         rc = 0;
2195 out:
2196         return rc;
2197 }
2198
2199 static int
2200 lpfc_debugfs_dumpDif_open(struct inode *inode, struct file *file)
2201 {
2202         struct lpfc_debug *debug;
2203         int rc = -ENOMEM;
2204
2205         if (!_dump_buf_dif)
2206                 return -EBUSY;
2207
2208         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2209         if (!debug)
2210                 goto out;
2211
2212         /* Round to page boundary */
2213         pr_err("9060 BLKGRD: %s: _dump_buf_dif=0x%p file=%pD\n",
2214                         __func__, _dump_buf_dif, file);
2215         debug->buffer = _dump_buf_dif;
2216         if (!debug->buffer) {
2217                 kfree(debug);
2218                 goto out;
2219         }
2220
2221         debug->len = (1 << _dump_buf_dif_order) << PAGE_SHIFT;
2222         file->private_data = debug;
2223
2224         rc = 0;
2225 out:
2226         return rc;
2227 }
2228
2229 static ssize_t
2230 lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf,
2231                   size_t nbytes, loff_t *ppos)
2232 {
2233         /*
2234          * The Data/DIF buffers only save one failing IO
2235          * The write op is used as a reset mechanism after an IO has
2236          * already been saved to the next one can be saved
2237          */
2238         spin_lock(&_dump_buf_lock);
2239
2240         memset((void *)_dump_buf_data, 0,
2241                         ((1 << PAGE_SHIFT) << _dump_buf_data_order));
2242         memset((void *)_dump_buf_dif, 0,
2243                         ((1 << PAGE_SHIFT) << _dump_buf_dif_order));
2244
2245         _dump_buf_done = 0;
2246
2247         spin_unlock(&_dump_buf_lock);
2248
2249         return nbytes;
2250 }
2251
2252 static ssize_t
2253 lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
2254         size_t nbytes, loff_t *ppos)
2255 {
2256         struct dentry *dent = file->f_path.dentry;
2257         struct lpfc_hba *phba = file->private_data;
2258         char cbuf[32];
2259         uint64_t tmp = 0;
2260         int cnt = 0;
2261
2262         if (dent == phba->debug_writeGuard)
2263                 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt);
2264         else if (dent == phba->debug_writeApp)
2265                 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt);
2266         else if (dent == phba->debug_writeRef)
2267                 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt);
2268         else if (dent == phba->debug_readGuard)
2269                 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt);
2270         else if (dent == phba->debug_readApp)
2271                 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt);
2272         else if (dent == phba->debug_readRef)
2273                 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt);
2274         else if (dent == phba->debug_InjErrNPortID)
2275                 cnt = scnprintf(cbuf, 32, "0x%06x\n",
2276                                 phba->lpfc_injerr_nportid);
2277         else if (dent == phba->debug_InjErrWWPN) {
2278                 memcpy(&tmp, &phba->lpfc_injerr_wwpn, sizeof(struct lpfc_name));
2279                 tmp = cpu_to_be64(tmp);
2280                 cnt = scnprintf(cbuf, 32, "0x%016llx\n", tmp);
2281         } else if (dent == phba->debug_InjErrLBA) {
2282                 if (phba->lpfc_injerr_lba == (sector_t)(-1))
2283                         cnt = scnprintf(cbuf, 32, "off\n");
2284                 else
2285                         cnt = scnprintf(cbuf, 32, "0x%llx\n",
2286                                  (uint64_t) phba->lpfc_injerr_lba);
2287         } else
2288                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2289                          "0547 Unknown debugfs error injection entry\n");
2290
2291         return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt);
2292 }
2293
2294 static ssize_t
2295 lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
2296         size_t nbytes, loff_t *ppos)
2297 {
2298         struct dentry *dent = file->f_path.dentry;
2299         struct lpfc_hba *phba = file->private_data;
2300         char dstbuf[33];
2301         uint64_t tmp = 0;
2302         int size;
2303
2304         memset(dstbuf, 0, 33);
2305         size = (nbytes < 32) ? nbytes : 32;
2306         if (copy_from_user(dstbuf, buf, size))
2307                 return 0;
2308
2309         if (dent == phba->debug_InjErrLBA) {
2310                 if ((buf[0] == 'o') && (buf[1] == 'f') && (buf[2] == 'f'))
2311                         tmp = (uint64_t)(-1);
2312         }
2313
2314         if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp)))
2315                 return 0;
2316
2317         if (dent == phba->debug_writeGuard)
2318                 phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
2319         else if (dent == phba->debug_writeApp)
2320                 phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
2321         else if (dent == phba->debug_writeRef)
2322                 phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
2323         else if (dent == phba->debug_readGuard)
2324                 phba->lpfc_injerr_rgrd_cnt = (uint32_t)tmp;
2325         else if (dent == phba->debug_readApp)
2326                 phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
2327         else if (dent == phba->debug_readRef)
2328                 phba->lpfc_injerr_rref_cnt = (uint32_t)tmp;
2329         else if (dent == phba->debug_InjErrLBA)
2330                 phba->lpfc_injerr_lba = (sector_t)tmp;
2331         else if (dent == phba->debug_InjErrNPortID)
2332                 phba->lpfc_injerr_nportid = (uint32_t)(tmp & Mask_DID);
2333         else if (dent == phba->debug_InjErrWWPN) {
2334                 tmp = cpu_to_be64(tmp);
2335                 memcpy(&phba->lpfc_injerr_wwpn, &tmp, sizeof(struct lpfc_name));
2336         } else
2337                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2338                          "0548 Unknown debugfs error injection entry\n");
2339
2340         return nbytes;
2341 }
2342
2343 static int
2344 lpfc_debugfs_dif_err_release(struct inode *inode, struct file *file)
2345 {
2346         return 0;
2347 }
2348
2349 /**
2350  * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file
2351  * @inode: The inode pointer that contains a vport pointer.
2352  * @file: The file pointer to attach the log output.
2353  *
2354  * Description:
2355  * This routine is the entry point for the debugfs open file operation. It gets
2356  * the vport from the i_private field in @inode, allocates the necessary buffer
2357  * for the log, fills the buffer from the in-memory log for this vport, and then
2358  * returns a pointer to that log in the private_data field in @file.
2359  *
2360  * Returns:
2361  * This function returns zero if successful. On error it will return a negative
2362  * error value.
2363  **/
2364 static int
2365 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
2366 {
2367         struct lpfc_vport *vport = inode->i_private;
2368         struct lpfc_debug *debug;
2369         int rc = -ENOMEM;
2370
2371         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2372         if (!debug)
2373                 goto out;
2374
2375         /* Round to page boundary */
2376         debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
2377         if (!debug->buffer) {
2378                 kfree(debug);
2379                 goto out;
2380         }
2381
2382         debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
2383                 LPFC_NODELIST_SIZE);
2384         file->private_data = debug;
2385
2386         rc = 0;
2387 out:
2388         return rc;
2389 }
2390
2391 /**
2392  * lpfc_debugfs_lseek - Seek through a debugfs file
2393  * @file: The file pointer to seek through.
2394  * @off: The offset to seek to or the amount to seek by.
2395  * @whence: Indicates how to seek.
2396  *
2397  * Description:
2398  * This routine is the entry point for the debugfs lseek file operation. The
2399  * @whence parameter indicates whether @off is the offset to directly seek to,
2400  * or if it is a value to seek forward or reverse by. This function figures out
2401  * what the new offset of the debugfs file will be and assigns that value to the
2402  * f_pos field of @file.
2403  *
2404  * Returns:
2405  * This function returns the new offset if successful and returns a negative
2406  * error if unable to process the seek.
2407  **/
2408 static loff_t
2409 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
2410 {
2411         struct lpfc_debug *debug = file->private_data;
2412         return fixed_size_llseek(file, off, whence, debug->len);
2413 }
2414
2415 /**
2416  * lpfc_debugfs_read - Read a debugfs file
2417  * @file: The file pointer to read from.
2418  * @buf: The buffer to copy the data to.
2419  * @nbytes: The number of bytes to read.
2420  * @ppos: The position in the file to start reading from.
2421  *
2422  * Description:
2423  * This routine reads data from from the buffer indicated in the private_data
2424  * field of @file. It will start reading at @ppos and copy up to @nbytes of
2425  * data to @buf.
2426  *
2427  * Returns:
2428  * This function returns the amount of data that was read (this could be less
2429  * than @nbytes if the end of the file was reached) or a negative error value.
2430  **/
2431 static ssize_t
2432 lpfc_debugfs_read(struct file *file, char __user *buf,
2433                   size_t nbytes, loff_t *ppos)
2434 {
2435         struct lpfc_debug *debug = file->private_data;
2436
2437         return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
2438                                        debug->len);
2439 }
2440
2441 /**
2442  * lpfc_debugfs_release - Release the buffer used to store debugfs file data
2443  * @inode: The inode pointer that contains a vport pointer. (unused)
2444  * @file: The file pointer that contains the buffer to release.
2445  *
2446  * Description:
2447  * This routine frees the buffer that was allocated when the debugfs file was
2448  * opened.
2449  *
2450  * Returns:
2451  * This function returns zero.
2452  **/
2453 static int
2454 lpfc_debugfs_release(struct inode *inode, struct file *file)
2455 {
2456         struct lpfc_debug *debug = file->private_data;
2457
2458         kfree(debug->buffer);
2459         kfree(debug);
2460
2461         return 0;
2462 }
2463
2464 static int
2465 lpfc_debugfs_dumpDataDif_release(struct inode *inode, struct file *file)
2466 {
2467         struct lpfc_debug *debug = file->private_data;
2468
2469         debug->buffer = NULL;
2470         kfree(debug);
2471
2472         return 0;
2473 }
2474
2475 /**
2476  * lpfc_debugfs_multixripools_write - Clear multi-XRI pools statistics
2477  * @file: The file pointer to read from.
2478  * @buf: The buffer to copy the user data from.
2479  * @nbytes: The number of bytes to get.
2480  * @ppos: The position in the file to start reading from.
2481  *
2482  * Description:
2483  * This routine clears multi-XRI pools statistics when buf contains "clear".
2484  *
2485  * Return Value:
2486  * It returns the @nbytges passing in from debugfs user space when successful.
2487  * In case of error conditions, it returns proper error code back to the user
2488  * space.
2489  **/
2490 static ssize_t
2491 lpfc_debugfs_multixripools_write(struct file *file, const char __user *buf,
2492                                  size_t nbytes, loff_t *ppos)
2493 {
2494         struct lpfc_debug *debug = file->private_data;
2495         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2496         char mybuf[64];
2497         char *pbuf;
2498         u32 i;
2499         u32 hwq_count;
2500         struct lpfc_sli4_hdw_queue *qp;
2501         struct lpfc_multixri_pool *multixri_pool;
2502
2503         if (nbytes > 64)
2504                 nbytes = 64;
2505
2506         /* Protect copy from user */
2507         if (!access_ok(buf, nbytes))
2508                 return -EFAULT;
2509
2510         memset(mybuf, 0, sizeof(mybuf));
2511
2512         if (copy_from_user(mybuf, buf, nbytes))
2513                 return -EFAULT;
2514         pbuf = &mybuf[0];
2515
2516         if ((strncmp(pbuf, "clear", strlen("clear"))) == 0) {
2517                 hwq_count = phba->cfg_hdw_queue;
2518                 for (i = 0; i < hwq_count; i++) {
2519                         qp = &phba->sli4_hba.hdwq[i];
2520                         multixri_pool = qp->p_multixri_pool;
2521                         if (!multixri_pool)
2522                                 continue;
2523
2524                         qp->empty_io_bufs = 0;
2525                         multixri_pool->pbl_empty_count = 0;
2526 #ifdef LPFC_MXP_STAT
2527                         multixri_pool->above_limit_count = 0;
2528                         multixri_pool->below_limit_count = 0;
2529                         multixri_pool->stat_max_hwm = 0;
2530                         multixri_pool->local_pbl_hit_count = 0;
2531                         multixri_pool->other_pbl_hit_count = 0;
2532
2533                         multixri_pool->stat_pbl_count = 0;
2534                         multixri_pool->stat_pvt_count = 0;
2535                         multixri_pool->stat_busy_count = 0;
2536                         multixri_pool->stat_snapshot_taken = 0;
2537 #endif
2538                 }
2539                 return strlen(pbuf);
2540         }
2541
2542         return -EINVAL;
2543 }
2544
2545 static int
2546 lpfc_debugfs_nvmestat_open(struct inode *inode, struct file *file)
2547 {
2548         struct lpfc_vport *vport = inode->i_private;
2549         struct lpfc_debug *debug;
2550         int rc = -ENOMEM;
2551
2552         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2553         if (!debug)
2554                 goto out;
2555
2556          /* Round to page boundary */
2557         debug->buffer = kmalloc(LPFC_NVMESTAT_SIZE, GFP_KERNEL);
2558         if (!debug->buffer) {
2559                 kfree(debug);
2560                 goto out;
2561         }
2562
2563         debug->len = lpfc_debugfs_nvmestat_data(vport, debug->buffer,
2564                 LPFC_NVMESTAT_SIZE);
2565
2566         debug->i_private = inode->i_private;
2567         file->private_data = debug;
2568
2569         rc = 0;
2570 out:
2571         return rc;
2572 }
2573
2574 static ssize_t
2575 lpfc_debugfs_nvmestat_write(struct file *file, const char __user *buf,
2576                             size_t nbytes, loff_t *ppos)
2577 {
2578         struct lpfc_debug *debug = file->private_data;
2579         struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
2580         struct lpfc_hba   *phba = vport->phba;
2581         struct lpfc_nvmet_tgtport *tgtp;
2582         char mybuf[64];
2583         char *pbuf;
2584
2585         if (!phba->targetport)
2586                 return -ENXIO;
2587
2588         if (nbytes > 64)
2589                 nbytes = 64;
2590
2591         memset(mybuf, 0, sizeof(mybuf));
2592
2593         if (copy_from_user(mybuf, buf, nbytes))
2594                 return -EFAULT;
2595         pbuf = &mybuf[0];
2596
2597         tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
2598         if ((strncmp(pbuf, "reset", strlen("reset")) == 0) ||
2599             (strncmp(pbuf, "zero", strlen("zero")) == 0)) {
2600                 atomic_set(&tgtp->rcv_ls_req_in, 0);
2601                 atomic_set(&tgtp->rcv_ls_req_out, 0);
2602                 atomic_set(&tgtp->rcv_ls_req_drop, 0);
2603                 atomic_set(&tgtp->xmt_ls_abort, 0);
2604                 atomic_set(&tgtp->xmt_ls_abort_cmpl, 0);
2605                 atomic_set(&tgtp->xmt_ls_rsp, 0);
2606                 atomic_set(&tgtp->xmt_ls_drop, 0);
2607                 atomic_set(&tgtp->xmt_ls_rsp_error, 0);
2608                 atomic_set(&tgtp->xmt_ls_rsp_cmpl, 0);
2609
2610                 atomic_set(&tgtp->rcv_fcp_cmd_in, 0);
2611                 atomic_set(&tgtp->rcv_fcp_cmd_out, 0);
2612                 atomic_set(&tgtp->rcv_fcp_cmd_drop, 0);
2613                 atomic_set(&tgtp->xmt_fcp_drop, 0);
2614                 atomic_set(&tgtp->xmt_fcp_read_rsp, 0);
2615                 atomic_set(&tgtp->xmt_fcp_read, 0);
2616                 atomic_set(&tgtp->xmt_fcp_write, 0);
2617                 atomic_set(&tgtp->xmt_fcp_rsp, 0);
2618                 atomic_set(&tgtp->xmt_fcp_release, 0);
2619                 atomic_set(&tgtp->xmt_fcp_rsp_cmpl, 0);
2620                 atomic_set(&tgtp->xmt_fcp_rsp_error, 0);
2621                 atomic_set(&tgtp->xmt_fcp_rsp_drop, 0);
2622
2623                 atomic_set(&tgtp->xmt_fcp_abort, 0);
2624                 atomic_set(&tgtp->xmt_fcp_abort_cmpl, 0);
2625                 atomic_set(&tgtp->xmt_abort_sol, 0);
2626                 atomic_set(&tgtp->xmt_abort_unsol, 0);
2627                 atomic_set(&tgtp->xmt_abort_rsp, 0);
2628                 atomic_set(&tgtp->xmt_abort_rsp_error, 0);
2629         }
2630         return nbytes;
2631 }
2632
2633 static int
2634 lpfc_debugfs_scsistat_open(struct inode *inode, struct file *file)
2635 {
2636         struct lpfc_vport *vport = inode->i_private;
2637         struct lpfc_debug *debug;
2638         int rc = -ENOMEM;
2639
2640         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2641         if (!debug)
2642                 goto out;
2643
2644          /* Round to page boundary */
2645         debug->buffer = kzalloc(LPFC_SCSISTAT_SIZE, GFP_KERNEL);
2646         if (!debug->buffer) {
2647                 kfree(debug);
2648                 goto out;
2649         }
2650
2651         debug->len = lpfc_debugfs_scsistat_data(vport, debug->buffer,
2652                 LPFC_SCSISTAT_SIZE);
2653
2654         debug->i_private = inode->i_private;
2655         file->private_data = debug;
2656
2657         rc = 0;
2658 out:
2659         return rc;
2660 }
2661
2662 static ssize_t
2663 lpfc_debugfs_scsistat_write(struct file *file, const char __user *buf,
2664                             size_t nbytes, loff_t *ppos)
2665 {
2666         struct lpfc_debug *debug = file->private_data;
2667         struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
2668         struct lpfc_hba *phba = vport->phba;
2669         char mybuf[6] = {0};
2670         int i;
2671
2672         /* Protect copy from user */
2673         if (!access_ok(buf, nbytes))
2674                 return -EFAULT;
2675
2676         if (copy_from_user(mybuf, buf, (nbytes >= sizeof(mybuf)) ?
2677                                        (sizeof(mybuf) - 1) : nbytes))
2678                 return -EFAULT;
2679
2680         if ((strncmp(&mybuf[0], "reset", strlen("reset")) == 0) ||
2681             (strncmp(&mybuf[0], "zero", strlen("zero")) == 0)) {
2682                 for (i = 0; i < phba->cfg_hdw_queue; i++) {
2683                         memset(&phba->sli4_hba.hdwq[i].scsi_cstat, 0,
2684                                sizeof(phba->sli4_hba.hdwq[i].scsi_cstat));
2685                 }
2686         }
2687
2688         return nbytes;
2689 }
2690
2691 static int
2692 lpfc_debugfs_nvmektime_open(struct inode *inode, struct file *file)
2693 {
2694         struct lpfc_vport *vport = inode->i_private;
2695         struct lpfc_debug *debug;
2696         int rc = -ENOMEM;
2697
2698         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2699         if (!debug)
2700                 goto out;
2701
2702          /* Round to page boundary */
2703         debug->buffer = kmalloc(LPFC_NVMEKTIME_SIZE, GFP_KERNEL);
2704         if (!debug->buffer) {
2705                 kfree(debug);
2706                 goto out;
2707         }
2708
2709         debug->len = lpfc_debugfs_nvmektime_data(vport, debug->buffer,
2710                 LPFC_NVMEKTIME_SIZE);
2711
2712         debug->i_private = inode->i_private;
2713         file->private_data = debug;
2714
2715         rc = 0;
2716 out:
2717         return rc;
2718 }
2719
2720 static ssize_t
2721 lpfc_debugfs_nvmektime_write(struct file *file, const char __user *buf,
2722                              size_t nbytes, loff_t *ppos)
2723 {
2724         struct lpfc_debug *debug = file->private_data;
2725         struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
2726         struct lpfc_hba   *phba = vport->phba;
2727         char mybuf[64];
2728         char *pbuf;
2729
2730         if (nbytes > 64)
2731                 nbytes = 64;
2732
2733         memset(mybuf, 0, sizeof(mybuf));
2734
2735         if (copy_from_user(mybuf, buf, nbytes))
2736                 return -EFAULT;
2737         pbuf = &mybuf[0];
2738
2739         if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
2740                 phba->ktime_data_samples = 0;
2741                 phba->ktime_status_samples = 0;
2742                 phba->ktime_seg1_total = 0;
2743                 phba->ktime_seg1_max = 0;
2744                 phba->ktime_seg1_min = 0xffffffff;
2745                 phba->ktime_seg2_total = 0;
2746                 phba->ktime_seg2_max = 0;
2747                 phba->ktime_seg2_min = 0xffffffff;
2748                 phba->ktime_seg3_total = 0;
2749                 phba->ktime_seg3_max = 0;
2750                 phba->ktime_seg3_min = 0xffffffff;
2751                 phba->ktime_seg4_total = 0;
2752                 phba->ktime_seg4_max = 0;
2753                 phba->ktime_seg4_min = 0xffffffff;
2754                 phba->ktime_seg5_total = 0;
2755                 phba->ktime_seg5_max = 0;
2756                 phba->ktime_seg5_min = 0xffffffff;
2757                 phba->ktime_seg6_total = 0;
2758                 phba->ktime_seg6_max = 0;
2759                 phba->ktime_seg6_min = 0xffffffff;
2760                 phba->ktime_seg7_total = 0;
2761                 phba->ktime_seg7_max = 0;
2762                 phba->ktime_seg7_min = 0xffffffff;
2763                 phba->ktime_seg8_total = 0;
2764                 phba->ktime_seg8_max = 0;
2765                 phba->ktime_seg8_min = 0xffffffff;
2766                 phba->ktime_seg9_total = 0;
2767                 phba->ktime_seg9_max = 0;
2768                 phba->ktime_seg9_min = 0xffffffff;
2769                 phba->ktime_seg10_total = 0;
2770                 phba->ktime_seg10_max = 0;
2771                 phba->ktime_seg10_min = 0xffffffff;
2772
2773                 phba->ktime_on = 1;
2774                 return strlen(pbuf);
2775         } else if ((strncmp(pbuf, "off",
2776                    sizeof("off") - 1) == 0)) {
2777                 phba->ktime_on = 0;
2778                 return strlen(pbuf);
2779         } else if ((strncmp(pbuf, "zero",
2780                    sizeof("zero") - 1) == 0)) {
2781                 phba->ktime_data_samples = 0;
2782                 phba->ktime_status_samples = 0;
2783                 phba->ktime_seg1_total = 0;
2784                 phba->ktime_seg1_max = 0;
2785                 phba->ktime_seg1_min = 0xffffffff;
2786                 phba->ktime_seg2_total = 0;
2787                 phba->ktime_seg2_max = 0;
2788                 phba->ktime_seg2_min = 0xffffffff;
2789                 phba->ktime_seg3_total = 0;
2790                 phba->ktime_seg3_max = 0;
2791                 phba->ktime_seg3_min = 0xffffffff;
2792                 phba->ktime_seg4_total = 0;
2793                 phba->ktime_seg4_max = 0;
2794                 phba->ktime_seg4_min = 0xffffffff;
2795                 phba->ktime_seg5_total = 0;
2796                 phba->ktime_seg5_max = 0;
2797                 phba->ktime_seg5_min = 0xffffffff;
2798                 phba->ktime_seg6_total = 0;
2799                 phba->ktime_seg6_max = 0;
2800                 phba->ktime_seg6_min = 0xffffffff;
2801                 phba->ktime_seg7_total = 0;
2802                 phba->ktime_seg7_max = 0;
2803                 phba->ktime_seg7_min = 0xffffffff;
2804                 phba->ktime_seg8_total = 0;
2805                 phba->ktime_seg8_max = 0;
2806                 phba->ktime_seg8_min = 0xffffffff;
2807                 phba->ktime_seg9_total = 0;
2808                 phba->ktime_seg9_max = 0;
2809                 phba->ktime_seg9_min = 0xffffffff;
2810                 phba->ktime_seg10_total = 0;
2811                 phba->ktime_seg10_max = 0;
2812                 phba->ktime_seg10_min = 0xffffffff;
2813                 return strlen(pbuf);
2814         }
2815         return -EINVAL;
2816 }
2817
2818 static int
2819 lpfc_debugfs_nvmeio_trc_open(struct inode *inode, struct file *file)
2820 {
2821         struct lpfc_hba *phba = inode->i_private;
2822         struct lpfc_debug *debug;
2823         int rc = -ENOMEM;
2824
2825         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2826         if (!debug)
2827                 goto out;
2828
2829          /* Round to page boundary */
2830         debug->buffer = kmalloc(LPFC_NVMEIO_TRC_SIZE, GFP_KERNEL);
2831         if (!debug->buffer) {
2832                 kfree(debug);
2833                 goto out;
2834         }
2835
2836         debug->len = lpfc_debugfs_nvmeio_trc_data(phba, debug->buffer,
2837                 LPFC_NVMEIO_TRC_SIZE);
2838
2839         debug->i_private = inode->i_private;
2840         file->private_data = debug;
2841
2842         rc = 0;
2843 out:
2844         return rc;
2845 }
2846
2847 static ssize_t
2848 lpfc_debugfs_nvmeio_trc_write(struct file *file, const char __user *buf,
2849                               size_t nbytes, loff_t *ppos)
2850 {
2851         struct lpfc_debug *debug = file->private_data;
2852         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2853         int i;
2854         unsigned long sz;
2855         char mybuf[64];
2856         char *pbuf;
2857
2858         if (nbytes > 64)
2859                 nbytes = 64;
2860
2861         memset(mybuf, 0, sizeof(mybuf));
2862
2863         if (copy_from_user(mybuf, buf, nbytes))
2864                 return -EFAULT;
2865         pbuf = &mybuf[0];
2866
2867         if ((strncmp(pbuf, "off", sizeof("off") - 1) == 0)) {
2868                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2869                                 "0570 nvmeio_trc_off\n");
2870                 phba->nvmeio_trc_output_idx = 0;
2871                 phba->nvmeio_trc_on = 0;
2872                 return strlen(pbuf);
2873         } else if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
2874                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2875                                 "0571 nvmeio_trc_on\n");
2876                 phba->nvmeio_trc_output_idx = 0;
2877                 phba->nvmeio_trc_on = 1;
2878                 return strlen(pbuf);
2879         }
2880
2881         /* We must be off to allocate the trace buffer */
2882         if (phba->nvmeio_trc_on != 0)
2883                 return -EINVAL;
2884
2885         /* If not on or off, the parameter is the trace buffer size */
2886         i = kstrtoul(pbuf, 0, &sz);
2887         if (i)
2888                 return -EINVAL;
2889         phba->nvmeio_trc_size = (uint32_t)sz;
2890
2891         /* It must be a power of 2 - round down */
2892         i = 0;
2893         while (sz > 1) {
2894                 sz = sz >> 1;
2895                 i++;
2896         }
2897         sz = (1 << i);
2898         if (phba->nvmeio_trc_size != sz)
2899                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2900                                 "0572 nvmeio_trc_size changed to %ld\n",
2901                                 sz);
2902         phba->nvmeio_trc_size = (uint32_t)sz;
2903
2904         /* If one previously exists, free it */
2905         kfree(phba->nvmeio_trc);
2906
2907         /* Allocate new trace buffer and initialize */
2908         phba->nvmeio_trc = kzalloc((sizeof(struct lpfc_debugfs_nvmeio_trc) *
2909                                     sz), GFP_KERNEL);
2910         if (!phba->nvmeio_trc) {
2911                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2912                                 "0573 Cannot create debugfs "
2913                                 "nvmeio_trc buffer\n");
2914                 return -ENOMEM;
2915         }
2916         atomic_set(&phba->nvmeio_trc_cnt, 0);
2917         phba->nvmeio_trc_on = 0;
2918         phba->nvmeio_trc_output_idx = 0;
2919
2920         return strlen(pbuf);
2921 }
2922
2923 static int
2924 lpfc_debugfs_cpucheck_open(struct inode *inode, struct file *file)
2925 {
2926         struct lpfc_vport *vport = inode->i_private;
2927         struct lpfc_debug *debug;
2928         int rc = -ENOMEM;
2929
2930         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2931         if (!debug)
2932                 goto out;
2933
2934          /* Round to page boundary */
2935         debug->buffer = kmalloc(LPFC_CPUCHECK_SIZE, GFP_KERNEL);
2936         if (!debug->buffer) {
2937                 kfree(debug);
2938                 goto out;
2939         }
2940
2941         debug->len = lpfc_debugfs_cpucheck_data(vport, debug->buffer,
2942                 LPFC_CPUCHECK_SIZE);
2943
2944         debug->i_private = inode->i_private;
2945         file->private_data = debug;
2946
2947         rc = 0;
2948 out:
2949         return rc;
2950 }
2951
2952 static ssize_t
2953 lpfc_debugfs_cpucheck_write(struct file *file, const char __user *buf,
2954                             size_t nbytes, loff_t *ppos)
2955 {
2956         struct lpfc_debug *debug = file->private_data;
2957         struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
2958         struct lpfc_hba   *phba = vport->phba;
2959         struct lpfc_sli4_hdw_queue *qp;
2960         char mybuf[64];
2961         char *pbuf;
2962         int i, j;
2963
2964         if (nbytes > 64)
2965                 nbytes = 64;
2966
2967         memset(mybuf, 0, sizeof(mybuf));
2968
2969         if (copy_from_user(mybuf, buf, nbytes))
2970                 return -EFAULT;
2971         pbuf = &mybuf[0];
2972
2973         if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
2974                 if (phba->nvmet_support)
2975                         phba->cpucheck_on |= LPFC_CHECK_NVMET_IO;
2976                 else
2977                         phba->cpucheck_on |= (LPFC_CHECK_NVME_IO |
2978                                 LPFC_CHECK_SCSI_IO);
2979                 return strlen(pbuf);
2980         } else if ((strncmp(pbuf, "nvme_on", sizeof("nvme_on") - 1) == 0)) {
2981                 if (phba->nvmet_support)
2982                         phba->cpucheck_on |= LPFC_CHECK_NVMET_IO;
2983                 else
2984                         phba->cpucheck_on |= LPFC_CHECK_NVME_IO;
2985                 return strlen(pbuf);
2986         } else if ((strncmp(pbuf, "scsi_on", sizeof("scsi_on") - 1) == 0)) {
2987                 phba->cpucheck_on |= LPFC_CHECK_SCSI_IO;
2988                 return strlen(pbuf);
2989         } else if ((strncmp(pbuf, "rcv",
2990                    sizeof("rcv") - 1) == 0)) {
2991                 if (phba->nvmet_support)
2992                         phba->cpucheck_on |= LPFC_CHECK_NVMET_RCV;
2993                 else
2994                         return -EINVAL;
2995                 return strlen(pbuf);
2996         } else if ((strncmp(pbuf, "off",
2997                    sizeof("off") - 1) == 0)) {
2998                 phba->cpucheck_on = LPFC_CHECK_OFF;
2999                 return strlen(pbuf);
3000         } else if ((strncmp(pbuf, "zero",
3001                    sizeof("zero") - 1) == 0)) {
3002                 for (i = 0; i < phba->cfg_hdw_queue; i++) {
3003                         qp = &phba->sli4_hba.hdwq[i];
3004
3005                         for (j = 0; j < LPFC_CHECK_CPU_CNT; j++) {
3006                                 qp->cpucheck_rcv_io[j] = 0;
3007                                 qp->cpucheck_xmt_io[j] = 0;
3008                                 qp->cpucheck_cmpl_io[j] = 0;
3009                         }
3010                 }
3011                 return strlen(pbuf);
3012         }
3013         return -EINVAL;
3014 }
3015
3016 /*
3017  * ---------------------------------
3018  * iDiag debugfs file access methods
3019  * ---------------------------------
3020  *
3021  * All access methods are through the proper SLI4 PCI function's debugfs
3022  * iDiag directory:
3023  *
3024  *     /sys/kernel/debug/lpfc/fn<#>/iDiag
3025  */
3026
3027 /**
3028  * lpfc_idiag_cmd_get - Get and parse idiag debugfs comands from user space
3029  * @buf: The pointer to the user space buffer.
3030  * @nbytes: The number of bytes in the user space buffer.
3031  * @idiag_cmd: pointer to the idiag command struct.
3032  *
3033  * This routine reads data from debugfs user space buffer and parses the
3034  * buffer for getting the idiag command and arguments. The while space in
3035  * between the set of data is used as the parsing separator.
3036  *
3037  * This routine returns 0 when successful, it returns proper error code
3038  * back to the user space in error conditions.
3039  */
3040 static int lpfc_idiag_cmd_get(const char __user *buf, size_t nbytes,
3041                               struct lpfc_idiag_cmd *idiag_cmd)
3042 {
3043         char mybuf[64];
3044         char *pbuf, *step_str;
3045         int i;
3046         size_t bsize;
3047
3048         memset(mybuf, 0, sizeof(mybuf));
3049         memset(idiag_cmd, 0, sizeof(*idiag_cmd));
3050         bsize = min(nbytes, (sizeof(mybuf)-1));
3051
3052         if (copy_from_user(mybuf, buf, bsize))
3053                 return -EFAULT;
3054         pbuf = &mybuf[0];
3055         step_str = strsep(&pbuf, "\t ");
3056
3057         /* The opcode must present */
3058         if (!step_str)
3059                 return -EINVAL;
3060
3061         idiag_cmd->opcode = simple_strtol(step_str, NULL, 0);
3062         if (idiag_cmd->opcode == 0)
3063                 return -EINVAL;
3064
3065         for (i = 0; i < LPFC_IDIAG_CMD_DATA_SIZE; i++) {
3066                 step_str = strsep(&pbuf, "\t ");
3067                 if (!step_str)
3068                         return i;
3069                 idiag_cmd->data[i] = simple_strtol(step_str, NULL, 0);
3070         }
3071         return i;
3072 }
3073
3074 /**
3075  * lpfc_idiag_open - idiag open debugfs
3076  * @inode: The inode pointer that contains a pointer to phba.
3077  * @file: The file pointer to attach the file operation.
3078  *
3079  * Description:
3080  * This routine is the entry point for the debugfs open file operation. It
3081  * gets the reference to phba from the i_private field in @inode, it then
3082  * allocates buffer for the file operation, performs the necessary PCI config
3083  * space read into the allocated buffer according to the idiag user command
3084  * setup, and then returns a pointer to buffer in the private_data field in
3085  * @file.
3086  *
3087  * Returns:
3088  * This function returns zero if successful. On error it will return an
3089  * negative error value.
3090  **/
3091 static int
3092 lpfc_idiag_open(struct inode *inode, struct file *file)
3093 {
3094         struct lpfc_debug *debug;
3095
3096         debug = kmalloc(sizeof(*debug), GFP_KERNEL);
3097         if (!debug)
3098                 return -ENOMEM;
3099
3100         debug->i_private = inode->i_private;
3101         debug->buffer = NULL;
3102         file->private_data = debug;
3103
3104         return 0;
3105 }
3106
3107 /**
3108  * lpfc_idiag_release - Release idiag access file operation
3109  * @inode: The inode pointer that contains a vport pointer. (unused)
3110  * @file: The file pointer that contains the buffer to release.
3111  *
3112  * Description:
3113  * This routine is the generic release routine for the idiag access file
3114  * operation, it frees the buffer that was allocated when the debugfs file
3115  * was opened.
3116  *
3117  * Returns:
3118  * This function returns zero.
3119  **/
3120 static int
3121 lpfc_idiag_release(struct inode *inode, struct file *file)
3122 {
3123         struct lpfc_debug *debug = file->private_data;
3124
3125         /* Free the buffers to the file operation */
3126         kfree(debug->buffer);
3127         kfree(debug);
3128
3129         return 0;
3130 }
3131
3132 /**
3133  * lpfc_idiag_cmd_release - Release idiag cmd access file operation
3134  * @inode: The inode pointer that contains a vport pointer. (unused)
3135  * @file: The file pointer that contains the buffer to release.
3136  *
3137  * Description:
3138  * This routine frees the buffer that was allocated when the debugfs file
3139  * was opened. It also reset the fields in the idiag command struct in the
3140  * case of command for write operation.
3141  *
3142  * Returns:
3143  * This function returns zero.
3144  **/
3145 static int
3146 lpfc_idiag_cmd_release(struct inode *inode, struct file *file)
3147 {
3148         struct lpfc_debug *debug = file->private_data;
3149
3150         if (debug->op == LPFC_IDIAG_OP_WR) {
3151                 switch (idiag.cmd.opcode) {
3152                 case LPFC_IDIAG_CMD_PCICFG_WR:
3153                 case LPFC_IDIAG_CMD_PCICFG_ST:
3154                 case LPFC_IDIAG_CMD_PCICFG_CL:
3155                 case LPFC_IDIAG_CMD_QUEACC_WR:
3156                 case LPFC_IDIAG_CMD_QUEACC_ST:
3157                 case LPFC_IDIAG_CMD_QUEACC_CL:
3158                         memset(&idiag, 0, sizeof(idiag));
3159                         break;
3160                 default:
3161                         break;
3162                 }
3163         }
3164
3165         /* Free the buffers to the file operation */
3166         kfree(debug->buffer);
3167         kfree(debug);
3168
3169         return 0;
3170 }
3171
3172 /**
3173  * lpfc_idiag_pcicfg_read - idiag debugfs read pcicfg
3174  * @file: The file pointer to read from.
3175  * @buf: The buffer to copy the data to.
3176  * @nbytes: The number of bytes to read.
3177  * @ppos: The position in the file to start reading from.
3178  *
3179  * Description:
3180  * This routine reads data from the @phba pci config space according to the
3181  * idiag command, and copies to user @buf. Depending on the PCI config space
3182  * read command setup, it does either a single register read of a byte
3183  * (8 bits), a word (16 bits), or a dword (32 bits) or browsing through all
3184  * registers from the 4K extended PCI config space.
3185  *
3186  * Returns:
3187  * This function returns the amount of data that was read (this could be less
3188  * than @nbytes if the end of the file was reached) or a negative error value.
3189  **/
3190 static ssize_t
3191 lpfc_idiag_pcicfg_read(struct file *file, char __user *buf, size_t nbytes,
3192                        loff_t *ppos)
3193 {
3194         struct lpfc_debug *debug = file->private_data;
3195         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3196         int offset_label, offset, len = 0, index = LPFC_PCI_CFG_RD_SIZE;
3197         int where, count;
3198         char *pbuffer;
3199         struct pci_dev *pdev;
3200         uint32_t u32val;
3201         uint16_t u16val;
3202         uint8_t u8val;
3203
3204         pdev = phba->pcidev;
3205         if (!pdev)
3206                 return 0;
3207
3208         /* This is a user read operation */
3209         debug->op = LPFC_IDIAG_OP_RD;
3210
3211         if (!debug->buffer)
3212                 debug->buffer = kmalloc(LPFC_PCI_CFG_SIZE, GFP_KERNEL);
3213         if (!debug->buffer)
3214                 return 0;
3215         pbuffer = debug->buffer;
3216
3217         if (*ppos)
3218                 return 0;
3219
3220         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
3221                 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
3222                 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
3223         } else
3224                 return 0;
3225
3226         /* Read single PCI config space register */
3227         switch (count) {
3228         case SIZE_U8: /* byte (8 bits) */
3229                 pci_read_config_byte(pdev, where, &u8val);
3230                 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3231                                 "%03x: %02x\n", where, u8val);
3232                 break;
3233         case SIZE_U16: /* word (16 bits) */
3234                 pci_read_config_word(pdev, where, &u16val);
3235                 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3236                                 "%03x: %04x\n", where, u16val);
3237                 break;
3238         case SIZE_U32: /* double word (32 bits) */
3239                 pci_read_config_dword(pdev, where, &u32val);
3240                 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3241                                 "%03x: %08x\n", where, u32val);
3242                 break;
3243         case LPFC_PCI_CFG_BROWSE: /* browse all */
3244                 goto pcicfg_browse;
3245                 break;
3246         default:
3247                 /* illegal count */
3248                 len = 0;
3249                 break;
3250         }
3251         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3252
3253 pcicfg_browse:
3254
3255         /* Browse all PCI config space registers */
3256         offset_label = idiag.offset.last_rd;
3257         offset = offset_label;
3258
3259         /* Read PCI config space */
3260         len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3261                         "%03x: ", offset_label);
3262         while (index > 0) {
3263                 pci_read_config_dword(pdev, offset, &u32val);
3264                 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3265                                 "%08x ", u32val);
3266                 offset += sizeof(uint32_t);
3267                 if (offset >= LPFC_PCI_CFG_SIZE) {
3268                         len += scnprintf(pbuffer+len,
3269                                         LPFC_PCI_CFG_SIZE-len, "\n");
3270                         break;
3271                 }
3272                 index -= sizeof(uint32_t);
3273                 if (!index)
3274                         len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3275                                         "\n");
3276                 else if (!(index % (8 * sizeof(uint32_t)))) {
3277                         offset_label += (8 * sizeof(uint32_t));
3278                         len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3279                                         "\n%03x: ", offset_label);
3280                 }
3281         }
3282
3283         /* Set up the offset for next portion of pci cfg read */
3284         if (index == 0) {
3285                 idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE;
3286                 if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE)
3287                         idiag.offset.last_rd = 0;
3288         } else
3289                 idiag.offset.last_rd = 0;
3290
3291         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3292 }
3293
3294 /**
3295  * lpfc_idiag_pcicfg_write - Syntax check and set up idiag pcicfg commands
3296  * @file: The file pointer to read from.
3297  * @buf: The buffer to copy the user data from.
3298  * @nbytes: The number of bytes to get.
3299  * @ppos: The position in the file to start reading from.
3300  *
3301  * This routine get the debugfs idiag command struct from user space and
3302  * then perform the syntax check for PCI config space read or write command
3303  * accordingly. In the case of PCI config space read command, it sets up
3304  * the command in the idiag command struct for the debugfs read operation.
3305  * In the case of PCI config space write operation, it executes the write
3306  * operation into the PCI config space accordingly.
3307  *
3308  * It returns the @nbytges passing in from debugfs user space when successful.
3309  * In case of error conditions, it returns proper error code back to the user
3310  * space.
3311  */
3312 static ssize_t
3313 lpfc_idiag_pcicfg_write(struct file *file, const char __user *buf,
3314                         size_t nbytes, loff_t *ppos)
3315 {
3316         struct lpfc_debug *debug = file->private_data;
3317         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3318         uint32_t where, value, count;
3319         uint32_t u32val;
3320         uint16_t u16val;
3321         uint8_t u8val;
3322         struct pci_dev *pdev;
3323         int rc;
3324
3325         pdev = phba->pcidev;
3326         if (!pdev)
3327                 return -EFAULT;
3328
3329         /* This is a user write operation */
3330         debug->op = LPFC_IDIAG_OP_WR;
3331
3332         rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3333         if (rc < 0)
3334                 return rc;
3335
3336         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
3337                 /* Sanity check on PCI config read command line arguments */
3338                 if (rc != LPFC_PCI_CFG_RD_CMD_ARG)
3339                         goto error_out;
3340                 /* Read command from PCI config space, set up command fields */
3341                 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
3342                 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
3343                 if (count == LPFC_PCI_CFG_BROWSE) {
3344                         if (where % sizeof(uint32_t))
3345                                 goto error_out;
3346                         /* Starting offset to browse */
3347                         idiag.offset.last_rd = where;
3348                 } else if ((count != sizeof(uint8_t)) &&
3349                            (count != sizeof(uint16_t)) &&
3350                            (count != sizeof(uint32_t)))
3351                         goto error_out;
3352                 if (count == sizeof(uint8_t)) {
3353                         if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
3354                                 goto error_out;
3355                         if (where % sizeof(uint8_t))
3356                                 goto error_out;
3357                 }
3358                 if (count == sizeof(uint16_t)) {
3359                         if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
3360                                 goto error_out;
3361                         if (where % sizeof(uint16_t))
3362                                 goto error_out;
3363                 }
3364                 if (count == sizeof(uint32_t)) {
3365                         if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
3366                                 goto error_out;
3367                         if (where % sizeof(uint32_t))
3368                                 goto error_out;
3369                 }
3370         } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR ||
3371                    idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST ||
3372                    idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3373                 /* Sanity check on PCI config write command line arguments */
3374                 if (rc != LPFC_PCI_CFG_WR_CMD_ARG)
3375                         goto error_out;
3376                 /* Write command to PCI config space, read-modify-write */
3377                 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
3378                 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
3379                 value = idiag.cmd.data[IDIAG_PCICFG_VALUE_INDX];
3380                 /* Sanity checks */
3381                 if ((count != sizeof(uint8_t)) &&
3382                     (count != sizeof(uint16_t)) &&
3383                     (count != sizeof(uint32_t)))
3384                         goto error_out;
3385                 if (count == sizeof(uint8_t)) {
3386                         if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
3387                                 goto error_out;
3388                         if (where % sizeof(uint8_t))
3389                                 goto error_out;
3390                         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
3391                                 pci_write_config_byte(pdev, where,
3392                                                       (uint8_t)value);
3393                         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
3394                                 rc = pci_read_config_byte(pdev, where, &u8val);
3395                                 if (!rc) {
3396                                         u8val |= (uint8_t)value;
3397                                         pci_write_config_byte(pdev, where,
3398                                                               u8val);
3399                                 }
3400                         }
3401                         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3402                                 rc = pci_read_config_byte(pdev, where, &u8val);
3403                                 if (!rc) {
3404                                         u8val &= (uint8_t)(~value);
3405                                         pci_write_config_byte(pdev, where,
3406                                                               u8val);
3407                                 }
3408                         }
3409                 }
3410                 if (count == sizeof(uint16_t)) {
3411                         if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
3412                                 goto error_out;
3413                         if (where % sizeof(uint16_t))
3414                                 goto error_out;
3415                         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
3416                                 pci_write_config_word(pdev, where,
3417                                                       (uint16_t)value);
3418                         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
3419                                 rc = pci_read_config_word(pdev, where, &u16val);
3420                                 if (!rc) {
3421                                         u16val |= (uint16_t)value;
3422                                         pci_write_config_word(pdev, where,
3423                                                               u16val);
3424                                 }
3425                         }
3426                         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3427                                 rc = pci_read_config_word(pdev, where, &u16val);
3428                                 if (!rc) {
3429                                         u16val &= (uint16_t)(~value);
3430                                         pci_write_config_word(pdev, where,
3431                                                               u16val);
3432                                 }
3433                         }
3434                 }
3435                 if (count == sizeof(uint32_t)) {
3436                         if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
3437                                 goto error_out;
3438                         if (where % sizeof(uint32_t))
3439                                 goto error_out;
3440                         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
3441                                 pci_write_config_dword(pdev, where, value);
3442                         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
3443                                 rc = pci_read_config_dword(pdev, where,
3444                                                            &u32val);
3445                                 if (!rc) {
3446                                         u32val |= value;
3447                                         pci_write_config_dword(pdev, where,
3448                                                                u32val);
3449                                 }
3450                         }
3451                         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3452                                 rc = pci_read_config_dword(pdev, where,
3453                                                            &u32val);
3454                                 if (!rc) {
3455                                         u32val &= ~value;
3456                                         pci_write_config_dword(pdev, where,
3457                                                                u32val);
3458                                 }
3459                         }
3460                 }
3461         } else
3462                 /* All other opecodes are illegal for now */
3463                 goto error_out;
3464
3465         return nbytes;
3466 error_out:
3467         memset(&idiag, 0, sizeof(idiag));
3468         return -EINVAL;
3469 }
3470
3471 /**
3472  * lpfc_idiag_baracc_read - idiag debugfs pci bar access read
3473  * @file: The file pointer to read from.
3474  * @buf: The buffer to copy the data to.
3475  * @nbytes: The number of bytes to read.
3476  * @ppos: The position in the file to start reading from.
3477  *
3478  * Description:
3479  * This routine reads data from the @phba pci bar memory mapped space
3480  * according to the idiag command, and copies to user @buf.
3481  *
3482  * Returns:
3483  * This function returns the amount of data that was read (this could be less
3484  * than @nbytes if the end of the file was reached) or a negative error value.
3485  **/
3486 static ssize_t
3487 lpfc_idiag_baracc_read(struct file *file, char __user *buf, size_t nbytes,
3488                        loff_t *ppos)
3489 {
3490         struct lpfc_debug *debug = file->private_data;
3491         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3492         int offset_label, offset, offset_run, len = 0, index;
3493         int bar_num, acc_range, bar_size;
3494         char *pbuffer;
3495         void __iomem *mem_mapped_bar;
3496         uint32_t if_type;
3497         struct pci_dev *pdev;
3498         uint32_t u32val;
3499
3500         pdev = phba->pcidev;
3501         if (!pdev)
3502                 return 0;
3503
3504         /* This is a user read operation */
3505         debug->op = LPFC_IDIAG_OP_RD;
3506
3507         if (!debug->buffer)
3508                 debug->buffer = kmalloc(LPFC_PCI_BAR_RD_BUF_SIZE, GFP_KERNEL);
3509         if (!debug->buffer)
3510                 return 0;
3511         pbuffer = debug->buffer;
3512
3513         if (*ppos)
3514                 return 0;
3515
3516         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
3517                 bar_num   = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
3518                 offset    = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
3519                 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
3520                 bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
3521         } else
3522                 return 0;
3523
3524         if (acc_range == 0)
3525                 return 0;
3526
3527         if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
3528         if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
3529                 if (bar_num == IDIAG_BARACC_BAR_0)
3530                         mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3531                 else if (bar_num == IDIAG_BARACC_BAR_1)
3532                         mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
3533                 else if (bar_num == IDIAG_BARACC_BAR_2)
3534                         mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
3535                 else
3536                         return 0;
3537         } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
3538                 if (bar_num == IDIAG_BARACC_BAR_0)
3539                         mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3540                 else
3541                         return 0;
3542         } else
3543                 return 0;
3544
3545         /* Read single PCI bar space register */
3546         if (acc_range == SINGLE_WORD) {
3547                 offset_run = offset;
3548                 u32val = readl(mem_mapped_bar + offset_run);
3549                 len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
3550                                 "%05x: %08x\n", offset_run, u32val);
3551         } else
3552                 goto baracc_browse;
3553
3554         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3555
3556 baracc_browse:
3557
3558         /* Browse all PCI bar space registers */
3559         offset_label = idiag.offset.last_rd;
3560         offset_run = offset_label;
3561
3562         /* Read PCI bar memory mapped space */
3563         len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
3564                         "%05x: ", offset_label);
3565         index = LPFC_PCI_BAR_RD_SIZE;
3566         while (index > 0) {
3567                 u32val = readl(mem_mapped_bar + offset_run);
3568                 len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
3569                                 "%08x ", u32val);
3570                 offset_run += sizeof(uint32_t);
3571                 if (acc_range == LPFC_PCI_BAR_BROWSE) {
3572                         if (offset_run >= bar_size) {
3573                                 len += scnprintf(pbuffer+len,
3574                                         LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
3575                                 break;
3576                         }
3577                 } else {
3578                         if (offset_run >= offset +
3579                             (acc_range * sizeof(uint32_t))) {
3580                                 len += scnprintf(pbuffer+len,
3581                                         LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
3582                                 break;
3583                         }
3584                 }
3585                 index -= sizeof(uint32_t);
3586                 if (!index)
3587                         len += scnprintf(pbuffer+len,
3588                                         LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
3589                 else if (!(index % (8 * sizeof(uint32_t)))) {
3590                         offset_label += (8 * sizeof(uint32_t));
3591                         len += scnprintf(pbuffer+len,
3592                                         LPFC_PCI_BAR_RD_BUF_SIZE-len,
3593                                         "\n%05x: ", offset_label);
3594                 }
3595         }
3596
3597         /* Set up the offset for next portion of pci bar read */
3598         if (index == 0) {
3599                 idiag.offset.last_rd += LPFC_PCI_BAR_RD_SIZE;
3600                 if (acc_range == LPFC_PCI_BAR_BROWSE) {
3601                         if (idiag.offset.last_rd >= bar_size)
3602                                 idiag.offset.last_rd = 0;
3603                 } else {
3604                         if (offset_run >= offset +
3605                             (acc_range * sizeof(uint32_t)))
3606                                 idiag.offset.last_rd = offset;
3607                 }
3608         } else {
3609                 if (acc_range == LPFC_PCI_BAR_BROWSE)
3610                         idiag.offset.last_rd = 0;
3611                 else
3612                         idiag.offset.last_rd = offset;
3613         }
3614
3615         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3616 }
3617
3618 /**
3619  * lpfc_idiag_baracc_write - Syntax check and set up idiag bar access commands
3620  * @file: The file pointer to read from.
3621  * @buf: The buffer to copy the user data from.
3622  * @nbytes: The number of bytes to get.
3623  * @ppos: The position in the file to start reading from.
3624  *
3625  * This routine get the debugfs idiag command struct from user space and
3626  * then perform the syntax check for PCI bar memory mapped space read or
3627  * write command accordingly. In the case of PCI bar memory mapped space
3628  * read command, it sets up the command in the idiag command struct for
3629  * the debugfs read operation. In the case of PCI bar memorpy mapped space
3630  * write operation, it executes the write operation into the PCI bar memory
3631  * mapped space accordingly.
3632  *
3633  * It returns the @nbytges passing in from debugfs user space when successful.
3634  * In case of error conditions, it returns proper error code back to the user
3635  * space.
3636  */
3637 static ssize_t
3638 lpfc_idiag_baracc_write(struct file *file, const char __user *buf,
3639                         size_t nbytes, loff_t *ppos)
3640 {
3641         struct lpfc_debug *debug = file->private_data;
3642         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3643         uint32_t bar_num, bar_size, offset, value, acc_range;
3644         struct pci_dev *pdev;
3645         void __iomem *mem_mapped_bar;
3646         uint32_t if_type;
3647         uint32_t u32val;
3648         int rc;
3649
3650         pdev = phba->pcidev;
3651         if (!pdev)
3652                 return -EFAULT;
3653
3654         /* This is a user write operation */
3655         debug->op = LPFC_IDIAG_OP_WR;
3656
3657         rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3658         if (rc < 0)
3659                 return rc;
3660
3661         if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
3662         bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
3663
3664         if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
3665                 if ((bar_num != IDIAG_BARACC_BAR_0) &&
3666                     (bar_num != IDIAG_BARACC_BAR_1) &&
3667                     (bar_num != IDIAG_BARACC_BAR_2))
3668                         goto error_out;
3669         } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
3670                 if (bar_num != IDIAG_BARACC_BAR_0)
3671                         goto error_out;
3672         } else
3673                 goto error_out;
3674
3675         if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
3676                 if (bar_num == IDIAG_BARACC_BAR_0) {
3677                         idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3678                                 LPFC_PCI_IF0_BAR0_SIZE;
3679                         mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3680                 } else if (bar_num == IDIAG_BARACC_BAR_1) {
3681                         idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3682                                 LPFC_PCI_IF0_BAR1_SIZE;
3683                         mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
3684                 } else if (bar_num == IDIAG_BARACC_BAR_2) {
3685                         idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3686                                 LPFC_PCI_IF0_BAR2_SIZE;
3687                         mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
3688                 } else
3689                         goto error_out;
3690         } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
3691                 if (bar_num == IDIAG_BARACC_BAR_0) {
3692                         idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3693                                 LPFC_PCI_IF2_BAR0_SIZE;
3694                         mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3695                 } else
3696                         goto error_out;
3697         } else
3698                 goto error_out;
3699
3700         offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
3701         if (offset % sizeof(uint32_t))
3702                 goto error_out;
3703
3704         bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
3705         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
3706                 /* Sanity check on PCI config read command line arguments */
3707                 if (rc != LPFC_PCI_BAR_RD_CMD_ARG)
3708                         goto error_out;
3709                 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
3710                 if (acc_range == LPFC_PCI_BAR_BROWSE) {
3711                         if (offset > bar_size - sizeof(uint32_t))
3712                                 goto error_out;
3713                         /* Starting offset to browse */
3714                         idiag.offset.last_rd = offset;
3715                 } else if (acc_range > SINGLE_WORD) {
3716                         if (offset + acc_range * sizeof(uint32_t) > bar_size)
3717                                 goto error_out;
3718                         /* Starting offset to browse */
3719                         idiag.offset.last_rd = offset;
3720                 } else if (acc_range != SINGLE_WORD)
3721                         goto error_out;
3722         } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR ||
3723                    idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST ||
3724                    idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
3725                 /* Sanity check on PCI bar write command line arguments */
3726                 if (rc != LPFC_PCI_BAR_WR_CMD_ARG)
3727                         goto error_out;
3728                 /* Write command to PCI bar space, read-modify-write */
3729                 acc_range = SINGLE_WORD;
3730                 value = idiag.cmd.data[IDIAG_BARACC_REG_VAL_INDX];
3731                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR) {
3732                         writel(value, mem_mapped_bar + offset);
3733                         readl(mem_mapped_bar + offset);
3734                 }
3735                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST) {
3736                         u32val = readl(mem_mapped_bar + offset);
3737                         u32val |= value;
3738                         writel(u32val, mem_mapped_bar + offset);
3739                         readl(mem_mapped_bar + offset);
3740                 }
3741                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
3742                         u32val = readl(mem_mapped_bar + offset);
3743                         u32val &= ~value;
3744                         writel(u32val, mem_mapped_bar + offset);
3745                         readl(mem_mapped_bar + offset);
3746                 }
3747         } else
3748                 /* All other opecodes are illegal for now */
3749                 goto error_out;
3750
3751         return nbytes;
3752 error_out:
3753         memset(&idiag, 0, sizeof(idiag));
3754         return -EINVAL;
3755 }
3756
3757 static int
3758 __lpfc_idiag_print_wq(struct lpfc_queue *qp, char *wqtype,
3759                         char *pbuffer, int len)
3760 {
3761         if (!qp)
3762                 return len;
3763
3764         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3765                         "\t\t%s WQ info: ", wqtype);
3766         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3767                         "AssocCQID[%04d]: WQ-STAT[oflow:x%x posted:x%llx]\n",
3768                         qp->assoc_qid, qp->q_cnt_1,
3769                         (unsigned long long)qp->q_cnt_4);
3770         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3771                         "\t\tWQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3772                         "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]",
3773                         qp->queue_id, qp->entry_count,
3774                         qp->entry_size, qp->host_index,
3775                         qp->hba_index, qp->notify_interval);
3776         len +=  scnprintf(pbuffer + len,
3777                         LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n");
3778         return len;
3779 }
3780
3781 static int
3782 lpfc_idiag_wqs_for_cq(struct lpfc_hba *phba, char *wqtype, char *pbuffer,
3783                 int *len, int max_cnt, int cq_id)
3784 {
3785         struct lpfc_queue *qp;
3786         int qidx;
3787
3788         for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
3789                 qp = phba->sli4_hba.hdwq[qidx].fcp_wq;
3790                 if (qp->assoc_qid != cq_id)
3791                         continue;
3792                 *len = __lpfc_idiag_print_wq(qp, wqtype, pbuffer, *len);
3793                 if (*len >= max_cnt)
3794                         return 1;
3795         }
3796         if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
3797                 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
3798                         qp = phba->sli4_hba.hdwq[qidx].nvme_wq;
3799                         if (qp->assoc_qid != cq_id)
3800                                 continue;
3801                         *len = __lpfc_idiag_print_wq(qp, wqtype, pbuffer, *len);
3802                         if (*len >= max_cnt)
3803                                 return 1;
3804                 }
3805         }
3806         return 0;
3807 }
3808
3809 static int
3810 __lpfc_idiag_print_cq(struct lpfc_queue *qp, char *cqtype,
3811                         char *pbuffer, int len)
3812 {
3813         if (!qp)
3814                 return len;
3815
3816         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3817                         "\t%s CQ info: ", cqtype);
3818         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3819                         "AssocEQID[%02d]: CQ STAT[max:x%x relw:x%x "
3820                         "xabt:x%x wq:x%llx]\n",
3821                         qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2,
3822                         qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
3823         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3824                         "\tCQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3825                         "HST-IDX[%04d], NTFI[%03d], PLMT[%03d]",
3826                         qp->queue_id, qp->entry_count,
3827                         qp->entry_size, qp->host_index,
3828                         qp->notify_interval, qp->max_proc_limit);
3829
3830         len +=  scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3831                         "\n");
3832
3833         return len;
3834 }
3835
3836 static int
3837 __lpfc_idiag_print_rqpair(struct lpfc_queue *qp, struct lpfc_queue *datqp,
3838                         char *rqtype, char *pbuffer, int len)
3839 {
3840         if (!qp || !datqp)
3841                 return len;
3842
3843         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3844                         "\t\t%s RQ info: ", rqtype);
3845         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3846                         "AssocCQID[%02d]: RQ-STAT[nopost:x%x nobuf:x%x "
3847                         "posted:x%x rcv:x%llx]\n",
3848                         qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2,
3849                         qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
3850         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3851                         "\t\tHQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3852                         "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n",
3853                         qp->queue_id, qp->entry_count, qp->entry_size,
3854                         qp->host_index, qp->hba_index, qp->notify_interval);
3855         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3856                         "\t\tDQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3857                         "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n",
3858                         datqp->queue_id, datqp->entry_count,
3859                         datqp->entry_size, datqp->host_index,
3860                         datqp->hba_index, datqp->notify_interval);
3861         return len;
3862 }
3863
3864 static int
3865 lpfc_idiag_cqs_for_eq(struct lpfc_hba *phba, char *pbuffer,
3866                 int *len, int max_cnt, int eqidx, int eq_id)
3867 {
3868         struct lpfc_queue *qp;
3869         int rc;
3870
3871         qp = phba->sli4_hba.hdwq[eqidx].fcp_cq;
3872
3873         *len = __lpfc_idiag_print_cq(qp, "FCP", pbuffer, *len);
3874
3875         /* Reset max counter */
3876         qp->CQ_max_cqe = 0;
3877
3878         if (*len >= max_cnt)
3879                 return 1;
3880
3881         rc = lpfc_idiag_wqs_for_cq(phba, "FCP", pbuffer, len,
3882                                    max_cnt, qp->queue_id);
3883         if (rc)
3884                 return 1;
3885
3886         if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
3887                 qp = phba->sli4_hba.hdwq[eqidx].nvme_cq;
3888
3889                 *len = __lpfc_idiag_print_cq(qp, "NVME", pbuffer, *len);
3890
3891                 /* Reset max counter */
3892                 qp->CQ_max_cqe = 0;
3893
3894                 if (*len >= max_cnt)
3895                         return 1;
3896
3897                 rc = lpfc_idiag_wqs_for_cq(phba, "NVME", pbuffer, len,
3898                                            max_cnt, qp->queue_id);
3899                 if (rc)
3900                         return 1;
3901         }
3902
3903         if ((eqidx < phba->cfg_nvmet_mrq) && phba->nvmet_support) {
3904                 /* NVMET CQset */
3905                 qp = phba->sli4_hba.nvmet_cqset[eqidx];
3906                 *len = __lpfc_idiag_print_cq(qp, "NVMET CQset", pbuffer, *len);
3907
3908                 /* Reset max counter */
3909                 qp->CQ_max_cqe = 0;
3910
3911                 if (*len >= max_cnt)
3912                         return 1;
3913
3914                 /* RQ header */
3915                 qp = phba->sli4_hba.nvmet_mrq_hdr[eqidx];
3916                 *len = __lpfc_idiag_print_rqpair(qp,
3917                                 phba->sli4_hba.nvmet_mrq_data[eqidx],
3918                                 "NVMET MRQ", pbuffer, *len);
3919
3920                 if (*len >= max_cnt)
3921                         return 1;
3922         }
3923
3924         return 0;
3925 }
3926
3927 static int
3928 __lpfc_idiag_print_eq(struct lpfc_queue *qp, char *eqtype,
3929                         char *pbuffer, int len)
3930 {
3931         if (!qp)
3932                 return len;
3933
3934         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3935                         "\n%s EQ info: EQ-STAT[max:x%x noE:x%x "
3936                         "cqe_proc:x%x eqe_proc:x%llx eqd %d]\n",
3937                         eqtype, qp->q_cnt_1, qp->q_cnt_2, qp->q_cnt_3,
3938                         (unsigned long long)qp->q_cnt_4, qp->q_mode);
3939         len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3940                         "EQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3941                         "HST-IDX[%04d], NTFI[%03d], PLMT[%03d], AFFIN[%03d]",
3942                         qp->queue_id, qp->entry_count, qp->entry_size,
3943                         qp->host_index, qp->notify_interval,
3944                         qp->max_proc_limit, qp->chann);
3945         len +=  scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3946                         "\n");
3947
3948         return len;
3949 }
3950
3951 /**
3952  * lpfc_idiag_queinfo_read - idiag debugfs read queue information
3953  * @file: The file pointer to read from.
3954  * @buf: The buffer to copy the data to.
3955  * @nbytes: The number of bytes to read.
3956  * @ppos: The position in the file to start reading from.
3957  *
3958  * Description:
3959  * This routine reads data from the @phba SLI4 PCI function queue information,
3960  * and copies to user @buf.
3961  * This routine only returns 1 EQs worth of information. It remembers the last
3962  * EQ read and jumps to the next EQ. Thus subsequent calls to queInfo will
3963  * retrieve all EQs allocated for the phba.
3964  *
3965  * Returns:
3966  * This function returns the amount of data that was read (this could be less
3967  * than @nbytes if the end of the file was reached) or a negative error value.
3968  **/
3969 static ssize_t
3970 lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
3971                         loff_t *ppos)
3972 {
3973         struct lpfc_debug *debug = file->private_data;
3974         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3975         char *pbuffer;
3976         int max_cnt, rc, x, len = 0;
3977         struct lpfc_queue *qp = NULL;
3978
3979         if (!debug->buffer)
3980                 debug->buffer = kmalloc(LPFC_QUE_INFO_GET_BUF_SIZE, GFP_KERNEL);
3981         if (!debug->buffer)
3982                 return 0;
3983         pbuffer = debug->buffer;
3984         max_cnt = LPFC_QUE_INFO_GET_BUF_SIZE - 256;
3985
3986         if (*ppos)
3987                 return 0;
3988
3989         spin_lock_irq(&phba->hbalock);
3990
3991         /* Fast-path event queue */
3992         if (phba->sli4_hba.hdwq && phba->cfg_hdw_queue) {
3993
3994                 x = phba->lpfc_idiag_last_eq;
3995                 phba->lpfc_idiag_last_eq++;
3996                 if (phba->lpfc_idiag_last_eq >= phba->cfg_hdw_queue)
3997                         phba->lpfc_idiag_last_eq = 0;
3998
3999                 len += scnprintf(pbuffer + len,
4000                                  LPFC_QUE_INFO_GET_BUF_SIZE - len,
4001                                  "HDWQ %d out of %d HBA HDWQs\n",
4002                                  x, phba->cfg_hdw_queue);
4003
4004                 /* Fast-path EQ */
4005                 qp = phba->sli4_hba.hdwq[x].hba_eq;
4006                 if (!qp)
4007                         goto out;
4008
4009                 len = __lpfc_idiag_print_eq(qp, "HBA", pbuffer, len);
4010
4011                 /* Reset max counter */
4012                 qp->EQ_max_eqe = 0;
4013
4014                 if (len >= max_cnt)
4015                         goto too_big;
4016
4017                 /* will dump both fcp and nvme cqs/wqs for the eq */
4018                 rc = lpfc_idiag_cqs_for_eq(phba, pbuffer, &len,
4019                         max_cnt, x, qp->queue_id);
4020                 if (rc)
4021                         goto too_big;
4022
4023                 /* Only EQ 0 has slow path CQs configured */
4024                 if (x)
4025                         goto out;
4026
4027                 /* Slow-path mailbox CQ */
4028                 qp = phba->sli4_hba.mbx_cq;
4029                 len = __lpfc_idiag_print_cq(qp, "MBX", pbuffer, len);
4030                 if (len >= max_cnt)
4031                         goto too_big;
4032
4033                 /* Slow-path MBOX MQ */
4034                 qp = phba->sli4_hba.mbx_wq;
4035                 len = __lpfc_idiag_print_wq(qp, "MBX", pbuffer, len);
4036                 if (len >= max_cnt)
4037                         goto too_big;
4038
4039                 /* Slow-path ELS response CQ */
4040                 qp = phba->sli4_hba.els_cq;
4041                 len = __lpfc_idiag_print_cq(qp, "ELS", pbuffer, len);
4042                 /* Reset max counter */
4043                 if (qp)
4044                         qp->CQ_max_cqe = 0;
4045                 if (len >= max_cnt)
4046                         goto too_big;
4047
4048                 /* Slow-path ELS WQ */
4049                 qp = phba->sli4_hba.els_wq;
4050                 len = __lpfc_idiag_print_wq(qp, "ELS", pbuffer, len);
4051                 if (len >= max_cnt)
4052                         goto too_big;
4053
4054                 qp = phba->sli4_hba.hdr_rq;
4055                 len = __lpfc_idiag_print_rqpair(qp, phba->sli4_hba.dat_rq,
4056                                                 "ELS RQpair", pbuffer, len);
4057                 if (len >= max_cnt)
4058                         goto too_big;
4059
4060                 /* Slow-path NVME LS response CQ */
4061                 qp = phba->sli4_hba.nvmels_cq;
4062                 len = __lpfc_idiag_print_cq(qp, "NVME LS",
4063                                                 pbuffer, len);
4064                 /* Reset max counter */
4065                 if (qp)
4066                         qp->CQ_max_cqe = 0;
4067                 if (len >= max_cnt)
4068                         goto too_big;
4069
4070                 /* Slow-path NVME LS WQ */
4071                 qp = phba->sli4_hba.nvmels_wq;
4072                 len = __lpfc_idiag_print_wq(qp, "NVME LS",
4073                                                 pbuffer, len);
4074                 if (len >= max_cnt)
4075                         goto too_big;
4076
4077                 goto out;
4078         }
4079
4080         spin_unlock_irq(&phba->hbalock);
4081         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4082
4083 too_big:
4084         len +=  scnprintf(pbuffer + len,
4085                 LPFC_QUE_INFO_GET_BUF_SIZE - len, "Truncated ...\n");
4086 out:
4087         spin_unlock_irq(&phba->hbalock);
4088         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4089 }
4090
4091 /**
4092  * lpfc_idiag_que_param_check - queue access command parameter sanity check
4093  * @q: The pointer to queue structure.
4094  * @index: The index into a queue entry.
4095  * @count: The number of queue entries to access.
4096  *
4097  * Description:
4098  * The routine performs sanity check on device queue access method commands.
4099  *
4100  * Returns:
4101  * This function returns -EINVAL when fails the sanity check, otherwise, it
4102  * returns 0.
4103  **/
4104 static int
4105 lpfc_idiag_que_param_check(struct lpfc_queue *q, int index, int count)
4106 {
4107         /* Only support single entry read or browsing */
4108         if ((count != 1) && (count != LPFC_QUE_ACC_BROWSE))
4109                 return -EINVAL;
4110         if (index > q->entry_count - 1)
4111                 return -EINVAL;
4112         return 0;
4113 }
4114
4115 /**
4116  * lpfc_idiag_queacc_read_qe - read a single entry from the given queue index
4117  * @pbuffer: The pointer to buffer to copy the read data into.
4118  * @pque: The pointer to the queue to be read.
4119  * @index: The index into the queue entry.
4120  *
4121  * Description:
4122  * This routine reads out a single entry from the given queue's index location
4123  * and copies it into the buffer provided.
4124  *
4125  * Returns:
4126  * This function returns 0 when it fails, otherwise, it returns the length of
4127  * the data read into the buffer provided.
4128  **/
4129 static int
4130 lpfc_idiag_queacc_read_qe(char *pbuffer, int len, struct lpfc_queue *pque,
4131                           uint32_t index)
4132 {
4133         int offset, esize;
4134         uint32_t *pentry;
4135
4136         if (!pbuffer || !pque)
4137                 return 0;
4138
4139         esize = pque->entry_size;
4140         len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
4141                         "QE-INDEX[%04d]:\n", index);
4142
4143         offset = 0;
4144         pentry = lpfc_sli4_qe(pque, index);
4145         while (esize > 0) {
4146                 len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
4147                                 "%08x ", *pentry);
4148                 pentry++;
4149                 offset += sizeof(uint32_t);
4150                 esize -= sizeof(uint32_t);
4151                 if (esize > 0 && !(offset % (4 * sizeof(uint32_t))))
4152                         len += scnprintf(pbuffer+len,
4153                                         LPFC_QUE_ACC_BUF_SIZE-len, "\n");
4154         }
4155         len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, "\n");
4156
4157         return len;
4158 }
4159
4160 /**
4161  * lpfc_idiag_queacc_read - idiag debugfs read port queue
4162  * @file: The file pointer to read from.
4163  * @buf: The buffer to copy the data to.
4164  * @nbytes: The number of bytes to read.
4165  * @ppos: The position in the file to start reading from.
4166  *
4167  * Description:
4168  * This routine reads data from the @phba device queue memory according to the
4169  * idiag command, and copies to user @buf. Depending on the queue dump read
4170  * command setup, it does either a single queue entry read or browing through
4171  * all entries of the queue.
4172  *
4173  * Returns:
4174  * This function returns the amount of data that was read (this could be less
4175  * than @nbytes if the end of the file was reached) or a negative error value.
4176  **/
4177 static ssize_t
4178 lpfc_idiag_queacc_read(struct file *file, char __user *buf, size_t nbytes,
4179                        loff_t *ppos)
4180 {
4181         struct lpfc_debug *debug = file->private_data;
4182         uint32_t last_index, index, count;
4183         struct lpfc_queue *pque = NULL;
4184         char *pbuffer;
4185         int len = 0;
4186
4187         /* This is a user read operation */
4188         debug->op = LPFC_IDIAG_OP_RD;
4189
4190         if (!debug->buffer)
4191                 debug->buffer = kmalloc(LPFC_QUE_ACC_BUF_SIZE, GFP_KERNEL);
4192         if (!debug->buffer)
4193                 return 0;
4194         pbuffer = debug->buffer;
4195
4196         if (*ppos)
4197                 return 0;
4198
4199         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
4200                 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
4201                 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
4202                 pque = (struct lpfc_queue *)idiag.ptr_private;
4203         } else
4204                 return 0;
4205
4206         /* Browse the queue starting from index */
4207         if (count == LPFC_QUE_ACC_BROWSE)
4208                 goto que_browse;
4209
4210         /* Read a single entry from the queue */
4211         len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
4212
4213         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4214
4215 que_browse:
4216
4217         /* Browse all entries from the queue */
4218         last_index = idiag.offset.last_rd;
4219         index = last_index;
4220
4221         while (len < LPFC_QUE_ACC_SIZE - pque->entry_size) {
4222                 len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
4223                 index++;
4224                 if (index > pque->entry_count - 1)
4225                         break;
4226         }
4227
4228         /* Set up the offset for next portion of pci cfg read */
4229         if (index > pque->entry_count - 1)
4230                 index = 0;
4231         idiag.offset.last_rd = index;
4232
4233         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4234 }
4235
4236 /**
4237  * lpfc_idiag_queacc_write - Syntax check and set up idiag queacc commands
4238  * @file: The file pointer to read from.
4239  * @buf: The buffer to copy the user data from.
4240  * @nbytes: The number of bytes to get.
4241  * @ppos: The position in the file to start reading from.
4242  *
4243  * This routine get the debugfs idiag command struct from user space and then
4244  * perform the syntax check for port queue read (dump) or write (set) command
4245  * accordingly. In the case of port queue read command, it sets up the command
4246  * in the idiag command struct for the following debugfs read operation. In
4247  * the case of port queue write operation, it executes the write operation
4248  * into the port queue entry accordingly.
4249  *
4250  * It returns the @nbytges passing in from debugfs user space when successful.
4251  * In case of error conditions, it returns proper error code back to the user
4252  * space.
4253  **/
4254 static ssize_t
4255 lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
4256                         size_t nbytes, loff_t *ppos)
4257 {
4258         struct lpfc_debug *debug = file->private_data;
4259         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4260         uint32_t qidx, quetp, queid, index, count, offset, value;
4261         uint32_t *pentry;
4262         struct lpfc_queue *pque, *qp;
4263         int rc;
4264
4265         /* This is a user write operation */
4266         debug->op = LPFC_IDIAG_OP_WR;
4267
4268         rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
4269         if (rc < 0)
4270                 return rc;
4271
4272         /* Get and sanity check on command feilds */
4273         quetp  = idiag.cmd.data[IDIAG_QUEACC_QUETP_INDX];
4274         queid  = idiag.cmd.data[IDIAG_QUEACC_QUEID_INDX];
4275         index  = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
4276         count  = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
4277         offset = idiag.cmd.data[IDIAG_QUEACC_OFFST_INDX];
4278         value  = idiag.cmd.data[IDIAG_QUEACC_VALUE_INDX];
4279
4280         /* Sanity check on command line arguments */
4281         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
4282             idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
4283             idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
4284                 if (rc != LPFC_QUE_ACC_WR_CMD_ARG)
4285                         goto error_out;
4286                 if (count != 1)
4287                         goto error_out;
4288         } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
4289                 if (rc != LPFC_QUE_ACC_RD_CMD_ARG)
4290                         goto error_out;
4291         } else
4292                 goto error_out;
4293
4294         switch (quetp) {
4295         case LPFC_IDIAG_EQ:
4296                 /* HBA event queue */
4297                 if (phba->sli4_hba.hdwq) {
4298                         for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
4299                                 qp = phba->sli4_hba.hdwq[qidx].hba_eq;
4300                                 if (qp && qp->queue_id == queid) {
4301                                         /* Sanity check */
4302                                         rc = lpfc_idiag_que_param_check(qp,
4303                                                 index, count);
4304                                         if (rc)
4305                                                 goto error_out;
4306                                         idiag.ptr_private = qp;
4307                                         goto pass_check;
4308                                 }
4309                         }
4310                 }
4311                 goto error_out;
4312                 break;
4313         case LPFC_IDIAG_CQ:
4314                 /* MBX complete queue */
4315                 if (phba->sli4_hba.mbx_cq &&
4316                     phba->sli4_hba.mbx_cq->queue_id == queid) {
4317                         /* Sanity check */
4318                         rc = lpfc_idiag_que_param_check(
4319                                         phba->sli4_hba.mbx_cq, index, count);
4320                         if (rc)
4321                                 goto error_out;
4322                         idiag.ptr_private = phba->sli4_hba.mbx_cq;
4323                         goto pass_check;
4324                 }
4325                 /* ELS complete queue */
4326                 if (phba->sli4_hba.els_cq &&
4327                     phba->sli4_hba.els_cq->queue_id == queid) {
4328                         /* Sanity check */
4329                         rc = lpfc_idiag_que_param_check(
4330                                         phba->sli4_hba.els_cq, index, count);
4331                         if (rc)
4332                                 goto error_out;
4333                         idiag.ptr_private = phba->sli4_hba.els_cq;
4334                         goto pass_check;
4335                 }
4336                 /* NVME LS complete queue */
4337                 if (phba->sli4_hba.nvmels_cq &&
4338                     phba->sli4_hba.nvmels_cq->queue_id == queid) {
4339                         /* Sanity check */
4340                         rc = lpfc_idiag_que_param_check(
4341                                         phba->sli4_hba.nvmels_cq, index, count);
4342                         if (rc)
4343                                 goto error_out;
4344                         idiag.ptr_private = phba->sli4_hba.nvmels_cq;
4345                         goto pass_check;
4346                 }
4347                 /* FCP complete queue */
4348                 if (phba->sli4_hba.hdwq) {
4349                         for (qidx = 0; qidx < phba->cfg_hdw_queue;
4350                                                                 qidx++) {
4351                                 qp = phba->sli4_hba.hdwq[qidx].fcp_cq;
4352                                 if (qp && qp->queue_id == queid) {
4353                                         /* Sanity check */
4354                                         rc = lpfc_idiag_que_param_check(
4355                                                 qp, index, count);
4356                                         if (rc)
4357                                                 goto error_out;
4358                                         idiag.ptr_private = qp;
4359                                         goto pass_check;
4360                                 }
4361                         }
4362                 }
4363                 /* NVME complete queue */
4364                 if (phba->sli4_hba.hdwq) {
4365                         qidx = 0;
4366                         do {
4367                                 qp = phba->sli4_hba.hdwq[qidx].nvme_cq;
4368                                 if (qp && qp->queue_id == queid) {
4369                                         /* Sanity check */
4370                                         rc = lpfc_idiag_que_param_check(
4371                                                 qp, index, count);
4372                                         if (rc)
4373                                                 goto error_out;
4374                                         idiag.ptr_private = qp;
4375                                         goto pass_check;
4376                                 }
4377                         } while (++qidx < phba->cfg_hdw_queue);
4378                 }
4379                 goto error_out;
4380                 break;
4381         case LPFC_IDIAG_MQ:
4382                 /* MBX work queue */
4383                 if (phba->sli4_hba.mbx_wq &&
4384                     phba->sli4_hba.mbx_wq->queue_id == queid) {
4385                         /* Sanity check */
4386                         rc = lpfc_idiag_que_param_check(
4387                                         phba->sli4_hba.mbx_wq, index, count);
4388                         if (rc)
4389                                 goto error_out;
4390                         idiag.ptr_private = phba->sli4_hba.mbx_wq;
4391                         goto pass_check;
4392                 }
4393                 goto error_out;
4394                 break;
4395         case LPFC_IDIAG_WQ:
4396                 /* ELS work queue */
4397                 if (phba->sli4_hba.els_wq &&
4398                     phba->sli4_hba.els_wq->queue_id == queid) {
4399                         /* Sanity check */
4400                         rc = lpfc_idiag_que_param_check(
4401                                         phba->sli4_hba.els_wq, index, count);
4402                         if (rc)
4403                                 goto error_out;
4404                         idiag.ptr_private = phba->sli4_hba.els_wq;
4405                         goto pass_check;
4406                 }
4407                 /* NVME LS work queue */
4408                 if (phba->sli4_hba.nvmels_wq &&
4409                     phba->sli4_hba.nvmels_wq->queue_id == queid) {
4410                         /* Sanity check */
4411                         rc = lpfc_idiag_que_param_check(
4412                                         phba->sli4_hba.nvmels_wq, index, count);
4413                         if (rc)
4414                                 goto error_out;
4415                         idiag.ptr_private = phba->sli4_hba.nvmels_wq;
4416                         goto pass_check;
4417                 }
4418
4419                 if (phba->sli4_hba.hdwq) {
4420                         /* FCP/SCSI work queue */
4421                         for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
4422                                 qp = phba->sli4_hba.hdwq[qidx].fcp_wq;
4423                                 if (qp && qp->queue_id == queid) {
4424                                         /* Sanity check */
4425                                         rc = lpfc_idiag_que_param_check(
4426                                                 qp, index, count);
4427                                         if (rc)
4428                                                 goto error_out;
4429                                         idiag.ptr_private = qp;
4430                                         goto pass_check;
4431                                 }
4432                         }
4433                         /* NVME work queue */
4434                         for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
4435                                 qp = phba->sli4_hba.hdwq[qidx].nvme_wq;
4436                                 if (qp && qp->queue_id == queid) {
4437                                         /* Sanity check */
4438                                         rc = lpfc_idiag_que_param_check(
4439                                                 qp, index, count);
4440                                         if (rc)
4441                                                 goto error_out;
4442                                         idiag.ptr_private = qp;
4443                                         goto pass_check;
4444                                 }
4445                         }
4446                 }
4447
4448                 goto error_out;
4449                 break;
4450         case LPFC_IDIAG_RQ:
4451                 /* HDR queue */
4452                 if (phba->sli4_hba.hdr_rq &&
4453                     phba->sli4_hba.hdr_rq->queue_id == queid) {
4454                         /* Sanity check */
4455                         rc = lpfc_idiag_que_param_check(
4456                                         phba->sli4_hba.hdr_rq, index, count);
4457                         if (rc)
4458                                 goto error_out;
4459                         idiag.ptr_private = phba->sli4_hba.hdr_rq;
4460                         goto pass_check;
4461                 }
4462                 /* DAT queue */
4463                 if (phba->sli4_hba.dat_rq &&
4464                     phba->sli4_hba.dat_rq->queue_id == queid) {
4465                         /* Sanity check */
4466                         rc = lpfc_idiag_que_param_check(
4467                                         phba->sli4_hba.dat_rq, index, count);
4468                         if (rc)
4469                                 goto error_out;
4470                         idiag.ptr_private = phba->sli4_hba.dat_rq;
4471                         goto pass_check;
4472                 }
4473                 goto error_out;
4474                 break;
4475         default:
4476                 goto error_out;
4477                 break;
4478         }
4479
4480 pass_check:
4481
4482         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
4483                 if (count == LPFC_QUE_ACC_BROWSE)
4484                         idiag.offset.last_rd = index;
4485         }
4486
4487         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
4488             idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
4489             idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
4490                 /* Additional sanity checks on write operation */
4491                 pque = (struct lpfc_queue *)idiag.ptr_private;
4492                 if (offset > pque->entry_size/sizeof(uint32_t) - 1)
4493                         goto error_out;
4494                 pentry = lpfc_sli4_qe(pque, index);
4495                 pentry += offset;
4496                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR)
4497                         *pentry = value;
4498                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST)
4499                         *pentry |= value;
4500                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL)
4501                         *pentry &= ~value;
4502         }
4503         return nbytes;
4504
4505 error_out:
4506         /* Clean out command structure on command error out */
4507         memset(&idiag, 0, sizeof(idiag));
4508         return -EINVAL;
4509 }
4510
4511 /**
4512  * lpfc_idiag_drbacc_read_reg - idiag debugfs read a doorbell register
4513  * @phba: The pointer to hba structure.
4514  * @pbuffer: The pointer to the buffer to copy the data to.
4515  * @len: The length of bytes to copied.
4516  * @drbregid: The id to doorbell registers.
4517  *
4518  * Description:
4519  * This routine reads a doorbell register and copies its content to the
4520  * user buffer pointed to by @pbuffer.
4521  *
4522  * Returns:
4523  * This function returns the amount of data that was copied into @pbuffer.
4524  **/
4525 static int
4526 lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
4527                            int len, uint32_t drbregid)
4528 {
4529
4530         if (!pbuffer)
4531                 return 0;
4532
4533         switch (drbregid) {
4534         case LPFC_DRB_EQ:
4535                 len += scnprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len,
4536                                 "EQ-DRB-REG: 0x%08x\n",
4537                                 readl(phba->sli4_hba.EQDBregaddr));
4538                 break;
4539         case LPFC_DRB_CQ:
4540                 len += scnprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len,
4541                                 "CQ-DRB-REG: 0x%08x\n",
4542                                 readl(phba->sli4_hba.CQDBregaddr));
4543                 break;
4544         case LPFC_DRB_MQ:
4545                 len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
4546                                 "MQ-DRB-REG:   0x%08x\n",
4547                                 readl(phba->sli4_hba.MQDBregaddr));
4548                 break;
4549         case LPFC_DRB_WQ:
4550                 len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
4551                                 "WQ-DRB-REG:   0x%08x\n",
4552                                 readl(phba->sli4_hba.WQDBregaddr));
4553                 break;
4554         case LPFC_DRB_RQ:
4555                 len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
4556                                 "RQ-DRB-REG:   0x%08x\n",
4557                                 readl(phba->sli4_hba.RQDBregaddr));
4558                 break;
4559         default:
4560                 break;
4561         }
4562
4563         return len;
4564 }
4565
4566 /**
4567  * lpfc_idiag_drbacc_read - idiag debugfs read port doorbell
4568  * @file: The file pointer to read from.
4569  * @buf: The buffer to copy the data to.
4570  * @nbytes: The number of bytes to read.
4571  * @ppos: The position in the file to start reading from.
4572  *
4573  * Description:
4574  * This routine reads data from the @phba device doorbell register according
4575  * to the idiag command, and copies to user @buf. Depending on the doorbell
4576  * register read command setup, it does either a single doorbell register
4577  * read or dump all doorbell registers.
4578  *
4579  * Returns:
4580  * This function returns the amount of data that was read (this could be less
4581  * than @nbytes if the end of the file was reached) or a negative error value.
4582  **/
4583 static ssize_t
4584 lpfc_idiag_drbacc_read(struct file *file, char __user *buf, size_t nbytes,
4585                        loff_t *ppos)
4586 {
4587         struct lpfc_debug *debug = file->private_data;
4588         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4589         uint32_t drb_reg_id, i;
4590         char *pbuffer;
4591         int len = 0;
4592
4593         /* This is a user read operation */
4594         debug->op = LPFC_IDIAG_OP_RD;
4595
4596         if (!debug->buffer)
4597                 debug->buffer = kmalloc(LPFC_DRB_ACC_BUF_SIZE, GFP_KERNEL);
4598         if (!debug->buffer)
4599                 return 0;
4600         pbuffer = debug->buffer;
4601
4602         if (*ppos)
4603                 return 0;
4604
4605         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD)
4606                 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
4607         else
4608                 return 0;
4609
4610         if (drb_reg_id == LPFC_DRB_ACC_ALL)
4611                 for (i = 1; i <= LPFC_DRB_MAX; i++)
4612                         len = lpfc_idiag_drbacc_read_reg(phba,
4613                                                          pbuffer, len, i);
4614         else
4615                 len = lpfc_idiag_drbacc_read_reg(phba,
4616                                                  pbuffer, len, drb_reg_id);
4617
4618         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4619 }
4620
4621 /**
4622  * lpfc_idiag_drbacc_write - Syntax check and set up idiag drbacc commands
4623  * @file: The file pointer to read from.
4624  * @buf: The buffer to copy the user data from.
4625  * @nbytes: The number of bytes to get.
4626  * @ppos: The position in the file to start reading from.
4627  *
4628  * This routine get the debugfs idiag command struct from user space and then
4629  * perform the syntax check for port doorbell register read (dump) or write
4630  * (set) command accordingly. In the case of port queue read command, it sets
4631  * up the command in the idiag command struct for the following debugfs read
4632  * operation. In the case of port doorbell register write operation, it
4633  * executes the write operation into the port doorbell register accordingly.
4634  *
4635  * It returns the @nbytges passing in from debugfs user space when successful.
4636  * In case of error conditions, it returns proper error code back to the user
4637  * space.
4638  **/
4639 static ssize_t
4640 lpfc_idiag_drbacc_write(struct file *file, const char __user *buf,
4641                         size_t nbytes, loff_t *ppos)
4642 {
4643         struct lpfc_debug *debug = file->private_data;
4644         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4645         uint32_t drb_reg_id, value, reg_val = 0;
4646         void __iomem *drb_reg;
4647         int rc;
4648
4649         /* This is a user write operation */
4650         debug->op = LPFC_IDIAG_OP_WR;
4651
4652         rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
4653         if (rc < 0)
4654                 return rc;
4655
4656         /* Sanity check on command line arguments */
4657         drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
4658         value = idiag.cmd.data[IDIAG_DRBACC_VALUE_INDX];
4659
4660         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
4661             idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
4662             idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
4663                 if (rc != LPFC_DRB_ACC_WR_CMD_ARG)
4664                         goto error_out;
4665                 if (drb_reg_id > LPFC_DRB_MAX)
4666                         goto error_out;
4667         } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD) {
4668                 if (rc != LPFC_DRB_ACC_RD_CMD_ARG)
4669                         goto error_out;
4670                 if ((drb_reg_id > LPFC_DRB_MAX) &&
4671                     (drb_reg_id != LPFC_DRB_ACC_ALL))
4672                         goto error_out;
4673         } else
4674                 goto error_out;
4675
4676         /* Perform the write access operation */
4677         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
4678             idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
4679             idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
4680                 switch (drb_reg_id) {
4681                 case LPFC_DRB_EQ:
4682                         drb_reg = phba->sli4_hba.EQDBregaddr;
4683                         break;
4684                 case LPFC_DRB_CQ:
4685                         drb_reg = phba->sli4_hba.CQDBregaddr;
4686                         break;
4687                 case LPFC_DRB_MQ:
4688                         drb_reg = phba->sli4_hba.MQDBregaddr;
4689                         break;
4690                 case LPFC_DRB_WQ:
4691                         drb_reg = phba->sli4_hba.WQDBregaddr;
4692                         break;
4693                 case LPFC_DRB_RQ:
4694                         drb_reg = phba->sli4_hba.RQDBregaddr;
4695                         break;
4696                 default:
4697                         goto error_out;
4698                 }
4699
4700                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR)
4701                         reg_val = value;
4702                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST) {
4703                         reg_val = readl(drb_reg);
4704                         reg_val |= value;
4705                 }
4706                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
4707                         reg_val = readl(drb_reg);
4708                         reg_val &= ~value;
4709                 }
4710                 writel(reg_val, drb_reg);
4711                 readl(drb_reg); /* flush */
4712         }
4713         return nbytes;
4714
4715 error_out:
4716         /* Clean out command structure on command error out */
4717         memset(&idiag, 0, sizeof(idiag));
4718         return -EINVAL;
4719 }
4720
4721 /**
4722  * lpfc_idiag_ctlacc_read_reg - idiag debugfs read a control registers
4723  * @phba: The pointer to hba structure.
4724  * @pbuffer: The pointer to the buffer to copy the data to.
4725  * @len: The length of bytes to copied.
4726  * @drbregid: The id to doorbell registers.
4727  *
4728  * Description:
4729  * This routine reads a control register and copies its content to the
4730  * user buffer pointed to by @pbuffer.
4731  *
4732  * Returns:
4733  * This function returns the amount of data that was copied into @pbuffer.
4734  **/
4735 static int
4736 lpfc_idiag_ctlacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
4737                            int len, uint32_t ctlregid)
4738 {
4739
4740         if (!pbuffer)
4741                 return 0;
4742
4743         switch (ctlregid) {
4744         case LPFC_CTL_PORT_SEM:
4745                 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4746                                 "Port SemReg:   0x%08x\n",
4747                                 readl(phba->sli4_hba.conf_regs_memmap_p +
4748                                       LPFC_CTL_PORT_SEM_OFFSET));
4749                 break;
4750         case LPFC_CTL_PORT_STA:
4751                 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4752                                 "Port StaReg:   0x%08x\n",
4753                                 readl(phba->sli4_hba.conf_regs_memmap_p +
4754                                       LPFC_CTL_PORT_STA_OFFSET));
4755                 break;
4756         case LPFC_CTL_PORT_CTL:
4757                 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4758                                 "Port CtlReg:   0x%08x\n",
4759                                 readl(phba->sli4_hba.conf_regs_memmap_p +
4760                                       LPFC_CTL_PORT_CTL_OFFSET));
4761                 break;
4762         case LPFC_CTL_PORT_ER1:
4763                 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4764                                 "Port Er1Reg:   0x%08x\n",
4765                                 readl(phba->sli4_hba.conf_regs_memmap_p +
4766                                       LPFC_CTL_PORT_ER1_OFFSET));
4767                 break;
4768         case LPFC_CTL_PORT_ER2:
4769                 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4770                                 "Port Er2Reg:   0x%08x\n",
4771                                 readl(phba->sli4_hba.conf_regs_memmap_p +
4772                                       LPFC_CTL_PORT_ER2_OFFSET));
4773                 break;
4774         case LPFC_CTL_PDEV_CTL:
4775                 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4776                                 "PDev CtlReg:   0x%08x\n",
4777                                 readl(phba->sli4_hba.conf_regs_memmap_p +
4778                                       LPFC_CTL_PDEV_CTL_OFFSET));
4779                 break;
4780         default:
4781                 break;
4782         }
4783         return len;
4784 }
4785
4786 /**
4787  * lpfc_idiag_ctlacc_read - idiag debugfs read port and device control register
4788  * @file: The file pointer to read from.
4789  * @buf: The buffer to copy the data to.
4790  * @nbytes: The number of bytes to read.
4791  * @ppos: The position in the file to start reading from.
4792  *
4793  * Description:
4794  * This routine reads data from the @phba port and device registers according
4795  * to the idiag command, and copies to user @buf.
4796  *
4797  * Returns:
4798  * This function returns the amount of data that was read (this could be less
4799  * than @nbytes if the end of the file was reached) or a negative error value.
4800  **/
4801 static ssize_t
4802 lpfc_idiag_ctlacc_read(struct file *file, char __user *buf, size_t nbytes,
4803                        loff_t *ppos)
4804 {
4805         struct lpfc_debug *debug = file->private_data;
4806         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4807         uint32_t ctl_reg_id, i;
4808         char *pbuffer;
4809         int len = 0;
4810
4811         /* This is a user read operation */
4812         debug->op = LPFC_IDIAG_OP_RD;
4813
4814         if (!debug->buffer)
4815                 debug->buffer = kmalloc(LPFC_CTL_ACC_BUF_SIZE, GFP_KERNEL);
4816         if (!debug->buffer)
4817                 return 0;
4818         pbuffer = debug->buffer;
4819
4820         if (*ppos)
4821                 return 0;
4822
4823         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD)
4824                 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
4825         else
4826                 return 0;
4827
4828         if (ctl_reg_id == LPFC_CTL_ACC_ALL)
4829                 for (i = 1; i <= LPFC_CTL_MAX; i++)
4830                         len = lpfc_idiag_ctlacc_read_reg(phba,
4831                                                          pbuffer, len, i);
4832         else
4833                 len = lpfc_idiag_ctlacc_read_reg(phba,
4834                                                  pbuffer, len, ctl_reg_id);
4835
4836         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4837 }
4838
4839 /**
4840  * lpfc_idiag_ctlacc_write - Syntax check and set up idiag ctlacc commands
4841  * @file: The file pointer to read from.
4842  * @buf: The buffer to copy the user data from.
4843  * @nbytes: The number of bytes to get.
4844  * @ppos: The position in the file to start reading from.
4845  *
4846  * This routine get the debugfs idiag command struct from user space and then
4847  * perform the syntax check for port and device control register read (dump)
4848  * or write (set) command accordingly.
4849  *
4850  * It returns the @nbytges passing in from debugfs user space when successful.
4851  * In case of error conditions, it returns proper error code back to the user
4852  * space.
4853  **/
4854 static ssize_t
4855 lpfc_idiag_ctlacc_write(struct file *file, const char __user *buf,
4856                         size_t nbytes, loff_t *ppos)
4857 {
4858         struct lpfc_debug *debug = file->private_data;
4859         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4860         uint32_t ctl_reg_id, value, reg_val = 0;
4861         void __iomem *ctl_reg;
4862         int rc;
4863
4864         /* This is a user write operation */
4865         debug->op = LPFC_IDIAG_OP_WR;
4866
4867         rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
4868         if (rc < 0)
4869                 return rc;
4870
4871         /* Sanity check on command line arguments */
4872         ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
4873         value = idiag.cmd.data[IDIAG_CTLACC_VALUE_INDX];
4874
4875         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
4876             idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
4877             idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
4878                 if (rc != LPFC_CTL_ACC_WR_CMD_ARG)
4879                         goto error_out;
4880                 if (ctl_reg_id > LPFC_CTL_MAX)
4881                         goto error_out;
4882         } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD) {
4883                 if (rc != LPFC_CTL_ACC_RD_CMD_ARG)
4884                         goto error_out;
4885                 if ((ctl_reg_id > LPFC_CTL_MAX) &&
4886                     (ctl_reg_id != LPFC_CTL_ACC_ALL))
4887                         goto error_out;
4888         } else
4889                 goto error_out;
4890
4891         /* Perform the write access operation */
4892         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
4893             idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
4894             idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
4895                 switch (ctl_reg_id) {
4896                 case LPFC_CTL_PORT_SEM:
4897                         ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4898                                         LPFC_CTL_PORT_SEM_OFFSET;
4899                         break;
4900                 case LPFC_CTL_PORT_STA:
4901                         ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4902                                         LPFC_CTL_PORT_STA_OFFSET;
4903                         break;
4904                 case LPFC_CTL_PORT_CTL:
4905                         ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4906                                         LPFC_CTL_PORT_CTL_OFFSET;
4907                         break;
4908                 case LPFC_CTL_PORT_ER1:
4909                         ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4910                                         LPFC_CTL_PORT_ER1_OFFSET;
4911                         break;
4912                 case LPFC_CTL_PORT_ER2:
4913                         ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4914                                         LPFC_CTL_PORT_ER2_OFFSET;
4915                         break;
4916                 case LPFC_CTL_PDEV_CTL:
4917                         ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4918                                         LPFC_CTL_PDEV_CTL_OFFSET;
4919                         break;
4920                 default:
4921                         goto error_out;
4922                 }
4923
4924                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR)
4925                         reg_val = value;
4926                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST) {
4927                         reg_val = readl(ctl_reg);
4928                         reg_val |= value;
4929                 }
4930                 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
4931                         reg_val = readl(ctl_reg);
4932                         reg_val &= ~value;
4933                 }
4934                 writel(reg_val, ctl_reg);
4935                 readl(ctl_reg); /* flush */
4936         }
4937         return nbytes;
4938
4939 error_out:
4940         /* Clean out command structure on command error out */
4941         memset(&idiag, 0, sizeof(idiag));
4942         return -EINVAL;
4943 }
4944
4945 /**
4946  * lpfc_idiag_mbxacc_get_setup - idiag debugfs get mailbox access setup
4947  * @phba: Pointer to HBA context object.
4948  * @pbuffer: Pointer to data buffer.
4949  *
4950  * Description:
4951  * This routine gets the driver mailbox access debugfs setup information.
4952  *
4953  * Returns:
4954  * This function returns the amount of data that was read (this could be less
4955  * than @nbytes if the end of the file was reached) or a negative error value.
4956  **/
4957 static int
4958 lpfc_idiag_mbxacc_get_setup(struct lpfc_hba *phba, char *pbuffer)
4959 {
4960         uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
4961         int len = 0;
4962
4963         mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
4964         mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
4965         mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
4966         mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
4967
4968         len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
4969                         "mbx_dump_map: 0x%08x\n", mbx_dump_map);
4970         len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
4971                         "mbx_dump_cnt: %04d\n", mbx_dump_cnt);
4972         len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
4973                         "mbx_word_cnt: %04d\n", mbx_word_cnt);
4974         len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
4975                         "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd);
4976
4977         return len;
4978 }
4979
4980 /**
4981  * lpfc_idiag_mbxacc_read - idiag debugfs read on mailbox access
4982  * @file: The file pointer to read from.
4983  * @buf: The buffer to copy the data to.
4984  * @nbytes: The number of bytes to read.
4985  * @ppos: The position in the file to start reading from.
4986  *
4987  * Description:
4988  * This routine reads data from the @phba driver mailbox access debugfs setup
4989  * information.
4990  *
4991  * Returns:
4992  * This function returns the amount of data that was read (this could be less
4993  * than @nbytes if the end of the file was reached) or a negative error value.
4994  **/
4995 static ssize_t
4996 lpfc_idiag_mbxacc_read(struct file *file, char __user *buf, size_t nbytes,
4997                        loff_t *ppos)
4998 {
4999         struct lpfc_debug *debug = file->private_data;
5000         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
5001         char *pbuffer;
5002         int len = 0;
5003
5004         /* This is a user read operation */
5005         debug->op = LPFC_IDIAG_OP_RD;
5006
5007         if (!debug->buffer)
5008                 debug->buffer = kmalloc(LPFC_MBX_ACC_BUF_SIZE, GFP_KERNEL);
5009         if (!debug->buffer)
5010                 return 0;
5011         pbuffer = debug->buffer;
5012
5013         if (*ppos)
5014                 return 0;
5015
5016         if ((idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP) &&
5017             (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP))
5018                 return 0;
5019
5020         len = lpfc_idiag_mbxacc_get_setup(phba, pbuffer);
5021
5022         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
5023 }
5024
5025 /**
5026  * lpfc_idiag_mbxacc_write - Syntax check and set up idiag mbxacc commands
5027  * @file: The file pointer to read from.
5028  * @buf: The buffer to copy the user data from.
5029  * @nbytes: The number of bytes to get.
5030  * @ppos: The position in the file to start reading from.
5031  *
5032  * This routine get the debugfs idiag command struct from user space and then
5033  * perform the syntax check for driver mailbox command (dump) and sets up the
5034  * necessary states in the idiag command struct accordingly.
5035  *
5036  * It returns the @nbytges passing in from debugfs user space when successful.
5037  * In case of error conditions, it returns proper error code back to the user
5038  * space.
5039  **/
5040 static ssize_t
5041 lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf,
5042                         size_t nbytes, loff_t *ppos)
5043 {
5044         struct lpfc_debug *debug = file->private_data;
5045         uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
5046         int rc;
5047
5048         /* This is a user write operation */
5049         debug->op = LPFC_IDIAG_OP_WR;
5050
5051         rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
5052         if (rc < 0)
5053                 return rc;
5054
5055         /* Sanity check on command line arguments */
5056         mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
5057         mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
5058         mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
5059         mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
5060
5061         if (idiag.cmd.opcode == LPFC_IDIAG_CMD_MBXACC_DP) {
5062                 if (!(mbx_dump_map & LPFC_MBX_DMP_MBX_ALL))
5063                         goto error_out;
5064                 if ((mbx_dump_map & ~LPFC_MBX_DMP_MBX_ALL) &&
5065                     (mbx_dump_map != LPFC_MBX_DMP_ALL))
5066                         goto error_out;
5067                 if (mbx_word_cnt > sizeof(MAILBOX_t))
5068                         goto error_out;
5069         } else if (idiag.cmd.opcode == LPFC_IDIAG_BSG_MBXACC_DP) {
5070                 if (!(mbx_dump_map & LPFC_BSG_DMP_MBX_ALL))
5071                         goto error_out;
5072                 if ((mbx_dump_map & ~LPFC_BSG_DMP_MBX_ALL) &&
5073                     (mbx_dump_map != LPFC_MBX_DMP_ALL))
5074                         goto error_out;
5075                 if (mbx_word_cnt > (BSG_MBOX_SIZE)/4)
5076                         goto error_out;
5077                 if (mbx_mbox_cmd != 0x9b)
5078                         goto error_out;
5079         } else
5080                 goto error_out;
5081
5082         if (mbx_word_cnt == 0)
5083                 goto error_out;
5084         if (rc != LPFC_MBX_DMP_ARG)
5085                 goto error_out;
5086         if (mbx_mbox_cmd & ~0xff)
5087                 goto error_out;
5088
5089         /* condition for stop mailbox dump */
5090         if (mbx_dump_cnt == 0)
5091                 goto reset_out;
5092
5093         return nbytes;
5094
5095 reset_out:
5096         /* Clean out command structure on command error out */
5097         memset(&idiag, 0, sizeof(idiag));
5098         return nbytes;
5099
5100 error_out:
5101         /* Clean out command structure on command error out */
5102         memset(&idiag, 0, sizeof(idiag));
5103         return -EINVAL;
5104 }
5105
5106 /**
5107  * lpfc_idiag_extacc_avail_get - get the available extents information
5108  * @phba: pointer to lpfc hba data structure.
5109  * @pbuffer: pointer to internal buffer.
5110  * @len: length into the internal buffer data has been copied.
5111  *
5112  * Description:
5113  * This routine is to get the available extent information.
5114  *
5115  * Returns:
5116  * overall lenth of the data read into the internal buffer.
5117  **/
5118 static int
5119 lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
5120 {
5121         uint16_t ext_cnt, ext_size;
5122
5123         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5124                         "\nAvailable Extents Information:\n");
5125
5126         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5127                         "\tPort Available VPI extents: ");
5128         lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI,
5129                                        &ext_cnt, &ext_size);
5130         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5131                         "Count %3d, Size %3d\n", ext_cnt, ext_size);
5132
5133         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5134                         "\tPort Available VFI extents: ");
5135         lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI,
5136                                        &ext_cnt, &ext_size);
5137         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5138                         "Count %3d, Size %3d\n", ext_cnt, ext_size);
5139
5140         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5141                         "\tPort Available RPI extents: ");
5142         lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI,
5143                                        &ext_cnt, &ext_size);
5144         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5145                         "Count %3d, Size %3d\n", ext_cnt, ext_size);
5146
5147         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5148                         "\tPort Available XRI extents: ");
5149         lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI,
5150                                        &ext_cnt, &ext_size);
5151         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5152                         "Count %3d, Size %3d\n", ext_cnt, ext_size);
5153
5154         return len;
5155 }
5156
5157 /**
5158  * lpfc_idiag_extacc_alloc_get - get the allocated extents information
5159  * @phba: pointer to lpfc hba data structure.
5160  * @pbuffer: pointer to internal buffer.
5161  * @len: length into the internal buffer data has been copied.
5162  *
5163  * Description:
5164  * This routine is to get the allocated extent information.
5165  *
5166  * Returns:
5167  * overall lenth of the data read into the internal buffer.
5168  **/
5169 static int
5170 lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len)
5171 {
5172         uint16_t ext_cnt, ext_size;
5173         int rc;
5174
5175         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5176                         "\nAllocated Extents Information:\n");
5177
5178         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5179                         "\tHost Allocated VPI extents: ");
5180         rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI,
5181                                             &ext_cnt, &ext_size);
5182         if (!rc)
5183                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5184                                 "Port %d Extent %3d, Size %3d\n",
5185                                 phba->brd_no, ext_cnt, ext_size);
5186         else
5187                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5188                                 "N/A\n");
5189
5190         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5191                         "\tHost Allocated VFI extents: ");
5192         rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI,
5193                                             &ext_cnt, &ext_size);
5194         if (!rc)
5195                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5196                                 "Port %d Extent %3d, Size %3d\n",
5197                                 phba->brd_no, ext_cnt, ext_size);
5198         else
5199                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5200                                 "N/A\n");
5201
5202         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5203                         "\tHost Allocated RPI extents: ");
5204         rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI,
5205                                             &ext_cnt, &ext_size);
5206         if (!rc)
5207                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5208                                 "Port %d Extent %3d, Size %3d\n",
5209                                 phba->brd_no, ext_cnt, ext_size);
5210         else
5211                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5212                                 "N/A\n");
5213
5214         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5215                         "\tHost Allocated XRI extents: ");
5216         rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI,
5217                                             &ext_cnt, &ext_size);
5218         if (!rc)
5219                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5220                                 "Port %d Extent %3d, Size %3d\n",
5221                                 phba->brd_no, ext_cnt, ext_size);
5222         else
5223                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5224                                 "N/A\n");
5225
5226         return len;
5227 }
5228
5229 /**
5230  * lpfc_idiag_extacc_drivr_get - get driver extent information
5231  * @phba: pointer to lpfc hba data structure.
5232  * @pbuffer: pointer to internal buffer.
5233  * @len: length into the internal buffer data has been copied.
5234  *
5235  * Description:
5236  * This routine is to get the driver extent information.
5237  *
5238  * Returns:
5239  * overall lenth of the data read into the internal buffer.
5240  **/
5241 static int
5242 lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len)
5243 {
5244         struct lpfc_rsrc_blks *rsrc_blks;
5245         int index;
5246
5247         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5248                         "\nDriver Extents Information:\n");
5249
5250         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5251                         "\tVPI extents:\n");
5252         index = 0;
5253         list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) {
5254                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5255                                 "\t\tBlock %3d: Start %4d, Count %4d\n",
5256                                 index, rsrc_blks->rsrc_start,
5257                                 rsrc_blks->rsrc_size);
5258                 index++;
5259         }
5260         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5261                         "\tVFI extents:\n");
5262         index = 0;
5263         list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list,
5264                             list) {
5265                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5266                                 "\t\tBlock %3d: Start %4d, Count %4d\n",
5267                                 index, rsrc_blks->rsrc_start,
5268                                 rsrc_blks->rsrc_size);
5269                 index++;
5270         }
5271
5272         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5273                         "\tRPI extents:\n");
5274         index = 0;
5275         list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list,
5276                             list) {
5277                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5278                                 "\t\tBlock %3d: Start %4d, Count %4d\n",
5279                                 index, rsrc_blks->rsrc_start,
5280                                 rsrc_blks->rsrc_size);
5281                 index++;
5282         }
5283
5284         len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5285                         "\tXRI extents:\n");
5286         index = 0;
5287         list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list,
5288                             list) {
5289                 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5290                                 "\t\tBlock %3d: Start %4d, Count %4d\n",
5291                                 index, rsrc_blks->rsrc_start,
5292                                 rsrc_blks->rsrc_size);
5293                 index++;
5294         }
5295
5296         return len;
5297 }
5298
5299 /**
5300  * lpfc_idiag_extacc_write - Syntax check and set up idiag extacc commands
5301  * @file: The file pointer to read from.
5302  * @buf: The buffer to copy the user data from.
5303  * @nbytes: The number of bytes to get.
5304  * @ppos: The position in the file to start reading from.
5305  *
5306  * This routine get the debugfs idiag command struct from user space and then
5307  * perform the syntax check for extent information access commands and sets
5308  * up the necessary states in the idiag command struct accordingly.
5309  *
5310  * It returns the @nbytges passing in from debugfs user space when successful.
5311  * In case of error conditions, it returns proper error code back to the user
5312  * space.
5313  **/
5314 static ssize_t
5315 lpfc_idiag_extacc_write(struct file *file, const char __user *buf,
5316                         size_t nbytes, loff_t *ppos)
5317 {
5318         struct lpfc_debug *debug = file->private_data;
5319         uint32_t ext_map;
5320         int rc;
5321
5322         /* This is a user write operation */
5323         debug->op = LPFC_IDIAG_OP_WR;
5324
5325         rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
5326         if (rc < 0)
5327                 return rc;
5328
5329         ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
5330
5331         if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
5332                 goto error_out;
5333         if (rc != LPFC_EXT_ACC_CMD_ARG)
5334                 goto error_out;
5335         if (!(ext_map & LPFC_EXT_ACC_ALL))
5336                 goto error_out;
5337
5338         return nbytes;
5339 error_out:
5340         /* Clean out command structure on command error out */
5341         memset(&idiag, 0, sizeof(idiag));
5342         return -EINVAL;
5343 }
5344
5345 /**
5346  * lpfc_idiag_extacc_read - idiag debugfs read access to extent information
5347  * @file: The file pointer to read from.
5348  * @buf: The buffer to copy the data to.
5349  * @nbytes: The number of bytes to read.
5350  * @ppos: The position in the file to start reading from.
5351  *
5352  * Description:
5353  * This routine reads data from the proper extent information according to
5354  * the idiag command, and copies to user @buf.
5355  *
5356  * Returns:
5357  * This function returns the amount of data that was read (this could be less
5358  * than @nbytes if the end of the file was reached) or a negative error value.
5359  **/
5360 static ssize_t
5361 lpfc_idiag_extacc_read(struct file *file, char __user *buf, size_t nbytes,
5362                        loff_t *ppos)
5363 {
5364         struct lpfc_debug *debug = file->private_data;
5365         struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
5366         char *pbuffer;
5367         uint32_t ext_map;
5368         int len = 0;
5369
5370         /* This is a user read operation */
5371         debug->op = LPFC_IDIAG_OP_RD;
5372
5373         if (!debug->buffer)
5374                 debug->buffer = kmalloc(LPFC_EXT_ACC_BUF_SIZE, GFP_KERNEL);
5375         if (!debug->buffer)
5376                 return 0;
5377         pbuffer = debug->buffer;
5378         if (*ppos)
5379                 return 0;
5380         if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
5381                 return 0;
5382
5383         ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
5384         if (ext_map & LPFC_EXT_ACC_AVAIL)
5385                 len = lpfc_idiag_extacc_avail_get(phba, pbuffer, len);
5386         if (ext_map & LPFC_EXT_ACC_ALLOC)
5387                 len = lpfc_idiag_extacc_alloc_get(phba, pbuffer, len);
5388         if (ext_map & LPFC_EXT_ACC_DRIVR)
5389                 len = lpfc_idiag_extacc_drivr_get(phba, pbuffer, len);
5390
5391         return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
5392 }
5393
5394 #undef lpfc_debugfs_op_disc_trc
5395 static const struct file_operations lpfc_debugfs_op_disc_trc = {
5396         .owner =        THIS_MODULE,
5397         .open =         lpfc_debugfs_disc_trc_open,
5398         .llseek =       lpfc_debugfs_lseek,
5399         .read =         lpfc_debugfs_read,
5400         .release =      lpfc_debugfs_release,
5401 };
5402
5403 #undef lpfc_debugfs_op_nodelist
5404 static const struct file_operations lpfc_debugfs_op_nodelist = {
5405         .owner =        THIS_MODULE,
5406         .open =         lpfc_debugfs_nodelist_open,
5407         .llseek =       lpfc_debugfs_lseek,
5408         .read =         lpfc_debugfs_read,
5409         .release =      lpfc_debugfs_release,
5410 };
5411
5412 #undef lpfc_debugfs_op_multixripools
5413 static const struct file_operations lpfc_debugfs_op_multixripools = {
5414         .owner =        THIS_MODULE,
5415         .open =         lpfc_debugfs_multixripools_open,
5416         .llseek =       lpfc_debugfs_lseek,
5417         .read =         lpfc_debugfs_read,
5418         .write =        lpfc_debugfs_multixripools_write,
5419         .release =      lpfc_debugfs_release,
5420 };
5421
5422 #undef lpfc_debugfs_op_hbqinfo
5423 static const struct file_operations lpfc_debugfs_op_hbqinfo = {
5424         .owner =        THIS_MODULE,
5425         .open =         lpfc_debugfs_hbqinfo_open,
5426         .llseek =       lpfc_debugfs_lseek,
5427         .read =         lpfc_debugfs_read,
5428         .release =      lpfc_debugfs_release,
5429 };
5430
5431 #ifdef LPFC_HDWQ_LOCK_STAT
5432 #undef lpfc_debugfs_op_lockstat
5433 static const struct file_operations lpfc_debugfs_op_lockstat = {
5434         .owner =        THIS_MODULE,
5435         .open =         lpfc_debugfs_lockstat_open,
5436         .llseek =       lpfc_debugfs_lseek,
5437         .read =         lpfc_debugfs_read,
5438         .write =        lpfc_debugfs_lockstat_write,
5439         .release =      lpfc_debugfs_release,
5440 };
5441 #endif
5442
5443 #undef lpfc_debugfs_op_dumpHBASlim
5444 static const struct file_operations lpfc_debugfs_op_dumpHBASlim = {
5445         .owner =        THIS_MODULE,
5446         .open =         lpfc_debugfs_dumpHBASlim_open,
5447         .llseek =       lpfc_debugfs_lseek,
5448         .read =         lpfc_debugfs_read,
5449         .release =      lpfc_debugfs_release,
5450 };
5451
5452 #undef lpfc_debugfs_op_dumpHostSlim
5453 static const struct file_operations lpfc_debugfs_op_dumpHostSlim = {
5454         .owner =        THIS_MODULE,
5455         .open =         lpfc_debugfs_dumpHostSlim_open,
5456         .llseek =       lpfc_debugfs_lseek,
5457         .read =         lpfc_debugfs_read,
5458         .release =      lpfc_debugfs_release,
5459 };
5460
5461 #undef lpfc_debugfs_op_nvmestat
5462 static const struct file_operations lpfc_debugfs_op_nvmestat = {
5463         .owner =        THIS_MODULE,
5464         .open =         lpfc_debugfs_nvmestat_open,
5465         .llseek =       lpfc_debugfs_lseek,
5466         .read =         lpfc_debugfs_read,
5467         .write =        lpfc_debugfs_nvmestat_write,
5468         .release =      lpfc_debugfs_release,
5469 };
5470
5471 #undef lpfc_debugfs_op_scsistat
5472 static const struct file_operations lpfc_debugfs_op_scsistat = {
5473         .owner =        THIS_MODULE,
5474         .open =         lpfc_debugfs_scsistat_open,
5475         .llseek =       lpfc_debugfs_lseek,
5476         .read =         lpfc_debugfs_read,
5477         .write =        lpfc_debugfs_scsistat_write,
5478         .release =      lpfc_debugfs_release,
5479 };
5480
5481 #undef lpfc_debugfs_op_nvmektime
5482 static const struct file_operations lpfc_debugfs_op_nvmektime = {
5483         .owner =        THIS_MODULE,
5484         .open =         lpfc_debugfs_nvmektime_open,
5485         .llseek =       lpfc_debugfs_lseek,
5486         .read =         lpfc_debugfs_read,
5487         .write =        lpfc_debugfs_nvmektime_write,
5488         .release =      lpfc_debugfs_release,
5489 };
5490
5491 #undef lpfc_debugfs_op_nvmeio_trc
5492 static const struct file_operations lpfc_debugfs_op_nvmeio_trc = {
5493         .owner =        THIS_MODULE,
5494         .open =         lpfc_debugfs_nvmeio_trc_open,
5495         .llseek =       lpfc_debugfs_lseek,
5496         .read =         lpfc_debugfs_read,
5497         .write =        lpfc_debugfs_nvmeio_trc_write,
5498         .release =      lpfc_debugfs_release,
5499 };
5500
5501 #undef lpfc_debugfs_op_cpucheck
5502 static const struct file_operations lpfc_debugfs_op_cpucheck = {
5503         .owner =        THIS_MODULE,
5504         .open =         lpfc_debugfs_cpucheck_open,
5505         .llseek =       lpfc_debugfs_lseek,
5506         .read =         lpfc_debugfs_read,
5507         .write =        lpfc_debugfs_cpucheck_write,
5508         .release =      lpfc_debugfs_release,
5509 };
5510
5511 #undef lpfc_debugfs_op_dumpData
5512 static const struct file_operations lpfc_debugfs_op_dumpData = {
5513         .owner =        THIS_MODULE,
5514         .open =         lpfc_debugfs_dumpData_open,
5515         .llseek =       lpfc_debugfs_lseek,
5516         .read =         lpfc_debugfs_read,
5517         .write =        lpfc_debugfs_dumpDataDif_write,
5518         .release =      lpfc_debugfs_dumpDataDif_release,
5519 };
5520
5521 #undef lpfc_debugfs_op_dumpDif
5522 static const struct file_operations lpfc_debugfs_op_dumpDif = {
5523         .owner =        THIS_MODULE,
5524         .open =         lpfc_debugfs_dumpDif_open,
5525         .llseek =       lpfc_debugfs_lseek,
5526         .read =         lpfc_debugfs_read,
5527         .write =        lpfc_debugfs_dumpDataDif_write,
5528         .release =      lpfc_debugfs_dumpDataDif_release,
5529 };
5530
5531 #undef lpfc_debugfs_op_dif_err
5532 static const struct file_operations lpfc_debugfs_op_dif_err = {
5533         .owner =        THIS_MODULE,
5534         .open =         simple_open,
5535         .llseek =       lpfc_debugfs_lseek,
5536         .read =         lpfc_debugfs_dif_err_read,
5537         .write =        lpfc_debugfs_dif_err_write,
5538         .release =      lpfc_debugfs_dif_err_release,
5539 };
5540
5541 #undef lpfc_debugfs_op_slow_ring_trc
5542 static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
5543         .owner =        THIS_MODULE,
5544         .open =         lpfc_debugfs_slow_ring_trc_open,
5545         .llseek =       lpfc_debugfs_lseek,
5546         .read =         lpfc_debugfs_read,
5547         .release =      lpfc_debugfs_release,
5548 };
5549
5550 static struct dentry *lpfc_debugfs_root = NULL;
5551 static atomic_t lpfc_debugfs_hba_count;
5552
5553 /*
5554  * File operations for the iDiag debugfs
5555  */
5556 #undef lpfc_idiag_op_pciCfg
5557 static const struct file_operations lpfc_idiag_op_pciCfg = {
5558         .owner =        THIS_MODULE,
5559         .open =         lpfc_idiag_open,
5560         .llseek =       lpfc_debugfs_lseek,
5561         .read =         lpfc_idiag_pcicfg_read,
5562         .write =        lpfc_idiag_pcicfg_write,
5563         .release =      lpfc_idiag_cmd_release,
5564 };
5565
5566 #undef lpfc_idiag_op_barAcc
5567 static const struct file_operations lpfc_idiag_op_barAcc = {
5568         .owner =        THIS_MODULE,
5569         .open =         lpfc_idiag_open,
5570         .llseek =       lpfc_debugfs_lseek,
5571         .read =         lpfc_idiag_baracc_read,
5572         .write =        lpfc_idiag_baracc_write,
5573         .release =      lpfc_idiag_cmd_release,
5574 };
5575
5576 #undef lpfc_idiag_op_queInfo
5577 static const struct file_operations lpfc_idiag_op_queInfo = {
5578         .owner =        THIS_MODULE,
5579         .open =         lpfc_idiag_open,
5580         .read =         lpfc_idiag_queinfo_read,
5581         .release =      lpfc_idiag_release,
5582 };
5583
5584 #undef lpfc_idiag_op_queAcc
5585 static const struct file_operations lpfc_idiag_op_queAcc = {
5586         .owner =        THIS_MODULE,
5587         .open =         lpfc_idiag_open,
5588         .llseek =       lpfc_debugfs_lseek,
5589         .read =         lpfc_idiag_queacc_read,
5590         .write =        lpfc_idiag_queacc_write,
5591         .release =      lpfc_idiag_cmd_release,
5592 };
5593
5594 #undef lpfc_idiag_op_drbAcc
5595 static const struct file_operations lpfc_idiag_op_drbAcc = {
5596         .owner =        THIS_MODULE,
5597         .open =         lpfc_idiag_open,
5598         .llseek =       lpfc_debugfs_lseek,
5599         .read =         lpfc_idiag_drbacc_read,
5600         .write =        lpfc_idiag_drbacc_write,
5601         .release =      lpfc_idiag_cmd_release,
5602 };
5603
5604 #undef lpfc_idiag_op_ctlAcc
5605 static const struct file_operations lpfc_idiag_op_ctlAcc = {
5606         .owner =        THIS_MODULE,
5607         .open =         lpfc_idiag_open,
5608         .llseek =       lpfc_debugfs_lseek,
5609         .read =         lpfc_idiag_ctlacc_read,
5610         .write =        lpfc_idiag_ctlacc_write,
5611         .release =      lpfc_idiag_cmd_release,
5612 };
5613
5614 #undef lpfc_idiag_op_mbxAcc
5615 static const struct file_operations lpfc_idiag_op_mbxAcc = {
5616         .owner =        THIS_MODULE,
5617         .open =         lpfc_idiag_open,
5618         .llseek =       lpfc_debugfs_lseek,
5619         .read =         lpfc_idiag_mbxacc_read,
5620         .write =        lpfc_idiag_mbxacc_write,
5621         .release =      lpfc_idiag_cmd_release,
5622 };
5623
5624 #undef lpfc_idiag_op_extAcc
5625 static const struct file_operations lpfc_idiag_op_extAcc = {
5626         .owner =        THIS_MODULE,
5627         .open =         lpfc_idiag_open,
5628         .llseek =       lpfc_debugfs_lseek,
5629         .read =         lpfc_idiag_extacc_read,
5630         .write =        lpfc_idiag_extacc_write,
5631         .release =      lpfc_idiag_cmd_release,
5632 };
5633
5634 #endif
5635
5636 /* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command
5637  * @phba: Pointer to HBA context object.
5638  * @dmabuf: Pointer to a DMA buffer descriptor.
5639  *
5640  * Description:
5641  * This routine dump a bsg pass-through non-embedded mailbox command with
5642  * external buffer.
5643  **/
5644 void
5645 lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *phba, enum nemb_type nemb_tp,
5646                                 enum mbox_type mbox_tp, enum dma_type dma_tp,
5647                                 enum sta_type sta_tp,
5648                                 struct lpfc_dmabuf *dmabuf, uint32_t ext_buf)
5649 {
5650 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
5651         uint32_t *mbx_mbox_cmd, *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt;
5652         char line_buf[LPFC_MBX_ACC_LBUF_SZ];
5653         int len = 0;
5654         uint32_t do_dump = 0;
5655         uint32_t *pword;
5656         uint32_t i;
5657
5658         if (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP)
5659                 return;
5660
5661         mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
5662         mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
5663         mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
5664         mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
5665
5666         if (!(*mbx_dump_map & LPFC_MBX_DMP_ALL) ||
5667             (*mbx_dump_cnt == 0) ||
5668             (*mbx_word_cnt == 0))
5669                 return;
5670
5671         if (*mbx_mbox_cmd != 0x9B)
5672                 return;
5673
5674         if ((mbox_tp == mbox_rd) && (dma_tp == dma_mbox)) {
5675                 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_MBX) {
5676                         do_dump |= LPFC_BSG_DMP_MBX_RD_MBX;
5677                         pr_err("\nRead mbox command (x%x), "
5678                                "nemb:0x%x, extbuf_cnt:%d:\n",
5679                                sta_tp, nemb_tp, ext_buf);
5680                 }
5681         }
5682         if ((mbox_tp == mbox_rd) && (dma_tp == dma_ebuf)) {
5683                 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_BUF) {
5684                         do_dump |= LPFC_BSG_DMP_MBX_RD_BUF;
5685                         pr_err("\nRead mbox buffer (x%x), "
5686                                "nemb:0x%x, extbuf_seq:%d:\n",
5687                                sta_tp, nemb_tp, ext_buf);
5688                 }
5689         }
5690         if ((mbox_tp == mbox_wr) && (dma_tp == dma_mbox)) {
5691                 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_MBX) {
5692                         do_dump |= LPFC_BSG_DMP_MBX_WR_MBX;
5693                         pr_err("\nWrite mbox command (x%x), "
5694                                "nemb:0x%x, extbuf_cnt:%d:\n",
5695                                sta_tp, nemb_tp, ext_buf);
5696                 }
5697         }
5698         if ((mbox_tp == mbox_wr) && (dma_tp == dma_ebuf)) {
5699                 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_BUF) {
5700                         do_dump |= LPFC_BSG_DMP_MBX_WR_BUF;
5701                         pr_err("\nWrite mbox buffer (x%x), "
5702                                "nemb:0x%x, extbuf_seq:%d:\n",
5703                                sta_tp, nemb_tp, ext_buf);
5704                 }
5705         }
5706
5707         /* dump buffer content */
5708         if (do_dump) {
5709                 pword = (uint32_t *)dmabuf->virt;
5710                 for (i = 0; i < *mbx_word_cnt; i++) {
5711                         if (!(i % 8)) {
5712                                 if (i != 0)
5713                                         pr_err("%s\n", line_buf);
5714                                 len = 0;
5715                                 len += scnprintf(line_buf+len,
5716                                                 LPFC_MBX_ACC_LBUF_SZ-len,
5717                                                 "%03d: ", i);
5718                         }
5719                         len += scnprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
5720                                         "%08x ", (uint32_t)*pword);
5721                         pword++;
5722                 }
5723                 if ((i - 1) % 8)
5724                         pr_err("%s\n", line_buf);
5725                 (*mbx_dump_cnt)--;
5726         }
5727
5728         /* Clean out command structure on reaching dump count */
5729         if (*mbx_dump_cnt == 0)
5730                 memset(&idiag, 0, sizeof(idiag));
5731         return;
5732 #endif
5733 }
5734
5735 /* lpfc_idiag_mbxacc_dump_issue_mbox - idiag debugfs dump issue mailbox command
5736  * @phba: Pointer to HBA context object.
5737  * @dmabuf: Pointer to a DMA buffer descriptor.
5738  *
5739  * Description:
5740  * This routine dump a pass-through non-embedded mailbox command from issue
5741  * mailbox command.
5742  **/
5743 void
5744 lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox)
5745 {
5746 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
5747         uint32_t *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt, *mbx_mbox_cmd;
5748         char line_buf[LPFC_MBX_ACC_LBUF_SZ];
5749         int len = 0;
5750         uint32_t *pword;
5751         uint8_t *pbyte;
5752         uint32_t i, j;
5753
5754         if (idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP)
5755                 return;
5756
5757         mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
5758         mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
5759         mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
5760         mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
5761
5762         if (!(*mbx_dump_map & LPFC_MBX_DMP_MBX_ALL) ||
5763             (*mbx_dump_cnt == 0) ||
5764             (*mbx_word_cnt == 0))
5765                 return;
5766
5767         if ((*mbx_mbox_cmd != LPFC_MBX_ALL_CMD) &&
5768             (*mbx_mbox_cmd != pmbox->mbxCommand))
5769                 return;
5770
5771         /* dump buffer content */
5772         if (*mbx_dump_map & LPFC_MBX_DMP_MBX_WORD) {
5773                 pr_err("Mailbox command:0x%x dump by word:\n",
5774                        pmbox->mbxCommand);
5775                 pword = (uint32_t *)pmbox;
5776                 for (i = 0; i < *mbx_word_cnt; i++) {
5777                         if (!(i % 8)) {
5778                                 if (i != 0)
5779                                         pr_err("%s\n", line_buf);
5780                                 len = 0;
5781                                 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
5782                                 len += scnprintf(line_buf+len,
5783                                                 LPFC_MBX_ACC_LBUF_SZ-len,
5784                                                 "%03d: ", i);
5785                         }
5786                         len += scnprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
5787                                         "%08x ",
5788                                         ((uint32_t)*pword) & 0xffffffff);
5789                         pword++;
5790                 }
5791                 if ((i - 1) % 8)
5792                         pr_err("%s\n", line_buf);
5793                 pr_err("\n");
5794         }
5795         if (*mbx_dump_map & LPFC_MBX_DMP_MBX_BYTE) {
5796                 pr_err("Mailbox command:0x%x dump by byte:\n",
5797                        pmbox->mbxCommand);
5798                 pbyte = (uint8_t *)pmbox;
5799                 for (i = 0; i < *mbx_word_cnt; i++) {
5800                         if (!(i % 8)) {
5801                                 if (i != 0)
5802                                         pr_err("%s\n", line_buf);
5803                                 len = 0;
5804                                 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
5805                                 len += scnprintf(line_buf+len,
5806                                                 LPFC_MBX_ACC_LBUF_SZ-len,
5807                                                 "%03d: ", i);
5808                         }
5809                         for (j = 0; j < 4; j++) {
5810                                 len += scnprintf(line_buf+len,
5811                                                 LPFC_MBX_ACC_LBUF_SZ-len,
5812                                                 "%02x",
5813                                                 ((uint8_t)*pbyte) & 0xff);
5814                                 pbyte++;
5815                         }
5816                         len += scnprintf(line_buf+len,
5817                                         LPFC_MBX_ACC_LBUF_SZ-len, " ");
5818                 }
5819                 if ((i - 1) % 8)
5820                         pr_err("%s\n", line_buf);
5821                 pr_err("\n");
5822         }
5823         (*mbx_dump_cnt)--;
5824
5825         /* Clean out command structure on reaching dump count */
5826         if (*mbx_dump_cnt == 0)
5827                 memset(&idiag, 0, sizeof(idiag));
5828         return;
5829 #endif
5830 }
5831
5832 /**
5833  * lpfc_debugfs_initialize - Initialize debugfs for a vport
5834  * @vport: The vport pointer to initialize.
5835  *
5836  * Description:
5837  * When Debugfs is configured this routine sets up the lpfc debugfs file system.
5838  * If not already created, this routine will create the lpfc directory, and
5839  * lpfcX directory (for this HBA), and vportX directory for this vport. It will
5840  * also create each file used to access lpfc specific debugfs information.
5841  **/
5842 inline void
5843 lpfc_debugfs_initialize(struct lpfc_vport *vport)
5844 {
5845 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
5846         struct lpfc_hba   *phba = vport->phba;
5847         char name[64];
5848         uint32_t num, i;
5849         bool pport_setup = false;
5850
5851         if (!lpfc_debugfs_enable)
5852                 return;
5853
5854         /* Setup lpfc root directory */
5855         if (!lpfc_debugfs_root) {
5856                 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
5857                 atomic_set(&lpfc_debugfs_hba_count, 0);
5858         }
5859         if (!lpfc_debugfs_start_time)
5860                 lpfc_debugfs_start_time = jiffies;
5861
5862         /* Setup funcX directory for specific HBA PCI function */
5863         snprintf(name, sizeof(name), "fn%d", phba->brd_no);
5864         if (!phba->hba_debugfs_root) {
5865                 pport_setup = true;
5866                 phba->hba_debugfs_root =
5867                         debugfs_create_dir(name, lpfc_debugfs_root);
5868                 atomic_inc(&lpfc_debugfs_hba_count);
5869                 atomic_set(&phba->debugfs_vport_count, 0);
5870
5871                 /* Multi-XRI pools */
5872                 snprintf(name, sizeof(name), "multixripools");
5873                 phba->debug_multixri_pools =
5874                         debugfs_create_file(name, S_IFREG | 0644,
5875                                             phba->hba_debugfs_root,
5876                                             phba,
5877                                             &lpfc_debugfs_op_multixripools);
5878                 if (!phba->debug_multixri_pools) {
5879                         lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
5880                                          "0527 Cannot create debugfs multixripools\n");
5881                         goto debug_failed;
5882                 }
5883
5884                 /* Setup hbqinfo */
5885                 snprintf(name, sizeof(name), "hbqinfo");
5886                 phba->debug_hbqinfo =
5887                         debugfs_create_file(name, S_IFREG | 0644,
5888                                             phba->hba_debugfs_root,
5889                                             phba, &lpfc_debugfs_op_hbqinfo);
5890
5891 #ifdef LPFC_HDWQ_LOCK_STAT
5892                 /* Setup lockstat */
5893                 snprintf(name, sizeof(name), "lockstat");
5894                 phba->debug_lockstat =
5895                         debugfs_create_file(name, S_IFREG | 0644,
5896                                             phba->hba_debugfs_root,
5897                                             phba, &lpfc_debugfs_op_lockstat);
5898                 if (!phba->debug_lockstat) {
5899                         lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
5900                                          "4610 Cant create debugfs lockstat\n");
5901                         goto debug_failed;
5902                 }
5903 #endif
5904
5905                 /* Setup dumpHBASlim */
5906                 if (phba->sli_rev < LPFC_SLI_REV4) {
5907                         snprintf(name, sizeof(name), "dumpHBASlim");
5908                         phba->debug_dumpHBASlim =
5909                                 debugfs_create_file(name,
5910                                         S_IFREG|S_IRUGO|S_IWUSR,
5911                                         phba->hba_debugfs_root,
5912                                         phba, &lpfc_debugfs_op_dumpHBASlim);
5913                 } else
5914                         phba->debug_dumpHBASlim = NULL;
5915
5916                 /* Setup dumpHostSlim */
5917                 if (phba->sli_rev < LPFC_SLI_REV4) {
5918                         snprintf(name, sizeof(name), "dumpHostSlim");
5919                         phba->debug_dumpHostSlim =
5920                                 debugfs_create_file(name,
5921                                         S_IFREG|S_IRUGO|S_IWUSR,
5922                                         phba->hba_debugfs_root,
5923                                         phba, &lpfc_debugfs_op_dumpHostSlim);
5924                 } else
5925                         phba->debug_dumpHostSlim = NULL;
5926
5927                 /* Setup dumpData */
5928                 snprintf(name, sizeof(name), "dumpData");
5929                 phba->debug_dumpData =
5930                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5931                                  phba->hba_debugfs_root,
5932                                  phba, &lpfc_debugfs_op_dumpData);
5933
5934                 /* Setup dumpDif */
5935                 snprintf(name, sizeof(name), "dumpDif");
5936                 phba->debug_dumpDif =
5937                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5938                                  phba->hba_debugfs_root,
5939                                  phba, &lpfc_debugfs_op_dumpDif);
5940
5941                 /* Setup DIF Error Injections */
5942                 snprintf(name, sizeof(name), "InjErrLBA");
5943                 phba->debug_InjErrLBA =
5944                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5945                         phba->hba_debugfs_root,
5946                         phba, &lpfc_debugfs_op_dif_err);
5947                 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
5948
5949                 snprintf(name, sizeof(name), "InjErrNPortID");
5950                 phba->debug_InjErrNPortID =
5951                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5952                         phba->hba_debugfs_root,
5953                         phba, &lpfc_debugfs_op_dif_err);
5954
5955                 snprintf(name, sizeof(name), "InjErrWWPN");
5956                 phba->debug_InjErrWWPN =
5957                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5958                         phba->hba_debugfs_root,
5959                         phba, &lpfc_debugfs_op_dif_err);
5960
5961                 snprintf(name, sizeof(name), "writeGuardInjErr");
5962                 phba->debug_writeGuard =
5963                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5964                         phba->hba_debugfs_root,
5965                         phba, &lpfc_debugfs_op_dif_err);
5966
5967                 snprintf(name, sizeof(name), "writeAppInjErr");
5968                 phba->debug_writeApp =
5969                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5970                         phba->hba_debugfs_root,
5971                         phba, &lpfc_debugfs_op_dif_err);
5972
5973                 snprintf(name, sizeof(name), "writeRefInjErr");
5974                 phba->debug_writeRef =
5975                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5976                         phba->hba_debugfs_root,
5977                         phba, &lpfc_debugfs_op_dif_err);
5978
5979                 snprintf(name, sizeof(name), "readGuardInjErr");
5980                 phba->debug_readGuard =
5981                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5982                         phba->hba_debugfs_root,
5983                         phba, &lpfc_debugfs_op_dif_err);
5984
5985                 snprintf(name, sizeof(name), "readAppInjErr");
5986                 phba->debug_readApp =
5987                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5988                         phba->hba_debugfs_root,
5989                         phba, &lpfc_debugfs_op_dif_err);
5990
5991                 snprintf(name, sizeof(name), "readRefInjErr");
5992                 phba->debug_readRef =
5993                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5994                         phba->hba_debugfs_root,
5995                         phba, &lpfc_debugfs_op_dif_err);
5996
5997                 /* Setup slow ring trace */
5998                 if (lpfc_debugfs_max_slow_ring_trc) {
5999                         num = lpfc_debugfs_max_slow_ring_trc - 1;
6000                         if (num & lpfc_debugfs_max_slow_ring_trc) {
6001                                 /* Change to be a power of 2 */
6002                                 num = lpfc_debugfs_max_slow_ring_trc;
6003                                 i = 0;
6004                                 while (num > 1) {
6005                                         num = num >> 1;
6006                                         i++;
6007                                 }
6008                                 lpfc_debugfs_max_slow_ring_trc = (1 << i);
6009                                 pr_err("lpfc_debugfs_max_disc_trc changed to "
6010                                        "%d\n", lpfc_debugfs_max_disc_trc);
6011                         }
6012                 }
6013
6014                 snprintf(name, sizeof(name), "slow_ring_trace");
6015                 phba->debug_slow_ring_trc =
6016                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6017                                  phba->hba_debugfs_root,
6018                                  phba, &lpfc_debugfs_op_slow_ring_trc);
6019                 if (!phba->slow_ring_trc) {
6020                         phba->slow_ring_trc = kmalloc(
6021                                 (sizeof(struct lpfc_debugfs_trc) *
6022                                 lpfc_debugfs_max_slow_ring_trc),
6023                                 GFP_KERNEL);
6024                         if (!phba->slow_ring_trc) {
6025                                 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6026                                                  "0416 Cannot create debugfs "
6027                                                  "slow_ring buffer\n");
6028                                 goto debug_failed;
6029                         }
6030                         atomic_set(&phba->slow_ring_trc_cnt, 0);
6031                         memset(phba->slow_ring_trc, 0,
6032                                 (sizeof(struct lpfc_debugfs_trc) *
6033                                 lpfc_debugfs_max_slow_ring_trc));
6034                 }
6035
6036                 snprintf(name, sizeof(name), "nvmeio_trc");
6037                 phba->debug_nvmeio_trc =
6038                         debugfs_create_file(name, 0644,
6039                                             phba->hba_debugfs_root,
6040                                             phba, &lpfc_debugfs_op_nvmeio_trc);
6041
6042                 atomic_set(&phba->nvmeio_trc_cnt, 0);
6043                 if (lpfc_debugfs_max_nvmeio_trc) {
6044                         num = lpfc_debugfs_max_nvmeio_trc - 1;
6045                         if (num & lpfc_debugfs_max_disc_trc) {
6046                                 /* Change to be a power of 2 */
6047                                 num = lpfc_debugfs_max_nvmeio_trc;
6048                                 i = 0;
6049                                 while (num > 1) {
6050                                         num = num >> 1;
6051                                         i++;
6052                                 }
6053                                 lpfc_debugfs_max_nvmeio_trc = (1 << i);
6054                                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
6055                                                 "0575 lpfc_debugfs_max_nvmeio_trc "
6056                                                 "changed to %d\n",
6057                                                 lpfc_debugfs_max_nvmeio_trc);
6058                         }
6059                         phba->nvmeio_trc_size = lpfc_debugfs_max_nvmeio_trc;
6060
6061                         /* Allocate trace buffer and initialize */
6062                         phba->nvmeio_trc = kzalloc(
6063                                 (sizeof(struct lpfc_debugfs_nvmeio_trc) *
6064                                 phba->nvmeio_trc_size), GFP_KERNEL);
6065
6066                         if (!phba->nvmeio_trc) {
6067                                 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
6068                                                 "0576 Cannot create debugfs "
6069                                                 "nvmeio_trc buffer\n");
6070                                 goto nvmeio_off;
6071                         }
6072                         phba->nvmeio_trc_on = 1;
6073                         phba->nvmeio_trc_output_idx = 0;
6074                         phba->nvmeio_trc = NULL;
6075                 } else {
6076 nvmeio_off:
6077                         phba->nvmeio_trc_size = 0;
6078                         phba->nvmeio_trc_on = 0;
6079                         phba->nvmeio_trc_output_idx = 0;
6080                         phba->nvmeio_trc = NULL;
6081                 }
6082         }
6083
6084         snprintf(name, sizeof(name), "vport%d", vport->vpi);
6085         if (!vport->vport_debugfs_root) {
6086                 vport->vport_debugfs_root =
6087                         debugfs_create_dir(name, phba->hba_debugfs_root);
6088                 atomic_inc(&phba->debugfs_vport_count);
6089         }
6090
6091         if (lpfc_debugfs_max_disc_trc) {
6092                 num = lpfc_debugfs_max_disc_trc - 1;
6093                 if (num & lpfc_debugfs_max_disc_trc) {
6094                         /* Change to be a power of 2 */
6095                         num = lpfc_debugfs_max_disc_trc;
6096                         i = 0;
6097                         while (num > 1) {
6098                                 num = num >> 1;
6099                                 i++;
6100                         }
6101                         lpfc_debugfs_max_disc_trc = (1 << i);
6102                         pr_err("lpfc_debugfs_max_disc_trc changed to %d\n",
6103                                lpfc_debugfs_max_disc_trc);
6104                 }
6105         }
6106
6107         vport->disc_trc = kzalloc(
6108                 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
6109                 GFP_KERNEL);
6110
6111         if (!vport->disc_trc) {
6112                 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6113                                  "0418 Cannot create debugfs disc trace "
6114                                  "buffer\n");
6115                 goto debug_failed;
6116         }
6117         atomic_set(&vport->disc_trc_cnt, 0);
6118
6119         snprintf(name, sizeof(name), "discovery_trace");
6120         vport->debug_disc_trc =
6121                 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6122                                  vport->vport_debugfs_root,
6123                                  vport, &lpfc_debugfs_op_disc_trc);
6124         snprintf(name, sizeof(name), "nodelist");
6125         vport->debug_nodelist =
6126                 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6127                                  vport->vport_debugfs_root,
6128                                  vport, &lpfc_debugfs_op_nodelist);
6129
6130         snprintf(name, sizeof(name), "nvmestat");
6131         vport->debug_nvmestat =
6132                 debugfs_create_file(name, 0644,
6133                                     vport->vport_debugfs_root,
6134                                     vport, &lpfc_debugfs_op_nvmestat);
6135
6136         snprintf(name, sizeof(name), "scsistat");
6137         vport->debug_scsistat =
6138                 debugfs_create_file(name, 0644,
6139                                     vport->vport_debugfs_root,
6140                                     vport, &lpfc_debugfs_op_scsistat);
6141         if (!vport->debug_scsistat) {
6142                 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6143                                  "4611 Cannot create debugfs scsistat\n");
6144                 goto debug_failed;
6145         }
6146
6147         snprintf(name, sizeof(name), "nvmektime");
6148         vport->debug_nvmektime =
6149                 debugfs_create_file(name, 0644,
6150                                     vport->vport_debugfs_root,
6151                                     vport, &lpfc_debugfs_op_nvmektime);
6152
6153         snprintf(name, sizeof(name), "cpucheck");
6154         vport->debug_cpucheck =
6155                 debugfs_create_file(name, 0644,
6156                                     vport->vport_debugfs_root,
6157                                     vport, &lpfc_debugfs_op_cpucheck);
6158
6159         /*
6160          * The following section is for additional directories/files for the
6161          * physical port.
6162          */
6163
6164         if (!pport_setup)
6165                 goto debug_failed;
6166
6167         /*
6168          * iDiag debugfs root entry points for SLI4 device only
6169          */
6170         if (phba->sli_rev < LPFC_SLI_REV4)
6171                 goto debug_failed;
6172
6173         snprintf(name, sizeof(name), "iDiag");
6174         if (!phba->idiag_root) {
6175                 phba->idiag_root =
6176                         debugfs_create_dir(name, phba->hba_debugfs_root);
6177                 /* Initialize iDiag data structure */
6178                 memset(&idiag, 0, sizeof(idiag));
6179         }
6180
6181         /* iDiag read PCI config space */
6182         snprintf(name, sizeof(name), "pciCfg");
6183         if (!phba->idiag_pci_cfg) {
6184                 phba->idiag_pci_cfg =
6185                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6186                                 phba->idiag_root, phba, &lpfc_idiag_op_pciCfg);
6187                 idiag.offset.last_rd = 0;
6188         }
6189
6190         /* iDiag PCI BAR access */
6191         snprintf(name, sizeof(name), "barAcc");
6192         if (!phba->idiag_bar_acc) {
6193                 phba->idiag_bar_acc =
6194                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6195                                 phba->idiag_root, phba, &lpfc_idiag_op_barAcc);
6196                 idiag.offset.last_rd = 0;
6197         }
6198
6199         /* iDiag get PCI function queue information */
6200         snprintf(name, sizeof(name), "queInfo");
6201         if (!phba->idiag_que_info) {
6202                 phba->idiag_que_info =
6203                         debugfs_create_file(name, S_IFREG|S_IRUGO,
6204                         phba->idiag_root, phba, &lpfc_idiag_op_queInfo);
6205         }
6206
6207         /* iDiag access PCI function queue */
6208         snprintf(name, sizeof(name), "queAcc");
6209         if (!phba->idiag_que_acc) {
6210                 phba->idiag_que_acc =
6211                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6212                                 phba->idiag_root, phba, &lpfc_idiag_op_queAcc);
6213         }
6214
6215         /* iDiag access PCI function doorbell registers */
6216         snprintf(name, sizeof(name), "drbAcc");
6217         if (!phba->idiag_drb_acc) {
6218                 phba->idiag_drb_acc =
6219                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6220                                 phba->idiag_root, phba, &lpfc_idiag_op_drbAcc);
6221         }
6222
6223         /* iDiag access PCI function control registers */
6224         snprintf(name, sizeof(name), "ctlAcc");
6225         if (!phba->idiag_ctl_acc) {
6226                 phba->idiag_ctl_acc =
6227                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6228                                 phba->idiag_root, phba, &lpfc_idiag_op_ctlAcc);
6229         }
6230
6231         /* iDiag access mbox commands */
6232         snprintf(name, sizeof(name), "mbxAcc");
6233         if (!phba->idiag_mbx_acc) {
6234                 phba->idiag_mbx_acc =
6235                         debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6236                                 phba->idiag_root, phba, &lpfc_idiag_op_mbxAcc);
6237         }
6238
6239         /* iDiag extents access commands */
6240         if (phba->sli4_hba.extents_in_use) {
6241                 snprintf(name, sizeof(name), "extAcc");
6242                 if (!phba->idiag_ext_acc) {
6243                         phba->idiag_ext_acc =
6244                                 debugfs_create_file(name,
6245                                                     S_IFREG|S_IRUGO|S_IWUSR,
6246                                                     phba->idiag_root, phba,
6247                                                     &lpfc_idiag_op_extAcc);
6248                 }
6249         }
6250
6251 debug_failed:
6252         return;
6253 #endif
6254 }
6255
6256 /**
6257  * lpfc_debugfs_terminate -  Tear down debugfs infrastructure for this vport
6258  * @vport: The vport pointer to remove from debugfs.
6259  *
6260  * Description:
6261  * When Debugfs is configured this routine removes debugfs file system elements
6262  * that are specific to this vport. It also checks to see if there are any
6263  * users left for the debugfs directories associated with the HBA and driver. If
6264  * this is the last user of the HBA directory or driver directory then it will
6265  * remove those from the debugfs infrastructure as well.
6266  **/
6267 inline void
6268 lpfc_debugfs_terminate(struct lpfc_vport *vport)
6269 {
6270 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
6271         struct lpfc_hba   *phba = vport->phba;
6272
6273         kfree(vport->disc_trc);
6274         vport->disc_trc = NULL;
6275
6276         debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
6277         vport->debug_disc_trc = NULL;
6278
6279         debugfs_remove(vport->debug_nodelist); /* nodelist */
6280         vport->debug_nodelist = NULL;
6281
6282         debugfs_remove(vport->debug_nvmestat); /* nvmestat */
6283         vport->debug_nvmestat = NULL;
6284
6285         debugfs_remove(vport->debug_scsistat); /* scsistat */
6286         vport->debug_scsistat = NULL;
6287
6288         debugfs_remove(vport->debug_nvmektime); /* nvmektime */
6289         vport->debug_nvmektime = NULL;
6290
6291         debugfs_remove(vport->debug_cpucheck); /* cpucheck */
6292         vport->debug_cpucheck = NULL;
6293
6294         if (vport->vport_debugfs_root) {
6295                 debugfs_remove(vport->vport_debugfs_root); /* vportX */
6296                 vport->vport_debugfs_root = NULL;
6297                 atomic_dec(&phba->debugfs_vport_count);
6298         }
6299
6300         if (atomic_read(&phba->debugfs_vport_count) == 0) {
6301
6302                 debugfs_remove(phba->debug_multixri_pools); /* multixripools*/
6303                 phba->debug_multixri_pools = NULL;
6304
6305                 debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
6306                 phba->debug_hbqinfo = NULL;
6307
6308 #ifdef LPFC_HDWQ_LOCK_STAT
6309                 debugfs_remove(phba->debug_lockstat); /* lockstat */
6310                 phba->debug_lockstat = NULL;
6311 #endif
6312                 debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */
6313                 phba->debug_dumpHBASlim = NULL;
6314
6315                 debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */
6316                 phba->debug_dumpHostSlim = NULL;
6317
6318                 debugfs_remove(phba->debug_dumpData); /* dumpData */
6319                 phba->debug_dumpData = NULL;
6320
6321                 debugfs_remove(phba->debug_dumpDif); /* dumpDif */
6322                 phba->debug_dumpDif = NULL;
6323
6324                 debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */
6325                 phba->debug_InjErrLBA = NULL;
6326
6327                 debugfs_remove(phba->debug_InjErrNPortID);
6328                 phba->debug_InjErrNPortID = NULL;
6329
6330                 debugfs_remove(phba->debug_InjErrWWPN); /* InjErrWWPN */
6331                 phba->debug_InjErrWWPN = NULL;
6332
6333                 debugfs_remove(phba->debug_writeGuard); /* writeGuard */
6334                 phba->debug_writeGuard = NULL;
6335
6336                 debugfs_remove(phba->debug_writeApp); /* writeApp */
6337                 phba->debug_writeApp = NULL;
6338
6339                 debugfs_remove(phba->debug_writeRef); /* writeRef */
6340                 phba->debug_writeRef = NULL;
6341
6342                 debugfs_remove(phba->debug_readGuard); /* readGuard */
6343                 phba->debug_readGuard = NULL;
6344
6345                 debugfs_remove(phba->debug_readApp); /* readApp */
6346                 phba->debug_readApp = NULL;
6347
6348                 debugfs_remove(phba->debug_readRef); /* readRef */
6349                 phba->debug_readRef = NULL;
6350
6351                 kfree(phba->slow_ring_trc);
6352                 phba->slow_ring_trc = NULL;
6353
6354                 /* slow_ring_trace */
6355                 debugfs_remove(phba->debug_slow_ring_trc);
6356                 phba->debug_slow_ring_trc = NULL;
6357
6358                 debugfs_remove(phba->debug_nvmeio_trc);
6359                 phba->debug_nvmeio_trc = NULL;
6360
6361                 kfree(phba->nvmeio_trc);
6362                 phba->nvmeio_trc = NULL;
6363
6364                 /*
6365                  * iDiag release
6366                  */
6367                 if (phba->sli_rev == LPFC_SLI_REV4) {
6368                         /* iDiag extAcc */
6369                         debugfs_remove(phba->idiag_ext_acc);
6370                         phba->idiag_ext_acc = NULL;
6371
6372                         /* iDiag mbxAcc */
6373                         debugfs_remove(phba->idiag_mbx_acc);
6374                         phba->idiag_mbx_acc = NULL;
6375
6376                         /* iDiag ctlAcc */
6377                         debugfs_remove(phba->idiag_ctl_acc);
6378                         phba->idiag_ctl_acc = NULL;
6379
6380                         /* iDiag drbAcc */
6381                         debugfs_remove(phba->idiag_drb_acc);
6382                         phba->idiag_drb_acc = NULL;
6383
6384                         /* iDiag queAcc */
6385                         debugfs_remove(phba->idiag_que_acc);
6386                         phba->idiag_que_acc = NULL;
6387
6388                         /* iDiag queInfo */
6389                         debugfs_remove(phba->idiag_que_info);
6390                         phba->idiag_que_info = NULL;
6391
6392                         /* iDiag barAcc */
6393                         debugfs_remove(phba->idiag_bar_acc);
6394                         phba->idiag_bar_acc = NULL;
6395
6396                         /* iDiag pciCfg */
6397                         debugfs_remove(phba->idiag_pci_cfg);
6398                         phba->idiag_pci_cfg = NULL;
6399
6400                         /* Finally remove the iDiag debugfs root */
6401                         debugfs_remove(phba->idiag_root);
6402                         phba->idiag_root = NULL;
6403                 }
6404
6405                 if (phba->hba_debugfs_root) {
6406                         debugfs_remove(phba->hba_debugfs_root); /* fnX */
6407                         phba->hba_debugfs_root = NULL;
6408                         atomic_dec(&lpfc_debugfs_hba_count);
6409                 }
6410
6411                 if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
6412                         debugfs_remove(lpfc_debugfs_root); /* lpfc */
6413                         lpfc_debugfs_root = NULL;
6414                 }
6415         }
6416 #endif
6417         return;
6418 }
6419
6420 /*
6421  * Driver debug utility routines outside of debugfs. The debug utility
6422  * routines implemented here is intended to be used in the instrumented
6423  * debug driver for debugging host or port issues.
6424  */
6425
6426 /**
6427  * lpfc_debug_dump_all_queues - dump all the queues with a hba
6428  * @phba: Pointer to HBA context object.
6429  *
6430  * This function dumps entries of all the queues asociated with the @phba.
6431  **/
6432 void
6433 lpfc_debug_dump_all_queues(struct lpfc_hba *phba)
6434 {
6435         int idx;
6436
6437         /*
6438          * Dump Work Queues (WQs)
6439          */
6440         lpfc_debug_dump_wq(phba, DUMP_MBX, 0);
6441         lpfc_debug_dump_wq(phba, DUMP_ELS, 0);
6442         lpfc_debug_dump_wq(phba, DUMP_NVMELS, 0);
6443
6444         for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6445                 lpfc_debug_dump_wq(phba, DUMP_FCP, idx);
6446
6447         if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
6448                 for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6449                         lpfc_debug_dump_wq(phba, DUMP_NVME, idx);
6450         }
6451
6452         lpfc_debug_dump_hdr_rq(phba);
6453         lpfc_debug_dump_dat_rq(phba);
6454         /*
6455          * Dump Complete Queues (CQs)
6456          */
6457         lpfc_debug_dump_cq(phba, DUMP_MBX, 0);
6458         lpfc_debug_dump_cq(phba, DUMP_ELS, 0);
6459         lpfc_debug_dump_cq(phba, DUMP_NVMELS, 0);
6460
6461         for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6462                 lpfc_debug_dump_cq(phba, DUMP_FCP, idx);
6463
6464         if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
6465                 for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6466                         lpfc_debug_dump_cq(phba, DUMP_NVME, idx);
6467         }
6468
6469         /*
6470          * Dump Event Queues (EQs)
6471          */
6472         for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6473                 lpfc_debug_dump_hba_eq(phba, idx);
6474 }
This page took 0.429405 seconds and 4 git commands to generate.