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. *
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 *******************************************************************/
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>
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>
41 #include <linux/nvme-fc-driver.h>
46 #include "lpfc_sli4.h"
48 #include "lpfc_disc.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"
61 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
65 * To access this interface the user should:
66 * # mount -t debugfs none /sys/kernel/debug
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
73 * Debugging services available per vport:
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
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.
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");
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");
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");
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");
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");
120 #include <linux/debugfs.h>
122 static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
123 static unsigned long lpfc_debugfs_start_time = 0L;
126 static struct lpfc_idiag idiag;
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.
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.
141 * Discovery logging will be disabled while while this routine dumps the log.
144 * This routine returns the amount of bytes that were dumped into @buf and will
148 lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
150 int i, index, len, enable;
152 struct lpfc_debugfs_trc *dtp;
155 buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
159 enable = lpfc_debugfs_enable;
160 lpfc_debugfs_enable = 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;
169 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
171 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
172 dtp->seq_cnt, ms, dtp->fmt);
173 len += snprintf(buf+len, size-len, buffer,
174 dtp->data1, dtp->data2, dtp->data3);
176 for (i = 0; i < index; i++) {
177 dtp = vport->disc_trc + i;
180 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
182 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
183 dtp->seq_cnt, ms, dtp->fmt);
184 len += snprintf(buf+len, size-len, buffer,
185 dtp->data1, dtp->data2, dtp->data3);
188 lpfc_debugfs_enable = enable;
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.
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.
207 * Slow ring logging will be disabled while while this routine dumps the log.
210 * This routine returns the amount of bytes that were dumped into @buf and will
214 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
216 int i, index, len, enable;
218 struct lpfc_debugfs_trc *dtp;
221 buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
225 enable = lpfc_debugfs_enable;
226 lpfc_debugfs_enable = 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;
235 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
237 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
238 dtp->seq_cnt, ms, dtp->fmt);
239 len += snprintf(buf+len, size-len, buffer,
240 dtp->data1, dtp->data2, dtp->data3);
242 for (i = 0; i < index; i++) {
243 dtp = phba->slow_ring_trc + i;
246 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
248 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
249 dtp->seq_cnt, ms, dtp->fmt);
250 len += snprintf(buf+len, size-len, buffer,
251 dtp->data1, dtp->data2, dtp->data3);
254 lpfc_debugfs_enable = enable;
260 static int lpfc_debugfs_last_hbq = -1;
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.
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.
275 * This routine will rotate through each configured HBQ each time called.
278 * This routine returns the amount of bytes that were dumped into @buf and will
282 lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
285 int i, j, found, posted, low;
286 uint32_t phys, raw_index, getidx;
287 struct lpfc_hbq_init *hip;
289 struct lpfc_hbq_entry *hbqe;
290 struct lpfc_dmabuf *d_buf;
291 struct hbq_dmabuf *hbq_buf;
293 if (phba->sli_rev != 3)
296 spin_lock_irq(&phba->hbalock);
298 /* toggle between multiple hbqs, if any */
299 i = lpfc_sli_hbq_count();
301 lpfc_debugfs_last_hbq++;
302 if (lpfc_debugfs_last_hbq >= i)
303 lpfc_debugfs_last_hbq = 0;
306 lpfc_debugfs_last_hbq = 0;
308 i = lpfc_debugfs_last_hbq;
310 len += snprintf(buf+len, size-len, "HBQ %d Info\n", i);
312 hbqs = &phba->hbqs[i];
314 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
317 hip = lpfc_hbq_defs[i];
318 len += snprintf(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);
323 raw_index = phba->hbq_get[i];
324 getidx = le32_to_cpu(raw_index);
325 len += snprintf(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);
330 hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
331 for (j=0; j<hbqs->entry_count; j++) {
332 len += snprintf(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));
340 /* First calculate if slot has an associated posted buffer */
341 low = hbqs->hbqPutIdx - posted;
343 if ((j >= hbqs->hbqPutIdx) || (j < low)) {
344 len += snprintf(buf+len, size-len, "Unused\n");
349 if ((j >= hbqs->hbqPutIdx) &&
350 (j < (hbqs->entry_count+low))) {
351 len += snprintf(buf+len, size-len, "Unused\n");
356 /* Get the Buffer info for the posted buffer */
357 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
358 hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
359 phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
360 if (phys == le32_to_cpu(hbqe->bde.addrLow)) {
361 len += snprintf(buf+len, size-len,
362 "Buf%d: %p %06x\n", i,
363 hbq_buf->dbuf.virt, hbq_buf->tag);
370 len += snprintf(buf+len, size-len, "No DMAinfo?\n");
374 if (len > LPFC_HBQINFO_SIZE - 54)
377 spin_unlock_irq(&phba->hbalock);
381 static int lpfc_debugfs_last_xripool;
384 * lpfc_debugfs_common_xri_data - Dump Hardware Queue info to a buffer
385 * @phba: The HBA to gather host buffer info from.
386 * @buf: The buffer to dump log into.
387 * @size: The maximum amount of data to process.
390 * This routine dumps the Hardware Queue info from the @phba to @buf up to
391 * @size number of bytes. A header that describes the current hdwq state will be
392 * dumped to @buf first and then info on each hdwq entry will be dumped to @buf
393 * until @size bytes have been dumped or all the hdwq info has been dumped.
396 * This routine will rotate through each configured Hardware Queue each
400 * This routine returns the amount of bytes that were dumped into @buf and will
404 lpfc_debugfs_commonxripools_data(struct lpfc_hba *phba, char *buf, int size)
406 struct lpfc_sli4_hdw_queue *qp;
411 for (i = 0; i < phba->cfg_hdw_queue; i++) {
412 if (len > (LPFC_DUMP_MULTIXRIPOOL_SIZE - 80))
414 qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_xripool];
416 len += snprintf(buf + len, size - len, "HdwQ %d Info ", i);
417 spin_lock_irqsave(&qp->abts_scsi_buf_list_lock, iflag);
418 spin_lock(&qp->abts_nvme_buf_list_lock);
419 spin_lock(&qp->io_buf_list_get_lock);
420 spin_lock(&qp->io_buf_list_put_lock);
421 out = qp->total_io_bufs - (qp->get_io_bufs + qp->put_io_bufs +
422 qp->abts_scsi_io_bufs + qp->abts_nvme_io_bufs);
423 len += snprintf(buf + len, size - len,
424 "tot:%d get:%d put:%d mt:%d "
425 "ABTS scsi:%d nvme:%d Out:%d\n",
426 qp->total_io_bufs, qp->get_io_bufs, qp->put_io_bufs,
427 qp->empty_io_bufs, qp->abts_scsi_io_bufs,
428 qp->abts_nvme_io_bufs, out);
429 spin_unlock(&qp->io_buf_list_put_lock);
430 spin_unlock(&qp->io_buf_list_get_lock);
431 spin_unlock(&qp->abts_nvme_buf_list_lock);
432 spin_unlock_irqrestore(&qp->abts_scsi_buf_list_lock, iflag);
434 lpfc_debugfs_last_xripool++;
435 if (lpfc_debugfs_last_xripool >= phba->cfg_hdw_queue)
436 lpfc_debugfs_last_xripool = 0;
443 * lpfc_debugfs_multixripools_data - Display multi-XRI pools information
444 * @phba: The HBA to gather host buffer info from.
445 * @buf: The buffer to dump log into.
446 * @size: The maximum amount of data to process.
449 * This routine displays current multi-XRI pools information including XRI
450 * count in public, private and txcmplq. It also displays current high and
454 * This routine returns the amount of bytes that were dumped into @buf and will
458 lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size)
462 struct lpfc_sli4_hdw_queue *qp;
463 struct lpfc_multixri_pool *multixri_pool;
464 struct lpfc_pvt_pool *pvt_pool;
465 struct lpfc_pbl_pool *pbl_pool;
467 char tmp[LPFC_DEBUG_OUT_LINE_SZ] = {0};
469 if (phba->sli_rev != LPFC_SLI_REV4)
472 if (!phba->sli4_hba.hdwq)
475 if (!phba->cfg_xri_rebalancing) {
476 i = lpfc_debugfs_commonxripools_data(phba, buf, size);
481 * Pbl: Current number of free XRIs in public pool
482 * Pvt: Current number of free XRIs in private pool
483 * Busy: Current number of outstanding XRIs
484 * HWM: Current high watermark
485 * pvt_empty: Incremented by 1 when IO submission fails (no xri)
486 * pbl_empty: Incremented by 1 when all pbl_pool are empty during
489 scnprintf(tmp, sizeof(tmp),
490 "HWQ: Pbl Pvt Busy HWM | pvt_empty pbl_empty ");
491 if (strlcat(buf, tmp, size) >= size)
492 return strnlen(buf, size);
496 * MAXH: Max high watermark seen so far
497 * above_lmt: Incremented by 1 if xri_owned > xri_limit during
499 * below_lmt: Incremented by 1 if xri_owned <= xri_limit during
501 * locPbl_hit: Incremented by 1 if successfully get a batch of XRI from
503 * othPbl_hit: Incremented by 1 if successfully get a batch of XRI from
506 scnprintf(tmp, sizeof(tmp),
507 "MAXH above_lmt below_lmt locPbl_hit othPbl_hit");
508 if (strlcat(buf, tmp, size) >= size)
509 return strnlen(buf, size);
512 * sPbl: snapshot of Pbl 15 sec after stat gets cleared
513 * sPvt: snapshot of Pvt 15 sec after stat gets cleared
514 * sBusy: snapshot of Busy 15 sec after stat gets cleared
516 scnprintf(tmp, sizeof(tmp),
517 " | sPbl sPvt sBusy");
518 if (strlcat(buf, tmp, size) >= size)
519 return strnlen(buf, size);
522 scnprintf(tmp, sizeof(tmp), "\n");
523 if (strlcat(buf, tmp, size) >= size)
524 return strnlen(buf, size);
526 hwq_count = phba->cfg_hdw_queue;
527 for (i = 0; i < hwq_count; i++) {
528 qp = &phba->sli4_hba.hdwq[i];
529 multixri_pool = qp->p_multixri_pool;
532 pbl_pool = &multixri_pool->pbl_pool;
533 pvt_pool = &multixri_pool->pvt_pool;
534 txcmplq_cnt = qp->fcp_wq->pring->txcmplq_cnt;
536 txcmplq_cnt += qp->nvme_wq->pring->txcmplq_cnt;
538 scnprintf(tmp, sizeof(tmp),
539 "%03d: %4d %4d %4d %4d | %10d %10d ",
540 i, pbl_pool->count, pvt_pool->count,
541 txcmplq_cnt, pvt_pool->high_watermark,
542 qp->empty_io_bufs, multixri_pool->pbl_empty_count);
543 if (strlcat(buf, tmp, size) >= size)
547 scnprintf(tmp, sizeof(tmp),
548 "%4d %10d %10d %10d %10d",
549 multixri_pool->stat_max_hwm,
550 multixri_pool->above_limit_count,
551 multixri_pool->below_limit_count,
552 multixri_pool->local_pbl_hit_count,
553 multixri_pool->other_pbl_hit_count);
554 if (strlcat(buf, tmp, size) >= size)
557 scnprintf(tmp, sizeof(tmp),
559 multixri_pool->stat_pbl_count,
560 multixri_pool->stat_pvt_count,
561 multixri_pool->stat_busy_count);
562 if (strlcat(buf, tmp, size) >= size)
566 scnprintf(tmp, sizeof(tmp), "\n");
567 if (strlcat(buf, tmp, size) >= size)
570 return strnlen(buf, size);
574 #ifdef LPFC_HDWQ_LOCK_STAT
575 static int lpfc_debugfs_last_lock;
578 * lpfc_debugfs_lockstat_data - Dump Hardware Queue info to a buffer
579 * @phba: The HBA to gather host buffer info from.
580 * @buf: The buffer to dump log into.
581 * @size: The maximum amount of data to process.
584 * This routine dumps the Hardware Queue info from the @phba to @buf up to
585 * @size number of bytes. A header that describes the current hdwq state will be
586 * dumped to @buf first and then info on each hdwq entry will be dumped to @buf
587 * until @size bytes have been dumped or all the hdwq info has been dumped.
590 * This routine will rotate through each configured Hardware Queue each
594 * This routine returns the amount of bytes that were dumped into @buf and will
598 lpfc_debugfs_lockstat_data(struct lpfc_hba *phba, char *buf, int size)
600 struct lpfc_sli4_hdw_queue *qp;
604 if (phba->sli_rev != LPFC_SLI_REV4)
607 if (!phba->sli4_hba.hdwq)
610 for (i = 0; i < phba->cfg_hdw_queue; i++) {
611 if (len > (LPFC_HDWQINFO_SIZE - 100))
613 qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_lock];
615 len += snprintf(buf + len, size - len, "HdwQ %03d Lock ", i);
616 if (phba->cfg_xri_rebalancing) {
617 len += snprintf(buf + len, size - len,
618 "get_pvt:%d mv_pvt:%d "
619 "mv2pub:%d mv2pvt:%d "
620 "put_pvt:%d put_pub:%d wq:%d\n",
621 qp->lock_conflict.alloc_pvt_pool,
622 qp->lock_conflict.mv_from_pvt_pool,
623 qp->lock_conflict.mv_to_pub_pool,
624 qp->lock_conflict.mv_to_pvt_pool,
625 qp->lock_conflict.free_pvt_pool,
626 qp->lock_conflict.free_pub_pool,
627 qp->lock_conflict.wq_access);
629 len += snprintf(buf + len, size - len,
630 "get:%d put:%d free:%d wq:%d\n",
631 qp->lock_conflict.alloc_xri_get,
632 qp->lock_conflict.alloc_xri_put,
633 qp->lock_conflict.free_xri,
634 qp->lock_conflict.wq_access);
637 lpfc_debugfs_last_lock++;
638 if (lpfc_debugfs_last_lock >= phba->cfg_hdw_queue)
639 lpfc_debugfs_last_lock = 0;
646 static int lpfc_debugfs_last_hba_slim_off;
649 * lpfc_debugfs_dumpHBASlim_data - Dump HBA SLIM info to a buffer
650 * @phba: The HBA to gather SLIM info from.
651 * @buf: The buffer to dump log into.
652 * @size: The maximum amount of data to process.
655 * This routine dumps the current contents of HBA SLIM for the HBA associated
656 * with @phba to @buf up to @size bytes of data. This is the raw HBA SLIM data.
659 * This routine will only dump up to 1024 bytes of data each time called and
660 * should be called multiple times to dump the entire HBA SLIM.
663 * This routine returns the amount of bytes that were dumped into @buf and will
667 lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
674 buffer = kmalloc(1024, GFP_KERNEL);
679 spin_lock_irq(&phba->hbalock);
681 len += snprintf(buf+len, size-len, "HBA SLIM\n");
682 lpfc_memcpy_from_slim(buffer,
683 phba->MBslimaddr + lpfc_debugfs_last_hba_slim_off, 1024);
685 ptr = (uint32_t *)&buffer[0];
686 off = lpfc_debugfs_last_hba_slim_off;
688 /* Set it up for the next time */
689 lpfc_debugfs_last_hba_slim_off += 1024;
690 if (lpfc_debugfs_last_hba_slim_off >= 4096)
691 lpfc_debugfs_last_hba_slim_off = 0;
695 len += snprintf(buf+len, size-len,
696 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
697 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
698 *(ptr+5), *(ptr+6), *(ptr+7));
700 i -= (8 * sizeof(uint32_t));
701 off += (8 * sizeof(uint32_t));
704 spin_unlock_irq(&phba->hbalock);
711 * lpfc_debugfs_dumpHostSlim_data - Dump host SLIM info to a buffer
712 * @phba: The HBA to gather Host SLIM info from.
713 * @buf: The buffer to dump log into.
714 * @size: The maximum amount of data to process.
717 * This routine dumps the current contents of host SLIM for the host associated
718 * with @phba to @buf up to @size bytes of data. The dump will contain the
719 * Mailbox, PCB, Rings, and Registers that are located in host memory.
722 * This routine returns the amount of bytes that were dumped into @buf and will
726 lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
730 uint32_t word0, word1, word2, word3;
732 struct lpfc_pgp *pgpp;
733 struct lpfc_sli *psli = &phba->sli;
734 struct lpfc_sli_ring *pring;
737 spin_lock_irq(&phba->hbalock);
739 len += snprintf(buf+len, size-len, "SLIM Mailbox\n");
740 ptr = (uint32_t *)phba->slim2p.virt;
741 i = sizeof(MAILBOX_t);
743 len += snprintf(buf+len, size-len,
744 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
745 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
746 *(ptr+5), *(ptr+6), *(ptr+7));
748 i -= (8 * sizeof(uint32_t));
749 off += (8 * sizeof(uint32_t));
752 len += snprintf(buf+len, size-len, "SLIM PCB\n");
753 ptr = (uint32_t *)phba->pcb;
756 len += snprintf(buf+len, size-len,
757 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
758 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
759 *(ptr+5), *(ptr+6), *(ptr+7));
761 i -= (8 * sizeof(uint32_t));
762 off += (8 * sizeof(uint32_t));
765 if (phba->sli_rev <= LPFC_SLI_REV3) {
766 for (i = 0; i < 4; i++) {
767 pgpp = &phba->port_gp[i];
768 pring = &psli->sli3_ring[i];
769 len += snprintf(buf+len, size-len,
770 "Ring %d: CMD GetInx:%d "
773 "RSP PutInx:%d Max:%d\n",
775 pring->sli.sli3.numCiocb,
776 pring->sli.sli3.next_cmdidx,
777 pring->sli.sli3.local_getidx,
778 pring->flag, pgpp->rspPutInx,
779 pring->sli.sli3.numRiocb);
782 word0 = readl(phba->HAregaddr);
783 word1 = readl(phba->CAregaddr);
784 word2 = readl(phba->HSregaddr);
785 word3 = readl(phba->HCregaddr);
786 len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x "
787 "HC:%08x\n", word0, word1, word2, word3);
789 spin_unlock_irq(&phba->hbalock);
794 * lpfc_debugfs_nodelist_data - Dump target node list to a buffer
795 * @vport: The vport to gather target node info from.
796 * @buf: The buffer to dump log into.
797 * @size: The maximum amount of data to process.
800 * This routine dumps the current target node list associated with @vport to
801 * @buf up to @size bytes of data. Each node entry in the dump will contain a
802 * node state, DID, WWPN, WWNN, RPI, flags, type, and other useful fields.
805 * This routine returns the amount of bytes that were dumped into @buf and will
809 lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
812 int i, iocnt, outio, cnt;
813 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
814 struct lpfc_hba *phba = vport->phba;
815 struct lpfc_nodelist *ndlp;
816 unsigned char *statep;
817 struct nvme_fc_local_port *localport;
818 struct nvme_fc_remote_port *nrport = NULL;
819 struct lpfc_nvme_rport *rport;
821 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
824 len += snprintf(buf+len, size-len, "\nFCP Nodelist Entries ...\n");
825 spin_lock_irq(shost->host_lock);
826 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
829 len += snprintf(buf+len, size-len,
830 "Missing Nodelist Entries\n");
834 switch (ndlp->nlp_state) {
835 case NLP_STE_UNUSED_NODE:
838 case NLP_STE_PLOGI_ISSUE:
841 case NLP_STE_ADISC_ISSUE:
844 case NLP_STE_REG_LOGIN_ISSUE:
847 case NLP_STE_PRLI_ISSUE:
850 case NLP_STE_LOGO_ISSUE:
853 case NLP_STE_UNMAPPED_NODE:
857 case NLP_STE_MAPPED_NODE:
861 case NLP_STE_NPR_NODE:
867 len += snprintf(buf+len, size-len, "%s DID:x%06x ",
868 statep, ndlp->nlp_DID);
869 len += snprintf(buf+len, size-len,
871 wwn_to_u64(ndlp->nlp_portname.u.wwn));
872 len += snprintf(buf+len, size-len,
874 wwn_to_u64(ndlp->nlp_nodename.u.wwn));
875 if (ndlp->nlp_flag & NLP_RPI_REGISTERED)
876 len += snprintf(buf+len, size-len, "RPI:%03d ",
879 len += snprintf(buf+len, size-len, "RPI:none ");
880 len += snprintf(buf+len, size-len, "flag:x%08x ",
883 len += snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
884 if (ndlp->nlp_type & NLP_FC_NODE)
885 len += snprintf(buf+len, size-len, "FC_NODE ");
886 if (ndlp->nlp_type & NLP_FABRIC) {
887 len += snprintf(buf+len, size-len, "FABRIC ");
890 if (ndlp->nlp_type & NLP_FCP_TARGET)
891 len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ",
893 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
894 len += snprintf(buf+len, size-len, "FCP_INITIATOR ");
895 if (ndlp->nlp_type & NLP_NVME_TARGET)
896 len += snprintf(buf + len,
897 size - len, "NVME_TGT sid:%d ",
899 if (ndlp->nlp_type & NLP_NVME_INITIATOR)
900 len += snprintf(buf + len,
901 size - len, "NVME_INITIATOR ");
902 len += snprintf(buf+len, size-len, "usgmap:%x ",
904 len += snprintf(buf+len, size-len, "refcnt:%x",
905 kref_read(&ndlp->kref));
907 i = atomic_read(&ndlp->cmd_pending);
908 len += snprintf(buf + len, size - len,
909 " OutIO:x%x Qdepth x%x",
910 i, ndlp->cmd_qdepth);
913 len += snprintf(buf + len, size - len, "defer:%x ",
914 ndlp->nlp_defer_did);
915 len += snprintf(buf+len, size-len, "\n");
917 spin_unlock_irq(shost->host_lock);
919 len += snprintf(buf + len, size - len,
920 "\nOutstanding IO x%x\n", outio);
922 if (phba->nvmet_support && phba->targetport && (vport == phba->pport)) {
923 len += snprintf(buf + len, size - len,
924 "\nNVME Targetport Entry ...\n");
926 /* Port state is only one of two values for now. */
927 if (phba->targetport->port_id)
928 statep = "REGISTERED";
931 len += snprintf(buf + len, size - len,
932 "TGT WWNN x%llx WWPN x%llx State %s\n",
933 wwn_to_u64(vport->fc_nodename.u.wwn),
934 wwn_to_u64(vport->fc_portname.u.wwn),
936 len += snprintf(buf + len, size - len,
937 " Targetport DID x%06x\n",
938 phba->targetport->port_id);
942 len += snprintf(buf + len, size - len,
943 "\nNVME Lport/Rport Entries ...\n");
945 localport = vport->localport;
949 spin_lock_irq(shost->host_lock);
951 /* Port state is only one of two values for now. */
952 if (localport->port_id)
957 len += snprintf(buf + len, size - len,
958 "Lport DID x%06x PortState %s\n",
959 localport->port_id, statep);
961 len += snprintf(buf + len, size - len, "\tRport List:\n");
962 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
963 /* local short-hand pointer. */
964 spin_lock(&phba->hbalock);
965 rport = lpfc_ndlp_get_nrport(ndlp);
967 nrport = rport->remoteport;
970 spin_unlock(&phba->hbalock);
974 /* Port state is only one of two values for now. */
975 switch (nrport->port_state) {
976 case FC_OBJSTATE_ONLINE:
979 case FC_OBJSTATE_UNKNOWN:
983 statep = "UNSUPPORTED";
987 /* Tab in to show lport ownership. */
988 len += snprintf(buf + len, size - len,
989 "\t%s Port ID:x%06x ",
990 statep, nrport->port_id);
991 len += snprintf(buf + len, size - len, "WWPN x%llx ",
993 len += snprintf(buf + len, size - len, "WWNN x%llx ",
996 /* An NVME rport can have multiple roles. */
997 if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR)
998 len += snprintf(buf + len, size - len,
1000 if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET)
1001 len += snprintf(buf + len, size - len,
1003 if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY)
1004 len += snprintf(buf + len, size - len,
1006 if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
1007 FC_PORT_ROLE_NVME_TARGET |
1008 FC_PORT_ROLE_NVME_DISCOVERY))
1009 len += snprintf(buf + len, size - len,
1012 /* Terminate the string. */
1013 len += snprintf(buf + len, size - len, "\n");
1016 spin_unlock_irq(shost->host_lock);
1022 * lpfc_debugfs_nvmestat_data - Dump target node list to a buffer
1023 * @vport: The vport to gather target node info from.
1024 * @buf: The buffer to dump log into.
1025 * @size: The maximum amount of data to process.
1028 * This routine dumps the NVME statistics associated with @vport
1031 * This routine returns the amount of bytes that were dumped into @buf and will
1035 lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size)
1037 struct lpfc_hba *phba = vport->phba;
1038 struct lpfc_nvmet_tgtport *tgtp;
1039 struct lpfc_nvmet_rcv_ctx *ctxp, *next_ctxp;
1040 struct nvme_fc_local_port *localport;
1041 struct lpfc_fc4_ctrl_stat *cstat;
1042 struct lpfc_nvme_lport *lport;
1043 uint64_t data1, data2, data3;
1044 uint64_t tot, totin, totout;
1048 if (phba->nvmet_support) {
1049 if (!phba->targetport)
1051 tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
1052 len += snprintf(buf + len, size - len,
1053 "\nNVME Targetport Statistics\n");
1055 len += snprintf(buf + len, size - len,
1056 "LS: Rcv %08x Drop %08x Abort %08x\n",
1057 atomic_read(&tgtp->rcv_ls_req_in),
1058 atomic_read(&tgtp->rcv_ls_req_drop),
1059 atomic_read(&tgtp->xmt_ls_abort));
1060 if (atomic_read(&tgtp->rcv_ls_req_in) !=
1061 atomic_read(&tgtp->rcv_ls_req_out)) {
1062 len += snprintf(buf + len, size - len,
1063 "Rcv LS: in %08x != out %08x\n",
1064 atomic_read(&tgtp->rcv_ls_req_in),
1065 atomic_read(&tgtp->rcv_ls_req_out));
1068 len += snprintf(buf + len, size - len,
1069 "LS: Xmt %08x Drop %08x Cmpl %08x\n",
1070 atomic_read(&tgtp->xmt_ls_rsp),
1071 atomic_read(&tgtp->xmt_ls_drop),
1072 atomic_read(&tgtp->xmt_ls_rsp_cmpl));
1074 len += snprintf(buf + len, size - len,
1075 "LS: RSP Abort %08x xb %08x Err %08x\n",
1076 atomic_read(&tgtp->xmt_ls_rsp_aborted),
1077 atomic_read(&tgtp->xmt_ls_rsp_xb_set),
1078 atomic_read(&tgtp->xmt_ls_rsp_error));
1080 len += snprintf(buf + len, size - len,
1081 "FCP: Rcv %08x Defer %08x Release %08x "
1083 atomic_read(&tgtp->rcv_fcp_cmd_in),
1084 atomic_read(&tgtp->rcv_fcp_cmd_defer),
1085 atomic_read(&tgtp->xmt_fcp_release),
1086 atomic_read(&tgtp->rcv_fcp_cmd_drop));
1088 if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
1089 atomic_read(&tgtp->rcv_fcp_cmd_out)) {
1090 len += snprintf(buf + len, size - len,
1091 "Rcv FCP: in %08x != out %08x\n",
1092 atomic_read(&tgtp->rcv_fcp_cmd_in),
1093 atomic_read(&tgtp->rcv_fcp_cmd_out));
1096 len += snprintf(buf + len, size - len,
1097 "FCP Rsp: read %08x readrsp %08x "
1098 "write %08x rsp %08x\n",
1099 atomic_read(&tgtp->xmt_fcp_read),
1100 atomic_read(&tgtp->xmt_fcp_read_rsp),
1101 atomic_read(&tgtp->xmt_fcp_write),
1102 atomic_read(&tgtp->xmt_fcp_rsp));
1104 len += snprintf(buf + len, size - len,
1105 "FCP Rsp Cmpl: %08x err %08x drop %08x\n",
1106 atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
1107 atomic_read(&tgtp->xmt_fcp_rsp_error),
1108 atomic_read(&tgtp->xmt_fcp_rsp_drop));
1110 len += snprintf(buf + len, size - len,
1111 "FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
1112 atomic_read(&tgtp->xmt_fcp_rsp_aborted),
1113 atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
1114 atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
1116 len += snprintf(buf + len, size - len,
1117 "ABORT: Xmt %08x Cmpl %08x\n",
1118 atomic_read(&tgtp->xmt_fcp_abort),
1119 atomic_read(&tgtp->xmt_fcp_abort_cmpl));
1121 len += snprintf(buf + len, size - len,
1122 "ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x",
1123 atomic_read(&tgtp->xmt_abort_sol),
1124 atomic_read(&tgtp->xmt_abort_unsol),
1125 atomic_read(&tgtp->xmt_abort_rsp),
1126 atomic_read(&tgtp->xmt_abort_rsp_error));
1128 len += snprintf(buf + len, size - len, "\n");
1131 spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1132 list_for_each_entry_safe(ctxp, next_ctxp,
1133 &phba->sli4_hba.lpfc_abts_nvmet_ctx_list,
1137 spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1139 len += snprintf(buf + len, size - len,
1140 "ABORT: %d ctx entries\n", cnt);
1141 spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1142 list_for_each_entry_safe(ctxp, next_ctxp,
1143 &phba->sli4_hba.lpfc_abts_nvmet_ctx_list,
1145 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ))
1147 len += snprintf(buf + len, size - len,
1148 "Entry: oxid %x state %x "
1150 ctxp->oxid, ctxp->state,
1153 spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1156 /* Calculate outstanding IOs */
1157 tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
1158 tot += atomic_read(&tgtp->xmt_fcp_release);
1159 tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot;
1161 len += snprintf(buf + len, size - len,
1162 "IO_CTX: %08x WAIT: cur %08x tot %08x\n"
1163 "CTX Outstanding %08llx\n",
1164 phba->sli4_hba.nvmet_xri_cnt,
1165 phba->sli4_hba.nvmet_io_wait_cnt,
1166 phba->sli4_hba.nvmet_io_wait_total,
1169 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME))
1172 localport = vport->localport;
1175 lport = (struct lpfc_nvme_lport *)localport->private;
1179 len += snprintf(buf + len, size - len,
1180 "\nNVME HDWQ Statistics\n");
1182 len += snprintf(buf + len, size - len,
1183 "LS: Xmt %016x Cmpl %016x\n",
1184 atomic_read(&lport->fc4NvmeLsRequests),
1185 atomic_read(&lport->fc4NvmeLsCmpls));
1189 for (i = 0; i < phba->cfg_hdw_queue; i++) {
1190 cstat = &phba->sli4_hba.hdwq[i].nvme_cstat;
1191 tot = cstat->io_cmpls;
1193 data1 = cstat->input_requests;
1194 data2 = cstat->output_requests;
1195 data3 = cstat->control_requests;
1196 totout += (data1 + data2 + data3);
1198 /* Limit to 32, debugfs display buffer limitation */
1202 len += snprintf(buf + len, PAGE_SIZE - len,
1203 "HDWQ (%d): Rd %016llx Wr %016llx "
1205 i, data1, data2, data3);
1206 len += snprintf(buf + len, PAGE_SIZE - len,
1207 "Cmpl %016llx OutIO %016llx\n",
1208 tot, ((data1 + data2 + data3) - tot));
1210 len += snprintf(buf + len, PAGE_SIZE - len,
1211 "Total FCP Cmpl %016llx Issue %016llx "
1213 totin, totout, totout - totin);
1215 len += snprintf(buf + len, size - len,
1216 "LS Xmt Err: Abrt %08x Err %08x "
1217 "Cmpl Err: xb %08x Err %08x\n",
1218 atomic_read(&lport->xmt_ls_abort),
1219 atomic_read(&lport->xmt_ls_err),
1220 atomic_read(&lport->cmpl_ls_xb),
1221 atomic_read(&lport->cmpl_ls_err));
1223 len += snprintf(buf + len, size - len,
1224 "FCP Xmt Err: noxri %06x nondlp %06x "
1225 "qdepth %06x wqerr %06x err %06x Abrt %06x\n",
1226 atomic_read(&lport->xmt_fcp_noxri),
1227 atomic_read(&lport->xmt_fcp_bad_ndlp),
1228 atomic_read(&lport->xmt_fcp_qdepth),
1229 atomic_read(&lport->xmt_fcp_wqerr),
1230 atomic_read(&lport->xmt_fcp_err),
1231 atomic_read(&lport->xmt_fcp_abort));
1233 len += snprintf(buf + len, size - len,
1234 "FCP Cmpl Err: xb %08x Err %08x\n",
1235 atomic_read(&lport->cmpl_fcp_xb),
1236 atomic_read(&lport->cmpl_fcp_err));
1244 * lpfc_debugfs_scsistat_data - Dump target node list to a buffer
1245 * @vport: The vport to gather target node info from.
1246 * @buf: The buffer to dump log into.
1247 * @size: The maximum amount of data to process.
1250 * This routine dumps the SCSI statistics associated with @vport
1253 * This routine returns the amount of bytes that were dumped into @buf and will
1257 lpfc_debugfs_scsistat_data(struct lpfc_vport *vport, char *buf, int size)
1260 struct lpfc_hba *phba = vport->phba;
1261 struct lpfc_fc4_ctrl_stat *cstat;
1262 u64 data1, data2, data3;
1263 u64 tot, totin, totout;
1265 char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
1267 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
1268 (phba->sli_rev != LPFC_SLI_REV4))
1271 scnprintf(buf, size, "SCSI HDWQ Statistics\n");
1275 for (i = 0; i < phba->cfg_hdw_queue; i++) {
1276 cstat = &phba->sli4_hba.hdwq[i].scsi_cstat;
1277 tot = cstat->io_cmpls;
1279 data1 = cstat->input_requests;
1280 data2 = cstat->output_requests;
1281 data3 = cstat->control_requests;
1282 totout += (data1 + data2 + data3);
1284 scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx "
1285 "IO %016llx ", i, data1, data2, data3);
1286 if (strlcat(buf, tmp, size) >= size)
1289 scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n",
1290 tot, ((data1 + data2 + data3) - tot));
1291 if (strlcat(buf, tmp, size) >= size)
1294 scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx "
1295 "OutIO %016llx\n", totin, totout, totout - totin);
1296 strlcat(buf, tmp, size);
1299 len = strnlen(buf, size);
1305 * lpfc_debugfs_nvmektime_data - Dump target node list to a buffer
1306 * @vport: The vport to gather target node info from.
1307 * @buf: The buffer to dump log into.
1308 * @size: The maximum amount of data to process.
1311 * This routine dumps the NVME statistics associated with @vport
1314 * This routine returns the amount of bytes that were dumped into @buf and will
1318 lpfc_debugfs_nvmektime_data(struct lpfc_vport *vport, char *buf, int size)
1320 struct lpfc_hba *phba = vport->phba;
1323 if (phba->nvmet_support == 0) {
1324 /* NVME Initiator */
1325 len += snprintf(buf + len, PAGE_SIZE - len,
1326 "ktime %s: Total Samples: %lld\n",
1327 (phba->ktime_on ? "Enabled" : "Disabled"),
1328 phba->ktime_data_samples);
1329 if (phba->ktime_data_samples == 0)
1333 buf + len, PAGE_SIZE - len,
1334 "Segment 1: Last NVME Cmd cmpl "
1335 "done -to- Start of next NVME cnd (in driver)\n");
1337 buf + len, PAGE_SIZE - len,
1338 "avg:%08lld min:%08lld max %08lld\n",
1339 div_u64(phba->ktime_seg1_total,
1340 phba->ktime_data_samples),
1341 phba->ktime_seg1_min,
1342 phba->ktime_seg1_max);
1344 buf + len, PAGE_SIZE - len,
1345 "Segment 2: Driver start of NVME cmd "
1346 "-to- Firmware WQ doorbell\n");
1348 buf + len, PAGE_SIZE - len,
1349 "avg:%08lld min:%08lld max %08lld\n",
1350 div_u64(phba->ktime_seg2_total,
1351 phba->ktime_data_samples),
1352 phba->ktime_seg2_min,
1353 phba->ktime_seg2_max);
1355 buf + len, PAGE_SIZE - len,
1356 "Segment 3: Firmware WQ doorbell -to- "
1357 "MSI-X ISR cmpl\n");
1359 buf + len, PAGE_SIZE - len,
1360 "avg:%08lld min:%08lld max %08lld\n",
1361 div_u64(phba->ktime_seg3_total,
1362 phba->ktime_data_samples),
1363 phba->ktime_seg3_min,
1364 phba->ktime_seg3_max);
1366 buf + len, PAGE_SIZE - len,
1367 "Segment 4: MSI-X ISR cmpl -to- "
1368 "NVME cmpl done\n");
1370 buf + len, PAGE_SIZE - len,
1371 "avg:%08lld min:%08lld max %08lld\n",
1372 div_u64(phba->ktime_seg4_total,
1373 phba->ktime_data_samples),
1374 phba->ktime_seg4_min,
1375 phba->ktime_seg4_max);
1377 buf + len, PAGE_SIZE - len,
1378 "Total IO avg time: %08lld\n",
1379 div_u64(phba->ktime_seg1_total +
1380 phba->ktime_seg2_total +
1381 phba->ktime_seg3_total +
1382 phba->ktime_seg4_total,
1383 phba->ktime_data_samples));
1388 len += snprintf(buf + len, PAGE_SIZE-len,
1389 "ktime %s: Total Samples: %lld %lld\n",
1390 (phba->ktime_on ? "Enabled" : "Disabled"),
1391 phba->ktime_data_samples,
1392 phba->ktime_status_samples);
1393 if (phba->ktime_data_samples == 0)
1396 len += snprintf(buf + len, PAGE_SIZE-len,
1397 "Segment 1: MSI-X ISR Rcv cmd -to- "
1398 "cmd pass to NVME Layer\n");
1399 len += snprintf(buf + len, PAGE_SIZE-len,
1400 "avg:%08lld min:%08lld max %08lld\n",
1401 div_u64(phba->ktime_seg1_total,
1402 phba->ktime_data_samples),
1403 phba->ktime_seg1_min,
1404 phba->ktime_seg1_max);
1405 len += snprintf(buf + len, PAGE_SIZE-len,
1406 "Segment 2: cmd pass to NVME Layer- "
1407 "-to- Driver rcv cmd OP (action)\n");
1408 len += snprintf(buf + len, PAGE_SIZE-len,
1409 "avg:%08lld min:%08lld max %08lld\n",
1410 div_u64(phba->ktime_seg2_total,
1411 phba->ktime_data_samples),
1412 phba->ktime_seg2_min,
1413 phba->ktime_seg2_max);
1414 len += snprintf(buf + len, PAGE_SIZE-len,
1415 "Segment 3: Driver rcv cmd OP -to- "
1416 "Firmware WQ doorbell: cmd\n");
1417 len += snprintf(buf + len, PAGE_SIZE-len,
1418 "avg:%08lld min:%08lld max %08lld\n",
1419 div_u64(phba->ktime_seg3_total,
1420 phba->ktime_data_samples),
1421 phba->ktime_seg3_min,
1422 phba->ktime_seg3_max);
1423 len += snprintf(buf + len, PAGE_SIZE-len,
1424 "Segment 4: Firmware WQ doorbell: cmd "
1425 "-to- MSI-X ISR for cmd cmpl\n");
1426 len += snprintf(buf + len, PAGE_SIZE-len,
1427 "avg:%08lld min:%08lld max %08lld\n",
1428 div_u64(phba->ktime_seg4_total,
1429 phba->ktime_data_samples),
1430 phba->ktime_seg4_min,
1431 phba->ktime_seg4_max);
1432 len += snprintf(buf + len, PAGE_SIZE-len,
1433 "Segment 5: MSI-X ISR for cmd cmpl "
1434 "-to- NVME layer passed cmd done\n");
1435 len += snprintf(buf + len, PAGE_SIZE-len,
1436 "avg:%08lld min:%08lld max %08lld\n",
1437 div_u64(phba->ktime_seg5_total,
1438 phba->ktime_data_samples),
1439 phba->ktime_seg5_min,
1440 phba->ktime_seg5_max);
1442 if (phba->ktime_status_samples == 0) {
1443 len += snprintf(buf + len, PAGE_SIZE-len,
1444 "Total: cmd received by MSI-X ISR "
1445 "-to- cmd completed on wire\n");
1446 len += snprintf(buf + len, PAGE_SIZE-len,
1447 "avg:%08lld min:%08lld "
1449 div_u64(phba->ktime_seg10_total,
1450 phba->ktime_data_samples),
1451 phba->ktime_seg10_min,
1452 phba->ktime_seg10_max);
1456 len += snprintf(buf + len, PAGE_SIZE-len,
1457 "Segment 6: NVME layer passed cmd done "
1458 "-to- Driver rcv rsp status OP\n");
1459 len += snprintf(buf + len, PAGE_SIZE-len,
1460 "avg:%08lld min:%08lld max %08lld\n",
1461 div_u64(phba->ktime_seg6_total,
1462 phba->ktime_status_samples),
1463 phba->ktime_seg6_min,
1464 phba->ktime_seg6_max);
1465 len += snprintf(buf + len, PAGE_SIZE-len,
1466 "Segment 7: Driver rcv rsp status OP "
1467 "-to- Firmware WQ doorbell: status\n");
1468 len += snprintf(buf + len, PAGE_SIZE-len,
1469 "avg:%08lld min:%08lld max %08lld\n",
1470 div_u64(phba->ktime_seg7_total,
1471 phba->ktime_status_samples),
1472 phba->ktime_seg7_min,
1473 phba->ktime_seg7_max);
1474 len += snprintf(buf + len, PAGE_SIZE-len,
1475 "Segment 8: Firmware WQ doorbell: status"
1476 " -to- MSI-X ISR for status cmpl\n");
1477 len += snprintf(buf + len, PAGE_SIZE-len,
1478 "avg:%08lld min:%08lld max %08lld\n",
1479 div_u64(phba->ktime_seg8_total,
1480 phba->ktime_status_samples),
1481 phba->ktime_seg8_min,
1482 phba->ktime_seg8_max);
1483 len += snprintf(buf + len, PAGE_SIZE-len,
1484 "Segment 9: MSI-X ISR for status cmpl "
1485 "-to- NVME layer passed status done\n");
1486 len += snprintf(buf + len, PAGE_SIZE-len,
1487 "avg:%08lld min:%08lld max %08lld\n",
1488 div_u64(phba->ktime_seg9_total,
1489 phba->ktime_status_samples),
1490 phba->ktime_seg9_min,
1491 phba->ktime_seg9_max);
1492 len += snprintf(buf + len, PAGE_SIZE-len,
1493 "Total: cmd received by MSI-X ISR -to- "
1494 "cmd completed on wire\n");
1495 len += snprintf(buf + len, PAGE_SIZE-len,
1496 "avg:%08lld min:%08lld max %08lld\n",
1497 div_u64(phba->ktime_seg10_total,
1498 phba->ktime_status_samples),
1499 phba->ktime_seg10_min,
1500 phba->ktime_seg10_max);
1505 * lpfc_debugfs_nvmeio_trc_data - Dump NVME IO trace list to a buffer
1506 * @phba: The phba to gather target node info from.
1507 * @buf: The buffer to dump log into.
1508 * @size: The maximum amount of data to process.
1511 * This routine dumps the NVME IO trace associated with @phba
1514 * This routine returns the amount of bytes that were dumped into @buf and will
1518 lpfc_debugfs_nvmeio_trc_data(struct lpfc_hba *phba, char *buf, int size)
1520 struct lpfc_debugfs_nvmeio_trc *dtp;
1521 int i, state, index, skip;
1524 state = phba->nvmeio_trc_on;
1526 index = (atomic_read(&phba->nvmeio_trc_cnt) + 1) &
1527 (phba->nvmeio_trc_size - 1);
1528 skip = phba->nvmeio_trc_output_idx;
1530 len += snprintf(buf + len, size - len,
1531 "%s IO Trace %s: next_idx %d skip %d size %d\n",
1532 (phba->nvmet_support ? "NVME" : "NVMET"),
1533 (state ? "Enabled" : "Disabled"),
1534 index, skip, phba->nvmeio_trc_size);
1536 if (!phba->nvmeio_trc || state)
1539 /* trace MUST bhe off to continue */
1541 for (i = index; i < phba->nvmeio_trc_size; i++) {
1546 dtp = phba->nvmeio_trc + i;
1547 phba->nvmeio_trc_output_idx++;
1552 len += snprintf(buf + len, size - len, dtp->fmt,
1553 dtp->data1, dtp->data2, dtp->data3);
1555 if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) {
1556 phba->nvmeio_trc_output_idx = 0;
1557 len += snprintf(buf + len, size - len,
1558 "Trace Complete\n");
1562 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) {
1563 len += snprintf(buf + len, size - len,
1564 "Trace Continue (%d of %d)\n",
1565 phba->nvmeio_trc_output_idx,
1566 phba->nvmeio_trc_size);
1570 for (i = 0; i < index; i++) {
1575 dtp = phba->nvmeio_trc + i;
1576 phba->nvmeio_trc_output_idx++;
1581 len += snprintf(buf + len, size - len, dtp->fmt,
1582 dtp->data1, dtp->data2, dtp->data3);
1584 if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) {
1585 phba->nvmeio_trc_output_idx = 0;
1586 len += snprintf(buf + len, size - len,
1587 "Trace Complete\n");
1591 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) {
1592 len += snprintf(buf + len, size - len,
1593 "Trace Continue (%d of %d)\n",
1594 phba->nvmeio_trc_output_idx,
1595 phba->nvmeio_trc_size);
1600 len += snprintf(buf + len, size - len,
1607 * lpfc_debugfs_cpucheck_data - Dump target node list to a buffer
1608 * @vport: The vport to gather target node info from.
1609 * @buf: The buffer to dump log into.
1610 * @size: The maximum amount of data to process.
1613 * This routine dumps the NVME statistics associated with @vport
1616 * This routine returns the amount of bytes that were dumped into @buf and will
1620 lpfc_debugfs_cpucheck_data(struct lpfc_vport *vport, char *buf, int size)
1622 struct lpfc_hba *phba = vport->phba;
1623 struct lpfc_sli4_hdw_queue *qp;
1630 len += snprintf(buf + len, PAGE_SIZE - len,
1632 (phba->cpucheck_on & LPFC_CHECK_NVME_IO ?
1633 "Enabled" : "Disabled"));
1634 if (phba->nvmet_support) {
1635 len += snprintf(buf + len, PAGE_SIZE - len,
1637 (phba->cpucheck_on & LPFC_CHECK_NVMET_RCV ?
1638 "Rcv Enabled\n" : "Rcv Disabled\n"));
1640 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1642 max_cnt = size - LPFC_DEBUG_OUT_LINE_SZ;
1644 for (i = 0; i < phba->cfg_hdw_queue; i++) {
1645 qp = &phba->sli4_hba.hdwq[i];
1650 for (j = 0; j < LPFC_CHECK_CPU_CNT; j++) {
1651 tot_xmt += qp->cpucheck_xmt_io[j];
1652 tot_cmpl += qp->cpucheck_cmpl_io[j];
1653 if (phba->nvmet_support)
1654 tot_rcv += qp->cpucheck_rcv_io[j];
1657 /* Only display Hardware Qs with something */
1658 if (!tot_xmt && !tot_cmpl && !tot_rcv)
1661 len += snprintf(buf + len, PAGE_SIZE - len,
1663 for (j = 0; j < LPFC_CHECK_CPU_CNT; j++) {
1664 /* Only display non-zero counters */
1665 if (!qp->cpucheck_xmt_io[j] &&
1666 !qp->cpucheck_cmpl_io[j] &&
1667 !qp->cpucheck_rcv_io[j])
1669 if (phba->nvmet_support) {
1670 len += snprintf(buf + len, PAGE_SIZE - len,
1671 "CPU %03d: %x/%x/%x ", j,
1672 qp->cpucheck_rcv_io[j],
1673 qp->cpucheck_xmt_io[j],
1674 qp->cpucheck_cmpl_io[j]);
1676 len += snprintf(buf + len, PAGE_SIZE - len,
1677 "CPU %03d: %x/%x ", j,
1678 qp->cpucheck_xmt_io[j],
1679 qp->cpucheck_cmpl_io[j]);
1682 len += snprintf(buf + len, PAGE_SIZE - len,
1683 "Total: %x\n", tot_xmt);
1684 if (len >= max_cnt) {
1685 len += snprintf(buf + len, PAGE_SIZE - len,
1696 * lpfc_debugfs_disc_trc - Store discovery trace log
1697 * @vport: The vport to associate this trace string with for retrieval.
1698 * @mask: Log entry classification.
1699 * @fmt: Format string to be displayed when dumping the log.
1700 * @data1: 1st data parameter to be applied to @fmt.
1701 * @data2: 2nd data parameter to be applied to @fmt.
1702 * @data3: 3rd data parameter to be applied to @fmt.
1705 * This routine is used by the driver code to add a debugfs log entry to the
1706 * discovery trace buffer associated with @vport. Only entries with a @mask that
1707 * match the current debugfs discovery mask will be saved. Entries that do not
1708 * match will be thrown away. @fmt, @data1, @data2, and @data3 are used like
1709 * printf when displaying the log.
1712 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
1713 uint32_t data1, uint32_t data2, uint32_t data3)
1715 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1716 struct lpfc_debugfs_trc *dtp;
1719 if (!(lpfc_debugfs_mask_disc_trc & mask))
1722 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
1723 !vport || !vport->disc_trc)
1726 index = atomic_inc_return(&vport->disc_trc_cnt) &
1727 (lpfc_debugfs_max_disc_trc - 1);
1728 dtp = vport->disc_trc + index;
1733 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
1740 * lpfc_debugfs_slow_ring_trc - Store slow ring trace log
1741 * @phba: The phba to associate this trace string with for retrieval.
1742 * @fmt: Format string to be displayed when dumping the log.
1743 * @data1: 1st data parameter to be applied to @fmt.
1744 * @data2: 2nd data parameter to be applied to @fmt.
1745 * @data3: 3rd data parameter to be applied to @fmt.
1748 * This routine is used by the driver code to add a debugfs log entry to the
1749 * discovery trace buffer associated with @vport. @fmt, @data1, @data2, and
1750 * @data3 are used like printf when displaying the log.
1753 lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
1754 uint32_t data1, uint32_t data2, uint32_t data3)
1756 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1757 struct lpfc_debugfs_trc *dtp;
1760 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
1761 !phba || !phba->slow_ring_trc)
1764 index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
1765 (lpfc_debugfs_max_slow_ring_trc - 1);
1766 dtp = phba->slow_ring_trc + index;
1771 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
1778 * lpfc_debugfs_nvme_trc - Store NVME/NVMET trace log
1779 * @phba: The phba to associate this trace string with for retrieval.
1780 * @fmt: Format string to be displayed when dumping the log.
1781 * @data1: 1st data parameter to be applied to @fmt.
1782 * @data2: 2nd data parameter to be applied to @fmt.
1783 * @data3: 3rd data parameter to be applied to @fmt.
1786 * This routine is used by the driver code to add a debugfs log entry to the
1787 * nvme trace buffer associated with @phba. @fmt, @data1, @data2, and
1788 * @data3 are used like printf when displaying the log.
1791 lpfc_debugfs_nvme_trc(struct lpfc_hba *phba, char *fmt,
1792 uint16_t data1, uint16_t data2, uint32_t data3)
1794 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1795 struct lpfc_debugfs_nvmeio_trc *dtp;
1798 if (!phba->nvmeio_trc_on || !phba->nvmeio_trc)
1801 index = atomic_inc_return(&phba->nvmeio_trc_cnt) &
1802 (phba->nvmeio_trc_size - 1);
1803 dtp = phba->nvmeio_trc + index;
1811 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1813 * lpfc_debugfs_disc_trc_open - Open the discovery trace log
1814 * @inode: The inode pointer that contains a vport pointer.
1815 * @file: The file pointer to attach the log output.
1818 * This routine is the entry point for the debugfs open file operation. It gets
1819 * the vport from the i_private field in @inode, allocates the necessary buffer
1820 * for the log, fills the buffer from the in-memory log for this vport, and then
1821 * returns a pointer to that log in the private_data field in @file.
1824 * This function returns zero if successful. On error it will return a negative
1828 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
1830 struct lpfc_vport *vport = inode->i_private;
1831 struct lpfc_debug *debug;
1835 if (!lpfc_debugfs_max_disc_trc) {
1840 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1844 /* Round to page boundary */
1845 size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
1846 size = PAGE_ALIGN(size);
1848 debug->buffer = kmalloc(size, GFP_KERNEL);
1849 if (!debug->buffer) {
1854 debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
1855 file->private_data = debug;
1863 * lpfc_debugfs_slow_ring_trc_open - Open the Slow Ring trace log
1864 * @inode: The inode pointer that contains a vport pointer.
1865 * @file: The file pointer to attach the log output.
1868 * This routine is the entry point for the debugfs open file operation. It gets
1869 * the vport from the i_private field in @inode, allocates the necessary buffer
1870 * for the log, fills the buffer from the in-memory log for this vport, and then
1871 * returns a pointer to that log in the private_data field in @file.
1874 * This function returns zero if successful. On error it will return a negative
1878 lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
1880 struct lpfc_hba *phba = inode->i_private;
1881 struct lpfc_debug *debug;
1885 if (!lpfc_debugfs_max_slow_ring_trc) {
1890 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1894 /* Round to page boundary */
1895 size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
1896 size = PAGE_ALIGN(size);
1898 debug->buffer = kmalloc(size, GFP_KERNEL);
1899 if (!debug->buffer) {
1904 debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
1905 file->private_data = debug;
1913 * lpfc_debugfs_hbqinfo_open - Open the hbqinfo debugfs buffer
1914 * @inode: The inode pointer that contains a vport pointer.
1915 * @file: The file pointer to attach the log output.
1918 * This routine is the entry point for the debugfs open file operation. It gets
1919 * the vport from the i_private field in @inode, allocates the necessary buffer
1920 * for the log, fills the buffer from the in-memory log for this vport, and then
1921 * returns a pointer to that log in the private_data field in @file.
1924 * This function returns zero if successful. On error it will return a negative
1928 lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
1930 struct lpfc_hba *phba = inode->i_private;
1931 struct lpfc_debug *debug;
1934 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1938 /* Round to page boundary */
1939 debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
1940 if (!debug->buffer) {
1945 debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
1947 file->private_data = debug;
1955 * lpfc_debugfs_multixripools_open - Open the multixripool debugfs buffer
1956 * @inode: The inode pointer that contains a hba pointer.
1957 * @file: The file pointer to attach the log output.
1960 * This routine is the entry point for the debugfs open file operation. It gets
1961 * the hba from the i_private field in @inode, allocates the necessary buffer
1962 * for the log, fills the buffer from the in-memory log for this hba, and then
1963 * returns a pointer to that log in the private_data field in @file.
1966 * This function returns zero if successful. On error it will return a negative
1970 lpfc_debugfs_multixripools_open(struct inode *inode, struct file *file)
1972 struct lpfc_hba *phba = inode->i_private;
1973 struct lpfc_debug *debug;
1976 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1980 /* Round to page boundary */
1981 debug->buffer = kzalloc(LPFC_DUMP_MULTIXRIPOOL_SIZE, GFP_KERNEL);
1982 if (!debug->buffer) {
1987 debug->len = lpfc_debugfs_multixripools_data(
1988 phba, debug->buffer, LPFC_DUMP_MULTIXRIPOOL_SIZE);
1990 debug->i_private = inode->i_private;
1991 file->private_data = debug;
1998 #ifdef LPFC_HDWQ_LOCK_STAT
2000 * lpfc_debugfs_lockstat_open - Open the lockstat debugfs buffer
2001 * @inode: The inode pointer that contains a vport pointer.
2002 * @file: The file pointer to attach the log output.
2005 * This routine is the entry point for the debugfs open file operation. It gets
2006 * the vport from the i_private field in @inode, allocates the necessary buffer
2007 * for the log, fills the buffer from the in-memory log for this vport, and then
2008 * returns a pointer to that log in the private_data field in @file.
2011 * This function returns zero if successful. On error it will return a negative
2015 lpfc_debugfs_lockstat_open(struct inode *inode, struct file *file)
2017 struct lpfc_hba *phba = inode->i_private;
2018 struct lpfc_debug *debug;
2021 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2025 /* Round to page boundary */
2026 debug->buffer = kmalloc(LPFC_HDWQINFO_SIZE, GFP_KERNEL);
2027 if (!debug->buffer) {
2032 debug->len = lpfc_debugfs_lockstat_data(phba, debug->buffer,
2034 file->private_data = debug;
2042 lpfc_debugfs_lockstat_write(struct file *file, const char __user *buf,
2043 size_t nbytes, loff_t *ppos)
2045 struct lpfc_debug *debug = file->private_data;
2046 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2047 struct lpfc_sli4_hdw_queue *qp;
2052 /* Protect copy from user */
2053 if (!access_ok(buf, nbytes))
2056 memset(mybuf, 0, sizeof(mybuf));
2058 if (copy_from_user(mybuf, buf, nbytes))
2062 if ((strncmp(pbuf, "reset", strlen("reset")) == 0) ||
2063 (strncmp(pbuf, "zero", strlen("zero")) == 0)) {
2064 for (i = 0; i < phba->cfg_hdw_queue; i++) {
2065 qp = &phba->sli4_hba.hdwq[i];
2066 qp->lock_conflict.alloc_xri_get = 0;
2067 qp->lock_conflict.alloc_xri_put = 0;
2068 qp->lock_conflict.free_xri = 0;
2069 qp->lock_conflict.wq_access = 0;
2070 qp->lock_conflict.alloc_pvt_pool = 0;
2071 qp->lock_conflict.mv_from_pvt_pool = 0;
2072 qp->lock_conflict.mv_to_pub_pool = 0;
2073 qp->lock_conflict.mv_to_pvt_pool = 0;
2074 qp->lock_conflict.free_pvt_pool = 0;
2075 qp->lock_conflict.free_pub_pool = 0;
2076 qp->lock_conflict.wq_access = 0;
2084 * lpfc_debugfs_dumpHBASlim_open - Open the Dump HBA SLIM debugfs buffer
2085 * @inode: The inode pointer that contains a vport pointer.
2086 * @file: The file pointer to attach the log output.
2089 * This routine is the entry point for the debugfs open file operation. It gets
2090 * the vport from the i_private field in @inode, allocates the necessary buffer
2091 * for the log, fills the buffer from the in-memory log for this vport, and then
2092 * returns a pointer to that log in the private_data field in @file.
2095 * This function returns zero if successful. On error it will return a negative
2099 lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file)
2101 struct lpfc_hba *phba = inode->i_private;
2102 struct lpfc_debug *debug;
2105 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2109 /* Round to page boundary */
2110 debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL);
2111 if (!debug->buffer) {
2116 debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer,
2117 LPFC_DUMPHBASLIM_SIZE);
2118 file->private_data = debug;
2126 * lpfc_debugfs_dumpHostSlim_open - Open the Dump Host SLIM debugfs buffer
2127 * @inode: The inode pointer that contains a vport pointer.
2128 * @file: The file pointer to attach the log output.
2131 * This routine is the entry point for the debugfs open file operation. It gets
2132 * the vport from the i_private field in @inode, allocates the necessary buffer
2133 * for the log, fills the buffer from the in-memory log for this vport, and then
2134 * returns a pointer to that log in the private_data field in @file.
2137 * This function returns zero if successful. On error it will return a negative
2141 lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file)
2143 struct lpfc_hba *phba = inode->i_private;
2144 struct lpfc_debug *debug;
2147 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2151 /* Round to page boundary */
2152 debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL);
2153 if (!debug->buffer) {
2158 debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer,
2159 LPFC_DUMPHOSTSLIM_SIZE);
2160 file->private_data = debug;
2168 lpfc_debugfs_dumpData_open(struct inode *inode, struct file *file)
2170 struct lpfc_debug *debug;
2173 if (!_dump_buf_data)
2176 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2180 /* Round to page boundary */
2181 pr_err("9059 BLKGRD: %s: _dump_buf_data=0x%p\n",
2182 __func__, _dump_buf_data);
2183 debug->buffer = _dump_buf_data;
2184 if (!debug->buffer) {
2189 debug->len = (1 << _dump_buf_data_order) << PAGE_SHIFT;
2190 file->private_data = debug;
2198 lpfc_debugfs_dumpDif_open(struct inode *inode, struct file *file)
2200 struct lpfc_debug *debug;
2206 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2210 /* Round to page boundary */
2211 pr_err("9060 BLKGRD: %s: _dump_buf_dif=0x%p file=%pD\n",
2212 __func__, _dump_buf_dif, file);
2213 debug->buffer = _dump_buf_dif;
2214 if (!debug->buffer) {
2219 debug->len = (1 << _dump_buf_dif_order) << PAGE_SHIFT;
2220 file->private_data = debug;
2228 lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf,
2229 size_t nbytes, loff_t *ppos)
2232 * The Data/DIF buffers only save one failing IO
2233 * The write op is used as a reset mechanism after an IO has
2234 * already been saved to the next one can be saved
2236 spin_lock(&_dump_buf_lock);
2238 memset((void *)_dump_buf_data, 0,
2239 ((1 << PAGE_SHIFT) << _dump_buf_data_order));
2240 memset((void *)_dump_buf_dif, 0,
2241 ((1 << PAGE_SHIFT) << _dump_buf_dif_order));
2245 spin_unlock(&_dump_buf_lock);
2251 lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
2252 size_t nbytes, loff_t *ppos)
2254 struct dentry *dent = file->f_path.dentry;
2255 struct lpfc_hba *phba = file->private_data;
2260 if (dent == phba->debug_writeGuard)
2261 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt);
2262 else if (dent == phba->debug_writeApp)
2263 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt);
2264 else if (dent == phba->debug_writeRef)
2265 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt);
2266 else if (dent == phba->debug_readGuard)
2267 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt);
2268 else if (dent == phba->debug_readApp)
2269 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt);
2270 else if (dent == phba->debug_readRef)
2271 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt);
2272 else if (dent == phba->debug_InjErrNPortID)
2273 cnt = snprintf(cbuf, 32, "0x%06x\n", phba->lpfc_injerr_nportid);
2274 else if (dent == phba->debug_InjErrWWPN) {
2275 memcpy(&tmp, &phba->lpfc_injerr_wwpn, sizeof(struct lpfc_name));
2276 tmp = cpu_to_be64(tmp);
2277 cnt = snprintf(cbuf, 32, "0x%016llx\n", tmp);
2278 } else if (dent == phba->debug_InjErrLBA) {
2279 if (phba->lpfc_injerr_lba == (sector_t)(-1))
2280 cnt = snprintf(cbuf, 32, "off\n");
2282 cnt = snprintf(cbuf, 32, "0x%llx\n",
2283 (uint64_t) phba->lpfc_injerr_lba);
2285 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2286 "0547 Unknown debugfs error injection entry\n");
2288 return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt);
2292 lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
2293 size_t nbytes, loff_t *ppos)
2295 struct dentry *dent = file->f_path.dentry;
2296 struct lpfc_hba *phba = file->private_data;
2301 memset(dstbuf, 0, 33);
2302 size = (nbytes < 32) ? nbytes : 32;
2303 if (copy_from_user(dstbuf, buf, size))
2306 if (dent == phba->debug_InjErrLBA) {
2307 if ((buf[0] == 'o') && (buf[1] == 'f') && (buf[2] == 'f'))
2308 tmp = (uint64_t)(-1);
2311 if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp)))
2314 if (dent == phba->debug_writeGuard)
2315 phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
2316 else if (dent == phba->debug_writeApp)
2317 phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
2318 else if (dent == phba->debug_writeRef)
2319 phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
2320 else if (dent == phba->debug_readGuard)
2321 phba->lpfc_injerr_rgrd_cnt = (uint32_t)tmp;
2322 else if (dent == phba->debug_readApp)
2323 phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
2324 else if (dent == phba->debug_readRef)
2325 phba->lpfc_injerr_rref_cnt = (uint32_t)tmp;
2326 else if (dent == phba->debug_InjErrLBA)
2327 phba->lpfc_injerr_lba = (sector_t)tmp;
2328 else if (dent == phba->debug_InjErrNPortID)
2329 phba->lpfc_injerr_nportid = (uint32_t)(tmp & Mask_DID);
2330 else if (dent == phba->debug_InjErrWWPN) {
2331 tmp = cpu_to_be64(tmp);
2332 memcpy(&phba->lpfc_injerr_wwpn, &tmp, sizeof(struct lpfc_name));
2334 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2335 "0548 Unknown debugfs error injection entry\n");
2341 lpfc_debugfs_dif_err_release(struct inode *inode, struct file *file)
2347 * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file
2348 * @inode: The inode pointer that contains a vport pointer.
2349 * @file: The file pointer to attach the log output.
2352 * This routine is the entry point for the debugfs open file operation. It gets
2353 * the vport from the i_private field in @inode, allocates the necessary buffer
2354 * for the log, fills the buffer from the in-memory log for this vport, and then
2355 * returns a pointer to that log in the private_data field in @file.
2358 * This function returns zero if successful. On error it will return a negative
2362 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
2364 struct lpfc_vport *vport = inode->i_private;
2365 struct lpfc_debug *debug;
2368 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2372 /* Round to page boundary */
2373 debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
2374 if (!debug->buffer) {
2379 debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
2380 LPFC_NODELIST_SIZE);
2381 file->private_data = debug;
2389 * lpfc_debugfs_lseek - Seek through a debugfs file
2390 * @file: The file pointer to seek through.
2391 * @off: The offset to seek to or the amount to seek by.
2392 * @whence: Indicates how to seek.
2395 * This routine is the entry point for the debugfs lseek file operation. The
2396 * @whence parameter indicates whether @off is the offset to directly seek to,
2397 * or if it is a value to seek forward or reverse by. This function figures out
2398 * what the new offset of the debugfs file will be and assigns that value to the
2399 * f_pos field of @file.
2402 * This function returns the new offset if successful and returns a negative
2403 * error if unable to process the seek.
2406 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
2408 struct lpfc_debug *debug = file->private_data;
2409 return fixed_size_llseek(file, off, whence, debug->len);
2413 * lpfc_debugfs_read - Read a debugfs file
2414 * @file: The file pointer to read from.
2415 * @buf: The buffer to copy the data to.
2416 * @nbytes: The number of bytes to read.
2417 * @ppos: The position in the file to start reading from.
2420 * This routine reads data from from the buffer indicated in the private_data
2421 * field of @file. It will start reading at @ppos and copy up to @nbytes of
2425 * This function returns the amount of data that was read (this could be less
2426 * than @nbytes if the end of the file was reached) or a negative error value.
2429 lpfc_debugfs_read(struct file *file, char __user *buf,
2430 size_t nbytes, loff_t *ppos)
2432 struct lpfc_debug *debug = file->private_data;
2434 return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
2439 * lpfc_debugfs_release - Release the buffer used to store debugfs file data
2440 * @inode: The inode pointer that contains a vport pointer. (unused)
2441 * @file: The file pointer that contains the buffer to release.
2444 * This routine frees the buffer that was allocated when the debugfs file was
2448 * This function returns zero.
2451 lpfc_debugfs_release(struct inode *inode, struct file *file)
2453 struct lpfc_debug *debug = file->private_data;
2455 kfree(debug->buffer);
2462 lpfc_debugfs_dumpDataDif_release(struct inode *inode, struct file *file)
2464 struct lpfc_debug *debug = file->private_data;
2466 debug->buffer = NULL;
2473 * lpfc_debugfs_multixripools_write - Clear multi-XRI pools statistics
2474 * @file: The file pointer to read from.
2475 * @buf: The buffer to copy the user data from.
2476 * @nbytes: The number of bytes to get.
2477 * @ppos: The position in the file to start reading from.
2480 * This routine clears multi-XRI pools statistics when buf contains "clear".
2483 * It returns the @nbytges passing in from debugfs user space when successful.
2484 * In case of error conditions, it returns proper error code back to the user
2488 lpfc_debugfs_multixripools_write(struct file *file, const char __user *buf,
2489 size_t nbytes, loff_t *ppos)
2491 struct lpfc_debug *debug = file->private_data;
2492 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2497 struct lpfc_sli4_hdw_queue *qp;
2498 struct lpfc_multixri_pool *multixri_pool;
2503 /* Protect copy from user */
2504 if (!access_ok(buf, nbytes))
2507 memset(mybuf, 0, sizeof(mybuf));
2509 if (copy_from_user(mybuf, buf, nbytes))
2513 if ((strncmp(pbuf, "clear", strlen("clear"))) == 0) {
2514 hwq_count = phba->cfg_hdw_queue;
2515 for (i = 0; i < hwq_count; i++) {
2516 qp = &phba->sli4_hba.hdwq[i];
2517 multixri_pool = qp->p_multixri_pool;
2521 qp->empty_io_bufs = 0;
2522 multixri_pool->pbl_empty_count = 0;
2523 #ifdef LPFC_MXP_STAT
2524 multixri_pool->above_limit_count = 0;
2525 multixri_pool->below_limit_count = 0;
2526 multixri_pool->stat_max_hwm = 0;
2527 multixri_pool->local_pbl_hit_count = 0;
2528 multixri_pool->other_pbl_hit_count = 0;
2530 multixri_pool->stat_pbl_count = 0;
2531 multixri_pool->stat_pvt_count = 0;
2532 multixri_pool->stat_busy_count = 0;
2533 multixri_pool->stat_snapshot_taken = 0;
2536 return strlen(pbuf);
2543 lpfc_debugfs_nvmestat_open(struct inode *inode, struct file *file)
2545 struct lpfc_vport *vport = inode->i_private;
2546 struct lpfc_debug *debug;
2549 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2553 /* Round to page boundary */
2554 debug->buffer = kmalloc(LPFC_NVMESTAT_SIZE, GFP_KERNEL);
2555 if (!debug->buffer) {
2560 debug->len = lpfc_debugfs_nvmestat_data(vport, debug->buffer,
2561 LPFC_NVMESTAT_SIZE);
2563 debug->i_private = inode->i_private;
2564 file->private_data = debug;
2572 lpfc_debugfs_nvmestat_write(struct file *file, const char __user *buf,
2573 size_t nbytes, loff_t *ppos)
2575 struct lpfc_debug *debug = file->private_data;
2576 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
2577 struct lpfc_hba *phba = vport->phba;
2578 struct lpfc_nvmet_tgtport *tgtp;
2582 if (!phba->targetport)
2588 memset(mybuf, 0, sizeof(mybuf));
2590 if (copy_from_user(mybuf, buf, nbytes))
2594 tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
2595 if ((strncmp(pbuf, "reset", strlen("reset")) == 0) ||
2596 (strncmp(pbuf, "zero", strlen("zero")) == 0)) {
2597 atomic_set(&tgtp->rcv_ls_req_in, 0);
2598 atomic_set(&tgtp->rcv_ls_req_out, 0);
2599 atomic_set(&tgtp->rcv_ls_req_drop, 0);
2600 atomic_set(&tgtp->xmt_ls_abort, 0);
2601 atomic_set(&tgtp->xmt_ls_abort_cmpl, 0);
2602 atomic_set(&tgtp->xmt_ls_rsp, 0);
2603 atomic_set(&tgtp->xmt_ls_drop, 0);
2604 atomic_set(&tgtp->xmt_ls_rsp_error, 0);
2605 atomic_set(&tgtp->xmt_ls_rsp_cmpl, 0);
2607 atomic_set(&tgtp->rcv_fcp_cmd_in, 0);
2608 atomic_set(&tgtp->rcv_fcp_cmd_out, 0);
2609 atomic_set(&tgtp->rcv_fcp_cmd_drop, 0);
2610 atomic_set(&tgtp->xmt_fcp_drop, 0);
2611 atomic_set(&tgtp->xmt_fcp_read_rsp, 0);
2612 atomic_set(&tgtp->xmt_fcp_read, 0);
2613 atomic_set(&tgtp->xmt_fcp_write, 0);
2614 atomic_set(&tgtp->xmt_fcp_rsp, 0);
2615 atomic_set(&tgtp->xmt_fcp_release, 0);
2616 atomic_set(&tgtp->xmt_fcp_rsp_cmpl, 0);
2617 atomic_set(&tgtp->xmt_fcp_rsp_error, 0);
2618 atomic_set(&tgtp->xmt_fcp_rsp_drop, 0);
2620 atomic_set(&tgtp->xmt_fcp_abort, 0);
2621 atomic_set(&tgtp->xmt_fcp_abort_cmpl, 0);
2622 atomic_set(&tgtp->xmt_abort_sol, 0);
2623 atomic_set(&tgtp->xmt_abort_unsol, 0);
2624 atomic_set(&tgtp->xmt_abort_rsp, 0);
2625 atomic_set(&tgtp->xmt_abort_rsp_error, 0);
2631 lpfc_debugfs_scsistat_open(struct inode *inode, struct file *file)
2633 struct lpfc_vport *vport = inode->i_private;
2634 struct lpfc_debug *debug;
2637 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2641 /* Round to page boundary */
2642 debug->buffer = kzalloc(LPFC_SCSISTAT_SIZE, GFP_KERNEL);
2643 if (!debug->buffer) {
2648 debug->len = lpfc_debugfs_scsistat_data(vport, debug->buffer,
2649 LPFC_SCSISTAT_SIZE);
2651 debug->i_private = inode->i_private;
2652 file->private_data = debug;
2660 lpfc_debugfs_scsistat_write(struct file *file, const char __user *buf,
2661 size_t nbytes, loff_t *ppos)
2663 struct lpfc_debug *debug = file->private_data;
2664 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
2665 struct lpfc_hba *phba = vport->phba;
2666 char mybuf[6] = {0};
2669 /* Protect copy from user */
2670 if (!access_ok(buf, nbytes))
2673 if (copy_from_user(mybuf, buf, (nbytes >= sizeof(mybuf)) ?
2674 (sizeof(mybuf) - 1) : nbytes))
2677 if ((strncmp(&mybuf[0], "reset", strlen("reset")) == 0) ||
2678 (strncmp(&mybuf[0], "zero", strlen("zero")) == 0)) {
2679 for (i = 0; i < phba->cfg_hdw_queue; i++) {
2680 memset(&phba->sli4_hba.hdwq[i].scsi_cstat, 0,
2681 sizeof(phba->sli4_hba.hdwq[i].scsi_cstat));
2689 lpfc_debugfs_nvmektime_open(struct inode *inode, struct file *file)
2691 struct lpfc_vport *vport = inode->i_private;
2692 struct lpfc_debug *debug;
2695 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2699 /* Round to page boundary */
2700 debug->buffer = kmalloc(LPFC_NVMEKTIME_SIZE, GFP_KERNEL);
2701 if (!debug->buffer) {
2706 debug->len = lpfc_debugfs_nvmektime_data(vport, debug->buffer,
2707 LPFC_NVMEKTIME_SIZE);
2709 debug->i_private = inode->i_private;
2710 file->private_data = debug;
2718 lpfc_debugfs_nvmektime_write(struct file *file, const char __user *buf,
2719 size_t nbytes, loff_t *ppos)
2721 struct lpfc_debug *debug = file->private_data;
2722 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
2723 struct lpfc_hba *phba = vport->phba;
2730 memset(mybuf, 0, sizeof(mybuf));
2732 if (copy_from_user(mybuf, buf, nbytes))
2736 if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
2737 phba->ktime_data_samples = 0;
2738 phba->ktime_status_samples = 0;
2739 phba->ktime_seg1_total = 0;
2740 phba->ktime_seg1_max = 0;
2741 phba->ktime_seg1_min = 0xffffffff;
2742 phba->ktime_seg2_total = 0;
2743 phba->ktime_seg2_max = 0;
2744 phba->ktime_seg2_min = 0xffffffff;
2745 phba->ktime_seg3_total = 0;
2746 phba->ktime_seg3_max = 0;
2747 phba->ktime_seg3_min = 0xffffffff;
2748 phba->ktime_seg4_total = 0;
2749 phba->ktime_seg4_max = 0;
2750 phba->ktime_seg4_min = 0xffffffff;
2751 phba->ktime_seg5_total = 0;
2752 phba->ktime_seg5_max = 0;
2753 phba->ktime_seg5_min = 0xffffffff;
2754 phba->ktime_seg6_total = 0;
2755 phba->ktime_seg6_max = 0;
2756 phba->ktime_seg6_min = 0xffffffff;
2757 phba->ktime_seg7_total = 0;
2758 phba->ktime_seg7_max = 0;
2759 phba->ktime_seg7_min = 0xffffffff;
2760 phba->ktime_seg8_total = 0;
2761 phba->ktime_seg8_max = 0;
2762 phba->ktime_seg8_min = 0xffffffff;
2763 phba->ktime_seg9_total = 0;
2764 phba->ktime_seg9_max = 0;
2765 phba->ktime_seg9_min = 0xffffffff;
2766 phba->ktime_seg10_total = 0;
2767 phba->ktime_seg10_max = 0;
2768 phba->ktime_seg10_min = 0xffffffff;
2771 return strlen(pbuf);
2772 } else if ((strncmp(pbuf, "off",
2773 sizeof("off") - 1) == 0)) {
2775 return strlen(pbuf);
2776 } else if ((strncmp(pbuf, "zero",
2777 sizeof("zero") - 1) == 0)) {
2778 phba->ktime_data_samples = 0;
2779 phba->ktime_status_samples = 0;
2780 phba->ktime_seg1_total = 0;
2781 phba->ktime_seg1_max = 0;
2782 phba->ktime_seg1_min = 0xffffffff;
2783 phba->ktime_seg2_total = 0;
2784 phba->ktime_seg2_max = 0;
2785 phba->ktime_seg2_min = 0xffffffff;
2786 phba->ktime_seg3_total = 0;
2787 phba->ktime_seg3_max = 0;
2788 phba->ktime_seg3_min = 0xffffffff;
2789 phba->ktime_seg4_total = 0;
2790 phba->ktime_seg4_max = 0;
2791 phba->ktime_seg4_min = 0xffffffff;
2792 phba->ktime_seg5_total = 0;
2793 phba->ktime_seg5_max = 0;
2794 phba->ktime_seg5_min = 0xffffffff;
2795 phba->ktime_seg6_total = 0;
2796 phba->ktime_seg6_max = 0;
2797 phba->ktime_seg6_min = 0xffffffff;
2798 phba->ktime_seg7_total = 0;
2799 phba->ktime_seg7_max = 0;
2800 phba->ktime_seg7_min = 0xffffffff;
2801 phba->ktime_seg8_total = 0;
2802 phba->ktime_seg8_max = 0;
2803 phba->ktime_seg8_min = 0xffffffff;
2804 phba->ktime_seg9_total = 0;
2805 phba->ktime_seg9_max = 0;
2806 phba->ktime_seg9_min = 0xffffffff;
2807 phba->ktime_seg10_total = 0;
2808 phba->ktime_seg10_max = 0;
2809 phba->ktime_seg10_min = 0xffffffff;
2810 return strlen(pbuf);
2816 lpfc_debugfs_nvmeio_trc_open(struct inode *inode, struct file *file)
2818 struct lpfc_hba *phba = inode->i_private;
2819 struct lpfc_debug *debug;
2822 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2826 /* Round to page boundary */
2827 debug->buffer = kmalloc(LPFC_NVMEIO_TRC_SIZE, GFP_KERNEL);
2828 if (!debug->buffer) {
2833 debug->len = lpfc_debugfs_nvmeio_trc_data(phba, debug->buffer,
2834 LPFC_NVMEIO_TRC_SIZE);
2836 debug->i_private = inode->i_private;
2837 file->private_data = debug;
2845 lpfc_debugfs_nvmeio_trc_write(struct file *file, const char __user *buf,
2846 size_t nbytes, loff_t *ppos)
2848 struct lpfc_debug *debug = file->private_data;
2849 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2858 memset(mybuf, 0, sizeof(mybuf));
2860 if (copy_from_user(mybuf, buf, nbytes))
2864 if ((strncmp(pbuf, "off", sizeof("off") - 1) == 0)) {
2865 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2866 "0570 nvmeio_trc_off\n");
2867 phba->nvmeio_trc_output_idx = 0;
2868 phba->nvmeio_trc_on = 0;
2869 return strlen(pbuf);
2870 } else if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
2871 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2872 "0571 nvmeio_trc_on\n");
2873 phba->nvmeio_trc_output_idx = 0;
2874 phba->nvmeio_trc_on = 1;
2875 return strlen(pbuf);
2878 /* We must be off to allocate the trace buffer */
2879 if (phba->nvmeio_trc_on != 0)
2882 /* If not on or off, the parameter is the trace buffer size */
2883 i = kstrtoul(pbuf, 0, &sz);
2886 phba->nvmeio_trc_size = (uint32_t)sz;
2888 /* It must be a power of 2 - round down */
2895 if (phba->nvmeio_trc_size != sz)
2896 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2897 "0572 nvmeio_trc_size changed to %ld\n",
2899 phba->nvmeio_trc_size = (uint32_t)sz;
2901 /* If one previously exists, free it */
2902 kfree(phba->nvmeio_trc);
2904 /* Allocate new trace buffer and initialize */
2905 phba->nvmeio_trc = kzalloc((sizeof(struct lpfc_debugfs_nvmeio_trc) *
2907 if (!phba->nvmeio_trc) {
2908 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2909 "0573 Cannot create debugfs "
2910 "nvmeio_trc buffer\n");
2913 atomic_set(&phba->nvmeio_trc_cnt, 0);
2914 phba->nvmeio_trc_on = 0;
2915 phba->nvmeio_trc_output_idx = 0;
2917 return strlen(pbuf);
2921 lpfc_debugfs_cpucheck_open(struct inode *inode, struct file *file)
2923 struct lpfc_vport *vport = inode->i_private;
2924 struct lpfc_debug *debug;
2927 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2931 /* Round to page boundary */
2932 debug->buffer = kmalloc(LPFC_CPUCHECK_SIZE, GFP_KERNEL);
2933 if (!debug->buffer) {
2938 debug->len = lpfc_debugfs_cpucheck_data(vport, debug->buffer,
2939 LPFC_CPUCHECK_SIZE);
2941 debug->i_private = inode->i_private;
2942 file->private_data = debug;
2950 lpfc_debugfs_cpucheck_write(struct file *file, const char __user *buf,
2951 size_t nbytes, loff_t *ppos)
2953 struct lpfc_debug *debug = file->private_data;
2954 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
2955 struct lpfc_hba *phba = vport->phba;
2956 struct lpfc_sli4_hdw_queue *qp;
2964 memset(mybuf, 0, sizeof(mybuf));
2966 if (copy_from_user(mybuf, buf, nbytes))
2970 if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
2971 if (phba->nvmet_support)
2972 phba->cpucheck_on |= LPFC_CHECK_NVMET_IO;
2974 phba->cpucheck_on |= (LPFC_CHECK_NVME_IO |
2975 LPFC_CHECK_SCSI_IO);
2976 return strlen(pbuf);
2977 } else if ((strncmp(pbuf, "nvme_on", sizeof("nvme_on") - 1) == 0)) {
2978 if (phba->nvmet_support)
2979 phba->cpucheck_on |= LPFC_CHECK_NVMET_IO;
2981 phba->cpucheck_on |= LPFC_CHECK_NVME_IO;
2982 return strlen(pbuf);
2983 } else if ((strncmp(pbuf, "scsi_on", sizeof("scsi_on") - 1) == 0)) {
2984 phba->cpucheck_on |= LPFC_CHECK_SCSI_IO;
2985 return strlen(pbuf);
2986 } else if ((strncmp(pbuf, "rcv",
2987 sizeof("rcv") - 1) == 0)) {
2988 if (phba->nvmet_support)
2989 phba->cpucheck_on |= LPFC_CHECK_NVMET_RCV;
2992 return strlen(pbuf);
2993 } else if ((strncmp(pbuf, "off",
2994 sizeof("off") - 1) == 0)) {
2995 phba->cpucheck_on = LPFC_CHECK_OFF;
2996 return strlen(pbuf);
2997 } else if ((strncmp(pbuf, "zero",
2998 sizeof("zero") - 1) == 0)) {
2999 for (i = 0; i < phba->cfg_hdw_queue; i++) {
3000 qp = &phba->sli4_hba.hdwq[i];
3002 for (j = 0; j < LPFC_CHECK_CPU_CNT; j++) {
3003 qp->cpucheck_rcv_io[j] = 0;
3004 qp->cpucheck_xmt_io[j] = 0;
3005 qp->cpucheck_cmpl_io[j] = 0;
3008 return strlen(pbuf);
3014 * ---------------------------------
3015 * iDiag debugfs file access methods
3016 * ---------------------------------
3018 * All access methods are through the proper SLI4 PCI function's debugfs
3021 * /sys/kernel/debug/lpfc/fn<#>/iDiag
3025 * lpfc_idiag_cmd_get - Get and parse idiag debugfs comands from user space
3026 * @buf: The pointer to the user space buffer.
3027 * @nbytes: The number of bytes in the user space buffer.
3028 * @idiag_cmd: pointer to the idiag command struct.
3030 * This routine reads data from debugfs user space buffer and parses the
3031 * buffer for getting the idiag command and arguments. The while space in
3032 * between the set of data is used as the parsing separator.
3034 * This routine returns 0 when successful, it returns proper error code
3035 * back to the user space in error conditions.
3037 static int lpfc_idiag_cmd_get(const char __user *buf, size_t nbytes,
3038 struct lpfc_idiag_cmd *idiag_cmd)
3041 char *pbuf, *step_str;
3045 memset(mybuf, 0, sizeof(mybuf));
3046 memset(idiag_cmd, 0, sizeof(*idiag_cmd));
3047 bsize = min(nbytes, (sizeof(mybuf)-1));
3049 if (copy_from_user(mybuf, buf, bsize))
3052 step_str = strsep(&pbuf, "\t ");
3054 /* The opcode must present */
3058 idiag_cmd->opcode = simple_strtol(step_str, NULL, 0);
3059 if (idiag_cmd->opcode == 0)
3062 for (i = 0; i < LPFC_IDIAG_CMD_DATA_SIZE; i++) {
3063 step_str = strsep(&pbuf, "\t ");
3066 idiag_cmd->data[i] = simple_strtol(step_str, NULL, 0);
3072 * lpfc_idiag_open - idiag open debugfs
3073 * @inode: The inode pointer that contains a pointer to phba.
3074 * @file: The file pointer to attach the file operation.
3077 * This routine is the entry point for the debugfs open file operation. It
3078 * gets the reference to phba from the i_private field in @inode, it then
3079 * allocates buffer for the file operation, performs the necessary PCI config
3080 * space read into the allocated buffer according to the idiag user command
3081 * setup, and then returns a pointer to buffer in the private_data field in
3085 * This function returns zero if successful. On error it will return an
3086 * negative error value.
3089 lpfc_idiag_open(struct inode *inode, struct file *file)
3091 struct lpfc_debug *debug;
3093 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
3097 debug->i_private = inode->i_private;
3098 debug->buffer = NULL;
3099 file->private_data = debug;
3105 * lpfc_idiag_release - Release idiag access file operation
3106 * @inode: The inode pointer that contains a vport pointer. (unused)
3107 * @file: The file pointer that contains the buffer to release.
3110 * This routine is the generic release routine for the idiag access file
3111 * operation, it frees the buffer that was allocated when the debugfs file
3115 * This function returns zero.
3118 lpfc_idiag_release(struct inode *inode, struct file *file)
3120 struct lpfc_debug *debug = file->private_data;
3122 /* Free the buffers to the file operation */
3123 kfree(debug->buffer);
3130 * lpfc_idiag_cmd_release - Release idiag cmd access file operation
3131 * @inode: The inode pointer that contains a vport pointer. (unused)
3132 * @file: The file pointer that contains the buffer to release.
3135 * This routine frees the buffer that was allocated when the debugfs file
3136 * was opened. It also reset the fields in the idiag command struct in the
3137 * case of command for write operation.
3140 * This function returns zero.
3143 lpfc_idiag_cmd_release(struct inode *inode, struct file *file)
3145 struct lpfc_debug *debug = file->private_data;
3147 if (debug->op == LPFC_IDIAG_OP_WR) {
3148 switch (idiag.cmd.opcode) {
3149 case LPFC_IDIAG_CMD_PCICFG_WR:
3150 case LPFC_IDIAG_CMD_PCICFG_ST:
3151 case LPFC_IDIAG_CMD_PCICFG_CL:
3152 case LPFC_IDIAG_CMD_QUEACC_WR:
3153 case LPFC_IDIAG_CMD_QUEACC_ST:
3154 case LPFC_IDIAG_CMD_QUEACC_CL:
3155 memset(&idiag, 0, sizeof(idiag));
3162 /* Free the buffers to the file operation */
3163 kfree(debug->buffer);
3170 * lpfc_idiag_pcicfg_read - idiag debugfs read pcicfg
3171 * @file: The file pointer to read from.
3172 * @buf: The buffer to copy the data to.
3173 * @nbytes: The number of bytes to read.
3174 * @ppos: The position in the file to start reading from.
3177 * This routine reads data from the @phba pci config space according to the
3178 * idiag command, and copies to user @buf. Depending on the PCI config space
3179 * read command setup, it does either a single register read of a byte
3180 * (8 bits), a word (16 bits), or a dword (32 bits) or browsing through all
3181 * registers from the 4K extended PCI config space.
3184 * This function returns the amount of data that was read (this could be less
3185 * than @nbytes if the end of the file was reached) or a negative error value.
3188 lpfc_idiag_pcicfg_read(struct file *file, char __user *buf, size_t nbytes,
3191 struct lpfc_debug *debug = file->private_data;
3192 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3193 int offset_label, offset, len = 0, index = LPFC_PCI_CFG_RD_SIZE;
3196 struct pci_dev *pdev;
3201 pdev = phba->pcidev;
3205 /* This is a user read operation */
3206 debug->op = LPFC_IDIAG_OP_RD;
3209 debug->buffer = kmalloc(LPFC_PCI_CFG_SIZE, GFP_KERNEL);
3212 pbuffer = debug->buffer;
3217 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
3218 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
3219 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
3223 /* Read single PCI config space register */
3225 case SIZE_U8: /* byte (8 bits) */
3226 pci_read_config_byte(pdev, where, &u8val);
3227 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3228 "%03x: %02x\n", where, u8val);
3230 case SIZE_U16: /* word (16 bits) */
3231 pci_read_config_word(pdev, where, &u16val);
3232 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3233 "%03x: %04x\n", where, u16val);
3235 case SIZE_U32: /* double word (32 bits) */
3236 pci_read_config_dword(pdev, where, &u32val);
3237 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3238 "%03x: %08x\n", where, u32val);
3240 case LPFC_PCI_CFG_BROWSE: /* browse all */
3248 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3252 /* Browse all PCI config space registers */
3253 offset_label = idiag.offset.last_rd;
3254 offset = offset_label;
3256 /* Read PCI config space */
3257 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3258 "%03x: ", offset_label);
3260 pci_read_config_dword(pdev, offset, &u32val);
3261 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3263 offset += sizeof(uint32_t);
3264 if (offset >= LPFC_PCI_CFG_SIZE) {
3265 len += snprintf(pbuffer+len,
3266 LPFC_PCI_CFG_SIZE-len, "\n");
3269 index -= sizeof(uint32_t);
3271 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3273 else if (!(index % (8 * sizeof(uint32_t)))) {
3274 offset_label += (8 * sizeof(uint32_t));
3275 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3276 "\n%03x: ", offset_label);
3280 /* Set up the offset for next portion of pci cfg read */
3282 idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE;
3283 if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE)
3284 idiag.offset.last_rd = 0;
3286 idiag.offset.last_rd = 0;
3288 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3292 * lpfc_idiag_pcicfg_write - Syntax check and set up idiag pcicfg commands
3293 * @file: The file pointer to read from.
3294 * @buf: The buffer to copy the user data from.
3295 * @nbytes: The number of bytes to get.
3296 * @ppos: The position in the file to start reading from.
3298 * This routine get the debugfs idiag command struct from user space and
3299 * then perform the syntax check for PCI config space read or write command
3300 * accordingly. In the case of PCI config space read command, it sets up
3301 * the command in the idiag command struct for the debugfs read operation.
3302 * In the case of PCI config space write operation, it executes the write
3303 * operation into the PCI config space accordingly.
3305 * It returns the @nbytges passing in from debugfs user space when successful.
3306 * In case of error conditions, it returns proper error code back to the user
3310 lpfc_idiag_pcicfg_write(struct file *file, const char __user *buf,
3311 size_t nbytes, loff_t *ppos)
3313 struct lpfc_debug *debug = file->private_data;
3314 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3315 uint32_t where, value, count;
3319 struct pci_dev *pdev;
3322 pdev = phba->pcidev;
3326 /* This is a user write operation */
3327 debug->op = LPFC_IDIAG_OP_WR;
3329 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3333 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
3334 /* Sanity check on PCI config read command line arguments */
3335 if (rc != LPFC_PCI_CFG_RD_CMD_ARG)
3337 /* Read command from PCI config space, set up command fields */
3338 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
3339 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
3340 if (count == LPFC_PCI_CFG_BROWSE) {
3341 if (where % sizeof(uint32_t))
3343 /* Starting offset to browse */
3344 idiag.offset.last_rd = where;
3345 } else if ((count != sizeof(uint8_t)) &&
3346 (count != sizeof(uint16_t)) &&
3347 (count != sizeof(uint32_t)))
3349 if (count == sizeof(uint8_t)) {
3350 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
3352 if (where % sizeof(uint8_t))
3355 if (count == sizeof(uint16_t)) {
3356 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
3358 if (where % sizeof(uint16_t))
3361 if (count == sizeof(uint32_t)) {
3362 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
3364 if (where % sizeof(uint32_t))
3367 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR ||
3368 idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST ||
3369 idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3370 /* Sanity check on PCI config write command line arguments */
3371 if (rc != LPFC_PCI_CFG_WR_CMD_ARG)
3373 /* Write command to PCI config space, read-modify-write */
3374 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
3375 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
3376 value = idiag.cmd.data[IDIAG_PCICFG_VALUE_INDX];
3378 if ((count != sizeof(uint8_t)) &&
3379 (count != sizeof(uint16_t)) &&
3380 (count != sizeof(uint32_t)))
3382 if (count == sizeof(uint8_t)) {
3383 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
3385 if (where % sizeof(uint8_t))
3387 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
3388 pci_write_config_byte(pdev, where,
3390 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
3391 rc = pci_read_config_byte(pdev, where, &u8val);
3393 u8val |= (uint8_t)value;
3394 pci_write_config_byte(pdev, where,
3398 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3399 rc = pci_read_config_byte(pdev, where, &u8val);
3401 u8val &= (uint8_t)(~value);
3402 pci_write_config_byte(pdev, where,
3407 if (count == sizeof(uint16_t)) {
3408 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
3410 if (where % sizeof(uint16_t))
3412 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
3413 pci_write_config_word(pdev, where,
3415 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
3416 rc = pci_read_config_word(pdev, where, &u16val);
3418 u16val |= (uint16_t)value;
3419 pci_write_config_word(pdev, where,
3423 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3424 rc = pci_read_config_word(pdev, where, &u16val);
3426 u16val &= (uint16_t)(~value);
3427 pci_write_config_word(pdev, where,
3432 if (count == sizeof(uint32_t)) {
3433 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
3435 if (where % sizeof(uint32_t))
3437 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
3438 pci_write_config_dword(pdev, where, value);
3439 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
3440 rc = pci_read_config_dword(pdev, where,
3444 pci_write_config_dword(pdev, where,
3448 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3449 rc = pci_read_config_dword(pdev, where,
3453 pci_write_config_dword(pdev, where,
3459 /* All other opecodes are illegal for now */
3464 memset(&idiag, 0, sizeof(idiag));
3469 * lpfc_idiag_baracc_read - idiag debugfs pci bar access read
3470 * @file: The file pointer to read from.
3471 * @buf: The buffer to copy the data to.
3472 * @nbytes: The number of bytes to read.
3473 * @ppos: The position in the file to start reading from.
3476 * This routine reads data from the @phba pci bar memory mapped space
3477 * according to the idiag command, and copies to user @buf.
3480 * This function returns the amount of data that was read (this could be less
3481 * than @nbytes if the end of the file was reached) or a negative error value.
3484 lpfc_idiag_baracc_read(struct file *file, char __user *buf, size_t nbytes,
3487 struct lpfc_debug *debug = file->private_data;
3488 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3489 int offset_label, offset, offset_run, len = 0, index;
3490 int bar_num, acc_range, bar_size;
3492 void __iomem *mem_mapped_bar;
3494 struct pci_dev *pdev;
3497 pdev = phba->pcidev;
3501 /* This is a user read operation */
3502 debug->op = LPFC_IDIAG_OP_RD;
3505 debug->buffer = kmalloc(LPFC_PCI_BAR_RD_BUF_SIZE, GFP_KERNEL);
3508 pbuffer = debug->buffer;
3513 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
3514 bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
3515 offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
3516 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
3517 bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
3524 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
3525 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
3526 if (bar_num == IDIAG_BARACC_BAR_0)
3527 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3528 else if (bar_num == IDIAG_BARACC_BAR_1)
3529 mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
3530 else if (bar_num == IDIAG_BARACC_BAR_2)
3531 mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
3534 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
3535 if (bar_num == IDIAG_BARACC_BAR_0)
3536 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3542 /* Read single PCI bar space register */
3543 if (acc_range == SINGLE_WORD) {
3544 offset_run = offset;
3545 u32val = readl(mem_mapped_bar + offset_run);
3546 len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
3547 "%05x: %08x\n", offset_run, u32val);
3551 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3555 /* Browse all PCI bar space registers */
3556 offset_label = idiag.offset.last_rd;
3557 offset_run = offset_label;
3559 /* Read PCI bar memory mapped space */
3560 len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
3561 "%05x: ", offset_label);
3562 index = LPFC_PCI_BAR_RD_SIZE;
3564 u32val = readl(mem_mapped_bar + offset_run);
3565 len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
3567 offset_run += sizeof(uint32_t);
3568 if (acc_range == LPFC_PCI_BAR_BROWSE) {
3569 if (offset_run >= bar_size) {
3570 len += snprintf(pbuffer+len,
3571 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
3575 if (offset_run >= offset +
3576 (acc_range * sizeof(uint32_t))) {
3577 len += snprintf(pbuffer+len,
3578 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
3582 index -= sizeof(uint32_t);
3584 len += snprintf(pbuffer+len,
3585 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
3586 else if (!(index % (8 * sizeof(uint32_t)))) {
3587 offset_label += (8 * sizeof(uint32_t));
3588 len += snprintf(pbuffer+len,
3589 LPFC_PCI_BAR_RD_BUF_SIZE-len,
3590 "\n%05x: ", offset_label);
3594 /* Set up the offset for next portion of pci bar read */
3596 idiag.offset.last_rd += LPFC_PCI_BAR_RD_SIZE;
3597 if (acc_range == LPFC_PCI_BAR_BROWSE) {
3598 if (idiag.offset.last_rd >= bar_size)
3599 idiag.offset.last_rd = 0;
3601 if (offset_run >= offset +
3602 (acc_range * sizeof(uint32_t)))
3603 idiag.offset.last_rd = offset;
3606 if (acc_range == LPFC_PCI_BAR_BROWSE)
3607 idiag.offset.last_rd = 0;
3609 idiag.offset.last_rd = offset;
3612 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3616 * lpfc_idiag_baracc_write - Syntax check and set up idiag bar access commands
3617 * @file: The file pointer to read from.
3618 * @buf: The buffer to copy the user data from.
3619 * @nbytes: The number of bytes to get.
3620 * @ppos: The position in the file to start reading from.
3622 * This routine get the debugfs idiag command struct from user space and
3623 * then perform the syntax check for PCI bar memory mapped space read or
3624 * write command accordingly. In the case of PCI bar memory mapped space
3625 * read command, it sets up the command in the idiag command struct for
3626 * the debugfs read operation. In the case of PCI bar memorpy mapped space
3627 * write operation, it executes the write operation into the PCI bar memory
3628 * mapped space accordingly.
3630 * It returns the @nbytges passing in from debugfs user space when successful.
3631 * In case of error conditions, it returns proper error code back to the user
3635 lpfc_idiag_baracc_write(struct file *file, const char __user *buf,
3636 size_t nbytes, loff_t *ppos)
3638 struct lpfc_debug *debug = file->private_data;
3639 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3640 uint32_t bar_num, bar_size, offset, value, acc_range;
3641 struct pci_dev *pdev;
3642 void __iomem *mem_mapped_bar;
3647 pdev = phba->pcidev;
3651 /* This is a user write operation */
3652 debug->op = LPFC_IDIAG_OP_WR;
3654 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3658 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
3659 bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
3661 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
3662 if ((bar_num != IDIAG_BARACC_BAR_0) &&
3663 (bar_num != IDIAG_BARACC_BAR_1) &&
3664 (bar_num != IDIAG_BARACC_BAR_2))
3666 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
3667 if (bar_num != IDIAG_BARACC_BAR_0)
3672 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
3673 if (bar_num == IDIAG_BARACC_BAR_0) {
3674 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3675 LPFC_PCI_IF0_BAR0_SIZE;
3676 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3677 } else if (bar_num == IDIAG_BARACC_BAR_1) {
3678 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3679 LPFC_PCI_IF0_BAR1_SIZE;
3680 mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
3681 } else if (bar_num == IDIAG_BARACC_BAR_2) {
3682 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3683 LPFC_PCI_IF0_BAR2_SIZE;
3684 mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
3687 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
3688 if (bar_num == IDIAG_BARACC_BAR_0) {
3689 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3690 LPFC_PCI_IF2_BAR0_SIZE;
3691 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3697 offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
3698 if (offset % sizeof(uint32_t))
3701 bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
3702 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
3703 /* Sanity check on PCI config read command line arguments */
3704 if (rc != LPFC_PCI_BAR_RD_CMD_ARG)
3706 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
3707 if (acc_range == LPFC_PCI_BAR_BROWSE) {
3708 if (offset > bar_size - sizeof(uint32_t))
3710 /* Starting offset to browse */
3711 idiag.offset.last_rd = offset;
3712 } else if (acc_range > SINGLE_WORD) {
3713 if (offset + acc_range * sizeof(uint32_t) > bar_size)
3715 /* Starting offset to browse */
3716 idiag.offset.last_rd = offset;
3717 } else if (acc_range != SINGLE_WORD)
3719 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR ||
3720 idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST ||
3721 idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
3722 /* Sanity check on PCI bar write command line arguments */
3723 if (rc != LPFC_PCI_BAR_WR_CMD_ARG)
3725 /* Write command to PCI bar space, read-modify-write */
3726 acc_range = SINGLE_WORD;
3727 value = idiag.cmd.data[IDIAG_BARACC_REG_VAL_INDX];
3728 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR) {
3729 writel(value, mem_mapped_bar + offset);
3730 readl(mem_mapped_bar + offset);
3732 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST) {
3733 u32val = readl(mem_mapped_bar + offset);
3735 writel(u32val, mem_mapped_bar + offset);
3736 readl(mem_mapped_bar + offset);
3738 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
3739 u32val = readl(mem_mapped_bar + offset);
3741 writel(u32val, mem_mapped_bar + offset);
3742 readl(mem_mapped_bar + offset);
3745 /* All other opecodes are illegal for now */
3750 memset(&idiag, 0, sizeof(idiag));
3755 __lpfc_idiag_print_wq(struct lpfc_queue *qp, char *wqtype,
3756 char *pbuffer, int len)
3761 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3762 "\t\t%s WQ info: ", wqtype);
3763 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3764 "AssocCQID[%04d]: WQ-STAT[oflow:x%x posted:x%llx]\n",
3765 qp->assoc_qid, qp->q_cnt_1,
3766 (unsigned long long)qp->q_cnt_4);
3767 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3768 "\t\tWQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3769 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]",
3770 qp->queue_id, qp->entry_count,
3771 qp->entry_size, qp->host_index,
3772 qp->hba_index, qp->notify_interval);
3773 len += snprintf(pbuffer + len,
3774 LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n");
3779 lpfc_idiag_wqs_for_cq(struct lpfc_hba *phba, char *wqtype, char *pbuffer,
3780 int *len, int max_cnt, int cq_id)
3782 struct lpfc_queue *qp;
3785 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
3786 qp = phba->sli4_hba.hdwq[qidx].fcp_wq;
3787 if (qp->assoc_qid != cq_id)
3789 *len = __lpfc_idiag_print_wq(qp, wqtype, pbuffer, *len);
3790 if (*len >= max_cnt)
3793 if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
3794 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
3795 qp = phba->sli4_hba.hdwq[qidx].nvme_wq;
3796 if (qp->assoc_qid != cq_id)
3798 *len = __lpfc_idiag_print_wq(qp, wqtype, pbuffer, *len);
3799 if (*len >= max_cnt)
3807 __lpfc_idiag_print_cq(struct lpfc_queue *qp, char *cqtype,
3808 char *pbuffer, int len)
3813 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3814 "\t%s CQ info: ", cqtype);
3815 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3816 "AssocEQID[%02d]: CQ STAT[max:x%x relw:x%x "
3817 "xabt:x%x wq:x%llx]\n",
3818 qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2,
3819 qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
3820 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3821 "\tCQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3822 "HST-IDX[%04d], NTFI[%03d], PLMT[%03d]",
3823 qp->queue_id, qp->entry_count,
3824 qp->entry_size, qp->host_index,
3825 qp->notify_interval, qp->max_proc_limit);
3827 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n");
3833 __lpfc_idiag_print_rqpair(struct lpfc_queue *qp, struct lpfc_queue *datqp,
3834 char *rqtype, char *pbuffer, int len)
3839 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3840 "\t\t%s RQ info: ", rqtype);
3841 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3842 "AssocCQID[%02d]: RQ-STAT[nopost:x%x nobuf:x%x "
3843 "posted:x%x rcv:x%llx]\n",
3844 qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2,
3845 qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
3846 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3847 "\t\tHQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3848 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n",
3849 qp->queue_id, qp->entry_count, qp->entry_size,
3850 qp->host_index, qp->hba_index, qp->notify_interval);
3851 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3852 "\t\tDQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3853 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n",
3854 datqp->queue_id, datqp->entry_count,
3855 datqp->entry_size, datqp->host_index,
3856 datqp->hba_index, datqp->notify_interval);
3861 lpfc_idiag_cqs_for_eq(struct lpfc_hba *phba, char *pbuffer,
3862 int *len, int max_cnt, int eqidx, int eq_id)
3864 struct lpfc_queue *qp;
3867 qp = phba->sli4_hba.hdwq[eqidx].fcp_cq;
3869 *len = __lpfc_idiag_print_cq(qp, "FCP", pbuffer, *len);
3871 /* Reset max counter */
3874 if (*len >= max_cnt)
3877 rc = lpfc_idiag_wqs_for_cq(phba, "FCP", pbuffer, len,
3878 max_cnt, qp->queue_id);
3882 if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
3883 qp = phba->sli4_hba.hdwq[eqidx].nvme_cq;
3885 *len = __lpfc_idiag_print_cq(qp, "NVME", pbuffer, *len);
3887 /* Reset max counter */
3890 if (*len >= max_cnt)
3893 rc = lpfc_idiag_wqs_for_cq(phba, "NVME", pbuffer, len,
3894 max_cnt, qp->queue_id);
3899 if ((eqidx < phba->cfg_nvmet_mrq) && phba->nvmet_support) {
3901 qp = phba->sli4_hba.nvmet_cqset[eqidx];
3902 *len = __lpfc_idiag_print_cq(qp, "NVMET CQset", pbuffer, *len);
3904 /* Reset max counter */
3907 if (*len >= max_cnt)
3911 qp = phba->sli4_hba.nvmet_mrq_hdr[eqidx];
3912 *len = __lpfc_idiag_print_rqpair(qp,
3913 phba->sli4_hba.nvmet_mrq_data[eqidx],
3914 "NVMET MRQ", pbuffer, *len);
3916 if (*len >= max_cnt)
3924 __lpfc_idiag_print_eq(struct lpfc_queue *qp, char *eqtype,
3925 char *pbuffer, int len)
3930 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3931 "\n%s EQ info: EQ-STAT[max:x%x noE:x%x "
3932 "cqe_proc:x%x eqe_proc:x%llx eqd %d]\n",
3933 eqtype, qp->q_cnt_1, qp->q_cnt_2, qp->q_cnt_3,
3934 (unsigned long long)qp->q_cnt_4, qp->q_mode);
3935 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3936 "EQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3937 "HST-IDX[%04d], NTFI[%03d], PLMT[%03d], AFFIN[%03d]",
3938 qp->queue_id, qp->entry_count, qp->entry_size,
3939 qp->host_index, qp->notify_interval,
3940 qp->max_proc_limit, qp->chann);
3941 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n");
3947 * lpfc_idiag_queinfo_read - idiag debugfs read queue information
3948 * @file: The file pointer to read from.
3949 * @buf: The buffer to copy the data to.
3950 * @nbytes: The number of bytes to read.
3951 * @ppos: The position in the file to start reading from.
3954 * This routine reads data from the @phba SLI4 PCI function queue information,
3955 * and copies to user @buf.
3956 * This routine only returns 1 EQs worth of information. It remembers the last
3957 * EQ read and jumps to the next EQ. Thus subsequent calls to queInfo will
3958 * retrieve all EQs allocated for the phba.
3961 * This function returns the amount of data that was read (this could be less
3962 * than @nbytes if the end of the file was reached) or a negative error value.
3965 lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
3968 struct lpfc_debug *debug = file->private_data;
3969 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3971 int max_cnt, rc, x, len = 0;
3972 struct lpfc_queue *qp = NULL;
3975 debug->buffer = kmalloc(LPFC_QUE_INFO_GET_BUF_SIZE, GFP_KERNEL);
3978 pbuffer = debug->buffer;
3979 max_cnt = LPFC_QUE_INFO_GET_BUF_SIZE - 256;
3984 spin_lock_irq(&phba->hbalock);
3986 /* Fast-path event queue */
3987 if (phba->sli4_hba.hdwq && phba->cfg_hdw_queue) {
3989 x = phba->lpfc_idiag_last_eq;
3990 phba->lpfc_idiag_last_eq++;
3991 if (phba->lpfc_idiag_last_eq >= phba->cfg_hdw_queue)
3992 phba->lpfc_idiag_last_eq = 0;
3994 len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3995 "HDWQ %d out of %d HBA HDWQs\n",
3996 x, phba->cfg_hdw_queue);
3999 qp = phba->sli4_hba.hdwq[x].hba_eq;
4003 len = __lpfc_idiag_print_eq(qp, "HBA", pbuffer, len);
4005 /* Reset max counter */
4011 /* will dump both fcp and nvme cqs/wqs for the eq */
4012 rc = lpfc_idiag_cqs_for_eq(phba, pbuffer, &len,
4013 max_cnt, x, qp->queue_id);
4017 /* Only EQ 0 has slow path CQs configured */
4021 /* Slow-path mailbox CQ */
4022 qp = phba->sli4_hba.mbx_cq;
4023 len = __lpfc_idiag_print_cq(qp, "MBX", pbuffer, len);
4027 /* Slow-path MBOX MQ */
4028 qp = phba->sli4_hba.mbx_wq;
4029 len = __lpfc_idiag_print_wq(qp, "MBX", pbuffer, len);
4033 /* Slow-path ELS response CQ */
4034 qp = phba->sli4_hba.els_cq;
4035 len = __lpfc_idiag_print_cq(qp, "ELS", pbuffer, len);
4036 /* Reset max counter */
4042 /* Slow-path ELS WQ */
4043 qp = phba->sli4_hba.els_wq;
4044 len = __lpfc_idiag_print_wq(qp, "ELS", pbuffer, len);
4048 qp = phba->sli4_hba.hdr_rq;
4049 len = __lpfc_idiag_print_rqpair(qp, phba->sli4_hba.dat_rq,
4050 "ELS RQpair", pbuffer, len);
4054 /* Slow-path NVME LS response CQ */
4055 qp = phba->sli4_hba.nvmels_cq;
4056 len = __lpfc_idiag_print_cq(qp, "NVME LS",
4058 /* Reset max counter */
4064 /* Slow-path NVME LS WQ */
4065 qp = phba->sli4_hba.nvmels_wq;
4066 len = __lpfc_idiag_print_wq(qp, "NVME LS",
4074 spin_unlock_irq(&phba->hbalock);
4075 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4078 len += snprintf(pbuffer + len,
4079 LPFC_QUE_INFO_GET_BUF_SIZE - len, "Truncated ...\n");
4081 spin_unlock_irq(&phba->hbalock);
4082 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4086 * lpfc_idiag_que_param_check - queue access command parameter sanity check
4087 * @q: The pointer to queue structure.
4088 * @index: The index into a queue entry.
4089 * @count: The number of queue entries to access.
4092 * The routine performs sanity check on device queue access method commands.
4095 * This function returns -EINVAL when fails the sanity check, otherwise, it
4099 lpfc_idiag_que_param_check(struct lpfc_queue *q, int index, int count)
4101 /* Only support single entry read or browsing */
4102 if ((count != 1) && (count != LPFC_QUE_ACC_BROWSE))
4104 if (index > q->entry_count - 1)
4110 * lpfc_idiag_queacc_read_qe - read a single entry from the given queue index
4111 * @pbuffer: The pointer to buffer to copy the read data into.
4112 * @pque: The pointer to the queue to be read.
4113 * @index: The index into the queue entry.
4116 * This routine reads out a single entry from the given queue's index location
4117 * and copies it into the buffer provided.
4120 * This function returns 0 when it fails, otherwise, it returns the length of
4121 * the data read into the buffer provided.
4124 lpfc_idiag_queacc_read_qe(char *pbuffer, int len, struct lpfc_queue *pque,
4130 if (!pbuffer || !pque)
4133 esize = pque->entry_size;
4134 len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
4135 "QE-INDEX[%04d]:\n", index);
4138 pentry = pque->qe[index].address;
4140 len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
4143 offset += sizeof(uint32_t);
4144 esize -= sizeof(uint32_t);
4145 if (esize > 0 && !(offset % (4 * sizeof(uint32_t))))
4146 len += snprintf(pbuffer+len,
4147 LPFC_QUE_ACC_BUF_SIZE-len, "\n");
4149 len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, "\n");
4155 * lpfc_idiag_queacc_read - idiag debugfs read port queue
4156 * @file: The file pointer to read from.
4157 * @buf: The buffer to copy the data to.
4158 * @nbytes: The number of bytes to read.
4159 * @ppos: The position in the file to start reading from.
4162 * This routine reads data from the @phba device queue memory according to the
4163 * idiag command, and copies to user @buf. Depending on the queue dump read
4164 * command setup, it does either a single queue entry read or browing through
4165 * all entries of the queue.
4168 * This function returns the amount of data that was read (this could be less
4169 * than @nbytes if the end of the file was reached) or a negative error value.
4172 lpfc_idiag_queacc_read(struct file *file, char __user *buf, size_t nbytes,
4175 struct lpfc_debug *debug = file->private_data;
4176 uint32_t last_index, index, count;
4177 struct lpfc_queue *pque = NULL;
4181 /* This is a user read operation */
4182 debug->op = LPFC_IDIAG_OP_RD;
4185 debug->buffer = kmalloc(LPFC_QUE_ACC_BUF_SIZE, GFP_KERNEL);
4188 pbuffer = debug->buffer;
4193 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
4194 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
4195 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
4196 pque = (struct lpfc_queue *)idiag.ptr_private;
4200 /* Browse the queue starting from index */
4201 if (count == LPFC_QUE_ACC_BROWSE)
4204 /* Read a single entry from the queue */
4205 len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
4207 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4211 /* Browse all entries from the queue */
4212 last_index = idiag.offset.last_rd;
4215 while (len < LPFC_QUE_ACC_SIZE - pque->entry_size) {
4216 len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
4218 if (index > pque->entry_count - 1)
4222 /* Set up the offset for next portion of pci cfg read */
4223 if (index > pque->entry_count - 1)
4225 idiag.offset.last_rd = index;
4227 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4231 * lpfc_idiag_queacc_write - Syntax check and set up idiag queacc commands
4232 * @file: The file pointer to read from.
4233 * @buf: The buffer to copy the user data from.
4234 * @nbytes: The number of bytes to get.
4235 * @ppos: The position in the file to start reading from.
4237 * This routine get the debugfs idiag command struct from user space and then
4238 * perform the syntax check for port queue read (dump) or write (set) command
4239 * accordingly. In the case of port queue read command, it sets up the command
4240 * in the idiag command struct for the following debugfs read operation. In
4241 * the case of port queue write operation, it executes the write operation
4242 * into the port queue entry accordingly.
4244 * It returns the @nbytges passing in from debugfs user space when successful.
4245 * In case of error conditions, it returns proper error code back to the user
4249 lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
4250 size_t nbytes, loff_t *ppos)
4252 struct lpfc_debug *debug = file->private_data;
4253 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4254 uint32_t qidx, quetp, queid, index, count, offset, value;
4256 struct lpfc_queue *pque, *qp;
4259 /* This is a user write operation */
4260 debug->op = LPFC_IDIAG_OP_WR;
4262 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
4266 /* Get and sanity check on command feilds */
4267 quetp = idiag.cmd.data[IDIAG_QUEACC_QUETP_INDX];
4268 queid = idiag.cmd.data[IDIAG_QUEACC_QUEID_INDX];
4269 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
4270 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
4271 offset = idiag.cmd.data[IDIAG_QUEACC_OFFST_INDX];
4272 value = idiag.cmd.data[IDIAG_QUEACC_VALUE_INDX];
4274 /* Sanity check on command line arguments */
4275 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
4276 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
4277 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
4278 if (rc != LPFC_QUE_ACC_WR_CMD_ARG)
4282 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
4283 if (rc != LPFC_QUE_ACC_RD_CMD_ARG)
4290 /* HBA event queue */
4291 if (phba->sli4_hba.hdwq) {
4292 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
4293 qp = phba->sli4_hba.hdwq[qidx].hba_eq;
4294 if (qp && qp->queue_id == queid) {
4296 rc = lpfc_idiag_que_param_check(qp,
4300 idiag.ptr_private = qp;
4308 /* MBX complete queue */
4309 if (phba->sli4_hba.mbx_cq &&
4310 phba->sli4_hba.mbx_cq->queue_id == queid) {
4312 rc = lpfc_idiag_que_param_check(
4313 phba->sli4_hba.mbx_cq, index, count);
4316 idiag.ptr_private = phba->sli4_hba.mbx_cq;
4319 /* ELS complete queue */
4320 if (phba->sli4_hba.els_cq &&
4321 phba->sli4_hba.els_cq->queue_id == queid) {
4323 rc = lpfc_idiag_que_param_check(
4324 phba->sli4_hba.els_cq, index, count);
4327 idiag.ptr_private = phba->sli4_hba.els_cq;
4330 /* NVME LS complete queue */
4331 if (phba->sli4_hba.nvmels_cq &&
4332 phba->sli4_hba.nvmels_cq->queue_id == queid) {
4334 rc = lpfc_idiag_que_param_check(
4335 phba->sli4_hba.nvmels_cq, index, count);
4338 idiag.ptr_private = phba->sli4_hba.nvmels_cq;
4341 /* FCP complete queue */
4342 if (phba->sli4_hba.hdwq) {
4343 for (qidx = 0; qidx < phba->cfg_hdw_queue;
4345 qp = phba->sli4_hba.hdwq[qidx].fcp_cq;
4346 if (qp && qp->queue_id == queid) {
4348 rc = lpfc_idiag_que_param_check(
4352 idiag.ptr_private = qp;
4357 /* NVME complete queue */
4358 if (phba->sli4_hba.hdwq) {
4361 qp = phba->sli4_hba.hdwq[qidx].nvme_cq;
4362 if (qp && qp->queue_id == queid) {
4364 rc = lpfc_idiag_que_param_check(
4368 idiag.ptr_private = qp;
4371 } while (++qidx < phba->cfg_hdw_queue);
4376 /* MBX work queue */
4377 if (phba->sli4_hba.mbx_wq &&
4378 phba->sli4_hba.mbx_wq->queue_id == queid) {
4380 rc = lpfc_idiag_que_param_check(
4381 phba->sli4_hba.mbx_wq, index, count);
4384 idiag.ptr_private = phba->sli4_hba.mbx_wq;
4390 /* ELS work queue */
4391 if (phba->sli4_hba.els_wq &&
4392 phba->sli4_hba.els_wq->queue_id == queid) {
4394 rc = lpfc_idiag_que_param_check(
4395 phba->sli4_hba.els_wq, index, count);
4398 idiag.ptr_private = phba->sli4_hba.els_wq;
4401 /* NVME LS work queue */
4402 if (phba->sli4_hba.nvmels_wq &&
4403 phba->sli4_hba.nvmels_wq->queue_id == queid) {
4405 rc = lpfc_idiag_que_param_check(
4406 phba->sli4_hba.nvmels_wq, index, count);
4409 idiag.ptr_private = phba->sli4_hba.nvmels_wq;
4413 if (phba->sli4_hba.hdwq) {
4414 /* FCP/SCSI work queue */
4415 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
4416 qp = phba->sli4_hba.hdwq[qidx].fcp_wq;
4417 if (qp && qp->queue_id == queid) {
4419 rc = lpfc_idiag_que_param_check(
4423 idiag.ptr_private = qp;
4427 /* NVME work queue */
4428 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
4429 qp = phba->sli4_hba.hdwq[qidx].nvme_wq;
4430 if (qp && qp->queue_id == queid) {
4432 rc = lpfc_idiag_que_param_check(
4436 idiag.ptr_private = qp;
4446 if (phba->sli4_hba.hdr_rq &&
4447 phba->sli4_hba.hdr_rq->queue_id == queid) {
4449 rc = lpfc_idiag_que_param_check(
4450 phba->sli4_hba.hdr_rq, index, count);
4453 idiag.ptr_private = phba->sli4_hba.hdr_rq;
4457 if (phba->sli4_hba.dat_rq &&
4458 phba->sli4_hba.dat_rq->queue_id == queid) {
4460 rc = lpfc_idiag_que_param_check(
4461 phba->sli4_hba.dat_rq, index, count);
4464 idiag.ptr_private = phba->sli4_hba.dat_rq;
4476 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
4477 if (count == LPFC_QUE_ACC_BROWSE)
4478 idiag.offset.last_rd = index;
4481 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
4482 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
4483 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
4484 /* Additional sanity checks on write operation */
4485 pque = (struct lpfc_queue *)idiag.ptr_private;
4486 if (offset > pque->entry_size/sizeof(uint32_t) - 1)
4488 pentry = pque->qe[index].address;
4490 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR)
4492 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST)
4494 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL)
4500 /* Clean out command structure on command error out */
4501 memset(&idiag, 0, sizeof(idiag));
4506 * lpfc_idiag_drbacc_read_reg - idiag debugfs read a doorbell register
4507 * @phba: The pointer to hba structure.
4508 * @pbuffer: The pointer to the buffer to copy the data to.
4509 * @len: The lenght of bytes to copied.
4510 * @drbregid: The id to doorbell registers.
4513 * This routine reads a doorbell register and copies its content to the
4514 * user buffer pointed to by @pbuffer.
4517 * This function returns the amount of data that was copied into @pbuffer.
4520 lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
4521 int len, uint32_t drbregid)
4529 len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len,
4530 "EQ-DRB-REG: 0x%08x\n",
4531 readl(phba->sli4_hba.EQDBregaddr));
4534 len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len,
4535 "CQ-DRB-REG: 0x%08x\n",
4536 readl(phba->sli4_hba.CQDBregaddr));
4539 len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
4540 "MQ-DRB-REG: 0x%08x\n",
4541 readl(phba->sli4_hba.MQDBregaddr));
4544 len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
4545 "WQ-DRB-REG: 0x%08x\n",
4546 readl(phba->sli4_hba.WQDBregaddr));
4549 len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
4550 "RQ-DRB-REG: 0x%08x\n",
4551 readl(phba->sli4_hba.RQDBregaddr));
4561 * lpfc_idiag_drbacc_read - idiag debugfs read port doorbell
4562 * @file: The file pointer to read from.
4563 * @buf: The buffer to copy the data to.
4564 * @nbytes: The number of bytes to read.
4565 * @ppos: The position in the file to start reading from.
4568 * This routine reads data from the @phba device doorbell register according
4569 * to the idiag command, and copies to user @buf. Depending on the doorbell
4570 * register read command setup, it does either a single doorbell register
4571 * read or dump all doorbell registers.
4574 * This function returns the amount of data that was read (this could be less
4575 * than @nbytes if the end of the file was reached) or a negative error value.
4578 lpfc_idiag_drbacc_read(struct file *file, char __user *buf, size_t nbytes,
4581 struct lpfc_debug *debug = file->private_data;
4582 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4583 uint32_t drb_reg_id, i;
4587 /* This is a user read operation */
4588 debug->op = LPFC_IDIAG_OP_RD;
4591 debug->buffer = kmalloc(LPFC_DRB_ACC_BUF_SIZE, GFP_KERNEL);
4594 pbuffer = debug->buffer;
4599 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD)
4600 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
4604 if (drb_reg_id == LPFC_DRB_ACC_ALL)
4605 for (i = 1; i <= LPFC_DRB_MAX; i++)
4606 len = lpfc_idiag_drbacc_read_reg(phba,
4609 len = lpfc_idiag_drbacc_read_reg(phba,
4610 pbuffer, len, drb_reg_id);
4612 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4616 * lpfc_idiag_drbacc_write - Syntax check and set up idiag drbacc commands
4617 * @file: The file pointer to read from.
4618 * @buf: The buffer to copy the user data from.
4619 * @nbytes: The number of bytes to get.
4620 * @ppos: The position in the file to start reading from.
4622 * This routine get the debugfs idiag command struct from user space and then
4623 * perform the syntax check for port doorbell register read (dump) or write
4624 * (set) command accordingly. In the case of port queue read command, it sets
4625 * up the command in the idiag command struct for the following debugfs read
4626 * operation. In the case of port doorbell register write operation, it
4627 * executes the write operation into the port doorbell register accordingly.
4629 * It returns the @nbytges passing in from debugfs user space when successful.
4630 * In case of error conditions, it returns proper error code back to the user
4634 lpfc_idiag_drbacc_write(struct file *file, const char __user *buf,
4635 size_t nbytes, loff_t *ppos)
4637 struct lpfc_debug *debug = file->private_data;
4638 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4639 uint32_t drb_reg_id, value, reg_val = 0;
4640 void __iomem *drb_reg;
4643 /* This is a user write operation */
4644 debug->op = LPFC_IDIAG_OP_WR;
4646 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
4650 /* Sanity check on command line arguments */
4651 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
4652 value = idiag.cmd.data[IDIAG_DRBACC_VALUE_INDX];
4654 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
4655 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
4656 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
4657 if (rc != LPFC_DRB_ACC_WR_CMD_ARG)
4659 if (drb_reg_id > LPFC_DRB_MAX)
4661 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD) {
4662 if (rc != LPFC_DRB_ACC_RD_CMD_ARG)
4664 if ((drb_reg_id > LPFC_DRB_MAX) &&
4665 (drb_reg_id != LPFC_DRB_ACC_ALL))
4670 /* Perform the write access operation */
4671 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
4672 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
4673 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
4674 switch (drb_reg_id) {
4676 drb_reg = phba->sli4_hba.EQDBregaddr;
4679 drb_reg = phba->sli4_hba.CQDBregaddr;
4682 drb_reg = phba->sli4_hba.MQDBregaddr;
4685 drb_reg = phba->sli4_hba.WQDBregaddr;
4688 drb_reg = phba->sli4_hba.RQDBregaddr;
4694 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR)
4696 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST) {
4697 reg_val = readl(drb_reg);
4700 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
4701 reg_val = readl(drb_reg);
4704 writel(reg_val, drb_reg);
4705 readl(drb_reg); /* flush */
4710 /* Clean out command structure on command error out */
4711 memset(&idiag, 0, sizeof(idiag));
4716 * lpfc_idiag_ctlacc_read_reg - idiag debugfs read a control registers
4717 * @phba: The pointer to hba structure.
4718 * @pbuffer: The pointer to the buffer to copy the data to.
4719 * @len: The lenght of bytes to copied.
4720 * @drbregid: The id to doorbell registers.
4723 * This routine reads a control register and copies its content to the
4724 * user buffer pointed to by @pbuffer.
4727 * This function returns the amount of data that was copied into @pbuffer.
4730 lpfc_idiag_ctlacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
4731 int len, uint32_t ctlregid)
4738 case LPFC_CTL_PORT_SEM:
4739 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4740 "Port SemReg: 0x%08x\n",
4741 readl(phba->sli4_hba.conf_regs_memmap_p +
4742 LPFC_CTL_PORT_SEM_OFFSET));
4744 case LPFC_CTL_PORT_STA:
4745 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4746 "Port StaReg: 0x%08x\n",
4747 readl(phba->sli4_hba.conf_regs_memmap_p +
4748 LPFC_CTL_PORT_STA_OFFSET));
4750 case LPFC_CTL_PORT_CTL:
4751 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4752 "Port CtlReg: 0x%08x\n",
4753 readl(phba->sli4_hba.conf_regs_memmap_p +
4754 LPFC_CTL_PORT_CTL_OFFSET));
4756 case LPFC_CTL_PORT_ER1:
4757 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4758 "Port Er1Reg: 0x%08x\n",
4759 readl(phba->sli4_hba.conf_regs_memmap_p +
4760 LPFC_CTL_PORT_ER1_OFFSET));
4762 case LPFC_CTL_PORT_ER2:
4763 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4764 "Port Er2Reg: 0x%08x\n",
4765 readl(phba->sli4_hba.conf_regs_memmap_p +
4766 LPFC_CTL_PORT_ER2_OFFSET));
4768 case LPFC_CTL_PDEV_CTL:
4769 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4770 "PDev CtlReg: 0x%08x\n",
4771 readl(phba->sli4_hba.conf_regs_memmap_p +
4772 LPFC_CTL_PDEV_CTL_OFFSET));
4781 * lpfc_idiag_ctlacc_read - idiag debugfs read port and device control register
4782 * @file: The file pointer to read from.
4783 * @buf: The buffer to copy the data to.
4784 * @nbytes: The number of bytes to read.
4785 * @ppos: The position in the file to start reading from.
4788 * This routine reads data from the @phba port and device registers according
4789 * to the idiag command, and copies to user @buf.
4792 * This function returns the amount of data that was read (this could be less
4793 * than @nbytes if the end of the file was reached) or a negative error value.
4796 lpfc_idiag_ctlacc_read(struct file *file, char __user *buf, size_t nbytes,
4799 struct lpfc_debug *debug = file->private_data;
4800 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4801 uint32_t ctl_reg_id, i;
4805 /* This is a user read operation */
4806 debug->op = LPFC_IDIAG_OP_RD;
4809 debug->buffer = kmalloc(LPFC_CTL_ACC_BUF_SIZE, GFP_KERNEL);
4812 pbuffer = debug->buffer;
4817 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD)
4818 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
4822 if (ctl_reg_id == LPFC_CTL_ACC_ALL)
4823 for (i = 1; i <= LPFC_CTL_MAX; i++)
4824 len = lpfc_idiag_ctlacc_read_reg(phba,
4827 len = lpfc_idiag_ctlacc_read_reg(phba,
4828 pbuffer, len, ctl_reg_id);
4830 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4834 * lpfc_idiag_ctlacc_write - Syntax check and set up idiag ctlacc commands
4835 * @file: The file pointer to read from.
4836 * @buf: The buffer to copy the user data from.
4837 * @nbytes: The number of bytes to get.
4838 * @ppos: The position in the file to start reading from.
4840 * This routine get the debugfs idiag command struct from user space and then
4841 * perform the syntax check for port and device control register read (dump)
4842 * or write (set) command accordingly.
4844 * It returns the @nbytges passing in from debugfs user space when successful.
4845 * In case of error conditions, it returns proper error code back to the user
4849 lpfc_idiag_ctlacc_write(struct file *file, const char __user *buf,
4850 size_t nbytes, loff_t *ppos)
4852 struct lpfc_debug *debug = file->private_data;
4853 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4854 uint32_t ctl_reg_id, value, reg_val = 0;
4855 void __iomem *ctl_reg;
4858 /* This is a user write operation */
4859 debug->op = LPFC_IDIAG_OP_WR;
4861 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
4865 /* Sanity check on command line arguments */
4866 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
4867 value = idiag.cmd.data[IDIAG_CTLACC_VALUE_INDX];
4869 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
4870 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
4871 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
4872 if (rc != LPFC_CTL_ACC_WR_CMD_ARG)
4874 if (ctl_reg_id > LPFC_CTL_MAX)
4876 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD) {
4877 if (rc != LPFC_CTL_ACC_RD_CMD_ARG)
4879 if ((ctl_reg_id > LPFC_CTL_MAX) &&
4880 (ctl_reg_id != LPFC_CTL_ACC_ALL))
4885 /* Perform the write access operation */
4886 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
4887 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
4888 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
4889 switch (ctl_reg_id) {
4890 case LPFC_CTL_PORT_SEM:
4891 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4892 LPFC_CTL_PORT_SEM_OFFSET;
4894 case LPFC_CTL_PORT_STA:
4895 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4896 LPFC_CTL_PORT_STA_OFFSET;
4898 case LPFC_CTL_PORT_CTL:
4899 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4900 LPFC_CTL_PORT_CTL_OFFSET;
4902 case LPFC_CTL_PORT_ER1:
4903 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4904 LPFC_CTL_PORT_ER1_OFFSET;
4906 case LPFC_CTL_PORT_ER2:
4907 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4908 LPFC_CTL_PORT_ER2_OFFSET;
4910 case LPFC_CTL_PDEV_CTL:
4911 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4912 LPFC_CTL_PDEV_CTL_OFFSET;
4918 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR)
4920 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST) {
4921 reg_val = readl(ctl_reg);
4924 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
4925 reg_val = readl(ctl_reg);
4928 writel(reg_val, ctl_reg);
4929 readl(ctl_reg); /* flush */
4934 /* Clean out command structure on command error out */
4935 memset(&idiag, 0, sizeof(idiag));
4940 * lpfc_idiag_mbxacc_get_setup - idiag debugfs get mailbox access setup
4941 * @phba: Pointer to HBA context object.
4942 * @pbuffer: Pointer to data buffer.
4945 * This routine gets the driver mailbox access debugfs setup information.
4948 * This function returns the amount of data that was read (this could be less
4949 * than @nbytes if the end of the file was reached) or a negative error value.
4952 lpfc_idiag_mbxacc_get_setup(struct lpfc_hba *phba, char *pbuffer)
4954 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
4957 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
4958 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
4959 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
4960 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
4962 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
4963 "mbx_dump_map: 0x%08x\n", mbx_dump_map);
4964 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
4965 "mbx_dump_cnt: %04d\n", mbx_dump_cnt);
4966 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
4967 "mbx_word_cnt: %04d\n", mbx_word_cnt);
4968 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
4969 "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd);
4975 * lpfc_idiag_mbxacc_read - idiag debugfs read on mailbox access
4976 * @file: The file pointer to read from.
4977 * @buf: The buffer to copy the data to.
4978 * @nbytes: The number of bytes to read.
4979 * @ppos: The position in the file to start reading from.
4982 * This routine reads data from the @phba driver mailbox access debugfs setup
4986 * This function returns the amount of data that was read (this could be less
4987 * than @nbytes if the end of the file was reached) or a negative error value.
4990 lpfc_idiag_mbxacc_read(struct file *file, char __user *buf, size_t nbytes,
4993 struct lpfc_debug *debug = file->private_data;
4994 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4998 /* This is a user read operation */
4999 debug->op = LPFC_IDIAG_OP_RD;
5002 debug->buffer = kmalloc(LPFC_MBX_ACC_BUF_SIZE, GFP_KERNEL);
5005 pbuffer = debug->buffer;
5010 if ((idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP) &&
5011 (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP))
5014 len = lpfc_idiag_mbxacc_get_setup(phba, pbuffer);
5016 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
5020 * lpfc_idiag_mbxacc_write - Syntax check and set up idiag mbxacc commands
5021 * @file: The file pointer to read from.
5022 * @buf: The buffer to copy the user data from.
5023 * @nbytes: The number of bytes to get.
5024 * @ppos: The position in the file to start reading from.
5026 * This routine get the debugfs idiag command struct from user space and then
5027 * perform the syntax check for driver mailbox command (dump) and sets up the
5028 * necessary states in the idiag command struct accordingly.
5030 * It returns the @nbytges passing in from debugfs user space when successful.
5031 * In case of error conditions, it returns proper error code back to the user
5035 lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf,
5036 size_t nbytes, loff_t *ppos)
5038 struct lpfc_debug *debug = file->private_data;
5039 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
5042 /* This is a user write operation */
5043 debug->op = LPFC_IDIAG_OP_WR;
5045 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
5049 /* Sanity check on command line arguments */
5050 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
5051 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
5052 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
5053 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
5055 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_MBXACC_DP) {
5056 if (!(mbx_dump_map & LPFC_MBX_DMP_MBX_ALL))
5058 if ((mbx_dump_map & ~LPFC_MBX_DMP_MBX_ALL) &&
5059 (mbx_dump_map != LPFC_MBX_DMP_ALL))
5061 if (mbx_word_cnt > sizeof(MAILBOX_t))
5063 } else if (idiag.cmd.opcode == LPFC_IDIAG_BSG_MBXACC_DP) {
5064 if (!(mbx_dump_map & LPFC_BSG_DMP_MBX_ALL))
5066 if ((mbx_dump_map & ~LPFC_BSG_DMP_MBX_ALL) &&
5067 (mbx_dump_map != LPFC_MBX_DMP_ALL))
5069 if (mbx_word_cnt > (BSG_MBOX_SIZE)/4)
5071 if (mbx_mbox_cmd != 0x9b)
5076 if (mbx_word_cnt == 0)
5078 if (rc != LPFC_MBX_DMP_ARG)
5080 if (mbx_mbox_cmd & ~0xff)
5083 /* condition for stop mailbox dump */
5084 if (mbx_dump_cnt == 0)
5090 /* Clean out command structure on command error out */
5091 memset(&idiag, 0, sizeof(idiag));
5095 /* Clean out command structure on command error out */
5096 memset(&idiag, 0, sizeof(idiag));
5101 * lpfc_idiag_extacc_avail_get - get the available extents information
5102 * @phba: pointer to lpfc hba data structure.
5103 * @pbuffer: pointer to internal buffer.
5104 * @len: length into the internal buffer data has been copied.
5107 * This routine is to get the available extent information.
5110 * overall lenth of the data read into the internal buffer.
5113 lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
5115 uint16_t ext_cnt, ext_size;
5117 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5118 "\nAvailable Extents Information:\n");
5120 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5121 "\tPort Available VPI extents: ");
5122 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI,
5123 &ext_cnt, &ext_size);
5124 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5125 "Count %3d, Size %3d\n", ext_cnt, ext_size);
5127 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5128 "\tPort Available VFI extents: ");
5129 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI,
5130 &ext_cnt, &ext_size);
5131 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5132 "Count %3d, Size %3d\n", ext_cnt, ext_size);
5134 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5135 "\tPort Available RPI extents: ");
5136 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI,
5137 &ext_cnt, &ext_size);
5138 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5139 "Count %3d, Size %3d\n", ext_cnt, ext_size);
5141 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5142 "\tPort Available XRI extents: ");
5143 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI,
5144 &ext_cnt, &ext_size);
5145 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5146 "Count %3d, Size %3d\n", ext_cnt, ext_size);
5152 * lpfc_idiag_extacc_alloc_get - get the allocated extents information
5153 * @phba: pointer to lpfc hba data structure.
5154 * @pbuffer: pointer to internal buffer.
5155 * @len: length into the internal buffer data has been copied.
5158 * This routine is to get the allocated extent information.
5161 * overall lenth of the data read into the internal buffer.
5164 lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len)
5166 uint16_t ext_cnt, ext_size;
5169 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5170 "\nAllocated Extents Information:\n");
5172 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5173 "\tHost Allocated VPI extents: ");
5174 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI,
5175 &ext_cnt, &ext_size);
5177 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5178 "Port %d Extent %3d, Size %3d\n",
5179 phba->brd_no, ext_cnt, ext_size);
5181 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5184 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5185 "\tHost Allocated VFI extents: ");
5186 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI,
5187 &ext_cnt, &ext_size);
5189 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5190 "Port %d Extent %3d, Size %3d\n",
5191 phba->brd_no, ext_cnt, ext_size);
5193 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5196 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5197 "\tHost Allocated RPI extents: ");
5198 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI,
5199 &ext_cnt, &ext_size);
5201 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5202 "Port %d Extent %3d, Size %3d\n",
5203 phba->brd_no, ext_cnt, ext_size);
5205 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5208 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5209 "\tHost Allocated XRI extents: ");
5210 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI,
5211 &ext_cnt, &ext_size);
5213 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5214 "Port %d Extent %3d, Size %3d\n",
5215 phba->brd_no, ext_cnt, ext_size);
5217 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5224 * lpfc_idiag_extacc_drivr_get - get driver extent information
5225 * @phba: pointer to lpfc hba data structure.
5226 * @pbuffer: pointer to internal buffer.
5227 * @len: length into the internal buffer data has been copied.
5230 * This routine is to get the driver extent information.
5233 * overall lenth of the data read into the internal buffer.
5236 lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len)
5238 struct lpfc_rsrc_blks *rsrc_blks;
5241 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5242 "\nDriver Extents Information:\n");
5244 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5245 "\tVPI extents:\n");
5247 list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) {
5248 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5249 "\t\tBlock %3d: Start %4d, Count %4d\n",
5250 index, rsrc_blks->rsrc_start,
5251 rsrc_blks->rsrc_size);
5254 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5255 "\tVFI extents:\n");
5257 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list,
5259 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5260 "\t\tBlock %3d: Start %4d, Count %4d\n",
5261 index, rsrc_blks->rsrc_start,
5262 rsrc_blks->rsrc_size);
5266 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5267 "\tRPI extents:\n");
5269 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list,
5271 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5272 "\t\tBlock %3d: Start %4d, Count %4d\n",
5273 index, rsrc_blks->rsrc_start,
5274 rsrc_blks->rsrc_size);
5278 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5279 "\tXRI extents:\n");
5281 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list,
5283 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5284 "\t\tBlock %3d: Start %4d, Count %4d\n",
5285 index, rsrc_blks->rsrc_start,
5286 rsrc_blks->rsrc_size);
5294 * lpfc_idiag_extacc_write - Syntax check and set up idiag extacc commands
5295 * @file: The file pointer to read from.
5296 * @buf: The buffer to copy the user data from.
5297 * @nbytes: The number of bytes to get.
5298 * @ppos: The position in the file to start reading from.
5300 * This routine get the debugfs idiag command struct from user space and then
5301 * perform the syntax check for extent information access commands and sets
5302 * up the necessary states in the idiag command struct accordingly.
5304 * It returns the @nbytges passing in from debugfs user space when successful.
5305 * In case of error conditions, it returns proper error code back to the user
5309 lpfc_idiag_extacc_write(struct file *file, const char __user *buf,
5310 size_t nbytes, loff_t *ppos)
5312 struct lpfc_debug *debug = file->private_data;
5316 /* This is a user write operation */
5317 debug->op = LPFC_IDIAG_OP_WR;
5319 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
5323 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
5325 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
5327 if (rc != LPFC_EXT_ACC_CMD_ARG)
5329 if (!(ext_map & LPFC_EXT_ACC_ALL))
5334 /* Clean out command structure on command error out */
5335 memset(&idiag, 0, sizeof(idiag));
5340 * lpfc_idiag_extacc_read - idiag debugfs read access to extent information
5341 * @file: The file pointer to read from.
5342 * @buf: The buffer to copy the data to.
5343 * @nbytes: The number of bytes to read.
5344 * @ppos: The position in the file to start reading from.
5347 * This routine reads data from the proper extent information according to
5348 * the idiag command, and copies to user @buf.
5351 * This function returns the amount of data that was read (this could be less
5352 * than @nbytes if the end of the file was reached) or a negative error value.
5355 lpfc_idiag_extacc_read(struct file *file, char __user *buf, size_t nbytes,
5358 struct lpfc_debug *debug = file->private_data;
5359 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
5364 /* This is a user read operation */
5365 debug->op = LPFC_IDIAG_OP_RD;
5368 debug->buffer = kmalloc(LPFC_EXT_ACC_BUF_SIZE, GFP_KERNEL);
5371 pbuffer = debug->buffer;
5374 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
5377 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
5378 if (ext_map & LPFC_EXT_ACC_AVAIL)
5379 len = lpfc_idiag_extacc_avail_get(phba, pbuffer, len);
5380 if (ext_map & LPFC_EXT_ACC_ALLOC)
5381 len = lpfc_idiag_extacc_alloc_get(phba, pbuffer, len);
5382 if (ext_map & LPFC_EXT_ACC_DRIVR)
5383 len = lpfc_idiag_extacc_drivr_get(phba, pbuffer, len);
5385 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
5388 #undef lpfc_debugfs_op_disc_trc
5389 static const struct file_operations lpfc_debugfs_op_disc_trc = {
5390 .owner = THIS_MODULE,
5391 .open = lpfc_debugfs_disc_trc_open,
5392 .llseek = lpfc_debugfs_lseek,
5393 .read = lpfc_debugfs_read,
5394 .release = lpfc_debugfs_release,
5397 #undef lpfc_debugfs_op_nodelist
5398 static const struct file_operations lpfc_debugfs_op_nodelist = {
5399 .owner = THIS_MODULE,
5400 .open = lpfc_debugfs_nodelist_open,
5401 .llseek = lpfc_debugfs_lseek,
5402 .read = lpfc_debugfs_read,
5403 .release = lpfc_debugfs_release,
5406 #undef lpfc_debugfs_op_multixripools
5407 static const struct file_operations lpfc_debugfs_op_multixripools = {
5408 .owner = THIS_MODULE,
5409 .open = lpfc_debugfs_multixripools_open,
5410 .llseek = lpfc_debugfs_lseek,
5411 .read = lpfc_debugfs_read,
5412 .write = lpfc_debugfs_multixripools_write,
5413 .release = lpfc_debugfs_release,
5416 #undef lpfc_debugfs_op_hbqinfo
5417 static const struct file_operations lpfc_debugfs_op_hbqinfo = {
5418 .owner = THIS_MODULE,
5419 .open = lpfc_debugfs_hbqinfo_open,
5420 .llseek = lpfc_debugfs_lseek,
5421 .read = lpfc_debugfs_read,
5422 .release = lpfc_debugfs_release,
5425 #ifdef LPFC_HDWQ_LOCK_STAT
5426 #undef lpfc_debugfs_op_lockstat
5427 static const struct file_operations lpfc_debugfs_op_lockstat = {
5428 .owner = THIS_MODULE,
5429 .open = lpfc_debugfs_lockstat_open,
5430 .llseek = lpfc_debugfs_lseek,
5431 .read = lpfc_debugfs_read,
5432 .write = lpfc_debugfs_lockstat_write,
5433 .release = lpfc_debugfs_release,
5437 #undef lpfc_debugfs_op_dumpHBASlim
5438 static const struct file_operations lpfc_debugfs_op_dumpHBASlim = {
5439 .owner = THIS_MODULE,
5440 .open = lpfc_debugfs_dumpHBASlim_open,
5441 .llseek = lpfc_debugfs_lseek,
5442 .read = lpfc_debugfs_read,
5443 .release = lpfc_debugfs_release,
5446 #undef lpfc_debugfs_op_dumpHostSlim
5447 static const struct file_operations lpfc_debugfs_op_dumpHostSlim = {
5448 .owner = THIS_MODULE,
5449 .open = lpfc_debugfs_dumpHostSlim_open,
5450 .llseek = lpfc_debugfs_lseek,
5451 .read = lpfc_debugfs_read,
5452 .release = lpfc_debugfs_release,
5455 #undef lpfc_debugfs_op_nvmestat
5456 static const struct file_operations lpfc_debugfs_op_nvmestat = {
5457 .owner = THIS_MODULE,
5458 .open = lpfc_debugfs_nvmestat_open,
5459 .llseek = lpfc_debugfs_lseek,
5460 .read = lpfc_debugfs_read,
5461 .write = lpfc_debugfs_nvmestat_write,
5462 .release = lpfc_debugfs_release,
5465 #undef lpfc_debugfs_op_scsistat
5466 static const struct file_operations lpfc_debugfs_op_scsistat = {
5467 .owner = THIS_MODULE,
5468 .open = lpfc_debugfs_scsistat_open,
5469 .llseek = lpfc_debugfs_lseek,
5470 .read = lpfc_debugfs_read,
5471 .write = lpfc_debugfs_scsistat_write,
5472 .release = lpfc_debugfs_release,
5475 #undef lpfc_debugfs_op_nvmektime
5476 static const struct file_operations lpfc_debugfs_op_nvmektime = {
5477 .owner = THIS_MODULE,
5478 .open = lpfc_debugfs_nvmektime_open,
5479 .llseek = lpfc_debugfs_lseek,
5480 .read = lpfc_debugfs_read,
5481 .write = lpfc_debugfs_nvmektime_write,
5482 .release = lpfc_debugfs_release,
5485 #undef lpfc_debugfs_op_nvmeio_trc
5486 static const struct file_operations lpfc_debugfs_op_nvmeio_trc = {
5487 .owner = THIS_MODULE,
5488 .open = lpfc_debugfs_nvmeio_trc_open,
5489 .llseek = lpfc_debugfs_lseek,
5490 .read = lpfc_debugfs_read,
5491 .write = lpfc_debugfs_nvmeio_trc_write,
5492 .release = lpfc_debugfs_release,
5495 #undef lpfc_debugfs_op_cpucheck
5496 static const struct file_operations lpfc_debugfs_op_cpucheck = {
5497 .owner = THIS_MODULE,
5498 .open = lpfc_debugfs_cpucheck_open,
5499 .llseek = lpfc_debugfs_lseek,
5500 .read = lpfc_debugfs_read,
5501 .write = lpfc_debugfs_cpucheck_write,
5502 .release = lpfc_debugfs_release,
5505 #undef lpfc_debugfs_op_dumpData
5506 static const struct file_operations lpfc_debugfs_op_dumpData = {
5507 .owner = THIS_MODULE,
5508 .open = lpfc_debugfs_dumpData_open,
5509 .llseek = lpfc_debugfs_lseek,
5510 .read = lpfc_debugfs_read,
5511 .write = lpfc_debugfs_dumpDataDif_write,
5512 .release = lpfc_debugfs_dumpDataDif_release,
5515 #undef lpfc_debugfs_op_dumpDif
5516 static const struct file_operations lpfc_debugfs_op_dumpDif = {
5517 .owner = THIS_MODULE,
5518 .open = lpfc_debugfs_dumpDif_open,
5519 .llseek = lpfc_debugfs_lseek,
5520 .read = lpfc_debugfs_read,
5521 .write = lpfc_debugfs_dumpDataDif_write,
5522 .release = lpfc_debugfs_dumpDataDif_release,
5525 #undef lpfc_debugfs_op_dif_err
5526 static const struct file_operations lpfc_debugfs_op_dif_err = {
5527 .owner = THIS_MODULE,
5528 .open = simple_open,
5529 .llseek = lpfc_debugfs_lseek,
5530 .read = lpfc_debugfs_dif_err_read,
5531 .write = lpfc_debugfs_dif_err_write,
5532 .release = lpfc_debugfs_dif_err_release,
5535 #undef lpfc_debugfs_op_slow_ring_trc
5536 static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
5537 .owner = THIS_MODULE,
5538 .open = lpfc_debugfs_slow_ring_trc_open,
5539 .llseek = lpfc_debugfs_lseek,
5540 .read = lpfc_debugfs_read,
5541 .release = lpfc_debugfs_release,
5544 static struct dentry *lpfc_debugfs_root = NULL;
5545 static atomic_t lpfc_debugfs_hba_count;
5548 * File operations for the iDiag debugfs
5550 #undef lpfc_idiag_op_pciCfg
5551 static const struct file_operations lpfc_idiag_op_pciCfg = {
5552 .owner = THIS_MODULE,
5553 .open = lpfc_idiag_open,
5554 .llseek = lpfc_debugfs_lseek,
5555 .read = lpfc_idiag_pcicfg_read,
5556 .write = lpfc_idiag_pcicfg_write,
5557 .release = lpfc_idiag_cmd_release,
5560 #undef lpfc_idiag_op_barAcc
5561 static const struct file_operations lpfc_idiag_op_barAcc = {
5562 .owner = THIS_MODULE,
5563 .open = lpfc_idiag_open,
5564 .llseek = lpfc_debugfs_lseek,
5565 .read = lpfc_idiag_baracc_read,
5566 .write = lpfc_idiag_baracc_write,
5567 .release = lpfc_idiag_cmd_release,
5570 #undef lpfc_idiag_op_queInfo
5571 static const struct file_operations lpfc_idiag_op_queInfo = {
5572 .owner = THIS_MODULE,
5573 .open = lpfc_idiag_open,
5574 .read = lpfc_idiag_queinfo_read,
5575 .release = lpfc_idiag_release,
5578 #undef lpfc_idiag_op_queAcc
5579 static const struct file_operations lpfc_idiag_op_queAcc = {
5580 .owner = THIS_MODULE,
5581 .open = lpfc_idiag_open,
5582 .llseek = lpfc_debugfs_lseek,
5583 .read = lpfc_idiag_queacc_read,
5584 .write = lpfc_idiag_queacc_write,
5585 .release = lpfc_idiag_cmd_release,
5588 #undef lpfc_idiag_op_drbAcc
5589 static const struct file_operations lpfc_idiag_op_drbAcc = {
5590 .owner = THIS_MODULE,
5591 .open = lpfc_idiag_open,
5592 .llseek = lpfc_debugfs_lseek,
5593 .read = lpfc_idiag_drbacc_read,
5594 .write = lpfc_idiag_drbacc_write,
5595 .release = lpfc_idiag_cmd_release,
5598 #undef lpfc_idiag_op_ctlAcc
5599 static const struct file_operations lpfc_idiag_op_ctlAcc = {
5600 .owner = THIS_MODULE,
5601 .open = lpfc_idiag_open,
5602 .llseek = lpfc_debugfs_lseek,
5603 .read = lpfc_idiag_ctlacc_read,
5604 .write = lpfc_idiag_ctlacc_write,
5605 .release = lpfc_idiag_cmd_release,
5608 #undef lpfc_idiag_op_mbxAcc
5609 static const struct file_operations lpfc_idiag_op_mbxAcc = {
5610 .owner = THIS_MODULE,
5611 .open = lpfc_idiag_open,
5612 .llseek = lpfc_debugfs_lseek,
5613 .read = lpfc_idiag_mbxacc_read,
5614 .write = lpfc_idiag_mbxacc_write,
5615 .release = lpfc_idiag_cmd_release,
5618 #undef lpfc_idiag_op_extAcc
5619 static const struct file_operations lpfc_idiag_op_extAcc = {
5620 .owner = THIS_MODULE,
5621 .open = lpfc_idiag_open,
5622 .llseek = lpfc_debugfs_lseek,
5623 .read = lpfc_idiag_extacc_read,
5624 .write = lpfc_idiag_extacc_write,
5625 .release = lpfc_idiag_cmd_release,
5630 /* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command
5631 * @phba: Pointer to HBA context object.
5632 * @dmabuf: Pointer to a DMA buffer descriptor.
5635 * This routine dump a bsg pass-through non-embedded mailbox command with
5639 lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *phba, enum nemb_type nemb_tp,
5640 enum mbox_type mbox_tp, enum dma_type dma_tp,
5641 enum sta_type sta_tp,
5642 struct lpfc_dmabuf *dmabuf, uint32_t ext_buf)
5644 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
5645 uint32_t *mbx_mbox_cmd, *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt;
5646 char line_buf[LPFC_MBX_ACC_LBUF_SZ];
5648 uint32_t do_dump = 0;
5652 if (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP)
5655 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
5656 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
5657 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
5658 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
5660 if (!(*mbx_dump_map & LPFC_MBX_DMP_ALL) ||
5661 (*mbx_dump_cnt == 0) ||
5662 (*mbx_word_cnt == 0))
5665 if (*mbx_mbox_cmd != 0x9B)
5668 if ((mbox_tp == mbox_rd) && (dma_tp == dma_mbox)) {
5669 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_MBX) {
5670 do_dump |= LPFC_BSG_DMP_MBX_RD_MBX;
5671 pr_err("\nRead mbox command (x%x), "
5672 "nemb:0x%x, extbuf_cnt:%d:\n",
5673 sta_tp, nemb_tp, ext_buf);
5676 if ((mbox_tp == mbox_rd) && (dma_tp == dma_ebuf)) {
5677 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_BUF) {
5678 do_dump |= LPFC_BSG_DMP_MBX_RD_BUF;
5679 pr_err("\nRead mbox buffer (x%x), "
5680 "nemb:0x%x, extbuf_seq:%d:\n",
5681 sta_tp, nemb_tp, ext_buf);
5684 if ((mbox_tp == mbox_wr) && (dma_tp == dma_mbox)) {
5685 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_MBX) {
5686 do_dump |= LPFC_BSG_DMP_MBX_WR_MBX;
5687 pr_err("\nWrite mbox command (x%x), "
5688 "nemb:0x%x, extbuf_cnt:%d:\n",
5689 sta_tp, nemb_tp, ext_buf);
5692 if ((mbox_tp == mbox_wr) && (dma_tp == dma_ebuf)) {
5693 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_BUF) {
5694 do_dump |= LPFC_BSG_DMP_MBX_WR_BUF;
5695 pr_err("\nWrite mbox buffer (x%x), "
5696 "nemb:0x%x, extbuf_seq:%d:\n",
5697 sta_tp, nemb_tp, ext_buf);
5701 /* dump buffer content */
5703 pword = (uint32_t *)dmabuf->virt;
5704 for (i = 0; i < *mbx_word_cnt; i++) {
5707 pr_err("%s\n", line_buf);
5709 len += snprintf(line_buf+len,
5710 LPFC_MBX_ACC_LBUF_SZ-len,
5713 len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
5714 "%08x ", (uint32_t)*pword);
5718 pr_err("%s\n", line_buf);
5722 /* Clean out command structure on reaching dump count */
5723 if (*mbx_dump_cnt == 0)
5724 memset(&idiag, 0, sizeof(idiag));
5729 /* lpfc_idiag_mbxacc_dump_issue_mbox - idiag debugfs dump issue mailbox command
5730 * @phba: Pointer to HBA context object.
5731 * @dmabuf: Pointer to a DMA buffer descriptor.
5734 * This routine dump a pass-through non-embedded mailbox command from issue
5738 lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox)
5740 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
5741 uint32_t *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt, *mbx_mbox_cmd;
5742 char line_buf[LPFC_MBX_ACC_LBUF_SZ];
5748 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP)
5751 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
5752 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
5753 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
5754 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
5756 if (!(*mbx_dump_map & LPFC_MBX_DMP_MBX_ALL) ||
5757 (*mbx_dump_cnt == 0) ||
5758 (*mbx_word_cnt == 0))
5761 if ((*mbx_mbox_cmd != LPFC_MBX_ALL_CMD) &&
5762 (*mbx_mbox_cmd != pmbox->mbxCommand))
5765 /* dump buffer content */
5766 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_WORD) {
5767 pr_err("Mailbox command:0x%x dump by word:\n",
5769 pword = (uint32_t *)pmbox;
5770 for (i = 0; i < *mbx_word_cnt; i++) {
5773 pr_err("%s\n", line_buf);
5775 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
5776 len += snprintf(line_buf+len,
5777 LPFC_MBX_ACC_LBUF_SZ-len,
5780 len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
5782 ((uint32_t)*pword) & 0xffffffff);
5786 pr_err("%s\n", line_buf);
5789 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_BYTE) {
5790 pr_err("Mailbox command:0x%x dump by byte:\n",
5792 pbyte = (uint8_t *)pmbox;
5793 for (i = 0; i < *mbx_word_cnt; i++) {
5796 pr_err("%s\n", line_buf);
5798 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
5799 len += snprintf(line_buf+len,
5800 LPFC_MBX_ACC_LBUF_SZ-len,
5803 for (j = 0; j < 4; j++) {
5804 len += snprintf(line_buf+len,
5805 LPFC_MBX_ACC_LBUF_SZ-len,
5807 ((uint8_t)*pbyte) & 0xff);
5810 len += snprintf(line_buf+len,
5811 LPFC_MBX_ACC_LBUF_SZ-len, " ");
5814 pr_err("%s\n", line_buf);
5819 /* Clean out command structure on reaching dump count */
5820 if (*mbx_dump_cnt == 0)
5821 memset(&idiag, 0, sizeof(idiag));
5827 * lpfc_debugfs_initialize - Initialize debugfs for a vport
5828 * @vport: The vport pointer to initialize.
5831 * When Debugfs is configured this routine sets up the lpfc debugfs file system.
5832 * If not already created, this routine will create the lpfc directory, and
5833 * lpfcX directory (for this HBA), and vportX directory for this vport. It will
5834 * also create each file used to access lpfc specific debugfs information.
5837 lpfc_debugfs_initialize(struct lpfc_vport *vport)
5839 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
5840 struct lpfc_hba *phba = vport->phba;
5843 bool pport_setup = false;
5845 if (!lpfc_debugfs_enable)
5848 /* Setup lpfc root directory */
5849 if (!lpfc_debugfs_root) {
5850 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
5851 atomic_set(&lpfc_debugfs_hba_count, 0);
5853 if (!lpfc_debugfs_start_time)
5854 lpfc_debugfs_start_time = jiffies;
5856 /* Setup funcX directory for specific HBA PCI function */
5857 snprintf(name, sizeof(name), "fn%d", phba->brd_no);
5858 if (!phba->hba_debugfs_root) {
5860 phba->hba_debugfs_root =
5861 debugfs_create_dir(name, lpfc_debugfs_root);
5862 atomic_inc(&lpfc_debugfs_hba_count);
5863 atomic_set(&phba->debugfs_vport_count, 0);
5865 /* Multi-XRI pools */
5866 snprintf(name, sizeof(name), "multixripools");
5867 phba->debug_multixri_pools =
5868 debugfs_create_file(name, S_IFREG | 0644,
5869 phba->hba_debugfs_root,
5871 &lpfc_debugfs_op_multixripools);
5872 if (!phba->debug_multixri_pools) {
5873 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
5874 "0527 Cannot create debugfs multixripools\n");
5879 snprintf(name, sizeof(name), "hbqinfo");
5880 phba->debug_hbqinfo =
5881 debugfs_create_file(name, S_IFREG | 0644,
5882 phba->hba_debugfs_root,
5883 phba, &lpfc_debugfs_op_hbqinfo);
5885 #ifdef LPFC_HDWQ_LOCK_STAT
5886 /* Setup lockstat */
5887 snprintf(name, sizeof(name), "lockstat");
5888 phba->debug_lockstat =
5889 debugfs_create_file(name, S_IFREG | 0644,
5890 phba->hba_debugfs_root,
5891 phba, &lpfc_debugfs_op_lockstat);
5892 if (!phba->debug_lockstat) {
5893 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
5894 "0913 Cant create debugfs lockstat\n");
5899 /* Setup dumpHBASlim */
5900 if (phba->sli_rev < LPFC_SLI_REV4) {
5901 snprintf(name, sizeof(name), "dumpHBASlim");
5902 phba->debug_dumpHBASlim =
5903 debugfs_create_file(name,
5904 S_IFREG|S_IRUGO|S_IWUSR,
5905 phba->hba_debugfs_root,
5906 phba, &lpfc_debugfs_op_dumpHBASlim);
5908 phba->debug_dumpHBASlim = NULL;
5910 /* Setup dumpHostSlim */
5911 if (phba->sli_rev < LPFC_SLI_REV4) {
5912 snprintf(name, sizeof(name), "dumpHostSlim");
5913 phba->debug_dumpHostSlim =
5914 debugfs_create_file(name,
5915 S_IFREG|S_IRUGO|S_IWUSR,
5916 phba->hba_debugfs_root,
5917 phba, &lpfc_debugfs_op_dumpHostSlim);
5919 phba->debug_dumpHostSlim = NULL;
5921 /* Setup dumpData */
5922 snprintf(name, sizeof(name), "dumpData");
5923 phba->debug_dumpData =
5924 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5925 phba->hba_debugfs_root,
5926 phba, &lpfc_debugfs_op_dumpData);
5929 snprintf(name, sizeof(name), "dumpDif");
5930 phba->debug_dumpDif =
5931 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5932 phba->hba_debugfs_root,
5933 phba, &lpfc_debugfs_op_dumpDif);
5935 /* Setup DIF Error Injections */
5936 snprintf(name, sizeof(name), "InjErrLBA");
5937 phba->debug_InjErrLBA =
5938 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5939 phba->hba_debugfs_root,
5940 phba, &lpfc_debugfs_op_dif_err);
5941 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
5943 snprintf(name, sizeof(name), "InjErrNPortID");
5944 phba->debug_InjErrNPortID =
5945 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5946 phba->hba_debugfs_root,
5947 phba, &lpfc_debugfs_op_dif_err);
5949 snprintf(name, sizeof(name), "InjErrWWPN");
5950 phba->debug_InjErrWWPN =
5951 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5952 phba->hba_debugfs_root,
5953 phba, &lpfc_debugfs_op_dif_err);
5955 snprintf(name, sizeof(name), "writeGuardInjErr");
5956 phba->debug_writeGuard =
5957 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5958 phba->hba_debugfs_root,
5959 phba, &lpfc_debugfs_op_dif_err);
5961 snprintf(name, sizeof(name), "writeAppInjErr");
5962 phba->debug_writeApp =
5963 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5964 phba->hba_debugfs_root,
5965 phba, &lpfc_debugfs_op_dif_err);
5967 snprintf(name, sizeof(name), "writeRefInjErr");
5968 phba->debug_writeRef =
5969 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5970 phba->hba_debugfs_root,
5971 phba, &lpfc_debugfs_op_dif_err);
5973 snprintf(name, sizeof(name), "readGuardInjErr");
5974 phba->debug_readGuard =
5975 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5976 phba->hba_debugfs_root,
5977 phba, &lpfc_debugfs_op_dif_err);
5979 snprintf(name, sizeof(name), "readAppInjErr");
5980 phba->debug_readApp =
5981 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5982 phba->hba_debugfs_root,
5983 phba, &lpfc_debugfs_op_dif_err);
5985 snprintf(name, sizeof(name), "readRefInjErr");
5986 phba->debug_readRef =
5987 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
5988 phba->hba_debugfs_root,
5989 phba, &lpfc_debugfs_op_dif_err);
5991 /* Setup slow ring trace */
5992 if (lpfc_debugfs_max_slow_ring_trc) {
5993 num = lpfc_debugfs_max_slow_ring_trc - 1;
5994 if (num & lpfc_debugfs_max_slow_ring_trc) {
5995 /* Change to be a power of 2 */
5996 num = lpfc_debugfs_max_slow_ring_trc;
6002 lpfc_debugfs_max_slow_ring_trc = (1 << i);
6003 pr_err("lpfc_debugfs_max_disc_trc changed to "
6004 "%d\n", lpfc_debugfs_max_disc_trc);
6008 snprintf(name, sizeof(name), "slow_ring_trace");
6009 phba->debug_slow_ring_trc =
6010 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6011 phba->hba_debugfs_root,
6012 phba, &lpfc_debugfs_op_slow_ring_trc);
6013 if (!phba->slow_ring_trc) {
6014 phba->slow_ring_trc = kmalloc(
6015 (sizeof(struct lpfc_debugfs_trc) *
6016 lpfc_debugfs_max_slow_ring_trc),
6018 if (!phba->slow_ring_trc) {
6019 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6020 "0416 Cannot create debugfs "
6021 "slow_ring buffer\n");
6024 atomic_set(&phba->slow_ring_trc_cnt, 0);
6025 memset(phba->slow_ring_trc, 0,
6026 (sizeof(struct lpfc_debugfs_trc) *
6027 lpfc_debugfs_max_slow_ring_trc));
6030 snprintf(name, sizeof(name), "nvmeio_trc");
6031 phba->debug_nvmeio_trc =
6032 debugfs_create_file(name, 0644,
6033 phba->hba_debugfs_root,
6034 phba, &lpfc_debugfs_op_nvmeio_trc);
6036 atomic_set(&phba->nvmeio_trc_cnt, 0);
6037 if (lpfc_debugfs_max_nvmeio_trc) {
6038 num = lpfc_debugfs_max_nvmeio_trc - 1;
6039 if (num & lpfc_debugfs_max_disc_trc) {
6040 /* Change to be a power of 2 */
6041 num = lpfc_debugfs_max_nvmeio_trc;
6047 lpfc_debugfs_max_nvmeio_trc = (1 << i);
6048 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
6049 "0575 lpfc_debugfs_max_nvmeio_trc "
6051 lpfc_debugfs_max_nvmeio_trc);
6053 phba->nvmeio_trc_size = lpfc_debugfs_max_nvmeio_trc;
6055 /* Allocate trace buffer and initialize */
6056 phba->nvmeio_trc = kzalloc(
6057 (sizeof(struct lpfc_debugfs_nvmeio_trc) *
6058 phba->nvmeio_trc_size), GFP_KERNEL);
6060 if (!phba->nvmeio_trc) {
6061 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
6062 "0576 Cannot create debugfs "
6063 "nvmeio_trc buffer\n");
6066 phba->nvmeio_trc_on = 1;
6067 phba->nvmeio_trc_output_idx = 0;
6068 phba->nvmeio_trc = NULL;
6071 phba->nvmeio_trc_size = 0;
6072 phba->nvmeio_trc_on = 0;
6073 phba->nvmeio_trc_output_idx = 0;
6074 phba->nvmeio_trc = NULL;
6078 snprintf(name, sizeof(name), "vport%d", vport->vpi);
6079 if (!vport->vport_debugfs_root) {
6080 vport->vport_debugfs_root =
6081 debugfs_create_dir(name, phba->hba_debugfs_root);
6082 atomic_inc(&phba->debugfs_vport_count);
6085 if (lpfc_debugfs_max_disc_trc) {
6086 num = lpfc_debugfs_max_disc_trc - 1;
6087 if (num & lpfc_debugfs_max_disc_trc) {
6088 /* Change to be a power of 2 */
6089 num = lpfc_debugfs_max_disc_trc;
6095 lpfc_debugfs_max_disc_trc = (1 << i);
6096 pr_err("lpfc_debugfs_max_disc_trc changed to %d\n",
6097 lpfc_debugfs_max_disc_trc);
6101 vport->disc_trc = kzalloc(
6102 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
6105 if (!vport->disc_trc) {
6106 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6107 "0418 Cannot create debugfs disc trace "
6111 atomic_set(&vport->disc_trc_cnt, 0);
6113 snprintf(name, sizeof(name), "discovery_trace");
6114 vport->debug_disc_trc =
6115 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6116 vport->vport_debugfs_root,
6117 vport, &lpfc_debugfs_op_disc_trc);
6118 snprintf(name, sizeof(name), "nodelist");
6119 vport->debug_nodelist =
6120 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6121 vport->vport_debugfs_root,
6122 vport, &lpfc_debugfs_op_nodelist);
6124 snprintf(name, sizeof(name), "nvmestat");
6125 vport->debug_nvmestat =
6126 debugfs_create_file(name, 0644,
6127 vport->vport_debugfs_root,
6128 vport, &lpfc_debugfs_op_nvmestat);
6130 snprintf(name, sizeof(name), "scsistat");
6131 vport->debug_scsistat =
6132 debugfs_create_file(name, 0644,
6133 vport->vport_debugfs_root,
6134 vport, &lpfc_debugfs_op_scsistat);
6135 if (!vport->debug_scsistat) {
6136 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6137 "0914 Cannot create debugfs scsistat\n");
6141 snprintf(name, sizeof(name), "nvmektime");
6142 vport->debug_nvmektime =
6143 debugfs_create_file(name, 0644,
6144 vport->vport_debugfs_root,
6145 vport, &lpfc_debugfs_op_nvmektime);
6147 snprintf(name, sizeof(name), "cpucheck");
6148 vport->debug_cpucheck =
6149 debugfs_create_file(name, 0644,
6150 vport->vport_debugfs_root,
6151 vport, &lpfc_debugfs_op_cpucheck);
6154 * The following section is for additional directories/files for the
6162 * iDiag debugfs root entry points for SLI4 device only
6164 if (phba->sli_rev < LPFC_SLI_REV4)
6167 snprintf(name, sizeof(name), "iDiag");
6168 if (!phba->idiag_root) {
6170 debugfs_create_dir(name, phba->hba_debugfs_root);
6171 /* Initialize iDiag data structure */
6172 memset(&idiag, 0, sizeof(idiag));
6175 /* iDiag read PCI config space */
6176 snprintf(name, sizeof(name), "pciCfg");
6177 if (!phba->idiag_pci_cfg) {
6178 phba->idiag_pci_cfg =
6179 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6180 phba->idiag_root, phba, &lpfc_idiag_op_pciCfg);
6181 idiag.offset.last_rd = 0;
6184 /* iDiag PCI BAR access */
6185 snprintf(name, sizeof(name), "barAcc");
6186 if (!phba->idiag_bar_acc) {
6187 phba->idiag_bar_acc =
6188 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6189 phba->idiag_root, phba, &lpfc_idiag_op_barAcc);
6190 idiag.offset.last_rd = 0;
6193 /* iDiag get PCI function queue information */
6194 snprintf(name, sizeof(name), "queInfo");
6195 if (!phba->idiag_que_info) {
6196 phba->idiag_que_info =
6197 debugfs_create_file(name, S_IFREG|S_IRUGO,
6198 phba->idiag_root, phba, &lpfc_idiag_op_queInfo);
6201 /* iDiag access PCI function queue */
6202 snprintf(name, sizeof(name), "queAcc");
6203 if (!phba->idiag_que_acc) {
6204 phba->idiag_que_acc =
6205 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6206 phba->idiag_root, phba, &lpfc_idiag_op_queAcc);
6209 /* iDiag access PCI function doorbell registers */
6210 snprintf(name, sizeof(name), "drbAcc");
6211 if (!phba->idiag_drb_acc) {
6212 phba->idiag_drb_acc =
6213 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6214 phba->idiag_root, phba, &lpfc_idiag_op_drbAcc);
6217 /* iDiag access PCI function control registers */
6218 snprintf(name, sizeof(name), "ctlAcc");
6219 if (!phba->idiag_ctl_acc) {
6220 phba->idiag_ctl_acc =
6221 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6222 phba->idiag_root, phba, &lpfc_idiag_op_ctlAcc);
6225 /* iDiag access mbox commands */
6226 snprintf(name, sizeof(name), "mbxAcc");
6227 if (!phba->idiag_mbx_acc) {
6228 phba->idiag_mbx_acc =
6229 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6230 phba->idiag_root, phba, &lpfc_idiag_op_mbxAcc);
6233 /* iDiag extents access commands */
6234 if (phba->sli4_hba.extents_in_use) {
6235 snprintf(name, sizeof(name), "extAcc");
6236 if (!phba->idiag_ext_acc) {
6237 phba->idiag_ext_acc =
6238 debugfs_create_file(name,
6239 S_IFREG|S_IRUGO|S_IWUSR,
6240 phba->idiag_root, phba,
6241 &lpfc_idiag_op_extAcc);
6251 * lpfc_debugfs_terminate - Tear down debugfs infrastructure for this vport
6252 * @vport: The vport pointer to remove from debugfs.
6255 * When Debugfs is configured this routine removes debugfs file system elements
6256 * that are specific to this vport. It also checks to see if there are any
6257 * users left for the debugfs directories associated with the HBA and driver. If
6258 * this is the last user of the HBA directory or driver directory then it will
6259 * remove those from the debugfs infrastructure as well.
6262 lpfc_debugfs_terminate(struct lpfc_vport *vport)
6264 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
6265 struct lpfc_hba *phba = vport->phba;
6267 kfree(vport->disc_trc);
6268 vport->disc_trc = NULL;
6270 debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
6271 vport->debug_disc_trc = NULL;
6273 debugfs_remove(vport->debug_nodelist); /* nodelist */
6274 vport->debug_nodelist = NULL;
6276 debugfs_remove(vport->debug_nvmestat); /* nvmestat */
6277 vport->debug_nvmestat = NULL;
6279 debugfs_remove(vport->debug_scsistat); /* scsistat */
6280 vport->debug_scsistat = NULL;
6282 debugfs_remove(vport->debug_nvmektime); /* nvmektime */
6283 vport->debug_nvmektime = NULL;
6285 debugfs_remove(vport->debug_cpucheck); /* cpucheck */
6286 vport->debug_cpucheck = NULL;
6288 if (vport->vport_debugfs_root) {
6289 debugfs_remove(vport->vport_debugfs_root); /* vportX */
6290 vport->vport_debugfs_root = NULL;
6291 atomic_dec(&phba->debugfs_vport_count);
6294 if (atomic_read(&phba->debugfs_vport_count) == 0) {
6296 debugfs_remove(phba->debug_multixri_pools); /* multixripools*/
6297 phba->debug_multixri_pools = NULL;
6299 debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
6300 phba->debug_hbqinfo = NULL;
6302 #ifdef LPFC_HDWQ_LOCK_STAT
6303 debugfs_remove(phba->debug_lockstat); /* lockstat */
6304 phba->debug_lockstat = NULL;
6306 debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */
6307 phba->debug_dumpHBASlim = NULL;
6309 debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */
6310 phba->debug_dumpHostSlim = NULL;
6312 debugfs_remove(phba->debug_dumpData); /* dumpData */
6313 phba->debug_dumpData = NULL;
6315 debugfs_remove(phba->debug_dumpDif); /* dumpDif */
6316 phba->debug_dumpDif = NULL;
6318 debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */
6319 phba->debug_InjErrLBA = NULL;
6321 debugfs_remove(phba->debug_InjErrNPortID);
6322 phba->debug_InjErrNPortID = NULL;
6324 debugfs_remove(phba->debug_InjErrWWPN); /* InjErrWWPN */
6325 phba->debug_InjErrWWPN = NULL;
6327 debugfs_remove(phba->debug_writeGuard); /* writeGuard */
6328 phba->debug_writeGuard = NULL;
6330 debugfs_remove(phba->debug_writeApp); /* writeApp */
6331 phba->debug_writeApp = NULL;
6333 debugfs_remove(phba->debug_writeRef); /* writeRef */
6334 phba->debug_writeRef = NULL;
6336 debugfs_remove(phba->debug_readGuard); /* readGuard */
6337 phba->debug_readGuard = NULL;
6339 debugfs_remove(phba->debug_readApp); /* readApp */
6340 phba->debug_readApp = NULL;
6342 debugfs_remove(phba->debug_readRef); /* readRef */
6343 phba->debug_readRef = NULL;
6345 kfree(phba->slow_ring_trc);
6346 phba->slow_ring_trc = NULL;
6348 /* slow_ring_trace */
6349 debugfs_remove(phba->debug_slow_ring_trc);
6350 phba->debug_slow_ring_trc = NULL;
6352 debugfs_remove(phba->debug_nvmeio_trc);
6353 phba->debug_nvmeio_trc = NULL;
6355 kfree(phba->nvmeio_trc);
6356 phba->nvmeio_trc = NULL;
6361 if (phba->sli_rev == LPFC_SLI_REV4) {
6363 debugfs_remove(phba->idiag_ext_acc);
6364 phba->idiag_ext_acc = NULL;
6367 debugfs_remove(phba->idiag_mbx_acc);
6368 phba->idiag_mbx_acc = NULL;
6371 debugfs_remove(phba->idiag_ctl_acc);
6372 phba->idiag_ctl_acc = NULL;
6375 debugfs_remove(phba->idiag_drb_acc);
6376 phba->idiag_drb_acc = NULL;
6379 debugfs_remove(phba->idiag_que_acc);
6380 phba->idiag_que_acc = NULL;
6383 debugfs_remove(phba->idiag_que_info);
6384 phba->idiag_que_info = NULL;
6387 debugfs_remove(phba->idiag_bar_acc);
6388 phba->idiag_bar_acc = NULL;
6391 debugfs_remove(phba->idiag_pci_cfg);
6392 phba->idiag_pci_cfg = NULL;
6394 /* Finally remove the iDiag debugfs root */
6395 debugfs_remove(phba->idiag_root);
6396 phba->idiag_root = NULL;
6399 if (phba->hba_debugfs_root) {
6400 debugfs_remove(phba->hba_debugfs_root); /* fnX */
6401 phba->hba_debugfs_root = NULL;
6402 atomic_dec(&lpfc_debugfs_hba_count);
6405 if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
6406 debugfs_remove(lpfc_debugfs_root); /* lpfc */
6407 lpfc_debugfs_root = NULL;
6415 * Driver debug utility routines outside of debugfs. The debug utility
6416 * routines implemented here is intended to be used in the instrumented
6417 * debug driver for debugging host or port issues.
6421 * lpfc_debug_dump_all_queues - dump all the queues with a hba
6422 * @phba: Pointer to HBA context object.
6424 * This function dumps entries of all the queues asociated with the @phba.
6427 lpfc_debug_dump_all_queues(struct lpfc_hba *phba)
6432 * Dump Work Queues (WQs)
6434 lpfc_debug_dump_wq(phba, DUMP_MBX, 0);
6435 lpfc_debug_dump_wq(phba, DUMP_ELS, 0);
6436 lpfc_debug_dump_wq(phba, DUMP_NVMELS, 0);
6438 for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6439 lpfc_debug_dump_wq(phba, DUMP_FCP, idx);
6441 if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
6442 for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6443 lpfc_debug_dump_wq(phba, DUMP_NVME, idx);
6446 lpfc_debug_dump_hdr_rq(phba);
6447 lpfc_debug_dump_dat_rq(phba);
6449 * Dump Complete Queues (CQs)
6451 lpfc_debug_dump_cq(phba, DUMP_MBX, 0);
6452 lpfc_debug_dump_cq(phba, DUMP_ELS, 0);
6453 lpfc_debug_dump_cq(phba, DUMP_NVMELS, 0);
6455 for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6456 lpfc_debug_dump_cq(phba, DUMP_FCP, idx);
6458 if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
6459 for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6460 lpfc_debug_dump_cq(phba, DUMP_NVME, idx);
6464 * Dump Event Queues (EQs)
6466 for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6467 lpfc_debug_dump_hba_eq(phba, idx);