1 /*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2017-2024 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>
34 #include <linux/vmalloc.h>
36 #include <scsi/scsi.h>
37 #include <scsi/scsi_device.h>
38 #include <scsi/scsi_host.h>
39 #include <scsi/scsi_transport_fc.h>
40 #include <scsi/fc/fc_fs.h>
45 #include "lpfc_sli4.h"
47 #include "lpfc_disc.h"
49 #include "lpfc_scsi.h"
50 #include "lpfc_nvme.h"
51 #include "lpfc_logmsg.h"
52 #include "lpfc_crtn.h"
53 #include "lpfc_vport.h"
54 #include "lpfc_version.h"
55 #include "lpfc_compat.h"
56 #include "lpfc_debugfs.h"
59 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
63 * To access this interface the user should:
64 * # mount -t debugfs none /sys/kernel/debug
66 * The lpfc debugfs directory hierarchy is:
67 * /sys/kernel/debug/lpfc/fnX/vportY
68 * where X is the lpfc hba function unique_id
69 * where Y is the vport VPI on that hba
71 * Debugging services available per vport:
73 * This is an ACSII readable file that contains a trace of the last
74 * lpfc_debugfs_max_disc_trc events that happened on a specific vport.
75 * See lpfc_debugfs.h for different categories of discovery events.
76 * To enable the discovery trace, the following module parameters must be set:
77 * lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support
78 * lpfc_debugfs_max_disc_trc=X Where X is the event trace depth for
79 * EACH vport. X MUST also be a power of 2.
80 * lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in
84 * This is an ACSII readable file that contains a trace of the last
85 * lpfc_debugfs_max_slow_ring_trc events that happened on a specific HBA.
86 * To enable the slow ring trace, the following module parameters must be set:
87 * lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support
88 * lpfc_debugfs_max_slow_ring_trc=X Where X is the event trace depth for
89 * the HBA. X MUST also be a power of 2.
91 static int lpfc_debugfs_enable
= 1;
92 module_param(lpfc_debugfs_enable
, int, S_IRUGO
);
93 MODULE_PARM_DESC(lpfc_debugfs_enable
, "Enable debugfs services");
95 /* This MUST be a power of 2 */
96 static int lpfc_debugfs_max_disc_trc
;
97 module_param(lpfc_debugfs_max_disc_trc
, int, S_IRUGO
);
98 MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc
,
99 "Set debugfs discovery trace depth");
101 /* This MUST be a power of 2 */
102 static int lpfc_debugfs_max_slow_ring_trc
;
103 module_param(lpfc_debugfs_max_slow_ring_trc
, int, S_IRUGO
);
104 MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc
,
105 "Set debugfs slow ring trace depth");
107 /* This MUST be a power of 2 */
108 static int lpfc_debugfs_max_nvmeio_trc
;
109 module_param(lpfc_debugfs_max_nvmeio_trc
, int, 0444);
110 MODULE_PARM_DESC(lpfc_debugfs_max_nvmeio_trc
,
111 "Set debugfs NVME IO trace depth");
113 static int lpfc_debugfs_mask_disc_trc
;
114 module_param(lpfc_debugfs_mask_disc_trc
, int, S_IRUGO
);
115 MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc
,
116 "Set debugfs discovery trace mask");
118 #include <linux/debugfs.h>
120 static atomic_t lpfc_debugfs_seq_trc_cnt
= ATOMIC_INIT(0);
121 static unsigned long lpfc_debugfs_start_time
= 0L;
124 static struct lpfc_idiag idiag
;
127 * lpfc_debugfs_disc_trc_data - Dump discovery logging to a buffer
128 * @vport: The vport to gather the log info from.
129 * @buf: The buffer to dump log into.
130 * @size: The maximum amount of data to process.
133 * This routine gathers the lpfc discovery debugfs data from the @vport and
134 * dumps it to @buf up to @size number of bytes. It will start at the next entry
135 * in the log and process the log until the end of the buffer. Then it will
136 * gather from the beginning of the log and process until the current entry.
139 * Discovery logging will be disabled while while this routine dumps the log.
142 * This routine returns the amount of bytes that were dumped into @buf and will
146 lpfc_debugfs_disc_trc_data(struct lpfc_vport
*vport
, char *buf
, int size
)
148 int i
, index
, len
, enable
;
150 struct lpfc_debugfs_trc
*dtp
;
153 buffer
= kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE
, GFP_KERNEL
);
157 enable
= lpfc_debugfs_enable
;
158 lpfc_debugfs_enable
= 0;
161 index
= (atomic_read(&vport
->disc_trc_cnt
) + 1) &
162 (lpfc_debugfs_max_disc_trc
- 1);
163 for (i
= index
; i
< lpfc_debugfs_max_disc_trc
; i
++) {
164 dtp
= vport
->disc_trc
+ i
;
167 ms
= jiffies_to_msecs(dtp
->jif
- lpfc_debugfs_start_time
);
169 LPFC_DEBUG_TRC_ENTRY_SIZE
, "%010d:%010d ms:%s\n",
170 dtp
->seq_cnt
, ms
, dtp
->fmt
);
171 len
+= scnprintf(buf
+len
, size
-len
, buffer
,
172 dtp
->data1
, dtp
->data2
, dtp
->data3
);
174 for (i
= 0; i
< index
; i
++) {
175 dtp
= vport
->disc_trc
+ i
;
178 ms
= jiffies_to_msecs(dtp
->jif
- lpfc_debugfs_start_time
);
180 LPFC_DEBUG_TRC_ENTRY_SIZE
, "%010d:%010d ms:%s\n",
181 dtp
->seq_cnt
, ms
, dtp
->fmt
);
182 len
+= scnprintf(buf
+len
, size
-len
, buffer
,
183 dtp
->data1
, dtp
->data2
, dtp
->data3
);
186 lpfc_debugfs_enable
= enable
;
193 * lpfc_debugfs_slow_ring_trc_data - Dump slow ring logging to a buffer
194 * @phba: The HBA to gather the log info from.
195 * @buf: The buffer to dump log into.
196 * @size: The maximum amount of data to process.
199 * This routine gathers the lpfc slow ring debugfs data from the @phba and
200 * dumps it to @buf up to @size number of bytes. It will start at the next entry
201 * in the log and process the log until the end of the buffer. Then it will
202 * gather from the beginning of the log and process until the current entry.
205 * Slow ring logging will be disabled while while this routine dumps the log.
208 * This routine returns the amount of bytes that were dumped into @buf and will
212 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba
*phba
, char *buf
, int size
)
214 int i
, index
, len
, enable
;
216 struct lpfc_debugfs_trc
*dtp
;
219 buffer
= kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE
, GFP_KERNEL
);
223 enable
= lpfc_debugfs_enable
;
224 lpfc_debugfs_enable
= 0;
227 index
= (atomic_read(&phba
->slow_ring_trc_cnt
) + 1) &
228 (lpfc_debugfs_max_slow_ring_trc
- 1);
229 for (i
= index
; i
< lpfc_debugfs_max_slow_ring_trc
; i
++) {
230 dtp
= phba
->slow_ring_trc
+ i
;
233 ms
= jiffies_to_msecs(dtp
->jif
- lpfc_debugfs_start_time
);
235 LPFC_DEBUG_TRC_ENTRY_SIZE
, "%010d:%010d ms:%s\n",
236 dtp
->seq_cnt
, ms
, dtp
->fmt
);
237 len
+= scnprintf(buf
+len
, size
-len
, buffer
,
238 dtp
->data1
, dtp
->data2
, dtp
->data3
);
240 for (i
= 0; i
< index
; i
++) {
241 dtp
= phba
->slow_ring_trc
+ i
;
244 ms
= jiffies_to_msecs(dtp
->jif
- lpfc_debugfs_start_time
);
246 LPFC_DEBUG_TRC_ENTRY_SIZE
, "%010d:%010d ms:%s\n",
247 dtp
->seq_cnt
, ms
, dtp
->fmt
);
248 len
+= scnprintf(buf
+len
, size
-len
, buffer
,
249 dtp
->data1
, dtp
->data2
, dtp
->data3
);
252 lpfc_debugfs_enable
= enable
;
258 static int lpfc_debugfs_last_hbq
= -1;
261 * lpfc_debugfs_hbqinfo_data - Dump host buffer queue info to a buffer
262 * @phba: The HBA to gather host buffer info from.
263 * @buf: The buffer to dump log into.
264 * @size: The maximum amount of data to process.
267 * This routine dumps the host buffer queue info from the @phba to @buf up to
268 * @size number of bytes. A header that describes the current hbq state will be
269 * dumped to @buf first and then info on each hbq entry will be dumped to @buf
270 * until @size bytes have been dumped or all the hbq info has been dumped.
273 * This routine will rotate through each configured HBQ each time called.
276 * This routine returns the amount of bytes that were dumped into @buf and will
280 lpfc_debugfs_hbqinfo_data(struct lpfc_hba
*phba
, char *buf
, int size
)
283 int i
, j
, found
, posted
, low
;
284 uint32_t phys
, raw_index
, getidx
;
285 struct lpfc_hbq_init
*hip
;
287 struct lpfc_hbq_entry
*hbqe
;
288 struct lpfc_dmabuf
*d_buf
;
289 struct hbq_dmabuf
*hbq_buf
;
291 if (phba
->sli_rev
!= 3)
294 spin_lock_irq(&phba
->hbalock
);
296 /* toggle between multiple hbqs, if any */
297 i
= lpfc_sli_hbq_count();
299 lpfc_debugfs_last_hbq
++;
300 if (lpfc_debugfs_last_hbq
>= i
)
301 lpfc_debugfs_last_hbq
= 0;
304 lpfc_debugfs_last_hbq
= 0;
306 i
= lpfc_debugfs_last_hbq
;
308 len
+= scnprintf(buf
+len
, size
-len
, "HBQ %d Info\n", i
);
310 hbqs
= &phba
->hbqs
[i
];
312 list_for_each_entry(d_buf
, &hbqs
->hbq_buffer_list
, list
)
315 hip
= lpfc_hbq_defs
[i
];
316 len
+= scnprintf(buf
+len
, size
-len
,
317 "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
318 hip
->hbq_index
, hip
->profile
, hip
->rn
,
319 hip
->buffer_count
, hip
->init_count
, hip
->add_count
, posted
);
321 raw_index
= phba
->hbq_get
[i
];
322 getidx
= le32_to_cpu(raw_index
);
323 len
+= scnprintf(buf
+len
, size
-len
,
324 "entries:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
325 hbqs
->entry_count
, hbqs
->buffer_count
, hbqs
->hbqPutIdx
,
326 hbqs
->next_hbqPutIdx
, hbqs
->local_hbqGetIdx
, getidx
);
328 hbqe
= (struct lpfc_hbq_entry
*) phba
->hbqs
[i
].hbq_virt
;
329 for (j
=0; j
<hbqs
->entry_count
; j
++) {
330 len
+= scnprintf(buf
+len
, size
-len
,
331 "%03d: %08x %04x %05x ", j
,
332 le32_to_cpu(hbqe
->bde
.addrLow
),
333 le32_to_cpu(hbqe
->bde
.tus
.w
),
334 le32_to_cpu(hbqe
->buffer_tag
));
338 /* First calculate if slot has an associated posted buffer */
339 low
= hbqs
->hbqPutIdx
- posted
;
341 if ((j
>= hbqs
->hbqPutIdx
) || (j
< low
)) {
342 len
+= scnprintf(buf
+ len
, size
- len
,
348 if ((j
>= hbqs
->hbqPutIdx
) &&
349 (j
< (hbqs
->entry_count
+low
))) {
350 len
+= scnprintf(buf
+ len
, size
- len
,
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
+= scnprintf(buf
+len
, size
-len
,
362 "Buf%d: x%px %06x\n", i
,
363 hbq_buf
->dbuf
.virt
, hbq_buf
->tag
);
370 len
+= scnprintf(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_commonxripools_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
+= scnprintf(buf
+ len
, size
- len
, "HdwQ %d Info ", i
);
417 spin_lock_irqsave(&qp
->abts_io_buf_list_lock
, iflag
);
418 spin_lock(&qp
->io_buf_list_get_lock
);
419 spin_lock(&qp
->io_buf_list_put_lock
);
420 out
= qp
->total_io_bufs
- (qp
->get_io_bufs
+ qp
->put_io_bufs
+
421 qp
->abts_scsi_io_bufs
+ qp
->abts_nvme_io_bufs
);
422 len
+= scnprintf(buf
+ len
, size
- len
,
423 "tot:%d get:%d put:%d mt:%d "
424 "ABTS scsi:%d nvme:%d Out:%d\n",
425 qp
->total_io_bufs
, qp
->get_io_bufs
, qp
->put_io_bufs
,
426 qp
->empty_io_bufs
, qp
->abts_scsi_io_bufs
,
427 qp
->abts_nvme_io_bufs
, out
);
428 spin_unlock(&qp
->io_buf_list_put_lock
);
429 spin_unlock(&qp
->io_buf_list_get_lock
);
430 spin_unlock_irqrestore(&qp
->abts_io_buf_list_lock
, iflag
);
432 lpfc_debugfs_last_xripool
++;
433 if (lpfc_debugfs_last_xripool
>= phba
->cfg_hdw_queue
)
434 lpfc_debugfs_last_xripool
= 0;
441 * lpfc_debugfs_multixripools_data - Display multi-XRI pools information
442 * @phba: The HBA to gather host buffer info from.
443 * @buf: The buffer to dump log into.
444 * @size: The maximum amount of data to process.
447 * This routine displays current multi-XRI pools information including XRI
448 * count in public, private and txcmplq. It also displays current high and
452 * This routine returns the amount of bytes that were dumped into @buf and will
456 lpfc_debugfs_multixripools_data(struct lpfc_hba
*phba
, char *buf
, int size
)
460 struct lpfc_sli4_hdw_queue
*qp
;
461 struct lpfc_multixri_pool
*multixri_pool
;
462 struct lpfc_pvt_pool
*pvt_pool
;
463 struct lpfc_pbl_pool
*pbl_pool
;
465 char tmp
[LPFC_DEBUG_OUT_LINE_SZ
] = {0};
467 if (phba
->sli_rev
!= LPFC_SLI_REV4
)
470 if (!phba
->sli4_hba
.hdwq
)
473 if (!phba
->cfg_xri_rebalancing
) {
474 i
= lpfc_debugfs_commonxripools_data(phba
, buf
, size
);
479 * Pbl: Current number of free XRIs in public pool
480 * Pvt: Current number of free XRIs in private pool
481 * Busy: Current number of outstanding XRIs
482 * HWM: Current high watermark
483 * pvt_empty: Incremented by 1 when IO submission fails (no xri)
484 * pbl_empty: Incremented by 1 when all pbl_pool are empty during
487 scnprintf(tmp
, sizeof(tmp
),
488 "HWQ: Pbl Pvt Busy HWM | pvt_empty pbl_empty ");
489 if (strlcat(buf
, tmp
, size
) >= size
)
490 return strnlen(buf
, size
);
494 * MAXH: Max high watermark seen so far
495 * above_lmt: Incremented by 1 if xri_owned > xri_limit during
497 * below_lmt: Incremented by 1 if xri_owned <= xri_limit during
499 * locPbl_hit: Incremented by 1 if successfully get a batch of XRI from
501 * othPbl_hit: Incremented by 1 if successfully get a batch of XRI from
504 scnprintf(tmp
, sizeof(tmp
),
505 "MAXH above_lmt below_lmt locPbl_hit othPbl_hit");
506 if (strlcat(buf
, tmp
, size
) >= size
)
507 return strnlen(buf
, size
);
510 * sPbl: snapshot of Pbl 15 sec after stat gets cleared
511 * sPvt: snapshot of Pvt 15 sec after stat gets cleared
512 * sBusy: snapshot of Busy 15 sec after stat gets cleared
514 scnprintf(tmp
, sizeof(tmp
),
515 " | sPbl sPvt sBusy");
516 if (strlcat(buf
, tmp
, size
) >= size
)
517 return strnlen(buf
, size
);
520 scnprintf(tmp
, sizeof(tmp
), "\n");
521 if (strlcat(buf
, tmp
, size
) >= size
)
522 return strnlen(buf
, size
);
524 hwq_count
= phba
->cfg_hdw_queue
;
525 for (i
= 0; i
< hwq_count
; i
++) {
526 qp
= &phba
->sli4_hba
.hdwq
[i
];
527 multixri_pool
= qp
->p_multixri_pool
;
530 pbl_pool
= &multixri_pool
->pbl_pool
;
531 pvt_pool
= &multixri_pool
->pvt_pool
;
532 txcmplq_cnt
= qp
->io_wq
->pring
->txcmplq_cnt
;
534 scnprintf(tmp
, sizeof(tmp
),
535 "%03d: %4d %4d %4d %4d | %10d %10d ",
536 i
, pbl_pool
->count
, pvt_pool
->count
,
537 txcmplq_cnt
, pvt_pool
->high_watermark
,
538 qp
->empty_io_bufs
, multixri_pool
->pbl_empty_count
);
539 if (strlcat(buf
, tmp
, size
) >= size
)
543 scnprintf(tmp
, sizeof(tmp
),
544 "%4d %10d %10d %10d %10d",
545 multixri_pool
->stat_max_hwm
,
546 multixri_pool
->above_limit_count
,
547 multixri_pool
->below_limit_count
,
548 multixri_pool
->local_pbl_hit_count
,
549 multixri_pool
->other_pbl_hit_count
);
550 if (strlcat(buf
, tmp
, size
) >= size
)
553 scnprintf(tmp
, sizeof(tmp
),
555 multixri_pool
->stat_pbl_count
,
556 multixri_pool
->stat_pvt_count
,
557 multixri_pool
->stat_busy_count
);
558 if (strlcat(buf
, tmp
, size
) >= size
)
562 scnprintf(tmp
, sizeof(tmp
), "\n");
563 if (strlcat(buf
, tmp
, size
) >= size
)
566 return strnlen(buf
, size
);
570 #ifdef LPFC_HDWQ_LOCK_STAT
571 static int lpfc_debugfs_last_lock
;
574 * lpfc_debugfs_lockstat_data - Dump Hardware Queue info to a buffer
575 * @phba: The HBA to gather host buffer info from.
576 * @buf: The buffer to dump log into.
577 * @size: The maximum amount of data to process.
580 * This routine dumps the Hardware Queue info from the @phba to @buf up to
581 * @size number of bytes. A header that describes the current hdwq state will be
582 * dumped to @buf first and then info on each hdwq entry will be dumped to @buf
583 * until @size bytes have been dumped or all the hdwq info has been dumped.
586 * This routine will rotate through each configured Hardware Queue each
590 * This routine returns the amount of bytes that were dumped into @buf and will
594 lpfc_debugfs_lockstat_data(struct lpfc_hba
*phba
, char *buf
, int size
)
596 struct lpfc_sli4_hdw_queue
*qp
;
600 if (phba
->sli_rev
!= LPFC_SLI_REV4
)
603 if (!phba
->sli4_hba
.hdwq
)
606 for (i
= 0; i
< phba
->cfg_hdw_queue
; i
++) {
607 if (len
> (LPFC_HDWQINFO_SIZE
- 100))
609 qp
= &phba
->sli4_hba
.hdwq
[lpfc_debugfs_last_lock
];
611 len
+= scnprintf(buf
+ len
, size
- len
, "HdwQ %03d Lock ", i
);
612 if (phba
->cfg_xri_rebalancing
) {
613 len
+= scnprintf(buf
+ len
, size
- len
,
614 "get_pvt:%d mv_pvt:%d "
615 "mv2pub:%d mv2pvt:%d "
616 "put_pvt:%d put_pub:%d wq:%d\n",
617 qp
->lock_conflict
.alloc_pvt_pool
,
618 qp
->lock_conflict
.mv_from_pvt_pool
,
619 qp
->lock_conflict
.mv_to_pub_pool
,
620 qp
->lock_conflict
.mv_to_pvt_pool
,
621 qp
->lock_conflict
.free_pvt_pool
,
622 qp
->lock_conflict
.free_pub_pool
,
623 qp
->lock_conflict
.wq_access
);
625 len
+= scnprintf(buf
+ len
, size
- len
,
626 "get:%d put:%d free:%d wq:%d\n",
627 qp
->lock_conflict
.alloc_xri_get
,
628 qp
->lock_conflict
.alloc_xri_put
,
629 qp
->lock_conflict
.free_xri
,
630 qp
->lock_conflict
.wq_access
);
633 lpfc_debugfs_last_lock
++;
634 if (lpfc_debugfs_last_lock
>= phba
->cfg_hdw_queue
)
635 lpfc_debugfs_last_lock
= 0;
642 static int lpfc_debugfs_last_hba_slim_off
;
645 * lpfc_debugfs_dumpHBASlim_data - Dump HBA SLIM info to a buffer
646 * @phba: The HBA to gather SLIM info from.
647 * @buf: The buffer to dump log into.
648 * @size: The maximum amount of data to process.
651 * This routine dumps the current contents of HBA SLIM for the HBA associated
652 * with @phba to @buf up to @size bytes of data. This is the raw HBA SLIM data.
655 * This routine will only dump up to 1024 bytes of data each time called and
656 * should be called multiple times to dump the entire HBA SLIM.
659 * This routine returns the amount of bytes that were dumped into @buf and will
663 lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba
*phba
, char *buf
, int size
)
670 buffer
= kmalloc(1024, GFP_KERNEL
);
675 spin_lock_irq(&phba
->hbalock
);
677 len
+= scnprintf(buf
+len
, size
-len
, "HBA SLIM\n");
678 lpfc_memcpy_from_slim(buffer
,
679 phba
->MBslimaddr
+ lpfc_debugfs_last_hba_slim_off
, 1024);
681 ptr
= (uint32_t *)&buffer
[0];
682 off
= lpfc_debugfs_last_hba_slim_off
;
684 /* Set it up for the next time */
685 lpfc_debugfs_last_hba_slim_off
+= 1024;
686 if (lpfc_debugfs_last_hba_slim_off
>= 4096)
687 lpfc_debugfs_last_hba_slim_off
= 0;
691 len
+= scnprintf(buf
+len
, size
-len
,
692 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
693 off
, *ptr
, *(ptr
+1), *(ptr
+2), *(ptr
+3), *(ptr
+4),
694 *(ptr
+5), *(ptr
+6), *(ptr
+7));
696 i
-= (8 * sizeof(uint32_t));
697 off
+= (8 * sizeof(uint32_t));
700 spin_unlock_irq(&phba
->hbalock
);
707 * lpfc_debugfs_dumpHostSlim_data - Dump host SLIM info to a buffer
708 * @phba: The HBA to gather Host SLIM info from.
709 * @buf: The buffer to dump log into.
710 * @size: The maximum amount of data to process.
713 * This routine dumps the current contents of host SLIM for the host associated
714 * with @phba to @buf up to @size bytes of data. The dump will contain the
715 * Mailbox, PCB, Rings, and Registers that are located in host memory.
718 * This routine returns the amount of bytes that were dumped into @buf and will
722 lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba
*phba
, char *buf
, int size
)
726 uint32_t word0
, word1
, word2
, word3
;
728 struct lpfc_pgp
*pgpp
;
729 struct lpfc_sli
*psli
= &phba
->sli
;
730 struct lpfc_sli_ring
*pring
;
733 spin_lock_irq(&phba
->hbalock
);
735 len
+= scnprintf(buf
+len
, size
-len
, "SLIM Mailbox\n");
736 ptr
= (uint32_t *)phba
->slim2p
.virt
;
737 i
= sizeof(MAILBOX_t
);
739 len
+= scnprintf(buf
+len
, size
-len
,
740 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
741 off
, *ptr
, *(ptr
+1), *(ptr
+2), *(ptr
+3), *(ptr
+4),
742 *(ptr
+5), *(ptr
+6), *(ptr
+7));
744 i
-= (8 * sizeof(uint32_t));
745 off
+= (8 * sizeof(uint32_t));
748 len
+= scnprintf(buf
+len
, size
-len
, "SLIM PCB\n");
749 ptr
= (uint32_t *)phba
->pcb
;
752 len
+= scnprintf(buf
+len
, size
-len
,
753 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
754 off
, *ptr
, *(ptr
+1), *(ptr
+2), *(ptr
+3), *(ptr
+4),
755 *(ptr
+5), *(ptr
+6), *(ptr
+7));
757 i
-= (8 * sizeof(uint32_t));
758 off
+= (8 * sizeof(uint32_t));
761 if (phba
->sli_rev
<= LPFC_SLI_REV3
) {
762 for (i
= 0; i
< 4; i
++) {
763 pgpp
= &phba
->port_gp
[i
];
764 pring
= &psli
->sli3_ring
[i
];
765 len
+= scnprintf(buf
+len
, size
-len
,
766 "Ring %d: CMD GetInx:%d "
769 "RSP PutInx:%d Max:%d\n",
771 pring
->sli
.sli3
.numCiocb
,
772 pring
->sli
.sli3
.next_cmdidx
,
773 pring
->sli
.sli3
.local_getidx
,
774 pring
->flag
, pgpp
->rspPutInx
,
775 pring
->sli
.sli3
.numRiocb
);
778 word0
= readl(phba
->HAregaddr
);
779 word1
= readl(phba
->CAregaddr
);
780 word2
= readl(phba
->HSregaddr
);
781 word3
= readl(phba
->HCregaddr
);
782 len
+= scnprintf(buf
+len
, size
-len
, "HA:%08x CA:%08x HS:%08x "
783 "HC:%08x\n", word0
, word1
, word2
, word3
);
785 spin_unlock_irq(&phba
->hbalock
);
790 * lpfc_debugfs_nodelist_data - Dump target node list to a buffer
791 * @vport: The vport to gather target node info from.
792 * @buf: The buffer to dump log into.
793 * @size: The maximum amount of data to process.
796 * This routine dumps the current target node list associated with @vport to
797 * @buf up to @size bytes of data. Each node entry in the dump will contain a
798 * node state, DID, WWPN, WWNN, RPI, flags, type, and other useful fields.
801 * This routine returns the amount of bytes that were dumped into @buf and will
805 lpfc_debugfs_nodelist_data(struct lpfc_vport
*vport
, char *buf
, int size
)
808 int i
, iocnt
, outio
, cnt
;
809 struct lpfc_hba
*phba
= vport
->phba
;
810 struct lpfc_nodelist
*ndlp
;
811 unsigned char *statep
;
812 unsigned long iflags
;
813 struct nvme_fc_local_port
*localport
;
814 struct nvme_fc_remote_port
*nrport
= NULL
;
815 struct lpfc_nvme_rport
*rport
;
817 cnt
= (LPFC_NODELIST_SIZE
/ LPFC_NODELIST_ENTRY_SIZE
);
820 len
+= scnprintf(buf
+len
, size
-len
, "\nFCP Nodelist Entries ...\n");
821 spin_lock_irqsave(&vport
->fc_nodes_list_lock
, iflags
);
822 list_for_each_entry(ndlp
, &vport
->fc_nodes
, nlp_listp
) {
825 len
+= scnprintf(buf
+len
, size
-len
,
826 "Missing Nodelist Entries\n");
830 switch (ndlp
->nlp_state
) {
831 case NLP_STE_UNUSED_NODE
:
834 case NLP_STE_PLOGI_ISSUE
:
837 case NLP_STE_ADISC_ISSUE
:
840 case NLP_STE_REG_LOGIN_ISSUE
:
843 case NLP_STE_PRLI_ISSUE
:
846 case NLP_STE_LOGO_ISSUE
:
849 case NLP_STE_UNMAPPED_NODE
:
853 case NLP_STE_MAPPED_NODE
:
857 case NLP_STE_NPR_NODE
:
863 len
+= scnprintf(buf
+len
, size
-len
, "%s DID:x%06x ",
864 statep
, ndlp
->nlp_DID
);
865 len
+= scnprintf(buf
+len
, size
-len
,
867 wwn_to_u64(ndlp
->nlp_portname
.u
.wwn
));
868 len
+= scnprintf(buf
+len
, size
-len
,
870 wwn_to_u64(ndlp
->nlp_nodename
.u
.wwn
));
871 len
+= scnprintf(buf
+len
, size
-len
, "RPI:x%04x ",
873 len
+= scnprintf(buf
+len
, size
-len
, "flag:x%08lx ",
876 len
+= scnprintf(buf
+len
, size
-len
, "UNKNOWN_TYPE ");
877 if (ndlp
->nlp_type
& NLP_FC_NODE
)
878 len
+= scnprintf(buf
+len
, size
-len
, "FC_NODE ");
879 if (ndlp
->nlp_type
& NLP_FABRIC
) {
880 len
+= scnprintf(buf
+len
, size
-len
, "FABRIC ");
883 if (ndlp
->nlp_type
& NLP_FCP_TARGET
)
884 len
+= scnprintf(buf
+len
, size
-len
, "FCP_TGT sid:%d ",
886 if (ndlp
->nlp_type
& NLP_FCP_INITIATOR
)
887 len
+= scnprintf(buf
+len
, size
-len
, "FCP_INITIATOR ");
888 if (ndlp
->nlp_type
& NLP_NVME_TARGET
)
889 len
+= scnprintf(buf
+ len
,
890 size
- len
, "NVME_TGT sid:%d ",
892 if (ndlp
->nlp_type
& NLP_NVME_INITIATOR
)
893 len
+= scnprintf(buf
+ len
,
894 size
- len
, "NVME_INITIATOR ");
895 len
+= scnprintf(buf
+len
, size
-len
, "refcnt:%d",
896 kref_read(&ndlp
->kref
));
898 i
= atomic_read(&ndlp
->cmd_pending
);
899 len
+= scnprintf(buf
+ len
, size
- len
,
900 " OutIO:x%x Qdepth x%x",
901 i
, ndlp
->cmd_qdepth
);
904 len
+= scnprintf(buf
+len
, size
-len
, " xpt:x%x",
905 ndlp
->fc4_xpt_flags
);
906 if (ndlp
->nlp_defer_did
!= NLP_EVT_NOTHING_PENDING
)
907 len
+= scnprintf(buf
+len
, size
-len
, " defer:%x",
908 ndlp
->nlp_defer_did
);
909 len
+= scnprintf(buf
+len
, size
-len
, "\n");
911 spin_unlock_irqrestore(&vport
->fc_nodes_list_lock
, iflags
);
913 len
+= scnprintf(buf
+ len
, size
- len
,
914 "\nOutstanding IO x%x\n", outio
);
916 if (phba
->nvmet_support
&& phba
->targetport
&& (vport
== phba
->pport
)) {
917 len
+= scnprintf(buf
+ len
, size
- len
,
918 "\nNVME Targetport Entry ...\n");
920 /* Port state is only one of two values for now. */
921 if (phba
->targetport
->port_id
)
922 statep
= "REGISTERED";
925 len
+= scnprintf(buf
+ len
, size
- len
,
926 "TGT WWNN x%llx WWPN x%llx State %s\n",
927 wwn_to_u64(vport
->fc_nodename
.u
.wwn
),
928 wwn_to_u64(vport
->fc_portname
.u
.wwn
),
930 len
+= scnprintf(buf
+ len
, size
- len
,
931 " Targetport DID x%06x\n",
932 phba
->targetport
->port_id
);
936 len
+= scnprintf(buf
+ len
, size
- len
,
937 "\nNVME Lport/Rport Entries ...\n");
939 localport
= vport
->localport
;
943 /* Port state is only one of two values for now. */
944 if (localport
->port_id
)
949 len
+= scnprintf(buf
+ len
, size
- len
,
950 "Lport DID x%06x PortState %s\n",
951 localport
->port_id
, statep
);
953 len
+= scnprintf(buf
+ len
, size
- len
, "\tRport List:\n");
954 spin_lock_irqsave(&vport
->fc_nodes_list_lock
, iflags
);
955 list_for_each_entry(ndlp
, &vport
->fc_nodes
, nlp_listp
) {
956 /* local short-hand pointer. */
957 spin_lock(&ndlp
->lock
);
958 rport
= lpfc_ndlp_get_nrport(ndlp
);
960 nrport
= rport
->remoteport
;
963 spin_unlock(&ndlp
->lock
);
967 /* Port state is only one of two values for now. */
968 switch (nrport
->port_state
) {
969 case FC_OBJSTATE_ONLINE
:
972 case FC_OBJSTATE_UNKNOWN
:
976 statep
= "UNSUPPORTED";
980 /* Tab in to show lport ownership. */
981 len
+= scnprintf(buf
+ len
, size
- len
,
982 "\t%s Port ID:x%06x ",
983 statep
, nrport
->port_id
);
984 len
+= scnprintf(buf
+ len
, size
- len
, "WWPN x%llx ",
986 len
+= scnprintf(buf
+ len
, size
- len
, "WWNN x%llx ",
989 /* An NVME rport can have multiple roles. */
990 if (nrport
->port_role
& FC_PORT_ROLE_NVME_INITIATOR
)
991 len
+= scnprintf(buf
+ len
, size
- len
,
993 if (nrport
->port_role
& FC_PORT_ROLE_NVME_TARGET
)
994 len
+= scnprintf(buf
+ len
, size
- len
,
996 if (nrport
->port_role
& FC_PORT_ROLE_NVME_DISCOVERY
)
997 len
+= scnprintf(buf
+ len
, size
- len
,
999 if (nrport
->port_role
& ~(FC_PORT_ROLE_NVME_INITIATOR
|
1000 FC_PORT_ROLE_NVME_TARGET
|
1001 FC_PORT_ROLE_NVME_DISCOVERY
))
1002 len
+= scnprintf(buf
+ len
, size
- len
,
1005 /* Terminate the string. */
1006 len
+= scnprintf(buf
+ len
, size
- len
, "\n");
1008 spin_unlock_irqrestore(&vport
->fc_nodes_list_lock
, iflags
);
1014 * lpfc_debugfs_nvmestat_data - Dump target node list to a buffer
1015 * @vport: The vport to gather target node info from.
1016 * @buf: The buffer to dump log into.
1017 * @size: The maximum amount of data to process.
1020 * This routine dumps the NVME statistics associated with @vport
1023 * This routine returns the amount of bytes that were dumped into @buf and will
1027 lpfc_debugfs_nvmestat_data(struct lpfc_vport
*vport
, char *buf
, int size
)
1029 struct lpfc_hba
*phba
= vport
->phba
;
1030 struct lpfc_nvmet_tgtport
*tgtp
;
1031 struct lpfc_async_xchg_ctx
*ctxp
, *next_ctxp
;
1032 struct nvme_fc_local_port
*localport
;
1033 struct lpfc_fc4_ctrl_stat
*cstat
;
1034 struct lpfc_nvme_lport
*lport
;
1035 uint64_t data1
, data2
, data3
;
1036 uint64_t tot
, totin
, totout
;
1040 if (phba
->nvmet_support
) {
1041 if (!phba
->targetport
)
1043 tgtp
= (struct lpfc_nvmet_tgtport
*)phba
->targetport
->private;
1044 len
+= scnprintf(buf
+ len
, size
- len
,
1045 "\nNVME Targetport Statistics\n");
1047 len
+= scnprintf(buf
+ len
, size
- len
,
1048 "LS: Rcv %08x Drop %08x Abort %08x\n",
1049 atomic_read(&tgtp
->rcv_ls_req_in
),
1050 atomic_read(&tgtp
->rcv_ls_req_drop
),
1051 atomic_read(&tgtp
->xmt_ls_abort
));
1052 if (atomic_read(&tgtp
->rcv_ls_req_in
) !=
1053 atomic_read(&tgtp
->rcv_ls_req_out
)) {
1054 len
+= scnprintf(buf
+ len
, size
- len
,
1055 "Rcv LS: in %08x != out %08x\n",
1056 atomic_read(&tgtp
->rcv_ls_req_in
),
1057 atomic_read(&tgtp
->rcv_ls_req_out
));
1060 len
+= scnprintf(buf
+ len
, size
- len
,
1061 "LS: Xmt %08x Drop %08x Cmpl %08x\n",
1062 atomic_read(&tgtp
->xmt_ls_rsp
),
1063 atomic_read(&tgtp
->xmt_ls_drop
),
1064 atomic_read(&tgtp
->xmt_ls_rsp_cmpl
));
1066 len
+= scnprintf(buf
+ len
, size
- len
,
1067 "LS: RSP Abort %08x xb %08x Err %08x\n",
1068 atomic_read(&tgtp
->xmt_ls_rsp_aborted
),
1069 atomic_read(&tgtp
->xmt_ls_rsp_xb_set
),
1070 atomic_read(&tgtp
->xmt_ls_rsp_error
));
1072 len
+= scnprintf(buf
+ len
, size
- len
,
1073 "FCP: Rcv %08x Defer %08x Release %08x "
1075 atomic_read(&tgtp
->rcv_fcp_cmd_in
),
1076 atomic_read(&tgtp
->rcv_fcp_cmd_defer
),
1077 atomic_read(&tgtp
->xmt_fcp_release
),
1078 atomic_read(&tgtp
->rcv_fcp_cmd_drop
));
1080 if (atomic_read(&tgtp
->rcv_fcp_cmd_in
) !=
1081 atomic_read(&tgtp
->rcv_fcp_cmd_out
)) {
1082 len
+= scnprintf(buf
+ len
, size
- len
,
1083 "Rcv FCP: in %08x != out %08x\n",
1084 atomic_read(&tgtp
->rcv_fcp_cmd_in
),
1085 atomic_read(&tgtp
->rcv_fcp_cmd_out
));
1088 len
+= scnprintf(buf
+ len
, size
- len
,
1089 "FCP Rsp: read %08x readrsp %08x "
1090 "write %08x rsp %08x\n",
1091 atomic_read(&tgtp
->xmt_fcp_read
),
1092 atomic_read(&tgtp
->xmt_fcp_read_rsp
),
1093 atomic_read(&tgtp
->xmt_fcp_write
),
1094 atomic_read(&tgtp
->xmt_fcp_rsp
));
1096 len
+= scnprintf(buf
+ len
, size
- len
,
1097 "FCP Rsp Cmpl: %08x err %08x drop %08x\n",
1098 atomic_read(&tgtp
->xmt_fcp_rsp_cmpl
),
1099 atomic_read(&tgtp
->xmt_fcp_rsp_error
),
1100 atomic_read(&tgtp
->xmt_fcp_rsp_drop
));
1102 len
+= scnprintf(buf
+ len
, size
- len
,
1103 "FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
1104 atomic_read(&tgtp
->xmt_fcp_rsp_aborted
),
1105 atomic_read(&tgtp
->xmt_fcp_rsp_xb_set
),
1106 atomic_read(&tgtp
->xmt_fcp_xri_abort_cqe
));
1108 len
+= scnprintf(buf
+ len
, size
- len
,
1109 "ABORT: Xmt %08x Cmpl %08x\n",
1110 atomic_read(&tgtp
->xmt_fcp_abort
),
1111 atomic_read(&tgtp
->xmt_fcp_abort_cmpl
));
1113 len
+= scnprintf(buf
+ len
, size
- len
,
1114 "ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x",
1115 atomic_read(&tgtp
->xmt_abort_sol
),
1116 atomic_read(&tgtp
->xmt_abort_unsol
),
1117 atomic_read(&tgtp
->xmt_abort_rsp
),
1118 atomic_read(&tgtp
->xmt_abort_rsp_error
));
1120 len
+= scnprintf(buf
+ len
, size
- len
, "\n");
1123 spin_lock(&phba
->sli4_hba
.abts_nvmet_buf_list_lock
);
1124 list_for_each_entry_safe(ctxp
, next_ctxp
,
1125 &phba
->sli4_hba
.lpfc_abts_nvmet_ctx_list
,
1129 spin_unlock(&phba
->sli4_hba
.abts_nvmet_buf_list_lock
);
1131 len
+= scnprintf(buf
+ len
, size
- len
,
1132 "ABORT: %d ctx entries\n", cnt
);
1133 spin_lock(&phba
->sli4_hba
.abts_nvmet_buf_list_lock
);
1134 list_for_each_entry_safe(ctxp
, next_ctxp
,
1135 &phba
->sli4_hba
.lpfc_abts_nvmet_ctx_list
,
1137 if (len
>= (size
- LPFC_DEBUG_OUT_LINE_SZ
))
1139 len
+= scnprintf(buf
+ len
, size
- len
,
1140 "Entry: oxid %x state %x "
1142 ctxp
->oxid
, ctxp
->state
,
1145 spin_unlock(&phba
->sli4_hba
.abts_nvmet_buf_list_lock
);
1148 /* Calculate outstanding IOs */
1149 tot
= atomic_read(&tgtp
->rcv_fcp_cmd_drop
);
1150 tot
+= atomic_read(&tgtp
->xmt_fcp_release
);
1151 tot
= atomic_read(&tgtp
->rcv_fcp_cmd_in
) - tot
;
1153 len
+= scnprintf(buf
+ len
, size
- len
,
1154 "IO_CTX: %08x WAIT: cur %08x tot %08x\n"
1155 "CTX Outstanding %08llx\n",
1156 phba
->sli4_hba
.nvmet_xri_cnt
,
1157 phba
->sli4_hba
.nvmet_io_wait_cnt
,
1158 phba
->sli4_hba
.nvmet_io_wait_total
,
1161 if (!(vport
->cfg_enable_fc4_type
& LPFC_ENABLE_NVME
))
1164 localport
= vport
->localport
;
1167 lport
= (struct lpfc_nvme_lport
*)localport
->private;
1171 len
+= scnprintf(buf
+ len
, size
- len
,
1172 "\nNVME HDWQ Statistics\n");
1174 len
+= scnprintf(buf
+ len
, size
- len
,
1175 "LS: Xmt %016x Cmpl %016x\n",
1176 atomic_read(&lport
->fc4NvmeLsRequests
),
1177 atomic_read(&lport
->fc4NvmeLsCmpls
));
1181 for (i
= 0; i
< phba
->cfg_hdw_queue
; i
++) {
1182 cstat
= &phba
->sli4_hba
.hdwq
[i
].nvme_cstat
;
1183 tot
= cstat
->io_cmpls
;
1185 data1
= cstat
->input_requests
;
1186 data2
= cstat
->output_requests
;
1187 data3
= cstat
->control_requests
;
1188 totout
+= (data1
+ data2
+ data3
);
1190 /* Limit to 32, debugfs display buffer limitation */
1194 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
1195 "HDWQ (%d): Rd %016llx Wr %016llx "
1197 i
, data1
, data2
, data3
);
1198 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
1199 "Cmpl %016llx OutIO %016llx\n",
1200 tot
, ((data1
+ data2
+ data3
) - tot
));
1202 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
1203 "Total FCP Cmpl %016llx Issue %016llx "
1205 totin
, totout
, totout
- totin
);
1207 len
+= scnprintf(buf
+ len
, size
- len
,
1208 "LS Xmt Err: Abrt %08x Err %08x "
1209 "Cmpl Err: xb %08x Err %08x\n",
1210 atomic_read(&lport
->xmt_ls_abort
),
1211 atomic_read(&lport
->xmt_ls_err
),
1212 atomic_read(&lport
->cmpl_ls_xb
),
1213 atomic_read(&lport
->cmpl_ls_err
));
1215 len
+= scnprintf(buf
+ len
, size
- len
,
1216 "FCP Xmt Err: noxri %06x nondlp %06x "
1217 "qdepth %06x wqerr %06x err %06x Abrt %06x\n",
1218 atomic_read(&lport
->xmt_fcp_noxri
),
1219 atomic_read(&lport
->xmt_fcp_bad_ndlp
),
1220 atomic_read(&lport
->xmt_fcp_qdepth
),
1221 atomic_read(&lport
->xmt_fcp_wqerr
),
1222 atomic_read(&lport
->xmt_fcp_err
),
1223 atomic_read(&lport
->xmt_fcp_abort
));
1225 len
+= scnprintf(buf
+ len
, size
- len
,
1226 "FCP Cmpl Err: xb %08x Err %08x\n",
1227 atomic_read(&lport
->cmpl_fcp_xb
),
1228 atomic_read(&lport
->cmpl_fcp_err
));
1236 * lpfc_debugfs_scsistat_data - Dump target node list to a buffer
1237 * @vport: The vport to gather target node info from.
1238 * @buf: The buffer to dump log into.
1239 * @size: The maximum amount of data to process.
1242 * This routine dumps the SCSI statistics associated with @vport
1245 * This routine returns the amount of bytes that were dumped into @buf and will
1249 lpfc_debugfs_scsistat_data(struct lpfc_vport
*vport
, char *buf
, int size
)
1252 struct lpfc_hba
*phba
= vport
->phba
;
1253 struct lpfc_fc4_ctrl_stat
*cstat
;
1254 u64 data1
, data2
, data3
;
1255 u64 tot
, totin
, totout
;
1257 char tmp
[LPFC_MAX_SCSI_INFO_TMP_LEN
] = {0};
1259 if (!(vport
->cfg_enable_fc4_type
& LPFC_ENABLE_FCP
) ||
1260 (phba
->sli_rev
!= LPFC_SLI_REV4
))
1263 scnprintf(buf
, size
, "SCSI HDWQ Statistics\n");
1267 for (i
= 0; i
< phba
->cfg_hdw_queue
; i
++) {
1268 cstat
= &phba
->sli4_hba
.hdwq
[i
].scsi_cstat
;
1269 tot
= cstat
->io_cmpls
;
1271 data1
= cstat
->input_requests
;
1272 data2
= cstat
->output_requests
;
1273 data3
= cstat
->control_requests
;
1274 totout
+= (data1
+ data2
+ data3
);
1276 scnprintf(tmp
, sizeof(tmp
), "HDWQ (%d): Rd %016llx Wr %016llx "
1277 "IO %016llx ", i
, data1
, data2
, data3
);
1278 if (strlcat(buf
, tmp
, size
) >= size
)
1281 scnprintf(tmp
, sizeof(tmp
), "Cmpl %016llx OutIO %016llx\n",
1282 tot
, ((data1
+ data2
+ data3
) - tot
));
1283 if (strlcat(buf
, tmp
, size
) >= size
)
1286 scnprintf(tmp
, sizeof(tmp
), "Total FCP Cmpl %016llx Issue %016llx "
1287 "OutIO %016llx\n", totin
, totout
, totout
- totin
);
1288 strlcat(buf
, tmp
, size
);
1291 len
= strnlen(buf
, size
);
1297 lpfc_io_ktime(struct lpfc_hba
*phba
, struct lpfc_io_buf
*lpfc_cmd
)
1299 uint64_t seg1
, seg2
, seg3
, seg4
;
1302 if (!lpfc_cmd
->ts_last_cmd
||
1303 !lpfc_cmd
->ts_cmd_start
||
1304 !lpfc_cmd
->ts_cmd_wqput
||
1305 !lpfc_cmd
->ts_isr_cmpl
||
1306 !lpfc_cmd
->ts_data_io
)
1309 if (lpfc_cmd
->ts_data_io
< lpfc_cmd
->ts_cmd_start
)
1311 if (lpfc_cmd
->ts_cmd_start
< lpfc_cmd
->ts_last_cmd
)
1313 if (lpfc_cmd
->ts_cmd_wqput
< lpfc_cmd
->ts_cmd_start
)
1315 if (lpfc_cmd
->ts_isr_cmpl
< lpfc_cmd
->ts_cmd_wqput
)
1317 if (lpfc_cmd
->ts_data_io
< lpfc_cmd
->ts_isr_cmpl
)
1320 * Segment 1 - Time from Last FCP command cmpl is handed
1321 * off to NVME Layer to start of next command.
1322 * Segment 2 - Time from Driver receives a IO cmd start
1323 * from NVME Layer to WQ put is done on IO cmd.
1324 * Segment 3 - Time from Driver WQ put is done on IO cmd
1325 * to MSI-X ISR for IO cmpl.
1326 * Segment 4 - Time from MSI-X ISR for IO cmpl to when
1327 * cmpl is handled off to the NVME Layer.
1329 seg1
= lpfc_cmd
->ts_cmd_start
- lpfc_cmd
->ts_last_cmd
;
1330 if (seg1
> 5000000) /* 5 ms - for sequential IOs only */
1333 /* Calculate times relative to start of IO */
1334 seg2
= (lpfc_cmd
->ts_cmd_wqput
- lpfc_cmd
->ts_cmd_start
);
1336 seg3
= lpfc_cmd
->ts_isr_cmpl
- lpfc_cmd
->ts_cmd_start
;
1342 seg4
= lpfc_cmd
->ts_data_io
- lpfc_cmd
->ts_cmd_start
;
1347 phba
->ktime_data_samples
++;
1348 phba
->ktime_seg1_total
+= seg1
;
1349 if (seg1
< phba
->ktime_seg1_min
)
1350 phba
->ktime_seg1_min
= seg1
;
1351 else if (seg1
> phba
->ktime_seg1_max
)
1352 phba
->ktime_seg1_max
= seg1
;
1353 phba
->ktime_seg2_total
+= seg2
;
1354 if (seg2
< phba
->ktime_seg2_min
)
1355 phba
->ktime_seg2_min
= seg2
;
1356 else if (seg2
> phba
->ktime_seg2_max
)
1357 phba
->ktime_seg2_max
= seg2
;
1358 phba
->ktime_seg3_total
+= seg3
;
1359 if (seg3
< phba
->ktime_seg3_min
)
1360 phba
->ktime_seg3_min
= seg3
;
1361 else if (seg3
> phba
->ktime_seg3_max
)
1362 phba
->ktime_seg3_max
= seg3
;
1363 phba
->ktime_seg4_total
+= seg4
;
1364 if (seg4
< phba
->ktime_seg4_min
)
1365 phba
->ktime_seg4_min
= seg4
;
1366 else if (seg4
> phba
->ktime_seg4_max
)
1367 phba
->ktime_seg4_max
= seg4
;
1369 lpfc_cmd
->ts_last_cmd
= 0;
1370 lpfc_cmd
->ts_cmd_start
= 0;
1371 lpfc_cmd
->ts_cmd_wqput
= 0;
1372 lpfc_cmd
->ts_isr_cmpl
= 0;
1373 lpfc_cmd
->ts_data_io
= 0;
1377 * lpfc_debugfs_ioktime_data - Dump target node list to a buffer
1378 * @vport: The vport to gather target node info from.
1379 * @buf: The buffer to dump log into.
1380 * @size: The maximum amount of data to process.
1383 * This routine dumps the NVME statistics associated with @vport
1386 * This routine returns the amount of bytes that were dumped into @buf and will
1390 lpfc_debugfs_ioktime_data(struct lpfc_vport
*vport
, char *buf
, int size
)
1392 struct lpfc_hba
*phba
= vport
->phba
;
1395 if (phba
->nvmet_support
== 0) {
1397 len
+= scnprintf(buf
+ len
, PAGE_SIZE
- len
,
1398 "ktime %s: Total Samples: %lld\n",
1399 (phba
->ktime_on
? "Enabled" : "Disabled"),
1400 phba
->ktime_data_samples
);
1401 if (phba
->ktime_data_samples
== 0)
1405 buf
+ len
, PAGE_SIZE
- len
,
1406 "Segment 1: Last Cmd cmpl "
1407 "done -to- Start of next Cmd (in driver)\n");
1409 buf
+ len
, PAGE_SIZE
- len
,
1410 "avg:%08lld min:%08lld max %08lld\n",
1411 div_u64(phba
->ktime_seg1_total
,
1412 phba
->ktime_data_samples
),
1413 phba
->ktime_seg1_min
,
1414 phba
->ktime_seg1_max
);
1416 buf
+ len
, PAGE_SIZE
- len
,
1417 "Segment 2: Driver start of Cmd "
1418 "-to- Firmware WQ doorbell\n");
1420 buf
+ len
, PAGE_SIZE
- len
,
1421 "avg:%08lld min:%08lld max %08lld\n",
1422 div_u64(phba
->ktime_seg2_total
,
1423 phba
->ktime_data_samples
),
1424 phba
->ktime_seg2_min
,
1425 phba
->ktime_seg2_max
);
1427 buf
+ len
, PAGE_SIZE
- len
,
1428 "Segment 3: Firmware WQ doorbell -to- "
1429 "MSI-X ISR cmpl\n");
1431 buf
+ len
, PAGE_SIZE
- len
,
1432 "avg:%08lld min:%08lld max %08lld\n",
1433 div_u64(phba
->ktime_seg3_total
,
1434 phba
->ktime_data_samples
),
1435 phba
->ktime_seg3_min
,
1436 phba
->ktime_seg3_max
);
1438 buf
+ len
, PAGE_SIZE
- len
,
1439 "Segment 4: MSI-X ISR cmpl -to- "
1442 buf
+ len
, PAGE_SIZE
- len
,
1443 "avg:%08lld min:%08lld max %08lld\n",
1444 div_u64(phba
->ktime_seg4_total
,
1445 phba
->ktime_data_samples
),
1446 phba
->ktime_seg4_min
,
1447 phba
->ktime_seg4_max
);
1449 buf
+ len
, PAGE_SIZE
- len
,
1450 "Total IO avg time: %08lld\n",
1451 div_u64(phba
->ktime_seg1_total
+
1452 phba
->ktime_seg2_total
+
1453 phba
->ktime_seg3_total
+
1454 phba
->ktime_seg4_total
,
1455 phba
->ktime_data_samples
));
1460 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1461 "ktime %s: Total Samples: %lld %lld\n",
1462 (phba
->ktime_on
? "Enabled" : "Disabled"),
1463 phba
->ktime_data_samples
,
1464 phba
->ktime_status_samples
);
1465 if (phba
->ktime_data_samples
== 0)
1468 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1469 "Segment 1: MSI-X ISR Rcv cmd -to- "
1470 "cmd pass to NVME Layer\n");
1471 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1472 "avg:%08lld min:%08lld max %08lld\n",
1473 div_u64(phba
->ktime_seg1_total
,
1474 phba
->ktime_data_samples
),
1475 phba
->ktime_seg1_min
,
1476 phba
->ktime_seg1_max
);
1477 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1478 "Segment 2: cmd pass to NVME Layer- "
1479 "-to- Driver rcv cmd OP (action)\n");
1480 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1481 "avg:%08lld min:%08lld max %08lld\n",
1482 div_u64(phba
->ktime_seg2_total
,
1483 phba
->ktime_data_samples
),
1484 phba
->ktime_seg2_min
,
1485 phba
->ktime_seg2_max
);
1486 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1487 "Segment 3: Driver rcv cmd OP -to- "
1488 "Firmware WQ doorbell: cmd\n");
1489 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1490 "avg:%08lld min:%08lld max %08lld\n",
1491 div_u64(phba
->ktime_seg3_total
,
1492 phba
->ktime_data_samples
),
1493 phba
->ktime_seg3_min
,
1494 phba
->ktime_seg3_max
);
1495 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1496 "Segment 4: Firmware WQ doorbell: cmd "
1497 "-to- MSI-X ISR for cmd cmpl\n");
1498 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1499 "avg:%08lld min:%08lld max %08lld\n",
1500 div_u64(phba
->ktime_seg4_total
,
1501 phba
->ktime_data_samples
),
1502 phba
->ktime_seg4_min
,
1503 phba
->ktime_seg4_max
);
1504 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1505 "Segment 5: MSI-X ISR for cmd cmpl "
1506 "-to- NVME layer passed cmd done\n");
1507 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1508 "avg:%08lld min:%08lld max %08lld\n",
1509 div_u64(phba
->ktime_seg5_total
,
1510 phba
->ktime_data_samples
),
1511 phba
->ktime_seg5_min
,
1512 phba
->ktime_seg5_max
);
1514 if (phba
->ktime_status_samples
== 0) {
1515 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1516 "Total: cmd received by MSI-X ISR "
1517 "-to- cmd completed on wire\n");
1518 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1519 "avg:%08lld min:%08lld "
1521 div_u64(phba
->ktime_seg10_total
,
1522 phba
->ktime_data_samples
),
1523 phba
->ktime_seg10_min
,
1524 phba
->ktime_seg10_max
);
1528 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1529 "Segment 6: NVME layer passed cmd done "
1530 "-to- Driver rcv rsp status OP\n");
1531 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1532 "avg:%08lld min:%08lld max %08lld\n",
1533 div_u64(phba
->ktime_seg6_total
,
1534 phba
->ktime_status_samples
),
1535 phba
->ktime_seg6_min
,
1536 phba
->ktime_seg6_max
);
1537 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1538 "Segment 7: Driver rcv rsp status OP "
1539 "-to- Firmware WQ doorbell: status\n");
1540 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1541 "avg:%08lld min:%08lld max %08lld\n",
1542 div_u64(phba
->ktime_seg7_total
,
1543 phba
->ktime_status_samples
),
1544 phba
->ktime_seg7_min
,
1545 phba
->ktime_seg7_max
);
1546 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1547 "Segment 8: Firmware WQ doorbell: status"
1548 " -to- MSI-X ISR for status cmpl\n");
1549 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1550 "avg:%08lld min:%08lld max %08lld\n",
1551 div_u64(phba
->ktime_seg8_total
,
1552 phba
->ktime_status_samples
),
1553 phba
->ktime_seg8_min
,
1554 phba
->ktime_seg8_max
);
1555 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1556 "Segment 9: MSI-X ISR for status cmpl "
1557 "-to- NVME layer passed status done\n");
1558 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1559 "avg:%08lld min:%08lld max %08lld\n",
1560 div_u64(phba
->ktime_seg9_total
,
1561 phba
->ktime_status_samples
),
1562 phba
->ktime_seg9_min
,
1563 phba
->ktime_seg9_max
);
1564 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1565 "Total: cmd received by MSI-X ISR -to- "
1566 "cmd completed on wire\n");
1567 len
+= scnprintf(buf
+ len
, PAGE_SIZE
-len
,
1568 "avg:%08lld min:%08lld max %08lld\n",
1569 div_u64(phba
->ktime_seg10_total
,
1570 phba
->ktime_status_samples
),
1571 phba
->ktime_seg10_min
,
1572 phba
->ktime_seg10_max
);
1577 * lpfc_debugfs_nvmeio_trc_data - Dump NVME IO trace list to a buffer
1578 * @phba: The phba to gather target node info from.
1579 * @buf: The buffer to dump log into.
1580 * @size: The maximum amount of data to process.
1583 * This routine dumps the NVME IO trace associated with @phba
1586 * This routine returns the amount of bytes that were dumped into @buf and will
1590 lpfc_debugfs_nvmeio_trc_data(struct lpfc_hba
*phba
, char *buf
, int size
)
1592 struct lpfc_debugfs_nvmeio_trc
*dtp
;
1593 int i
, state
, index
, skip
;
1596 state
= phba
->nvmeio_trc_on
;
1598 index
= (atomic_read(&phba
->nvmeio_trc_cnt
) + 1) &
1599 (phba
->nvmeio_trc_size
- 1);
1600 skip
= phba
->nvmeio_trc_output_idx
;
1602 len
+= scnprintf(buf
+ len
, size
- len
,
1603 "%s IO Trace %s: next_idx %d skip %d size %d\n",
1604 (phba
->nvmet_support
? "NVME" : "NVMET"),
1605 (state
? "Enabled" : "Disabled"),
1606 index
, skip
, phba
->nvmeio_trc_size
);
1608 if (!phba
->nvmeio_trc
|| state
)
1611 /* trace MUST bhe off to continue */
1613 for (i
= index
; i
< phba
->nvmeio_trc_size
; i
++) {
1618 dtp
= phba
->nvmeio_trc
+ i
;
1619 phba
->nvmeio_trc_output_idx
++;
1624 len
+= scnprintf(buf
+ len
, size
- len
, dtp
->fmt
,
1625 dtp
->data1
, dtp
->data2
, dtp
->data3
);
1627 if (phba
->nvmeio_trc_output_idx
>= phba
->nvmeio_trc_size
) {
1628 phba
->nvmeio_trc_output_idx
= 0;
1629 len
+= scnprintf(buf
+ len
, size
- len
,
1630 "Trace Complete\n");
1634 if (len
>= (size
- LPFC_DEBUG_OUT_LINE_SZ
)) {
1635 len
+= scnprintf(buf
+ len
, size
- len
,
1636 "Trace Continue (%d of %d)\n",
1637 phba
->nvmeio_trc_output_idx
,
1638 phba
->nvmeio_trc_size
);
1642 for (i
= 0; i
< index
; i
++) {
1647 dtp
= phba
->nvmeio_trc
+ i
;
1648 phba
->nvmeio_trc_output_idx
++;
1653 len
+= scnprintf(buf
+ len
, size
- len
, dtp
->fmt
,
1654 dtp
->data1
, dtp
->data2
, dtp
->data3
);
1656 if (phba
->nvmeio_trc_output_idx
>= phba
->nvmeio_trc_size
) {
1657 phba
->nvmeio_trc_output_idx
= 0;
1658 len
+= scnprintf(buf
+ len
, size
- len
,
1659 "Trace Complete\n");
1663 if (len
>= (size
- LPFC_DEBUG_OUT_LINE_SZ
)) {
1664 len
+= scnprintf(buf
+ len
, size
- len
,
1665 "Trace Continue (%d of %d)\n",
1666 phba
->nvmeio_trc_output_idx
,
1667 phba
->nvmeio_trc_size
);
1672 len
+= scnprintf(buf
+ len
, size
- len
,
1679 * lpfc_debugfs_hdwqstat_data - Dump I/O stats to a buffer
1680 * @vport: The vport to gather target node info from.
1681 * @buf: The buffer to dump log into.
1682 * @size: The maximum amount of data to process.
1685 * This routine dumps the NVME + SCSI statistics associated with @vport
1688 * This routine returns the amount of bytes that were dumped into @buf and will
1692 lpfc_debugfs_hdwqstat_data(struct lpfc_vport
*vport
, char *buf
, int size
)
1694 struct lpfc_hba
*phba
= vport
->phba
;
1695 struct lpfc_hdwq_stat
*c_stat
;
1700 char tmp
[LPFC_MAX_SCSI_INFO_TMP_LEN
] = {0};
1702 scnprintf(tmp
, sizeof(tmp
), "HDWQ Stats:\n\n");
1703 if (strlcat(buf
, tmp
, size
) >= size
)
1706 scnprintf(tmp
, sizeof(tmp
), "(NVME Accounting: %s) ",
1707 (phba
->hdwqstat_on
&
1708 (LPFC_CHECK_NVME_IO
| LPFC_CHECK_NVMET_IO
) ?
1709 "Enabled" : "Disabled"));
1710 if (strlcat(buf
, tmp
, size
) >= size
)
1713 scnprintf(tmp
, sizeof(tmp
), "(SCSI Accounting: %s) ",
1714 (phba
->hdwqstat_on
& LPFC_CHECK_SCSI_IO
?
1715 "Enabled" : "Disabled"));
1716 if (strlcat(buf
, tmp
, size
) >= size
)
1719 scnprintf(tmp
, sizeof(tmp
), "\n\n");
1720 if (strlcat(buf
, tmp
, size
) >= size
)
1723 for (i
= 0; i
< phba
->cfg_hdw_queue
; i
++) {
1728 for_each_present_cpu(j
) {
1729 c_stat
= per_cpu_ptr(phba
->sli4_hba
.c_stat
, j
);
1731 /* Only display for this HDWQ */
1732 if (i
!= c_stat
->hdwq_no
)
1735 /* Only display non-zero counters */
1736 if (!c_stat
->xmt_io
&& !c_stat
->cmpl_io
&&
1740 if (!tot_xmt
&& !tot_cmpl
&& !tot_rcv
) {
1741 /* Print HDWQ string only the first time */
1742 scnprintf(tmp
, sizeof(tmp
), "[HDWQ %d]:\t", i
);
1743 if (strlcat(buf
, tmp
, size
) >= size
)
1747 tot_xmt
+= c_stat
->xmt_io
;
1748 tot_cmpl
+= c_stat
->cmpl_io
;
1749 if (phba
->nvmet_support
)
1750 tot_rcv
+= c_stat
->rcv_io
;
1752 scnprintf(tmp
, sizeof(tmp
), "| [CPU %d]: ", j
);
1753 if (strlcat(buf
, tmp
, size
) >= size
)
1756 if (phba
->nvmet_support
) {
1757 scnprintf(tmp
, sizeof(tmp
),
1758 "XMT 0x%x CMPL 0x%x RCV 0x%x |",
1759 c_stat
->xmt_io
, c_stat
->cmpl_io
,
1761 if (strlcat(buf
, tmp
, size
) >= size
)
1764 scnprintf(tmp
, sizeof(tmp
),
1765 "XMT 0x%x CMPL 0x%x |",
1766 c_stat
->xmt_io
, c_stat
->cmpl_io
);
1767 if (strlcat(buf
, tmp
, size
) >= size
)
1772 /* Check if nothing to display */
1773 if (!tot_xmt
&& !tot_cmpl
&& !tot_rcv
)
1776 scnprintf(tmp
, sizeof(tmp
), "\t->\t[HDWQ Total: ");
1777 if (strlcat(buf
, tmp
, size
) >= size
)
1780 if (phba
->nvmet_support
) {
1781 scnprintf(tmp
, sizeof(tmp
),
1782 "XMT 0x%x CMPL 0x%x RCV 0x%x]\n\n",
1783 tot_xmt
, tot_cmpl
, tot_rcv
);
1784 if (strlcat(buf
, tmp
, size
) >= size
)
1787 scnprintf(tmp
, sizeof(tmp
),
1788 "XMT 0x%x CMPL 0x%x]\n\n",
1790 if (strlcat(buf
, tmp
, size
) >= size
)
1796 len
= strnlen(buf
, size
);
1803 * lpfc_debugfs_disc_trc - Store discovery trace log
1804 * @vport: The vport to associate this trace string with for retrieval.
1805 * @mask: Log entry classification.
1806 * @fmt: Format string to be displayed when dumping the log.
1807 * @data1: 1st data parameter to be applied to @fmt.
1808 * @data2: 2nd data parameter to be applied to @fmt.
1809 * @data3: 3rd data parameter to be applied to @fmt.
1812 * This routine is used by the driver code to add a debugfs log entry to the
1813 * discovery trace buffer associated with @vport. Only entries with a @mask that
1814 * match the current debugfs discovery mask will be saved. Entries that do not
1815 * match will be thrown away. @fmt, @data1, @data2, and @data3 are used like
1816 * printf when displaying the log.
1819 lpfc_debugfs_disc_trc(struct lpfc_vport
*vport
, int mask
, char *fmt
,
1820 uint32_t data1
, uint32_t data2
, uint32_t data3
)
1822 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1823 struct lpfc_debugfs_trc
*dtp
;
1826 if (!(lpfc_debugfs_mask_disc_trc
& mask
))
1829 if (!lpfc_debugfs_enable
|| !lpfc_debugfs_max_disc_trc
||
1830 !vport
|| !vport
->disc_trc
)
1833 index
= atomic_inc_return(&vport
->disc_trc_cnt
) &
1834 (lpfc_debugfs_max_disc_trc
- 1);
1835 dtp
= vport
->disc_trc
+ index
;
1840 dtp
->seq_cnt
= atomic_inc_return(&lpfc_debugfs_seq_trc_cnt
);
1847 * lpfc_debugfs_slow_ring_trc - Store slow ring trace log
1848 * @phba: The phba to associate this trace string with for retrieval.
1849 * @fmt: Format string to be displayed when dumping the log.
1850 * @data1: 1st data parameter to be applied to @fmt.
1851 * @data2: 2nd data parameter to be applied to @fmt.
1852 * @data3: 3rd data parameter to be applied to @fmt.
1855 * This routine is used by the driver code to add a debugfs log entry to the
1856 * discovery trace buffer associated with @vport. @fmt, @data1, @data2, and
1857 * @data3 are used like printf when displaying the log.
1860 lpfc_debugfs_slow_ring_trc(struct lpfc_hba
*phba
, char *fmt
,
1861 uint32_t data1
, uint32_t data2
, uint32_t data3
)
1863 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1864 struct lpfc_debugfs_trc
*dtp
;
1867 if (!lpfc_debugfs_enable
|| !lpfc_debugfs_max_slow_ring_trc
||
1868 !phba
|| !phba
->slow_ring_trc
)
1871 index
= atomic_inc_return(&phba
->slow_ring_trc_cnt
) &
1872 (lpfc_debugfs_max_slow_ring_trc
- 1);
1873 dtp
= phba
->slow_ring_trc
+ index
;
1878 dtp
->seq_cnt
= atomic_inc_return(&lpfc_debugfs_seq_trc_cnt
);
1885 * lpfc_debugfs_nvme_trc - Store NVME/NVMET trace log
1886 * @phba: The phba to associate this trace string with for retrieval.
1887 * @fmt: Format string to be displayed when dumping the log.
1888 * @data1: 1st data parameter to be applied to @fmt.
1889 * @data2: 2nd data parameter to be applied to @fmt.
1890 * @data3: 3rd data parameter to be applied to @fmt.
1893 * This routine is used by the driver code to add a debugfs log entry to the
1894 * nvme trace buffer associated with @phba. @fmt, @data1, @data2, and
1895 * @data3 are used like printf when displaying the log.
1898 lpfc_debugfs_nvme_trc(struct lpfc_hba
*phba
, char *fmt
,
1899 uint16_t data1
, uint16_t data2
, uint32_t data3
)
1901 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1902 struct lpfc_debugfs_nvmeio_trc
*dtp
;
1905 if (!phba
->nvmeio_trc_on
|| !phba
->nvmeio_trc
)
1908 index
= atomic_inc_return(&phba
->nvmeio_trc_cnt
) &
1909 (phba
->nvmeio_trc_size
- 1);
1910 dtp
= phba
->nvmeio_trc
+ index
;
1918 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1920 * lpfc_debugfs_disc_trc_open - Open the discovery trace log
1921 * @inode: The inode pointer that contains a vport pointer.
1922 * @file: The file pointer to attach the log output.
1925 * This routine is the entry point for the debugfs open file operation. It gets
1926 * the vport from the i_private field in @inode, allocates the necessary buffer
1927 * for the log, fills the buffer from the in-memory log for this vport, and then
1928 * returns a pointer to that log in the private_data field in @file.
1931 * This function returns zero if successful. On error it will return a negative
1935 lpfc_debugfs_disc_trc_open(struct inode
*inode
, struct file
*file
)
1937 struct lpfc_vport
*vport
= inode
->i_private
;
1938 struct lpfc_debug
*debug
;
1942 if (!lpfc_debugfs_max_disc_trc
) {
1947 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
1951 /* Round to page boundary */
1952 size
= (lpfc_debugfs_max_disc_trc
* LPFC_DEBUG_TRC_ENTRY_SIZE
);
1953 size
= PAGE_ALIGN(size
);
1955 debug
->buffer
= kmalloc(size
, GFP_KERNEL
);
1956 if (!debug
->buffer
) {
1961 debug
->len
= lpfc_debugfs_disc_trc_data(vport
, debug
->buffer
, size
);
1962 file
->private_data
= debug
;
1970 * lpfc_debugfs_slow_ring_trc_open - Open the Slow Ring trace log
1971 * @inode: The inode pointer that contains a vport pointer.
1972 * @file: The file pointer to attach the log output.
1975 * This routine is the entry point for the debugfs open file operation. It gets
1976 * the vport from the i_private field in @inode, allocates the necessary buffer
1977 * for the log, fills the buffer from the in-memory log for this vport, and then
1978 * returns a pointer to that log in the private_data field in @file.
1981 * This function returns zero if successful. On error it will return a negative
1985 lpfc_debugfs_slow_ring_trc_open(struct inode
*inode
, struct file
*file
)
1987 struct lpfc_hba
*phba
= inode
->i_private
;
1988 struct lpfc_debug
*debug
;
1992 if (!lpfc_debugfs_max_slow_ring_trc
) {
1997 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
2001 /* Round to page boundary */
2002 size
= (lpfc_debugfs_max_slow_ring_trc
* LPFC_DEBUG_TRC_ENTRY_SIZE
);
2003 size
= PAGE_ALIGN(size
);
2005 debug
->buffer
= kmalloc(size
, GFP_KERNEL
);
2006 if (!debug
->buffer
) {
2011 debug
->len
= lpfc_debugfs_slow_ring_trc_data(phba
, debug
->buffer
, size
);
2012 file
->private_data
= debug
;
2020 * lpfc_debugfs_hbqinfo_open - Open the hbqinfo debugfs buffer
2021 * @inode: The inode pointer that contains a vport pointer.
2022 * @file: The file pointer to attach the log output.
2025 * This routine is the entry point for the debugfs open file operation. It gets
2026 * the vport from the i_private field in @inode, allocates the necessary buffer
2027 * for the log, fills the buffer from the in-memory log for this vport, and then
2028 * returns a pointer to that log in the private_data field in @file.
2031 * This function returns zero if successful. On error it will return a negative
2035 lpfc_debugfs_hbqinfo_open(struct inode
*inode
, struct file
*file
)
2037 struct lpfc_hba
*phba
= inode
->i_private
;
2038 struct lpfc_debug
*debug
;
2041 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
2045 /* Round to page boundary */
2046 debug
->buffer
= kmalloc(LPFC_HBQINFO_SIZE
, GFP_KERNEL
);
2047 if (!debug
->buffer
) {
2052 debug
->len
= lpfc_debugfs_hbqinfo_data(phba
, debug
->buffer
,
2054 file
->private_data
= debug
;
2062 * lpfc_debugfs_multixripools_open - Open the multixripool debugfs buffer
2063 * @inode: The inode pointer that contains a hba pointer.
2064 * @file: The file pointer to attach the log output.
2067 * This routine is the entry point for the debugfs open file operation. It gets
2068 * the hba from the i_private field in @inode, allocates the necessary buffer
2069 * for the log, fills the buffer from the in-memory log for this hba, and then
2070 * returns a pointer to that log in the private_data field in @file.
2073 * This function returns zero if successful. On error it will return a negative
2077 lpfc_debugfs_multixripools_open(struct inode
*inode
, struct file
*file
)
2079 struct lpfc_hba
*phba
= inode
->i_private
;
2080 struct lpfc_debug
*debug
;
2083 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
2087 /* Round to page boundary */
2088 debug
->buffer
= kzalloc(LPFC_DUMP_MULTIXRIPOOL_SIZE
, GFP_KERNEL
);
2089 if (!debug
->buffer
) {
2094 debug
->len
= lpfc_debugfs_multixripools_data(
2095 phba
, debug
->buffer
, LPFC_DUMP_MULTIXRIPOOL_SIZE
);
2097 debug
->i_private
= inode
->i_private
;
2098 file
->private_data
= debug
;
2105 #ifdef LPFC_HDWQ_LOCK_STAT
2107 * lpfc_debugfs_lockstat_open - Open the lockstat debugfs buffer
2108 * @inode: The inode pointer that contains a vport pointer.
2109 * @file: The file pointer to attach the log output.
2112 * This routine is the entry point for the debugfs open file operation. It gets
2113 * the vport from the i_private field in @inode, allocates the necessary buffer
2114 * for the log, fills the buffer from the in-memory log for this vport, and then
2115 * returns a pointer to that log in the private_data field in @file.
2118 * This function returns zero if successful. On error it will return a negative
2122 lpfc_debugfs_lockstat_open(struct inode
*inode
, struct file
*file
)
2124 struct lpfc_hba
*phba
= inode
->i_private
;
2125 struct lpfc_debug
*debug
;
2128 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
2132 /* Round to page boundary */
2133 debug
->buffer
= kmalloc(LPFC_HDWQINFO_SIZE
, GFP_KERNEL
);
2134 if (!debug
->buffer
) {
2139 debug
->len
= lpfc_debugfs_lockstat_data(phba
, debug
->buffer
,
2141 file
->private_data
= debug
;
2149 lpfc_debugfs_lockstat_write(struct file
*file
, const char __user
*buf
,
2150 size_t nbytes
, loff_t
*ppos
)
2152 struct lpfc_debug
*debug
= file
->private_data
;
2153 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
2154 struct lpfc_sli4_hdw_queue
*qp
;
2160 memset(mybuf
, 0, sizeof(mybuf
));
2162 bsize
= min(nbytes
, (sizeof(mybuf
) - 1));
2164 if (copy_from_user(mybuf
, buf
, bsize
))
2168 if ((strncmp(pbuf
, "reset", strlen("reset")) == 0) ||
2169 (strncmp(pbuf
, "zero", strlen("zero")) == 0)) {
2170 for (i
= 0; i
< phba
->cfg_hdw_queue
; i
++) {
2171 qp
= &phba
->sli4_hba
.hdwq
[i
];
2172 qp
->lock_conflict
.alloc_xri_get
= 0;
2173 qp
->lock_conflict
.alloc_xri_put
= 0;
2174 qp
->lock_conflict
.free_xri
= 0;
2175 qp
->lock_conflict
.wq_access
= 0;
2176 qp
->lock_conflict
.alloc_pvt_pool
= 0;
2177 qp
->lock_conflict
.mv_from_pvt_pool
= 0;
2178 qp
->lock_conflict
.mv_to_pub_pool
= 0;
2179 qp
->lock_conflict
.mv_to_pvt_pool
= 0;
2180 qp
->lock_conflict
.free_pvt_pool
= 0;
2181 qp
->lock_conflict
.free_pub_pool
= 0;
2182 qp
->lock_conflict
.wq_access
= 0;
2189 static int lpfc_debugfs_ras_log_data(struct lpfc_hba
*phba
,
2190 char *buffer
, int size
)
2193 struct lpfc_dmabuf
*dmabuf
, *next
;
2195 memset(buffer
, 0, size
);
2197 spin_lock_irq(&phba
->ras_fwlog_lock
);
2198 if (phba
->ras_fwlog
.state
!= ACTIVE
) {
2199 spin_unlock_irq(&phba
->ras_fwlog_lock
);
2202 spin_unlock_irq(&phba
->ras_fwlog_lock
);
2204 list_for_each_entry_safe(dmabuf
, next
,
2205 &phba
->ras_fwlog
.fwlog_buff_list
, list
) {
2206 /* Check if copying will go over size and a '\0' char */
2207 if ((copied
+ LPFC_RAS_MAX_ENTRY_SIZE
) >= (size
- 1)) {
2208 memcpy(buffer
+ copied
, dmabuf
->virt
,
2210 copied
+= size
- copied
- 1;
2213 memcpy(buffer
+ copied
, dmabuf
->virt
, LPFC_RAS_MAX_ENTRY_SIZE
);
2214 copied
+= LPFC_RAS_MAX_ENTRY_SIZE
;
2220 lpfc_debugfs_ras_log_release(struct inode
*inode
, struct file
*file
)
2222 struct lpfc_debug
*debug
= file
->private_data
;
2224 vfree(debug
->buffer
);
2231 * lpfc_debugfs_ras_log_open - Open the RAS log debugfs buffer
2232 * @inode: The inode pointer that contains a vport pointer.
2233 * @file: The file pointer to attach the log output.
2236 * This routine is the entry point for the debugfs open file operation. It gets
2237 * the vport from the i_private field in @inode, allocates the necessary buffer
2238 * for the log, fills the buffer from the in-memory log for this vport, and then
2239 * returns a pointer to that log in the private_data field in @file.
2242 * This function returns zero if successful. On error it will return a negative
2246 lpfc_debugfs_ras_log_open(struct inode
*inode
, struct file
*file
)
2248 struct lpfc_hba
*phba
= inode
->i_private
;
2249 struct lpfc_debug
*debug
;
2253 spin_lock_irq(&phba
->ras_fwlog_lock
);
2254 if (phba
->ras_fwlog
.state
!= ACTIVE
) {
2255 spin_unlock_irq(&phba
->ras_fwlog_lock
);
2259 spin_unlock_irq(&phba
->ras_fwlog_lock
);
2261 if (check_mul_overflow(LPFC_RAS_MIN_BUFF_POST_SIZE
,
2262 phba
->cfg_ras_fwlog_buffsize
, &size
))
2265 debug
= kzalloc(sizeof(*debug
), GFP_KERNEL
);
2269 debug
->buffer
= vmalloc(size
);
2273 debug
->len
= lpfc_debugfs_ras_log_data(phba
, debug
->buffer
, size
);
2274 if (debug
->len
< 0) {
2278 file
->private_data
= debug
;
2283 vfree(debug
->buffer
);
2291 * lpfc_debugfs_dumpHBASlim_open - Open the Dump HBA SLIM debugfs buffer
2292 * @inode: The inode pointer that contains a vport pointer.
2293 * @file: The file pointer to attach the log output.
2296 * This routine is the entry point for the debugfs open file operation. It gets
2297 * the vport from the i_private field in @inode, allocates the necessary buffer
2298 * for the log, fills the buffer from the in-memory log for this vport, and then
2299 * returns a pointer to that log in the private_data field in @file.
2302 * This function returns zero if successful. On error it will return a negative
2306 lpfc_debugfs_dumpHBASlim_open(struct inode
*inode
, struct file
*file
)
2308 struct lpfc_hba
*phba
= inode
->i_private
;
2309 struct lpfc_debug
*debug
;
2312 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
2316 /* Round to page boundary */
2317 debug
->buffer
= kmalloc(LPFC_DUMPHBASLIM_SIZE
, GFP_KERNEL
);
2318 if (!debug
->buffer
) {
2323 debug
->len
= lpfc_debugfs_dumpHBASlim_data(phba
, debug
->buffer
,
2324 LPFC_DUMPHBASLIM_SIZE
);
2325 file
->private_data
= debug
;
2333 * lpfc_debugfs_dumpHostSlim_open - Open the Dump Host SLIM debugfs buffer
2334 * @inode: The inode pointer that contains a vport pointer.
2335 * @file: The file pointer to attach the log output.
2338 * This routine is the entry point for the debugfs open file operation. It gets
2339 * the vport from the i_private field in @inode, allocates the necessary buffer
2340 * for the log, fills the buffer from the in-memory log for this vport, and then
2341 * returns a pointer to that log in the private_data field in @file.
2344 * This function returns zero if successful. On error it will return a negative
2348 lpfc_debugfs_dumpHostSlim_open(struct inode
*inode
, struct file
*file
)
2350 struct lpfc_hba
*phba
= inode
->i_private
;
2351 struct lpfc_debug
*debug
;
2354 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
2358 /* Round to page boundary */
2359 debug
->buffer
= kmalloc(LPFC_DUMPHOSTSLIM_SIZE
, GFP_KERNEL
);
2360 if (!debug
->buffer
) {
2365 debug
->len
= lpfc_debugfs_dumpHostSlim_data(phba
, debug
->buffer
,
2366 LPFC_DUMPHOSTSLIM_SIZE
);
2367 file
->private_data
= debug
;
2375 lpfc_debugfs_dif_err_read(struct file
*file
, char __user
*buf
,
2376 size_t nbytes
, loff_t
*ppos
)
2378 struct dentry
*dent
= file
->f_path
.dentry
;
2379 struct lpfc_hba
*phba
= file
->private_data
;
2384 if (dent
== phba
->debug_writeGuard
)
2385 cnt
= scnprintf(cbuf
, 32, "%u\n", phba
->lpfc_injerr_wgrd_cnt
);
2386 else if (dent
== phba
->debug_writeApp
)
2387 cnt
= scnprintf(cbuf
, 32, "%u\n", phba
->lpfc_injerr_wapp_cnt
);
2388 else if (dent
== phba
->debug_writeRef
)
2389 cnt
= scnprintf(cbuf
, 32, "%u\n", phba
->lpfc_injerr_wref_cnt
);
2390 else if (dent
== phba
->debug_readGuard
)
2391 cnt
= scnprintf(cbuf
, 32, "%u\n", phba
->lpfc_injerr_rgrd_cnt
);
2392 else if (dent
== phba
->debug_readApp
)
2393 cnt
= scnprintf(cbuf
, 32, "%u\n", phba
->lpfc_injerr_rapp_cnt
);
2394 else if (dent
== phba
->debug_readRef
)
2395 cnt
= scnprintf(cbuf
, 32, "%u\n", phba
->lpfc_injerr_rref_cnt
);
2396 else if (dent
== phba
->debug_InjErrNPortID
)
2397 cnt
= scnprintf(cbuf
, 32, "0x%06x\n",
2398 phba
->lpfc_injerr_nportid
);
2399 else if (dent
== phba
->debug_InjErrWWPN
) {
2400 memcpy(&tmp
, &phba
->lpfc_injerr_wwpn
, sizeof(struct lpfc_name
));
2401 tmp
= cpu_to_be64(tmp
);
2402 cnt
= scnprintf(cbuf
, 32, "0x%016llx\n", tmp
);
2403 } else if (dent
== phba
->debug_InjErrLBA
) {
2404 if (phba
->lpfc_injerr_lba
== (sector_t
)(-1))
2405 cnt
= scnprintf(cbuf
, 32, "off\n");
2407 cnt
= scnprintf(cbuf
, 32, "0x%llx\n",
2408 (uint64_t) phba
->lpfc_injerr_lba
);
2410 lpfc_printf_log(phba
, KERN_ERR
, LOG_INIT
,
2411 "0547 Unknown debugfs error injection entry\n");
2413 return simple_read_from_buffer(buf
, nbytes
, ppos
, &cbuf
, cnt
);
2417 lpfc_debugfs_dif_err_write(struct file
*file
, const char __user
*buf
,
2418 size_t nbytes
, loff_t
*ppos
)
2420 struct dentry
*dent
= file
->f_path
.dentry
;
2421 struct lpfc_hba
*phba
= file
->private_data
;
2426 memset(dstbuf
, 0, 33);
2427 size
= (nbytes
< 32) ? nbytes
: 32;
2428 if (copy_from_user(dstbuf
, buf
, size
))
2431 if (dent
== phba
->debug_InjErrLBA
) {
2432 if ((dstbuf
[0] == 'o') && (dstbuf
[1] == 'f') &&
2434 tmp
= (uint64_t)(-1);
2437 if ((tmp
== 0) && (kstrtoull(dstbuf
, 0, &tmp
)))
2440 if (dent
== phba
->debug_writeGuard
)
2441 phba
->lpfc_injerr_wgrd_cnt
= (uint32_t)tmp
;
2442 else if (dent
== phba
->debug_writeApp
)
2443 phba
->lpfc_injerr_wapp_cnt
= (uint32_t)tmp
;
2444 else if (dent
== phba
->debug_writeRef
)
2445 phba
->lpfc_injerr_wref_cnt
= (uint32_t)tmp
;
2446 else if (dent
== phba
->debug_readGuard
)
2447 phba
->lpfc_injerr_rgrd_cnt
= (uint32_t)tmp
;
2448 else if (dent
== phba
->debug_readApp
)
2449 phba
->lpfc_injerr_rapp_cnt
= (uint32_t)tmp
;
2450 else if (dent
== phba
->debug_readRef
)
2451 phba
->lpfc_injerr_rref_cnt
= (uint32_t)tmp
;
2452 else if (dent
== phba
->debug_InjErrLBA
)
2453 phba
->lpfc_injerr_lba
= (sector_t
)tmp
;
2454 else if (dent
== phba
->debug_InjErrNPortID
)
2455 phba
->lpfc_injerr_nportid
= (uint32_t)(tmp
& Mask_DID
);
2456 else if (dent
== phba
->debug_InjErrWWPN
) {
2457 tmp
= cpu_to_be64(tmp
);
2458 memcpy(&phba
->lpfc_injerr_wwpn
, &tmp
, sizeof(struct lpfc_name
));
2460 lpfc_printf_log(phba
, KERN_ERR
, LOG_INIT
,
2461 "0548 Unknown debugfs error injection entry\n");
2467 lpfc_debugfs_dif_err_release(struct inode
*inode
, struct file
*file
)
2473 * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file
2474 * @inode: The inode pointer that contains a vport pointer.
2475 * @file: The file pointer to attach the log output.
2478 * This routine is the entry point for the debugfs open file operation. It gets
2479 * the vport from the i_private field in @inode, allocates the necessary buffer
2480 * for the log, fills the buffer from the in-memory log for this vport, and then
2481 * returns a pointer to that log in the private_data field in @file.
2484 * This function returns zero if successful. On error it will return a negative
2488 lpfc_debugfs_nodelist_open(struct inode
*inode
, struct file
*file
)
2490 struct lpfc_vport
*vport
= inode
->i_private
;
2491 struct lpfc_debug
*debug
;
2494 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
2498 /* Round to page boundary */
2499 debug
->buffer
= kmalloc(LPFC_NODELIST_SIZE
, GFP_KERNEL
);
2500 if (!debug
->buffer
) {
2505 debug
->len
= lpfc_debugfs_nodelist_data(vport
, debug
->buffer
,
2506 LPFC_NODELIST_SIZE
);
2507 file
->private_data
= debug
;
2515 * lpfc_debugfs_lseek - Seek through a debugfs file
2516 * @file: The file pointer to seek through.
2517 * @off: The offset to seek to or the amount to seek by.
2518 * @whence: Indicates how to seek.
2521 * This routine is the entry point for the debugfs lseek file operation. The
2522 * @whence parameter indicates whether @off is the offset to directly seek to,
2523 * or if it is a value to seek forward or reverse by. This function figures out
2524 * what the new offset of the debugfs file will be and assigns that value to the
2525 * f_pos field of @file.
2528 * This function returns the new offset if successful and returns a negative
2529 * error if unable to process the seek.
2532 lpfc_debugfs_lseek(struct file
*file
, loff_t off
, int whence
)
2534 struct lpfc_debug
*debug
= file
->private_data
;
2535 return fixed_size_llseek(file
, off
, whence
, debug
->len
);
2539 * lpfc_debugfs_read - Read a debugfs file
2540 * @file: The file pointer to read from.
2541 * @buf: The buffer to copy the data to.
2542 * @nbytes: The number of bytes to read.
2543 * @ppos: The position in the file to start reading from.
2546 * This routine reads data from from the buffer indicated in the private_data
2547 * field of @file. It will start reading at @ppos and copy up to @nbytes of
2551 * This function returns the amount of data that was read (this could be less
2552 * than @nbytes if the end of the file was reached) or a negative error value.
2555 lpfc_debugfs_read(struct file
*file
, char __user
*buf
,
2556 size_t nbytes
, loff_t
*ppos
)
2558 struct lpfc_debug
*debug
= file
->private_data
;
2560 return simple_read_from_buffer(buf
, nbytes
, ppos
, debug
->buffer
,
2565 * lpfc_debugfs_release - Release the buffer used to store debugfs file data
2566 * @inode: The inode pointer that contains a vport pointer. (unused)
2567 * @file: The file pointer that contains the buffer to release.
2570 * This routine frees the buffer that was allocated when the debugfs file was
2574 * This function returns zero.
2577 lpfc_debugfs_release(struct inode
*inode
, struct file
*file
)
2579 struct lpfc_debug
*debug
= file
->private_data
;
2581 kfree(debug
->buffer
);
2588 * lpfc_debugfs_multixripools_write - Clear multi-XRI pools statistics
2589 * @file: The file pointer to read from.
2590 * @buf: The buffer to copy the user data from.
2591 * @nbytes: The number of bytes to get.
2592 * @ppos: The position in the file to start reading from.
2595 * This routine clears multi-XRI pools statistics when buf contains "clear".
2598 * It returns the @nbytges passing in from debugfs user space when successful.
2599 * In case of error conditions, it returns proper error code back to the user
2603 lpfc_debugfs_multixripools_write(struct file
*file
, const char __user
*buf
,
2604 size_t nbytes
, loff_t
*ppos
)
2606 struct lpfc_debug
*debug
= file
->private_data
;
2607 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
2612 struct lpfc_sli4_hdw_queue
*qp
;
2613 struct lpfc_multixri_pool
*multixri_pool
;
2615 if (nbytes
> sizeof(mybuf
) - 1)
2616 nbytes
= sizeof(mybuf
) - 1;
2618 memset(mybuf
, 0, sizeof(mybuf
));
2620 if (copy_from_user(mybuf
, buf
, nbytes
))
2624 if ((strncmp(pbuf
, "clear", strlen("clear"))) == 0) {
2625 hwq_count
= phba
->cfg_hdw_queue
;
2626 for (i
= 0; i
< hwq_count
; i
++) {
2627 qp
= &phba
->sli4_hba
.hdwq
[i
];
2628 multixri_pool
= qp
->p_multixri_pool
;
2632 qp
->empty_io_bufs
= 0;
2633 multixri_pool
->pbl_empty_count
= 0;
2634 #ifdef LPFC_MXP_STAT
2635 multixri_pool
->above_limit_count
= 0;
2636 multixri_pool
->below_limit_count
= 0;
2637 multixri_pool
->stat_max_hwm
= 0;
2638 multixri_pool
->local_pbl_hit_count
= 0;
2639 multixri_pool
->other_pbl_hit_count
= 0;
2641 multixri_pool
->stat_pbl_count
= 0;
2642 multixri_pool
->stat_pvt_count
= 0;
2643 multixri_pool
->stat_busy_count
= 0;
2644 multixri_pool
->stat_snapshot_taken
= 0;
2647 return strlen(pbuf
);
2654 lpfc_debugfs_nvmestat_open(struct inode
*inode
, struct file
*file
)
2656 struct lpfc_vport
*vport
= inode
->i_private
;
2657 struct lpfc_debug
*debug
;
2660 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
2664 /* Round to page boundary */
2665 debug
->buffer
= kmalloc(LPFC_NVMESTAT_SIZE
, GFP_KERNEL
);
2666 if (!debug
->buffer
) {
2671 debug
->len
= lpfc_debugfs_nvmestat_data(vport
, debug
->buffer
,
2672 LPFC_NVMESTAT_SIZE
);
2674 debug
->i_private
= inode
->i_private
;
2675 file
->private_data
= debug
;
2683 lpfc_debugfs_nvmestat_write(struct file
*file
, const char __user
*buf
,
2684 size_t nbytes
, loff_t
*ppos
)
2686 struct lpfc_debug
*debug
= file
->private_data
;
2687 struct lpfc_vport
*vport
= (struct lpfc_vport
*)debug
->i_private
;
2688 struct lpfc_hba
*phba
= vport
->phba
;
2689 struct lpfc_nvmet_tgtport
*tgtp
;
2693 if (!phba
->targetport
)
2696 if (nbytes
> sizeof(mybuf
) - 1)
2697 nbytes
= sizeof(mybuf
) - 1;
2699 memset(mybuf
, 0, sizeof(mybuf
));
2701 if (copy_from_user(mybuf
, buf
, nbytes
))
2705 tgtp
= (struct lpfc_nvmet_tgtport
*)phba
->targetport
->private;
2706 if ((strncmp(pbuf
, "reset", strlen("reset")) == 0) ||
2707 (strncmp(pbuf
, "zero", strlen("zero")) == 0)) {
2708 atomic_set(&tgtp
->rcv_ls_req_in
, 0);
2709 atomic_set(&tgtp
->rcv_ls_req_out
, 0);
2710 atomic_set(&tgtp
->rcv_ls_req_drop
, 0);
2711 atomic_set(&tgtp
->xmt_ls_abort
, 0);
2712 atomic_set(&tgtp
->xmt_ls_abort_cmpl
, 0);
2713 atomic_set(&tgtp
->xmt_ls_rsp
, 0);
2714 atomic_set(&tgtp
->xmt_ls_drop
, 0);
2715 atomic_set(&tgtp
->xmt_ls_rsp_error
, 0);
2716 atomic_set(&tgtp
->xmt_ls_rsp_cmpl
, 0);
2718 atomic_set(&tgtp
->rcv_fcp_cmd_in
, 0);
2719 atomic_set(&tgtp
->rcv_fcp_cmd_out
, 0);
2720 atomic_set(&tgtp
->rcv_fcp_cmd_drop
, 0);
2721 atomic_set(&tgtp
->xmt_fcp_drop
, 0);
2722 atomic_set(&tgtp
->xmt_fcp_read_rsp
, 0);
2723 atomic_set(&tgtp
->xmt_fcp_read
, 0);
2724 atomic_set(&tgtp
->xmt_fcp_write
, 0);
2725 atomic_set(&tgtp
->xmt_fcp_rsp
, 0);
2726 atomic_set(&tgtp
->xmt_fcp_release
, 0);
2727 atomic_set(&tgtp
->xmt_fcp_rsp_cmpl
, 0);
2728 atomic_set(&tgtp
->xmt_fcp_rsp_error
, 0);
2729 atomic_set(&tgtp
->xmt_fcp_rsp_drop
, 0);
2731 atomic_set(&tgtp
->xmt_fcp_abort
, 0);
2732 atomic_set(&tgtp
->xmt_fcp_abort_cmpl
, 0);
2733 atomic_set(&tgtp
->xmt_abort_sol
, 0);
2734 atomic_set(&tgtp
->xmt_abort_unsol
, 0);
2735 atomic_set(&tgtp
->xmt_abort_rsp
, 0);
2736 atomic_set(&tgtp
->xmt_abort_rsp_error
, 0);
2742 lpfc_debugfs_scsistat_open(struct inode
*inode
, struct file
*file
)
2744 struct lpfc_vport
*vport
= inode
->i_private
;
2745 struct lpfc_debug
*debug
;
2748 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
2752 /* Round to page boundary */
2753 debug
->buffer
= kzalloc(LPFC_SCSISTAT_SIZE
, GFP_KERNEL
);
2754 if (!debug
->buffer
) {
2759 debug
->len
= lpfc_debugfs_scsistat_data(vport
, debug
->buffer
,
2760 LPFC_SCSISTAT_SIZE
);
2762 debug
->i_private
= inode
->i_private
;
2763 file
->private_data
= debug
;
2771 lpfc_debugfs_scsistat_write(struct file
*file
, const char __user
*buf
,
2772 size_t nbytes
, loff_t
*ppos
)
2774 struct lpfc_debug
*debug
= file
->private_data
;
2775 struct lpfc_vport
*vport
= (struct lpfc_vport
*)debug
->i_private
;
2776 struct lpfc_hba
*phba
= vport
->phba
;
2777 char mybuf
[6] = {0};
2780 if (copy_from_user(mybuf
, buf
, (nbytes
>= sizeof(mybuf
)) ?
2781 (sizeof(mybuf
) - 1) : nbytes
))
2784 if ((strncmp(&mybuf
[0], "reset", strlen("reset")) == 0) ||
2785 (strncmp(&mybuf
[0], "zero", strlen("zero")) == 0)) {
2786 for (i
= 0; i
< phba
->cfg_hdw_queue
; i
++) {
2787 memset(&phba
->sli4_hba
.hdwq
[i
].scsi_cstat
, 0,
2788 sizeof(phba
->sli4_hba
.hdwq
[i
].scsi_cstat
));
2796 lpfc_debugfs_ioktime_open(struct inode
*inode
, struct file
*file
)
2798 struct lpfc_vport
*vport
= inode
->i_private
;
2799 struct lpfc_debug
*debug
;
2802 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
2806 /* Round to page boundary */
2807 debug
->buffer
= kmalloc(LPFC_IOKTIME_SIZE
, GFP_KERNEL
);
2808 if (!debug
->buffer
) {
2813 debug
->len
= lpfc_debugfs_ioktime_data(vport
, debug
->buffer
,
2816 debug
->i_private
= inode
->i_private
;
2817 file
->private_data
= debug
;
2825 lpfc_debugfs_ioktime_write(struct file
*file
, const char __user
*buf
,
2826 size_t nbytes
, loff_t
*ppos
)
2828 struct lpfc_debug
*debug
= file
->private_data
;
2829 struct lpfc_vport
*vport
= (struct lpfc_vport
*)debug
->i_private
;
2830 struct lpfc_hba
*phba
= vport
->phba
;
2834 if (nbytes
> sizeof(mybuf
) - 1)
2835 nbytes
= sizeof(mybuf
) - 1;
2837 memset(mybuf
, 0, sizeof(mybuf
));
2839 if (copy_from_user(mybuf
, buf
, nbytes
))
2843 if ((strncmp(pbuf
, "on", sizeof("on") - 1) == 0)) {
2844 phba
->ktime_data_samples
= 0;
2845 phba
->ktime_status_samples
= 0;
2846 phba
->ktime_seg1_total
= 0;
2847 phba
->ktime_seg1_max
= 0;
2848 phba
->ktime_seg1_min
= 0xffffffff;
2849 phba
->ktime_seg2_total
= 0;
2850 phba
->ktime_seg2_max
= 0;
2851 phba
->ktime_seg2_min
= 0xffffffff;
2852 phba
->ktime_seg3_total
= 0;
2853 phba
->ktime_seg3_max
= 0;
2854 phba
->ktime_seg3_min
= 0xffffffff;
2855 phba
->ktime_seg4_total
= 0;
2856 phba
->ktime_seg4_max
= 0;
2857 phba
->ktime_seg4_min
= 0xffffffff;
2858 phba
->ktime_seg5_total
= 0;
2859 phba
->ktime_seg5_max
= 0;
2860 phba
->ktime_seg5_min
= 0xffffffff;
2861 phba
->ktime_seg6_total
= 0;
2862 phba
->ktime_seg6_max
= 0;
2863 phba
->ktime_seg6_min
= 0xffffffff;
2864 phba
->ktime_seg7_total
= 0;
2865 phba
->ktime_seg7_max
= 0;
2866 phba
->ktime_seg7_min
= 0xffffffff;
2867 phba
->ktime_seg8_total
= 0;
2868 phba
->ktime_seg8_max
= 0;
2869 phba
->ktime_seg8_min
= 0xffffffff;
2870 phba
->ktime_seg9_total
= 0;
2871 phba
->ktime_seg9_max
= 0;
2872 phba
->ktime_seg9_min
= 0xffffffff;
2873 phba
->ktime_seg10_total
= 0;
2874 phba
->ktime_seg10_max
= 0;
2875 phba
->ktime_seg10_min
= 0xffffffff;
2878 return strlen(pbuf
);
2879 } else if ((strncmp(pbuf
, "off",
2880 sizeof("off") - 1) == 0)) {
2882 return strlen(pbuf
);
2883 } else if ((strncmp(pbuf
, "zero",
2884 sizeof("zero") - 1) == 0)) {
2885 phba
->ktime_data_samples
= 0;
2886 phba
->ktime_status_samples
= 0;
2887 phba
->ktime_seg1_total
= 0;
2888 phba
->ktime_seg1_max
= 0;
2889 phba
->ktime_seg1_min
= 0xffffffff;
2890 phba
->ktime_seg2_total
= 0;
2891 phba
->ktime_seg2_max
= 0;
2892 phba
->ktime_seg2_min
= 0xffffffff;
2893 phba
->ktime_seg3_total
= 0;
2894 phba
->ktime_seg3_max
= 0;
2895 phba
->ktime_seg3_min
= 0xffffffff;
2896 phba
->ktime_seg4_total
= 0;
2897 phba
->ktime_seg4_max
= 0;
2898 phba
->ktime_seg4_min
= 0xffffffff;
2899 phba
->ktime_seg5_total
= 0;
2900 phba
->ktime_seg5_max
= 0;
2901 phba
->ktime_seg5_min
= 0xffffffff;
2902 phba
->ktime_seg6_total
= 0;
2903 phba
->ktime_seg6_max
= 0;
2904 phba
->ktime_seg6_min
= 0xffffffff;
2905 phba
->ktime_seg7_total
= 0;
2906 phba
->ktime_seg7_max
= 0;
2907 phba
->ktime_seg7_min
= 0xffffffff;
2908 phba
->ktime_seg8_total
= 0;
2909 phba
->ktime_seg8_max
= 0;
2910 phba
->ktime_seg8_min
= 0xffffffff;
2911 phba
->ktime_seg9_total
= 0;
2912 phba
->ktime_seg9_max
= 0;
2913 phba
->ktime_seg9_min
= 0xffffffff;
2914 phba
->ktime_seg10_total
= 0;
2915 phba
->ktime_seg10_max
= 0;
2916 phba
->ktime_seg10_min
= 0xffffffff;
2917 return strlen(pbuf
);
2923 lpfc_debugfs_nvmeio_trc_open(struct inode
*inode
, struct file
*file
)
2925 struct lpfc_hba
*phba
= inode
->i_private
;
2926 struct lpfc_debug
*debug
;
2929 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
2933 /* Round to page boundary */
2934 debug
->buffer
= kmalloc(LPFC_NVMEIO_TRC_SIZE
, GFP_KERNEL
);
2935 if (!debug
->buffer
) {
2940 debug
->len
= lpfc_debugfs_nvmeio_trc_data(phba
, debug
->buffer
,
2941 LPFC_NVMEIO_TRC_SIZE
);
2943 debug
->i_private
= inode
->i_private
;
2944 file
->private_data
= debug
;
2952 lpfc_debugfs_nvmeio_trc_write(struct file
*file
, const char __user
*buf
,
2953 size_t nbytes
, loff_t
*ppos
)
2955 struct lpfc_debug
*debug
= file
->private_data
;
2956 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
2962 if (nbytes
> sizeof(mybuf
) - 1)
2963 nbytes
= sizeof(mybuf
) - 1;
2965 memset(mybuf
, 0, sizeof(mybuf
));
2967 if (copy_from_user(mybuf
, buf
, nbytes
))
2971 if ((strncmp(pbuf
, "off", sizeof("off") - 1) == 0)) {
2972 lpfc_printf_log(phba
, KERN_ERR
, LOG_INIT
,
2973 "0570 nvmeio_trc_off\n");
2974 phba
->nvmeio_trc_output_idx
= 0;
2975 phba
->nvmeio_trc_on
= 0;
2976 return strlen(pbuf
);
2977 } else if ((strncmp(pbuf
, "on", sizeof("on") - 1) == 0)) {
2978 lpfc_printf_log(phba
, KERN_ERR
, LOG_INIT
,
2979 "0571 nvmeio_trc_on\n");
2980 phba
->nvmeio_trc_output_idx
= 0;
2981 phba
->nvmeio_trc_on
= 1;
2982 return strlen(pbuf
);
2985 /* We must be off to allocate the trace buffer */
2986 if (phba
->nvmeio_trc_on
!= 0)
2989 /* If not on or off, the parameter is the trace buffer size */
2990 i
= kstrtoul(pbuf
, 0, &sz
);
2993 phba
->nvmeio_trc_size
= (uint32_t)sz
;
2995 /* It must be a power of 2 - round down */
3002 if (phba
->nvmeio_trc_size
!= sz
)
3003 lpfc_printf_log(phba
, KERN_ERR
, LOG_INIT
,
3004 "0572 nvmeio_trc_size changed to %ld\n",
3006 phba
->nvmeio_trc_size
= (uint32_t)sz
;
3008 /* If one previously exists, free it */
3009 kfree(phba
->nvmeio_trc
);
3011 /* Allocate new trace buffer and initialize */
3012 phba
->nvmeio_trc
= kzalloc((sizeof(struct lpfc_debugfs_nvmeio_trc
) *
3014 if (!phba
->nvmeio_trc
) {
3015 lpfc_printf_log(phba
, KERN_ERR
, LOG_INIT
,
3016 "0573 Cannot create debugfs "
3017 "nvmeio_trc buffer\n");
3020 atomic_set(&phba
->nvmeio_trc_cnt
, 0);
3021 phba
->nvmeio_trc_on
= 0;
3022 phba
->nvmeio_trc_output_idx
= 0;
3024 return strlen(pbuf
);
3028 lpfc_debugfs_hdwqstat_open(struct inode
*inode
, struct file
*file
)
3030 struct lpfc_vport
*vport
= inode
->i_private
;
3031 struct lpfc_debug
*debug
;
3034 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
3038 /* Round to page boundary */
3039 debug
->buffer
= kcalloc(1, LPFC_SCSISTAT_SIZE
, GFP_KERNEL
);
3040 if (!debug
->buffer
) {
3045 debug
->len
= lpfc_debugfs_hdwqstat_data(vport
, debug
->buffer
,
3046 LPFC_SCSISTAT_SIZE
);
3048 debug
->i_private
= inode
->i_private
;
3049 file
->private_data
= debug
;
3057 lpfc_debugfs_hdwqstat_write(struct file
*file
, const char __user
*buf
,
3058 size_t nbytes
, loff_t
*ppos
)
3060 struct lpfc_debug
*debug
= file
->private_data
;
3061 struct lpfc_vport
*vport
= (struct lpfc_vport
*)debug
->i_private
;
3062 struct lpfc_hba
*phba
= vport
->phba
;
3063 struct lpfc_hdwq_stat
*c_stat
;
3068 if (nbytes
> sizeof(mybuf
) - 1)
3069 nbytes
= sizeof(mybuf
) - 1;
3071 memset(mybuf
, 0, sizeof(mybuf
));
3073 if (copy_from_user(mybuf
, buf
, nbytes
))
3077 if ((strncmp(pbuf
, "on", sizeof("on") - 1) == 0)) {
3078 if (phba
->nvmet_support
)
3079 phba
->hdwqstat_on
|= LPFC_CHECK_NVMET_IO
;
3081 phba
->hdwqstat_on
|= (LPFC_CHECK_NVME_IO
|
3082 LPFC_CHECK_SCSI_IO
);
3083 return strlen(pbuf
);
3084 } else if ((strncmp(pbuf
, "nvme_on", sizeof("nvme_on") - 1) == 0)) {
3085 if (phba
->nvmet_support
)
3086 phba
->hdwqstat_on
|= LPFC_CHECK_NVMET_IO
;
3088 phba
->hdwqstat_on
|= LPFC_CHECK_NVME_IO
;
3089 return strlen(pbuf
);
3090 } else if ((strncmp(pbuf
, "scsi_on", sizeof("scsi_on") - 1) == 0)) {
3091 if (!phba
->nvmet_support
)
3092 phba
->hdwqstat_on
|= LPFC_CHECK_SCSI_IO
;
3093 return strlen(pbuf
);
3094 } else if ((strncmp(pbuf
, "nvme_off", sizeof("nvme_off") - 1) == 0)) {
3095 phba
->hdwqstat_on
&= ~(LPFC_CHECK_NVME_IO
|
3096 LPFC_CHECK_NVMET_IO
);
3097 return strlen(pbuf
);
3098 } else if ((strncmp(pbuf
, "scsi_off", sizeof("scsi_off") - 1) == 0)) {
3099 phba
->hdwqstat_on
&= ~LPFC_CHECK_SCSI_IO
;
3100 return strlen(pbuf
);
3101 } else if ((strncmp(pbuf
, "off",
3102 sizeof("off") - 1) == 0)) {
3103 phba
->hdwqstat_on
= LPFC_CHECK_OFF
;
3104 return strlen(pbuf
);
3105 } else if ((strncmp(pbuf
, "zero",
3106 sizeof("zero") - 1) == 0)) {
3107 for_each_present_cpu(i
) {
3108 c_stat
= per_cpu_ptr(phba
->sli4_hba
.c_stat
, i
);
3110 c_stat
->cmpl_io
= 0;
3113 return strlen(pbuf
);
3119 * ---------------------------------
3120 * iDiag debugfs file access methods
3121 * ---------------------------------
3123 * All access methods are through the proper SLI4 PCI function's debugfs
3126 * /sys/kernel/debug/lpfc/fn<#>/iDiag
3130 * lpfc_idiag_cmd_get - Get and parse idiag debugfs comands from user space
3131 * @buf: The pointer to the user space buffer.
3132 * @nbytes: The number of bytes in the user space buffer.
3133 * @idiag_cmd: pointer to the idiag command struct.
3135 * This routine reads data from debugfs user space buffer and parses the
3136 * buffer for getting the idiag command and arguments. The while space in
3137 * between the set of data is used as the parsing separator.
3139 * This routine returns 0 when successful, it returns proper error code
3140 * back to the user space in error conditions.
3142 static int lpfc_idiag_cmd_get(const char __user
*buf
, size_t nbytes
,
3143 struct lpfc_idiag_cmd
*idiag_cmd
)
3146 char *pbuf
, *step_str
;
3150 memset(mybuf
, 0, sizeof(mybuf
));
3151 memset(idiag_cmd
, 0, sizeof(*idiag_cmd
));
3152 bsize
= min(nbytes
, (sizeof(mybuf
)-1));
3154 if (copy_from_user(mybuf
, buf
, bsize
))
3157 step_str
= strsep(&pbuf
, "\t ");
3159 /* The opcode must present */
3163 idiag_cmd
->opcode
= simple_strtol(step_str
, NULL
, 0);
3164 if (idiag_cmd
->opcode
== 0)
3167 for (i
= 0; i
< LPFC_IDIAG_CMD_DATA_SIZE
; i
++) {
3168 step_str
= strsep(&pbuf
, "\t ");
3171 idiag_cmd
->data
[i
] = simple_strtol(step_str
, NULL
, 0);
3177 * lpfc_idiag_open - idiag open debugfs
3178 * @inode: The inode pointer that contains a pointer to phba.
3179 * @file: The file pointer to attach the file operation.
3182 * This routine is the entry point for the debugfs open file operation. It
3183 * gets the reference to phba from the i_private field in @inode, it then
3184 * allocates buffer for the file operation, performs the necessary PCI config
3185 * space read into the allocated buffer according to the idiag user command
3186 * setup, and then returns a pointer to buffer in the private_data field in
3190 * This function returns zero if successful. On error it will return an
3191 * negative error value.
3194 lpfc_idiag_open(struct inode
*inode
, struct file
*file
)
3196 struct lpfc_debug
*debug
;
3198 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
3202 debug
->i_private
= inode
->i_private
;
3203 debug
->buffer
= NULL
;
3204 file
->private_data
= debug
;
3210 * lpfc_idiag_release - Release idiag access file operation
3211 * @inode: The inode pointer that contains a vport pointer. (unused)
3212 * @file: The file pointer that contains the buffer to release.
3215 * This routine is the generic release routine for the idiag access file
3216 * operation, it frees the buffer that was allocated when the debugfs file
3220 * This function returns zero.
3223 lpfc_idiag_release(struct inode
*inode
, struct file
*file
)
3225 struct lpfc_debug
*debug
= file
->private_data
;
3227 /* Free the buffers to the file operation */
3228 kfree(debug
->buffer
);
3235 * lpfc_idiag_cmd_release - Release idiag cmd access file operation
3236 * @inode: The inode pointer that contains a vport pointer. (unused)
3237 * @file: The file pointer that contains the buffer to release.
3240 * This routine frees the buffer that was allocated when the debugfs file
3241 * was opened. It also reset the fields in the idiag command struct in the
3242 * case of command for write operation.
3245 * This function returns zero.
3248 lpfc_idiag_cmd_release(struct inode
*inode
, struct file
*file
)
3250 struct lpfc_debug
*debug
= file
->private_data
;
3252 if (debug
->op
== LPFC_IDIAG_OP_WR
) {
3253 switch (idiag
.cmd
.opcode
) {
3254 case LPFC_IDIAG_CMD_PCICFG_WR
:
3255 case LPFC_IDIAG_CMD_PCICFG_ST
:
3256 case LPFC_IDIAG_CMD_PCICFG_CL
:
3257 case LPFC_IDIAG_CMD_QUEACC_WR
:
3258 case LPFC_IDIAG_CMD_QUEACC_ST
:
3259 case LPFC_IDIAG_CMD_QUEACC_CL
:
3260 memset(&idiag
, 0, sizeof(idiag
));
3267 /* Free the buffers to the file operation */
3268 kfree(debug
->buffer
);
3275 * lpfc_idiag_pcicfg_read - idiag debugfs read pcicfg
3276 * @file: The file pointer to read from.
3277 * @buf: The buffer to copy the data to.
3278 * @nbytes: The number of bytes to read.
3279 * @ppos: The position in the file to start reading from.
3282 * This routine reads data from the @phba pci config space according to the
3283 * idiag command, and copies to user @buf. Depending on the PCI config space
3284 * read command setup, it does either a single register read of a byte
3285 * (8 bits), a word (16 bits), or a dword (32 bits) or browsing through all
3286 * registers from the 4K extended PCI config space.
3289 * This function returns the amount of data that was read (this could be less
3290 * than @nbytes if the end of the file was reached) or a negative error value.
3293 lpfc_idiag_pcicfg_read(struct file
*file
, char __user
*buf
, size_t nbytes
,
3296 struct lpfc_debug
*debug
= file
->private_data
;
3297 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
3298 int offset_label
, offset
, len
= 0, index
= LPFC_PCI_CFG_RD_SIZE
;
3301 struct pci_dev
*pdev
;
3306 pdev
= phba
->pcidev
;
3310 /* This is a user read operation */
3311 debug
->op
= LPFC_IDIAG_OP_RD
;
3314 debug
->buffer
= kmalloc(LPFC_PCI_CFG_SIZE
, GFP_KERNEL
);
3317 pbuffer
= debug
->buffer
;
3322 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_RD
) {
3323 where
= idiag
.cmd
.data
[IDIAG_PCICFG_WHERE_INDX
];
3324 count
= idiag
.cmd
.data
[IDIAG_PCICFG_COUNT_INDX
];
3328 /* Read single PCI config space register */
3330 case SIZE_U8
: /* byte (8 bits) */
3331 pci_read_config_byte(pdev
, where
, &u8val
);
3332 len
+= scnprintf(pbuffer
+len
, LPFC_PCI_CFG_SIZE
-len
,
3333 "%03x: %02x\n", where
, u8val
);
3335 case SIZE_U16
: /* word (16 bits) */
3336 pci_read_config_word(pdev
, where
, &u16val
);
3337 len
+= scnprintf(pbuffer
+len
, LPFC_PCI_CFG_SIZE
-len
,
3338 "%03x: %04x\n", where
, u16val
);
3340 case SIZE_U32
: /* double word (32 bits) */
3341 pci_read_config_dword(pdev
, where
, &u32val
);
3342 len
+= scnprintf(pbuffer
+len
, LPFC_PCI_CFG_SIZE
-len
,
3343 "%03x: %08x\n", where
, u32val
);
3345 case LPFC_PCI_CFG_BROWSE
: /* browse all */
3352 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
3356 /* Browse all PCI config space registers */
3357 offset_label
= idiag
.offset
.last_rd
;
3358 offset
= offset_label
;
3360 /* Read PCI config space */
3361 len
+= scnprintf(pbuffer
+len
, LPFC_PCI_CFG_SIZE
-len
,
3362 "%03x: ", offset_label
);
3364 pci_read_config_dword(pdev
, offset
, &u32val
);
3365 len
+= scnprintf(pbuffer
+len
, LPFC_PCI_CFG_SIZE
-len
,
3367 offset
+= sizeof(uint32_t);
3368 if (offset
>= LPFC_PCI_CFG_SIZE
) {
3369 len
+= scnprintf(pbuffer
+len
,
3370 LPFC_PCI_CFG_SIZE
-len
, "\n");
3373 index
-= sizeof(uint32_t);
3375 len
+= scnprintf(pbuffer
+len
, LPFC_PCI_CFG_SIZE
-len
,
3377 else if (!(index
% (8 * sizeof(uint32_t)))) {
3378 offset_label
+= (8 * sizeof(uint32_t));
3379 len
+= scnprintf(pbuffer
+len
, LPFC_PCI_CFG_SIZE
-len
,
3380 "\n%03x: ", offset_label
);
3384 /* Set up the offset for next portion of pci cfg read */
3386 idiag
.offset
.last_rd
+= LPFC_PCI_CFG_RD_SIZE
;
3387 if (idiag
.offset
.last_rd
>= LPFC_PCI_CFG_SIZE
)
3388 idiag
.offset
.last_rd
= 0;
3390 idiag
.offset
.last_rd
= 0;
3392 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
3396 * lpfc_idiag_pcicfg_write - Syntax check and set up idiag pcicfg commands
3397 * @file: The file pointer to read from.
3398 * @buf: The buffer to copy the user data from.
3399 * @nbytes: The number of bytes to get.
3400 * @ppos: The position in the file to start reading from.
3402 * This routine get the debugfs idiag command struct from user space and
3403 * then perform the syntax check for PCI config space read or write command
3404 * accordingly. In the case of PCI config space read command, it sets up
3405 * the command in the idiag command struct for the debugfs read operation.
3406 * In the case of PCI config space write operation, it executes the write
3407 * operation into the PCI config space accordingly.
3409 * It returns the @nbytges passing in from debugfs user space when successful.
3410 * In case of error conditions, it returns proper error code back to the user
3414 lpfc_idiag_pcicfg_write(struct file
*file
, const char __user
*buf
,
3415 size_t nbytes
, loff_t
*ppos
)
3417 struct lpfc_debug
*debug
= file
->private_data
;
3418 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
3419 uint32_t where
, value
, count
;
3423 struct pci_dev
*pdev
;
3426 pdev
= phba
->pcidev
;
3430 /* This is a user write operation */
3431 debug
->op
= LPFC_IDIAG_OP_WR
;
3433 rc
= lpfc_idiag_cmd_get(buf
, nbytes
, &idiag
.cmd
);
3437 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_RD
) {
3438 /* Sanity check on PCI config read command line arguments */
3439 if (rc
!= LPFC_PCI_CFG_RD_CMD_ARG
)
3441 /* Read command from PCI config space, set up command fields */
3442 where
= idiag
.cmd
.data
[IDIAG_PCICFG_WHERE_INDX
];
3443 count
= idiag
.cmd
.data
[IDIAG_PCICFG_COUNT_INDX
];
3444 if (count
== LPFC_PCI_CFG_BROWSE
) {
3445 if (where
% sizeof(uint32_t))
3447 /* Starting offset to browse */
3448 idiag
.offset
.last_rd
= where
;
3449 } else if ((count
!= sizeof(uint8_t)) &&
3450 (count
!= sizeof(uint16_t)) &&
3451 (count
!= sizeof(uint32_t)))
3453 if (count
== sizeof(uint8_t)) {
3454 if (where
> LPFC_PCI_CFG_SIZE
- sizeof(uint8_t))
3456 if (where
% sizeof(uint8_t))
3459 if (count
== sizeof(uint16_t)) {
3460 if (where
> LPFC_PCI_CFG_SIZE
- sizeof(uint16_t))
3462 if (where
% sizeof(uint16_t))
3465 if (count
== sizeof(uint32_t)) {
3466 if (where
> LPFC_PCI_CFG_SIZE
- sizeof(uint32_t))
3468 if (where
% sizeof(uint32_t))
3471 } else if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_WR
||
3472 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_ST
||
3473 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_CL
) {
3474 /* Sanity check on PCI config write command line arguments */
3475 if (rc
!= LPFC_PCI_CFG_WR_CMD_ARG
)
3477 /* Write command to PCI config space, read-modify-write */
3478 where
= idiag
.cmd
.data
[IDIAG_PCICFG_WHERE_INDX
];
3479 count
= idiag
.cmd
.data
[IDIAG_PCICFG_COUNT_INDX
];
3480 value
= idiag
.cmd
.data
[IDIAG_PCICFG_VALUE_INDX
];
3482 if ((count
!= sizeof(uint8_t)) &&
3483 (count
!= sizeof(uint16_t)) &&
3484 (count
!= sizeof(uint32_t)))
3486 if (count
== sizeof(uint8_t)) {
3487 if (where
> LPFC_PCI_CFG_SIZE
- sizeof(uint8_t))
3489 if (where
% sizeof(uint8_t))
3491 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_WR
)
3492 pci_write_config_byte(pdev
, where
,
3494 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_ST
) {
3495 rc
= pci_read_config_byte(pdev
, where
, &u8val
);
3497 u8val
|= (uint8_t)value
;
3498 pci_write_config_byte(pdev
, where
,
3502 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_CL
) {
3503 rc
= pci_read_config_byte(pdev
, where
, &u8val
);
3505 u8val
&= (uint8_t)(~value
);
3506 pci_write_config_byte(pdev
, where
,
3511 if (count
== sizeof(uint16_t)) {
3512 if (where
> LPFC_PCI_CFG_SIZE
- sizeof(uint16_t))
3514 if (where
% sizeof(uint16_t))
3516 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_WR
)
3517 pci_write_config_word(pdev
, where
,
3519 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_ST
) {
3520 rc
= pci_read_config_word(pdev
, where
, &u16val
);
3522 u16val
|= (uint16_t)value
;
3523 pci_write_config_word(pdev
, where
,
3527 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_CL
) {
3528 rc
= pci_read_config_word(pdev
, where
, &u16val
);
3530 u16val
&= (uint16_t)(~value
);
3531 pci_write_config_word(pdev
, where
,
3536 if (count
== sizeof(uint32_t)) {
3537 if (where
> LPFC_PCI_CFG_SIZE
- sizeof(uint32_t))
3539 if (where
% sizeof(uint32_t))
3541 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_WR
)
3542 pci_write_config_dword(pdev
, where
, value
);
3543 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_ST
) {
3544 rc
= pci_read_config_dword(pdev
, where
,
3548 pci_write_config_dword(pdev
, where
,
3552 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_PCICFG_CL
) {
3553 rc
= pci_read_config_dword(pdev
, where
,
3557 pci_write_config_dword(pdev
, where
,
3563 /* All other opecodes are illegal for now */
3568 memset(&idiag
, 0, sizeof(idiag
));
3573 * lpfc_idiag_baracc_read - idiag debugfs pci bar access read
3574 * @file: The file pointer to read from.
3575 * @buf: The buffer to copy the data to.
3576 * @nbytes: The number of bytes to read.
3577 * @ppos: The position in the file to start reading from.
3580 * This routine reads data from the @phba pci bar memory mapped space
3581 * according to the idiag command, and copies to user @buf.
3584 * This function returns the amount of data that was read (this could be less
3585 * than @nbytes if the end of the file was reached) or a negative error value.
3588 lpfc_idiag_baracc_read(struct file
*file
, char __user
*buf
, size_t nbytes
,
3591 struct lpfc_debug
*debug
= file
->private_data
;
3592 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
3593 int offset_label
, offset
, offset_run
, len
= 0, index
;
3594 int bar_num
, acc_range
, bar_size
;
3596 void __iomem
*mem_mapped_bar
;
3598 struct pci_dev
*pdev
;
3601 pdev
= phba
->pcidev
;
3605 /* This is a user read operation */
3606 debug
->op
= LPFC_IDIAG_OP_RD
;
3609 debug
->buffer
= kmalloc(LPFC_PCI_BAR_RD_BUF_SIZE
, GFP_KERNEL
);
3612 pbuffer
= debug
->buffer
;
3617 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_BARACC_RD
) {
3618 bar_num
= idiag
.cmd
.data
[IDIAG_BARACC_BAR_NUM_INDX
];
3619 offset
= idiag
.cmd
.data
[IDIAG_BARACC_OFF_SET_INDX
];
3620 acc_range
= idiag
.cmd
.data
[IDIAG_BARACC_ACC_MOD_INDX
];
3621 bar_size
= idiag
.cmd
.data
[IDIAG_BARACC_BAR_SZE_INDX
];
3628 if_type
= bf_get(lpfc_sli_intf_if_type
, &phba
->sli4_hba
.sli_intf
);
3629 if (if_type
== LPFC_SLI_INTF_IF_TYPE_0
) {
3630 if (bar_num
== IDIAG_BARACC_BAR_0
)
3631 mem_mapped_bar
= phba
->sli4_hba
.conf_regs_memmap_p
;
3632 else if (bar_num
== IDIAG_BARACC_BAR_1
)
3633 mem_mapped_bar
= phba
->sli4_hba
.ctrl_regs_memmap_p
;
3634 else if (bar_num
== IDIAG_BARACC_BAR_2
)
3635 mem_mapped_bar
= phba
->sli4_hba
.drbl_regs_memmap_p
;
3638 } else if (if_type
== LPFC_SLI_INTF_IF_TYPE_2
) {
3639 if (bar_num
== IDIAG_BARACC_BAR_0
)
3640 mem_mapped_bar
= phba
->sli4_hba
.conf_regs_memmap_p
;
3646 /* Read single PCI bar space register */
3647 if (acc_range
== SINGLE_WORD
) {
3648 offset_run
= offset
;
3649 u32val
= readl(mem_mapped_bar
+ offset_run
);
3650 len
+= scnprintf(pbuffer
+len
, LPFC_PCI_BAR_RD_BUF_SIZE
-len
,
3651 "%05x: %08x\n", offset_run
, u32val
);
3655 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
3659 /* Browse all PCI bar space registers */
3660 offset_label
= idiag
.offset
.last_rd
;
3661 offset_run
= offset_label
;
3663 /* Read PCI bar memory mapped space */
3664 len
+= scnprintf(pbuffer
+len
, LPFC_PCI_BAR_RD_BUF_SIZE
-len
,
3665 "%05x: ", offset_label
);
3666 index
= LPFC_PCI_BAR_RD_SIZE
;
3668 u32val
= readl(mem_mapped_bar
+ offset_run
);
3669 len
+= scnprintf(pbuffer
+len
, LPFC_PCI_BAR_RD_BUF_SIZE
-len
,
3671 offset_run
+= sizeof(uint32_t);
3672 if (acc_range
== LPFC_PCI_BAR_BROWSE
) {
3673 if (offset_run
>= bar_size
) {
3674 len
+= scnprintf(pbuffer
+len
,
3675 LPFC_PCI_BAR_RD_BUF_SIZE
-len
, "\n");
3679 if (offset_run
>= offset
+
3680 (acc_range
* sizeof(uint32_t))) {
3681 len
+= scnprintf(pbuffer
+len
,
3682 LPFC_PCI_BAR_RD_BUF_SIZE
-len
, "\n");
3686 index
-= sizeof(uint32_t);
3688 len
+= scnprintf(pbuffer
+len
,
3689 LPFC_PCI_BAR_RD_BUF_SIZE
-len
, "\n");
3690 else if (!(index
% (8 * sizeof(uint32_t)))) {
3691 offset_label
+= (8 * sizeof(uint32_t));
3692 len
+= scnprintf(pbuffer
+len
,
3693 LPFC_PCI_BAR_RD_BUF_SIZE
-len
,
3694 "\n%05x: ", offset_label
);
3698 /* Set up the offset for next portion of pci bar read */
3700 idiag
.offset
.last_rd
+= LPFC_PCI_BAR_RD_SIZE
;
3701 if (acc_range
== LPFC_PCI_BAR_BROWSE
) {
3702 if (idiag
.offset
.last_rd
>= bar_size
)
3703 idiag
.offset
.last_rd
= 0;
3705 if (offset_run
>= offset
+
3706 (acc_range
* sizeof(uint32_t)))
3707 idiag
.offset
.last_rd
= offset
;
3710 if (acc_range
== LPFC_PCI_BAR_BROWSE
)
3711 idiag
.offset
.last_rd
= 0;
3713 idiag
.offset
.last_rd
= offset
;
3716 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
3720 * lpfc_idiag_baracc_write - Syntax check and set up idiag bar access commands
3721 * @file: The file pointer to read from.
3722 * @buf: The buffer to copy the user data from.
3723 * @nbytes: The number of bytes to get.
3724 * @ppos: The position in the file to start reading from.
3726 * This routine get the debugfs idiag command struct from user space and
3727 * then perform the syntax check for PCI bar memory mapped space read or
3728 * write command accordingly. In the case of PCI bar memory mapped space
3729 * read command, it sets up the command in the idiag command struct for
3730 * the debugfs read operation. In the case of PCI bar memorpy mapped space
3731 * write operation, it executes the write operation into the PCI bar memory
3732 * mapped space accordingly.
3734 * It returns the @nbytges passing in from debugfs user space when successful.
3735 * In case of error conditions, it returns proper error code back to the user
3739 lpfc_idiag_baracc_write(struct file
*file
, const char __user
*buf
,
3740 size_t nbytes
, loff_t
*ppos
)
3742 struct lpfc_debug
*debug
= file
->private_data
;
3743 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
3744 uint32_t bar_num
, bar_size
, offset
, value
, acc_range
;
3745 struct pci_dev
*pdev
;
3746 void __iomem
*mem_mapped_bar
;
3751 pdev
= phba
->pcidev
;
3755 /* This is a user write operation */
3756 debug
->op
= LPFC_IDIAG_OP_WR
;
3758 rc
= lpfc_idiag_cmd_get(buf
, nbytes
, &idiag
.cmd
);
3762 if_type
= bf_get(lpfc_sli_intf_if_type
, &phba
->sli4_hba
.sli_intf
);
3763 bar_num
= idiag
.cmd
.data
[IDIAG_BARACC_BAR_NUM_INDX
];
3765 if (if_type
== LPFC_SLI_INTF_IF_TYPE_0
) {
3766 if ((bar_num
!= IDIAG_BARACC_BAR_0
) &&
3767 (bar_num
!= IDIAG_BARACC_BAR_1
) &&
3768 (bar_num
!= IDIAG_BARACC_BAR_2
))
3770 } else if (if_type
== LPFC_SLI_INTF_IF_TYPE_2
) {
3771 if (bar_num
!= IDIAG_BARACC_BAR_0
)
3776 if (if_type
== LPFC_SLI_INTF_IF_TYPE_0
) {
3777 if (bar_num
== IDIAG_BARACC_BAR_0
) {
3778 idiag
.cmd
.data
[IDIAG_BARACC_BAR_SZE_INDX
] =
3779 LPFC_PCI_IF0_BAR0_SIZE
;
3780 mem_mapped_bar
= phba
->sli4_hba
.conf_regs_memmap_p
;
3781 } else if (bar_num
== IDIAG_BARACC_BAR_1
) {
3782 idiag
.cmd
.data
[IDIAG_BARACC_BAR_SZE_INDX
] =
3783 LPFC_PCI_IF0_BAR1_SIZE
;
3784 mem_mapped_bar
= phba
->sli4_hba
.ctrl_regs_memmap_p
;
3785 } else if (bar_num
== IDIAG_BARACC_BAR_2
) {
3786 idiag
.cmd
.data
[IDIAG_BARACC_BAR_SZE_INDX
] =
3787 LPFC_PCI_IF0_BAR2_SIZE
;
3788 mem_mapped_bar
= phba
->sli4_hba
.drbl_regs_memmap_p
;
3791 } else if (if_type
== LPFC_SLI_INTF_IF_TYPE_2
) {
3792 if (bar_num
== IDIAG_BARACC_BAR_0
) {
3793 idiag
.cmd
.data
[IDIAG_BARACC_BAR_SZE_INDX
] =
3794 LPFC_PCI_IF2_BAR0_SIZE
;
3795 mem_mapped_bar
= phba
->sli4_hba
.conf_regs_memmap_p
;
3801 offset
= idiag
.cmd
.data
[IDIAG_BARACC_OFF_SET_INDX
];
3802 if (offset
% sizeof(uint32_t))
3805 bar_size
= idiag
.cmd
.data
[IDIAG_BARACC_BAR_SZE_INDX
];
3806 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_BARACC_RD
) {
3807 /* Sanity check on PCI config read command line arguments */
3808 if (rc
!= LPFC_PCI_BAR_RD_CMD_ARG
)
3810 acc_range
= idiag
.cmd
.data
[IDIAG_BARACC_ACC_MOD_INDX
];
3811 if (acc_range
== LPFC_PCI_BAR_BROWSE
) {
3812 if (offset
> bar_size
- sizeof(uint32_t))
3814 /* Starting offset to browse */
3815 idiag
.offset
.last_rd
= offset
;
3816 } else if (acc_range
> SINGLE_WORD
) {
3817 if (offset
+ acc_range
* sizeof(uint32_t) > bar_size
)
3819 /* Starting offset to browse */
3820 idiag
.offset
.last_rd
= offset
;
3821 } else if (acc_range
!= SINGLE_WORD
)
3823 } else if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_BARACC_WR
||
3824 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_BARACC_ST
||
3825 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_BARACC_CL
) {
3826 /* Sanity check on PCI bar write command line arguments */
3827 if (rc
!= LPFC_PCI_BAR_WR_CMD_ARG
)
3829 /* Write command to PCI bar space, read-modify-write */
3830 acc_range
= SINGLE_WORD
;
3831 value
= idiag
.cmd
.data
[IDIAG_BARACC_REG_VAL_INDX
];
3832 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_BARACC_WR
) {
3833 writel(value
, mem_mapped_bar
+ offset
);
3834 readl(mem_mapped_bar
+ offset
);
3836 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_BARACC_ST
) {
3837 u32val
= readl(mem_mapped_bar
+ offset
);
3839 writel(u32val
, mem_mapped_bar
+ offset
);
3840 readl(mem_mapped_bar
+ offset
);
3842 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_BARACC_CL
) {
3843 u32val
= readl(mem_mapped_bar
+ offset
);
3845 writel(u32val
, mem_mapped_bar
+ offset
);
3846 readl(mem_mapped_bar
+ offset
);
3849 /* All other opecodes are illegal for now */
3854 memset(&idiag
, 0, sizeof(idiag
));
3859 __lpfc_idiag_print_wq(struct lpfc_queue
*qp
, char *wqtype
,
3860 char *pbuffer
, int len
)
3865 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
3866 "\t\t%s WQ info: ", wqtype
);
3867 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
3868 "AssocCQID[%04d]: WQ-STAT[oflow:x%x posted:x%llx]\n",
3869 qp
->assoc_qid
, qp
->q_cnt_1
,
3870 (unsigned long long)qp
->q_cnt_4
);
3871 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
3872 "\t\tWQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3873 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]",
3874 qp
->queue_id
, qp
->entry_count
,
3875 qp
->entry_size
, qp
->host_index
,
3876 qp
->hba_index
, qp
->notify_interval
);
3877 len
+= scnprintf(pbuffer
+ len
,
3878 LPFC_QUE_INFO_GET_BUF_SIZE
- len
, "\n");
3883 lpfc_idiag_wqs_for_cq(struct lpfc_hba
*phba
, char *wqtype
, char *pbuffer
,
3884 int *len
, int max_cnt
, int cq_id
)
3886 struct lpfc_queue
*qp
;
3889 for (qidx
= 0; qidx
< phba
->cfg_hdw_queue
; qidx
++) {
3890 qp
= phba
->sli4_hba
.hdwq
[qidx
].io_wq
;
3891 if (qp
->assoc_qid
!= cq_id
)
3893 *len
= __lpfc_idiag_print_wq(qp
, wqtype
, pbuffer
, *len
);
3894 if (*len
>= max_cnt
)
3901 __lpfc_idiag_print_cq(struct lpfc_queue
*qp
, char *cqtype
,
3902 char *pbuffer
, int len
)
3907 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
3908 "\t%s CQ info: ", cqtype
);
3909 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
3910 "AssocEQID[%02d]: CQ STAT[max:x%x relw:x%x "
3911 "xabt:x%x wq:x%llx]\n",
3912 qp
->assoc_qid
, qp
->q_cnt_1
, qp
->q_cnt_2
,
3913 qp
->q_cnt_3
, (unsigned long long)qp
->q_cnt_4
);
3914 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
3915 "\tCQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3916 "HST-IDX[%04d], NTFI[%03d], PLMT[%03d]",
3917 qp
->queue_id
, qp
->entry_count
,
3918 qp
->entry_size
, qp
->host_index
,
3919 qp
->notify_interval
, qp
->max_proc_limit
);
3921 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
3928 __lpfc_idiag_print_rqpair(struct lpfc_queue
*qp
, struct lpfc_queue
*datqp
,
3929 char *rqtype
, char *pbuffer
, int len
)
3934 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
3935 "\t\t%s RQ info: ", rqtype
);
3936 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
3937 "AssocCQID[%02d]: RQ-STAT[nopost:x%x nobuf:x%x "
3938 "posted:x%x rcv:x%llx]\n",
3939 qp
->assoc_qid
, qp
->q_cnt_1
, qp
->q_cnt_2
,
3940 qp
->q_cnt_3
, (unsigned long long)qp
->q_cnt_4
);
3941 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
3942 "\t\tHQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3943 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n",
3944 qp
->queue_id
, qp
->entry_count
, qp
->entry_size
,
3945 qp
->host_index
, qp
->hba_index
, qp
->notify_interval
);
3946 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
3947 "\t\tDQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3948 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n",
3949 datqp
->queue_id
, datqp
->entry_count
,
3950 datqp
->entry_size
, datqp
->host_index
,
3951 datqp
->hba_index
, datqp
->notify_interval
);
3956 lpfc_idiag_cqs_for_eq(struct lpfc_hba
*phba
, char *pbuffer
,
3957 int *len
, int max_cnt
, int eqidx
, int eq_id
)
3959 struct lpfc_queue
*qp
;
3962 qp
= phba
->sli4_hba
.hdwq
[eqidx
].io_cq
;
3964 *len
= __lpfc_idiag_print_cq(qp
, "IO", pbuffer
, *len
);
3966 /* Reset max counter */
3969 if (*len
>= max_cnt
)
3972 rc
= lpfc_idiag_wqs_for_cq(phba
, "IO", pbuffer
, len
,
3973 max_cnt
, qp
->queue_id
);
3977 if ((eqidx
< phba
->cfg_nvmet_mrq
) && phba
->nvmet_support
) {
3979 qp
= phba
->sli4_hba
.nvmet_cqset
[eqidx
];
3980 *len
= __lpfc_idiag_print_cq(qp
, "NVMET CQset", pbuffer
, *len
);
3982 /* Reset max counter */
3985 if (*len
>= max_cnt
)
3989 qp
= phba
->sli4_hba
.nvmet_mrq_hdr
[eqidx
];
3990 *len
= __lpfc_idiag_print_rqpair(qp
,
3991 phba
->sli4_hba
.nvmet_mrq_data
[eqidx
],
3992 "NVMET MRQ", pbuffer
, *len
);
3994 if (*len
>= max_cnt
)
4002 __lpfc_idiag_print_eq(struct lpfc_queue
*qp
, char *eqtype
,
4003 char *pbuffer
, int len
)
4008 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
4009 "\n%s EQ info: EQ-STAT[max:x%x noE:x%x "
4010 "cqe_proc:x%x eqe_proc:x%llx eqd %d]\n",
4011 eqtype
, qp
->q_cnt_1
, qp
->q_cnt_2
, qp
->q_cnt_3
,
4012 (unsigned long long)qp
->q_cnt_4
, qp
->q_mode
);
4013 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
4014 "EQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
4015 "HST-IDX[%04d], NTFI[%03d], PLMT[%03d], AFFIN[%03d]",
4016 qp
->queue_id
, qp
->entry_count
, qp
->entry_size
,
4017 qp
->host_index
, qp
->notify_interval
,
4018 qp
->max_proc_limit
, qp
->chann
);
4019 len
+= scnprintf(pbuffer
+ len
, LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
4026 * lpfc_idiag_queinfo_read - idiag debugfs read queue information
4027 * @file: The file pointer to read from.
4028 * @buf: The buffer to copy the data to.
4029 * @nbytes: The number of bytes to read.
4030 * @ppos: The position in the file to start reading from.
4033 * This routine reads data from the @phba SLI4 PCI function queue information,
4034 * and copies to user @buf.
4035 * This routine only returns 1 EQs worth of information. It remembers the last
4036 * EQ read and jumps to the next EQ. Thus subsequent calls to queInfo will
4037 * retrieve all EQs allocated for the phba.
4040 * This function returns the amount of data that was read (this could be less
4041 * than @nbytes if the end of the file was reached) or a negative error value.
4044 lpfc_idiag_queinfo_read(struct file
*file
, char __user
*buf
, size_t nbytes
,
4047 struct lpfc_debug
*debug
= file
->private_data
;
4048 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
4050 int max_cnt
, rc
, x
, len
= 0;
4051 struct lpfc_queue
*qp
= NULL
;
4054 debug
->buffer
= kmalloc(LPFC_QUE_INFO_GET_BUF_SIZE
, GFP_KERNEL
);
4057 pbuffer
= debug
->buffer
;
4058 max_cnt
= LPFC_QUE_INFO_GET_BUF_SIZE
- 256;
4063 spin_lock_irq(&phba
->hbalock
);
4065 /* Fast-path event queue */
4066 if (phba
->sli4_hba
.hdwq
&& phba
->cfg_hdw_queue
) {
4068 x
= phba
->lpfc_idiag_last_eq
;
4069 phba
->lpfc_idiag_last_eq
++;
4070 if (phba
->lpfc_idiag_last_eq
>= phba
->cfg_hdw_queue
)
4071 phba
->lpfc_idiag_last_eq
= 0;
4073 len
+= scnprintf(pbuffer
+ len
,
4074 LPFC_QUE_INFO_GET_BUF_SIZE
- len
,
4075 "HDWQ %d out of %d HBA HDWQs\n",
4076 x
, phba
->cfg_hdw_queue
);
4079 qp
= phba
->sli4_hba
.hdwq
[x
].hba_eq
;
4083 len
= __lpfc_idiag_print_eq(qp
, "HBA", pbuffer
, len
);
4085 /* Reset max counter */
4091 /* will dump both fcp and nvme cqs/wqs for the eq */
4092 rc
= lpfc_idiag_cqs_for_eq(phba
, pbuffer
, &len
,
4093 max_cnt
, x
, qp
->queue_id
);
4097 /* Only EQ 0 has slow path CQs configured */
4101 /* Slow-path mailbox CQ */
4102 qp
= phba
->sli4_hba
.mbx_cq
;
4103 len
= __lpfc_idiag_print_cq(qp
, "MBX", pbuffer
, len
);
4107 /* Slow-path MBOX MQ */
4108 qp
= phba
->sli4_hba
.mbx_wq
;
4109 len
= __lpfc_idiag_print_wq(qp
, "MBX", pbuffer
, len
);
4113 /* Slow-path ELS response CQ */
4114 qp
= phba
->sli4_hba
.els_cq
;
4115 len
= __lpfc_idiag_print_cq(qp
, "ELS", pbuffer
, len
);
4116 /* Reset max counter */
4122 /* Slow-path ELS WQ */
4123 qp
= phba
->sli4_hba
.els_wq
;
4124 len
= __lpfc_idiag_print_wq(qp
, "ELS", pbuffer
, len
);
4128 qp
= phba
->sli4_hba
.hdr_rq
;
4129 len
= __lpfc_idiag_print_rqpair(qp
, phba
->sli4_hba
.dat_rq
,
4130 "ELS RQpair", pbuffer
, len
);
4134 /* Slow-path NVME LS response CQ */
4135 qp
= phba
->sli4_hba
.nvmels_cq
;
4136 len
= __lpfc_idiag_print_cq(qp
, "NVME LS",
4138 /* Reset max counter */
4144 /* Slow-path NVME LS WQ */
4145 qp
= phba
->sli4_hba
.nvmels_wq
;
4146 len
= __lpfc_idiag_print_wq(qp
, "NVME LS",
4154 spin_unlock_irq(&phba
->hbalock
);
4155 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
4158 len
+= scnprintf(pbuffer
+ len
,
4159 LPFC_QUE_INFO_GET_BUF_SIZE
- len
, "Truncated ...\n");
4161 spin_unlock_irq(&phba
->hbalock
);
4162 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
4166 * lpfc_idiag_que_param_check - queue access command parameter sanity check
4167 * @q: The pointer to queue structure.
4168 * @index: The index into a queue entry.
4169 * @count: The number of queue entries to access.
4172 * The routine performs sanity check on device queue access method commands.
4175 * This function returns -EINVAL when fails the sanity check, otherwise, it
4179 lpfc_idiag_que_param_check(struct lpfc_queue
*q
, int index
, int count
)
4181 /* Only support single entry read or browsing */
4182 if ((count
!= 1) && (count
!= LPFC_QUE_ACC_BROWSE
))
4184 if (index
> q
->entry_count
- 1)
4190 * lpfc_idiag_queacc_read_qe - read a single entry from the given queue index
4191 * @pbuffer: The pointer to buffer to copy the read data into.
4192 * @len: Length of the buffer.
4193 * @pque: The pointer to the queue to be read.
4194 * @index: The index into the queue entry.
4197 * This routine reads out a single entry from the given queue's index location
4198 * and copies it into the buffer provided.
4201 * This function returns 0 when it fails, otherwise, it returns the length of
4202 * the data read into the buffer provided.
4205 lpfc_idiag_queacc_read_qe(char *pbuffer
, int len
, struct lpfc_queue
*pque
,
4211 if (!pbuffer
|| !pque
)
4214 esize
= pque
->entry_size
;
4215 len
+= scnprintf(pbuffer
+len
, LPFC_QUE_ACC_BUF_SIZE
-len
,
4216 "QE-INDEX[%04d]:\n", index
);
4219 pentry
= lpfc_sli4_qe(pque
, index
);
4221 len
+= scnprintf(pbuffer
+len
, LPFC_QUE_ACC_BUF_SIZE
-len
,
4224 offset
+= sizeof(uint32_t);
4225 esize
-= sizeof(uint32_t);
4226 if (esize
> 0 && !(offset
% (4 * sizeof(uint32_t))))
4227 len
+= scnprintf(pbuffer
+len
,
4228 LPFC_QUE_ACC_BUF_SIZE
-len
, "\n");
4230 len
+= scnprintf(pbuffer
+len
, LPFC_QUE_ACC_BUF_SIZE
-len
, "\n");
4236 * lpfc_idiag_queacc_read - idiag debugfs read port queue
4237 * @file: The file pointer to read from.
4238 * @buf: The buffer to copy the data to.
4239 * @nbytes: The number of bytes to read.
4240 * @ppos: The position in the file to start reading from.
4243 * This routine reads data from the @phba device queue memory according to the
4244 * idiag command, and copies to user @buf. Depending on the queue dump read
4245 * command setup, it does either a single queue entry read or browing through
4246 * all entries of the queue.
4249 * This function returns the amount of data that was read (this could be less
4250 * than @nbytes if the end of the file was reached) or a negative error value.
4253 lpfc_idiag_queacc_read(struct file
*file
, char __user
*buf
, size_t nbytes
,
4256 struct lpfc_debug
*debug
= file
->private_data
;
4257 uint32_t last_index
, index
, count
;
4258 struct lpfc_queue
*pque
= NULL
;
4262 /* This is a user read operation */
4263 debug
->op
= LPFC_IDIAG_OP_RD
;
4266 debug
->buffer
= kmalloc(LPFC_QUE_ACC_BUF_SIZE
, GFP_KERNEL
);
4269 pbuffer
= debug
->buffer
;
4274 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_RD
) {
4275 index
= idiag
.cmd
.data
[IDIAG_QUEACC_INDEX_INDX
];
4276 count
= idiag
.cmd
.data
[IDIAG_QUEACC_COUNT_INDX
];
4277 pque
= (struct lpfc_queue
*)idiag
.ptr_private
;
4281 /* Browse the queue starting from index */
4282 if (count
== LPFC_QUE_ACC_BROWSE
)
4285 /* Read a single entry from the queue */
4286 len
= lpfc_idiag_queacc_read_qe(pbuffer
, len
, pque
, index
);
4288 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
4292 /* Browse all entries from the queue */
4293 last_index
= idiag
.offset
.last_rd
;
4296 while (len
< LPFC_QUE_ACC_SIZE
- pque
->entry_size
) {
4297 len
= lpfc_idiag_queacc_read_qe(pbuffer
, len
, pque
, index
);
4299 if (index
> pque
->entry_count
- 1)
4303 /* Set up the offset for next portion of pci cfg read */
4304 if (index
> pque
->entry_count
- 1)
4306 idiag
.offset
.last_rd
= index
;
4308 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
4312 * lpfc_idiag_queacc_write - Syntax check and set up idiag queacc commands
4313 * @file: The file pointer to read from.
4314 * @buf: The buffer to copy the user data from.
4315 * @nbytes: The number of bytes to get.
4316 * @ppos: The position in the file to start reading from.
4318 * This routine get the debugfs idiag command struct from user space and then
4319 * perform the syntax check for port queue read (dump) or write (set) command
4320 * accordingly. In the case of port queue read command, it sets up the command
4321 * in the idiag command struct for the following debugfs read operation. In
4322 * the case of port queue write operation, it executes the write operation
4323 * into the port queue entry accordingly.
4325 * It returns the @nbytges passing in from debugfs user space when successful.
4326 * In case of error conditions, it returns proper error code back to the user
4330 lpfc_idiag_queacc_write(struct file
*file
, const char __user
*buf
,
4331 size_t nbytes
, loff_t
*ppos
)
4333 struct lpfc_debug
*debug
= file
->private_data
;
4334 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
4335 uint32_t qidx
, quetp
, queid
, index
, count
, offset
, value
;
4337 struct lpfc_queue
*pque
, *qp
;
4340 /* This is a user write operation */
4341 debug
->op
= LPFC_IDIAG_OP_WR
;
4343 rc
= lpfc_idiag_cmd_get(buf
, nbytes
, &idiag
.cmd
);
4347 /* Get and sanity check on command feilds */
4348 quetp
= idiag
.cmd
.data
[IDIAG_QUEACC_QUETP_INDX
];
4349 queid
= idiag
.cmd
.data
[IDIAG_QUEACC_QUEID_INDX
];
4350 index
= idiag
.cmd
.data
[IDIAG_QUEACC_INDEX_INDX
];
4351 count
= idiag
.cmd
.data
[IDIAG_QUEACC_COUNT_INDX
];
4352 offset
= idiag
.cmd
.data
[IDIAG_QUEACC_OFFST_INDX
];
4353 value
= idiag
.cmd
.data
[IDIAG_QUEACC_VALUE_INDX
];
4355 /* Sanity check on command line arguments */
4356 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_WR
||
4357 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_ST
||
4358 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_CL
) {
4359 if (rc
!= LPFC_QUE_ACC_WR_CMD_ARG
)
4363 } else if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_RD
) {
4364 if (rc
!= LPFC_QUE_ACC_RD_CMD_ARG
)
4371 /* HBA event queue */
4372 if (phba
->sli4_hba
.hdwq
) {
4373 for (qidx
= 0; qidx
< phba
->cfg_hdw_queue
; qidx
++) {
4374 qp
= phba
->sli4_hba
.hdwq
[qidx
].hba_eq
;
4375 if (qp
&& qp
->queue_id
== queid
) {
4377 rc
= lpfc_idiag_que_param_check(qp
,
4381 idiag
.ptr_private
= qp
;
4389 /* MBX complete queue */
4390 if (phba
->sli4_hba
.mbx_cq
&&
4391 phba
->sli4_hba
.mbx_cq
->queue_id
== queid
) {
4393 rc
= lpfc_idiag_que_param_check(
4394 phba
->sli4_hba
.mbx_cq
, index
, count
);
4397 idiag
.ptr_private
= phba
->sli4_hba
.mbx_cq
;
4400 /* ELS complete queue */
4401 if (phba
->sli4_hba
.els_cq
&&
4402 phba
->sli4_hba
.els_cq
->queue_id
== queid
) {
4404 rc
= lpfc_idiag_que_param_check(
4405 phba
->sli4_hba
.els_cq
, index
, count
);
4408 idiag
.ptr_private
= phba
->sli4_hba
.els_cq
;
4411 /* NVME LS complete queue */
4412 if (phba
->sli4_hba
.nvmels_cq
&&
4413 phba
->sli4_hba
.nvmels_cq
->queue_id
== queid
) {
4415 rc
= lpfc_idiag_que_param_check(
4416 phba
->sli4_hba
.nvmels_cq
, index
, count
);
4419 idiag
.ptr_private
= phba
->sli4_hba
.nvmels_cq
;
4422 /* FCP complete queue */
4423 if (phba
->sli4_hba
.hdwq
) {
4424 for (qidx
= 0; qidx
< phba
->cfg_hdw_queue
;
4426 qp
= phba
->sli4_hba
.hdwq
[qidx
].io_cq
;
4427 if (qp
&& qp
->queue_id
== queid
) {
4429 rc
= lpfc_idiag_que_param_check(
4433 idiag
.ptr_private
= qp
;
4441 /* MBX work queue */
4442 if (phba
->sli4_hba
.mbx_wq
&&
4443 phba
->sli4_hba
.mbx_wq
->queue_id
== queid
) {
4445 rc
= lpfc_idiag_que_param_check(
4446 phba
->sli4_hba
.mbx_wq
, index
, count
);
4449 idiag
.ptr_private
= phba
->sli4_hba
.mbx_wq
;
4455 /* ELS work queue */
4456 if (phba
->sli4_hba
.els_wq
&&
4457 phba
->sli4_hba
.els_wq
->queue_id
== queid
) {
4459 rc
= lpfc_idiag_que_param_check(
4460 phba
->sli4_hba
.els_wq
, index
, count
);
4463 idiag
.ptr_private
= phba
->sli4_hba
.els_wq
;
4466 /* NVME LS work queue */
4467 if (phba
->sli4_hba
.nvmels_wq
&&
4468 phba
->sli4_hba
.nvmels_wq
->queue_id
== queid
) {
4470 rc
= lpfc_idiag_que_param_check(
4471 phba
->sli4_hba
.nvmels_wq
, index
, count
);
4474 idiag
.ptr_private
= phba
->sli4_hba
.nvmels_wq
;
4478 if (phba
->sli4_hba
.hdwq
) {
4479 /* FCP/SCSI work queue */
4480 for (qidx
= 0; qidx
< phba
->cfg_hdw_queue
; qidx
++) {
4481 qp
= phba
->sli4_hba
.hdwq
[qidx
].io_wq
;
4482 if (qp
&& qp
->queue_id
== queid
) {
4484 rc
= lpfc_idiag_que_param_check(
4488 idiag
.ptr_private
= qp
;
4497 if (phba
->sli4_hba
.hdr_rq
&&
4498 phba
->sli4_hba
.hdr_rq
->queue_id
== queid
) {
4500 rc
= lpfc_idiag_que_param_check(
4501 phba
->sli4_hba
.hdr_rq
, index
, count
);
4504 idiag
.ptr_private
= phba
->sli4_hba
.hdr_rq
;
4508 if (phba
->sli4_hba
.dat_rq
&&
4509 phba
->sli4_hba
.dat_rq
->queue_id
== queid
) {
4511 rc
= lpfc_idiag_que_param_check(
4512 phba
->sli4_hba
.dat_rq
, index
, count
);
4515 idiag
.ptr_private
= phba
->sli4_hba
.dat_rq
;
4525 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_RD
) {
4526 if (count
== LPFC_QUE_ACC_BROWSE
)
4527 idiag
.offset
.last_rd
= index
;
4530 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_WR
||
4531 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_ST
||
4532 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_CL
) {
4533 /* Additional sanity checks on write operation */
4534 pque
= (struct lpfc_queue
*)idiag
.ptr_private
;
4535 if (offset
> pque
->entry_size
/sizeof(uint32_t) - 1)
4537 pentry
= lpfc_sli4_qe(pque
, index
);
4539 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_WR
)
4541 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_ST
)
4543 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_QUEACC_CL
)
4549 /* Clean out command structure on command error out */
4550 memset(&idiag
, 0, sizeof(idiag
));
4555 * lpfc_idiag_drbacc_read_reg - idiag debugfs read a doorbell register
4556 * @phba: The pointer to hba structure.
4557 * @pbuffer: The pointer to the buffer to copy the data to.
4558 * @len: The length of bytes to copied.
4559 * @drbregid: The id to doorbell registers.
4562 * This routine reads a doorbell register and copies its content to the
4563 * user buffer pointed to by @pbuffer.
4566 * This function returns the amount of data that was copied into @pbuffer.
4569 lpfc_idiag_drbacc_read_reg(struct lpfc_hba
*phba
, char *pbuffer
,
4570 int len
, uint32_t drbregid
)
4578 len
+= scnprintf(pbuffer
+ len
, LPFC_DRB_ACC_BUF_SIZE
-len
,
4579 "EQ-DRB-REG: 0x%08x\n",
4580 readl(phba
->sli4_hba
.EQDBregaddr
));
4583 len
+= scnprintf(pbuffer
+ len
, LPFC_DRB_ACC_BUF_SIZE
- len
,
4584 "CQ-DRB-REG: 0x%08x\n",
4585 readl(phba
->sli4_hba
.CQDBregaddr
));
4588 len
+= scnprintf(pbuffer
+len
, LPFC_DRB_ACC_BUF_SIZE
-len
,
4589 "MQ-DRB-REG: 0x%08x\n",
4590 readl(phba
->sli4_hba
.MQDBregaddr
));
4593 len
+= scnprintf(pbuffer
+len
, LPFC_DRB_ACC_BUF_SIZE
-len
,
4594 "WQ-DRB-REG: 0x%08x\n",
4595 readl(phba
->sli4_hba
.WQDBregaddr
));
4598 len
+= scnprintf(pbuffer
+len
, LPFC_DRB_ACC_BUF_SIZE
-len
,
4599 "RQ-DRB-REG: 0x%08x\n",
4600 readl(phba
->sli4_hba
.RQDBregaddr
));
4610 * lpfc_idiag_drbacc_read - idiag debugfs read port doorbell
4611 * @file: The file pointer to read from.
4612 * @buf: The buffer to copy the data to.
4613 * @nbytes: The number of bytes to read.
4614 * @ppos: The position in the file to start reading from.
4617 * This routine reads data from the @phba device doorbell register according
4618 * to the idiag command, and copies to user @buf. Depending on the doorbell
4619 * register read command setup, it does either a single doorbell register
4620 * read or dump all doorbell registers.
4623 * This function returns the amount of data that was read (this could be less
4624 * than @nbytes if the end of the file was reached) or a negative error value.
4627 lpfc_idiag_drbacc_read(struct file
*file
, char __user
*buf
, size_t nbytes
,
4630 struct lpfc_debug
*debug
= file
->private_data
;
4631 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
4632 uint32_t drb_reg_id
, i
;
4636 /* This is a user read operation */
4637 debug
->op
= LPFC_IDIAG_OP_RD
;
4640 debug
->buffer
= kmalloc(LPFC_DRB_ACC_BUF_SIZE
, GFP_KERNEL
);
4643 pbuffer
= debug
->buffer
;
4648 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_DRBACC_RD
)
4649 drb_reg_id
= idiag
.cmd
.data
[IDIAG_DRBACC_REGID_INDX
];
4653 if (drb_reg_id
== LPFC_DRB_ACC_ALL
)
4654 for (i
= 1; i
<= LPFC_DRB_MAX
; i
++)
4655 len
= lpfc_idiag_drbacc_read_reg(phba
,
4658 len
= lpfc_idiag_drbacc_read_reg(phba
,
4659 pbuffer
, len
, drb_reg_id
);
4661 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
4665 * lpfc_idiag_drbacc_write - Syntax check and set up idiag drbacc commands
4666 * @file: The file pointer to read from.
4667 * @buf: The buffer to copy the user data from.
4668 * @nbytes: The number of bytes to get.
4669 * @ppos: The position in the file to start reading from.
4671 * This routine get the debugfs idiag command struct from user space and then
4672 * perform the syntax check for port doorbell register read (dump) or write
4673 * (set) command accordingly. In the case of port queue read command, it sets
4674 * up the command in the idiag command struct for the following debugfs read
4675 * operation. In the case of port doorbell register write operation, it
4676 * executes the write operation into the port doorbell register accordingly.
4678 * It returns the @nbytges passing in from debugfs user space when successful.
4679 * In case of error conditions, it returns proper error code back to the user
4683 lpfc_idiag_drbacc_write(struct file
*file
, const char __user
*buf
,
4684 size_t nbytes
, loff_t
*ppos
)
4686 struct lpfc_debug
*debug
= file
->private_data
;
4687 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
4688 uint32_t drb_reg_id
, value
, reg_val
= 0;
4689 void __iomem
*drb_reg
;
4692 /* This is a user write operation */
4693 debug
->op
= LPFC_IDIAG_OP_WR
;
4695 rc
= lpfc_idiag_cmd_get(buf
, nbytes
, &idiag
.cmd
);
4699 /* Sanity check on command line arguments */
4700 drb_reg_id
= idiag
.cmd
.data
[IDIAG_DRBACC_REGID_INDX
];
4701 value
= idiag
.cmd
.data
[IDIAG_DRBACC_VALUE_INDX
];
4703 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_DRBACC_WR
||
4704 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_DRBACC_ST
||
4705 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_DRBACC_CL
) {
4706 if (rc
!= LPFC_DRB_ACC_WR_CMD_ARG
)
4708 if (drb_reg_id
> LPFC_DRB_MAX
)
4710 } else if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_DRBACC_RD
) {
4711 if (rc
!= LPFC_DRB_ACC_RD_CMD_ARG
)
4713 if ((drb_reg_id
> LPFC_DRB_MAX
) &&
4714 (drb_reg_id
!= LPFC_DRB_ACC_ALL
))
4719 /* Perform the write access operation */
4720 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_DRBACC_WR
||
4721 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_DRBACC_ST
||
4722 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_DRBACC_CL
) {
4723 switch (drb_reg_id
) {
4725 drb_reg
= phba
->sli4_hba
.EQDBregaddr
;
4728 drb_reg
= phba
->sli4_hba
.CQDBregaddr
;
4731 drb_reg
= phba
->sli4_hba
.MQDBregaddr
;
4734 drb_reg
= phba
->sli4_hba
.WQDBregaddr
;
4737 drb_reg
= phba
->sli4_hba
.RQDBregaddr
;
4743 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_DRBACC_WR
)
4745 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_DRBACC_ST
) {
4746 reg_val
= readl(drb_reg
);
4749 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_DRBACC_CL
) {
4750 reg_val
= readl(drb_reg
);
4753 writel(reg_val
, drb_reg
);
4754 readl(drb_reg
); /* flush */
4759 /* Clean out command structure on command error out */
4760 memset(&idiag
, 0, sizeof(idiag
));
4765 * lpfc_idiag_ctlacc_read_reg - idiag debugfs read a control registers
4766 * @phba: The pointer to hba structure.
4767 * @pbuffer: The pointer to the buffer to copy the data to.
4768 * @len: The length of bytes to copied.
4769 * @ctlregid: The id to doorbell registers.
4772 * This routine reads a control register and copies its content to the
4773 * user buffer pointed to by @pbuffer.
4776 * This function returns the amount of data that was copied into @pbuffer.
4779 lpfc_idiag_ctlacc_read_reg(struct lpfc_hba
*phba
, char *pbuffer
,
4780 int len
, uint32_t ctlregid
)
4787 case LPFC_CTL_PORT_SEM
:
4788 len
+= scnprintf(pbuffer
+len
, LPFC_CTL_ACC_BUF_SIZE
-len
,
4789 "Port SemReg: 0x%08x\n",
4790 readl(phba
->sli4_hba
.conf_regs_memmap_p
+
4791 LPFC_CTL_PORT_SEM_OFFSET
));
4793 case LPFC_CTL_PORT_STA
:
4794 len
+= scnprintf(pbuffer
+len
, LPFC_CTL_ACC_BUF_SIZE
-len
,
4795 "Port StaReg: 0x%08x\n",
4796 readl(phba
->sli4_hba
.conf_regs_memmap_p
+
4797 LPFC_CTL_PORT_STA_OFFSET
));
4799 case LPFC_CTL_PORT_CTL
:
4800 len
+= scnprintf(pbuffer
+len
, LPFC_CTL_ACC_BUF_SIZE
-len
,
4801 "Port CtlReg: 0x%08x\n",
4802 readl(phba
->sli4_hba
.conf_regs_memmap_p
+
4803 LPFC_CTL_PORT_CTL_OFFSET
));
4805 case LPFC_CTL_PORT_ER1
:
4806 len
+= scnprintf(pbuffer
+len
, LPFC_CTL_ACC_BUF_SIZE
-len
,
4807 "Port Er1Reg: 0x%08x\n",
4808 readl(phba
->sli4_hba
.conf_regs_memmap_p
+
4809 LPFC_CTL_PORT_ER1_OFFSET
));
4811 case LPFC_CTL_PORT_ER2
:
4812 len
+= scnprintf(pbuffer
+len
, LPFC_CTL_ACC_BUF_SIZE
-len
,
4813 "Port Er2Reg: 0x%08x\n",
4814 readl(phba
->sli4_hba
.conf_regs_memmap_p
+
4815 LPFC_CTL_PORT_ER2_OFFSET
));
4817 case LPFC_CTL_PDEV_CTL
:
4818 len
+= scnprintf(pbuffer
+len
, LPFC_CTL_ACC_BUF_SIZE
-len
,
4819 "PDev CtlReg: 0x%08x\n",
4820 readl(phba
->sli4_hba
.conf_regs_memmap_p
+
4821 LPFC_CTL_PDEV_CTL_OFFSET
));
4830 * lpfc_idiag_ctlacc_read - idiag debugfs read port and device control register
4831 * @file: The file pointer to read from.
4832 * @buf: The buffer to copy the data to.
4833 * @nbytes: The number of bytes to read.
4834 * @ppos: The position in the file to start reading from.
4837 * This routine reads data from the @phba port and device registers according
4838 * to the idiag command, and copies to user @buf.
4841 * This function returns the amount of data that was read (this could be less
4842 * than @nbytes if the end of the file was reached) or a negative error value.
4845 lpfc_idiag_ctlacc_read(struct file
*file
, char __user
*buf
, size_t nbytes
,
4848 struct lpfc_debug
*debug
= file
->private_data
;
4849 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
4850 uint32_t ctl_reg_id
, i
;
4854 /* This is a user read operation */
4855 debug
->op
= LPFC_IDIAG_OP_RD
;
4858 debug
->buffer
= kmalloc(LPFC_CTL_ACC_BUF_SIZE
, GFP_KERNEL
);
4861 pbuffer
= debug
->buffer
;
4866 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_CTLACC_RD
)
4867 ctl_reg_id
= idiag
.cmd
.data
[IDIAG_CTLACC_REGID_INDX
];
4871 if (ctl_reg_id
== LPFC_CTL_ACC_ALL
)
4872 for (i
= 1; i
<= LPFC_CTL_MAX
; i
++)
4873 len
= lpfc_idiag_ctlacc_read_reg(phba
,
4876 len
= lpfc_idiag_ctlacc_read_reg(phba
,
4877 pbuffer
, len
, ctl_reg_id
);
4879 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
4883 * lpfc_idiag_ctlacc_write - Syntax check and set up idiag ctlacc commands
4884 * @file: The file pointer to read from.
4885 * @buf: The buffer to copy the user data from.
4886 * @nbytes: The number of bytes to get.
4887 * @ppos: The position in the file to start reading from.
4889 * This routine get the debugfs idiag command struct from user space and then
4890 * perform the syntax check for port and device control register read (dump)
4891 * or write (set) command accordingly.
4893 * It returns the @nbytges passing in from debugfs user space when successful.
4894 * In case of error conditions, it returns proper error code back to the user
4898 lpfc_idiag_ctlacc_write(struct file
*file
, const char __user
*buf
,
4899 size_t nbytes
, loff_t
*ppos
)
4901 struct lpfc_debug
*debug
= file
->private_data
;
4902 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
4903 uint32_t ctl_reg_id
, value
, reg_val
= 0;
4904 void __iomem
*ctl_reg
;
4907 /* This is a user write operation */
4908 debug
->op
= LPFC_IDIAG_OP_WR
;
4910 rc
= lpfc_idiag_cmd_get(buf
, nbytes
, &idiag
.cmd
);
4914 /* Sanity check on command line arguments */
4915 ctl_reg_id
= idiag
.cmd
.data
[IDIAG_CTLACC_REGID_INDX
];
4916 value
= idiag
.cmd
.data
[IDIAG_CTLACC_VALUE_INDX
];
4918 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_CTLACC_WR
||
4919 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_CTLACC_ST
||
4920 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_CTLACC_CL
) {
4921 if (rc
!= LPFC_CTL_ACC_WR_CMD_ARG
)
4923 if (ctl_reg_id
> LPFC_CTL_MAX
)
4925 } else if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_CTLACC_RD
) {
4926 if (rc
!= LPFC_CTL_ACC_RD_CMD_ARG
)
4928 if ((ctl_reg_id
> LPFC_CTL_MAX
) &&
4929 (ctl_reg_id
!= LPFC_CTL_ACC_ALL
))
4934 /* Perform the write access operation */
4935 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_CTLACC_WR
||
4936 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_CTLACC_ST
||
4937 idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_CTLACC_CL
) {
4938 switch (ctl_reg_id
) {
4939 case LPFC_CTL_PORT_SEM
:
4940 ctl_reg
= phba
->sli4_hba
.conf_regs_memmap_p
+
4941 LPFC_CTL_PORT_SEM_OFFSET
;
4943 case LPFC_CTL_PORT_STA
:
4944 ctl_reg
= phba
->sli4_hba
.conf_regs_memmap_p
+
4945 LPFC_CTL_PORT_STA_OFFSET
;
4947 case LPFC_CTL_PORT_CTL
:
4948 ctl_reg
= phba
->sli4_hba
.conf_regs_memmap_p
+
4949 LPFC_CTL_PORT_CTL_OFFSET
;
4951 case LPFC_CTL_PORT_ER1
:
4952 ctl_reg
= phba
->sli4_hba
.conf_regs_memmap_p
+
4953 LPFC_CTL_PORT_ER1_OFFSET
;
4955 case LPFC_CTL_PORT_ER2
:
4956 ctl_reg
= phba
->sli4_hba
.conf_regs_memmap_p
+
4957 LPFC_CTL_PORT_ER2_OFFSET
;
4959 case LPFC_CTL_PDEV_CTL
:
4960 ctl_reg
= phba
->sli4_hba
.conf_regs_memmap_p
+
4961 LPFC_CTL_PDEV_CTL_OFFSET
;
4967 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_CTLACC_WR
)
4969 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_CTLACC_ST
) {
4970 reg_val
= readl(ctl_reg
);
4973 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_CTLACC_CL
) {
4974 reg_val
= readl(ctl_reg
);
4977 writel(reg_val
, ctl_reg
);
4978 readl(ctl_reg
); /* flush */
4983 /* Clean out command structure on command error out */
4984 memset(&idiag
, 0, sizeof(idiag
));
4989 * lpfc_idiag_mbxacc_get_setup - idiag debugfs get mailbox access setup
4990 * @phba: Pointer to HBA context object.
4991 * @pbuffer: Pointer to data buffer.
4994 * This routine gets the driver mailbox access debugfs setup information.
4997 * This function returns the amount of data that was read (this could be less
4998 * than @nbytes if the end of the file was reached) or a negative error value.
5001 lpfc_idiag_mbxacc_get_setup(struct lpfc_hba
*phba
, char *pbuffer
)
5003 uint32_t mbx_dump_map
, mbx_dump_cnt
, mbx_word_cnt
, mbx_mbox_cmd
;
5006 mbx_mbox_cmd
= idiag
.cmd
.data
[IDIAG_MBXACC_MBCMD_INDX
];
5007 mbx_dump_map
= idiag
.cmd
.data
[IDIAG_MBXACC_DPMAP_INDX
];
5008 mbx_dump_cnt
= idiag
.cmd
.data
[IDIAG_MBXACC_DPCNT_INDX
];
5009 mbx_word_cnt
= idiag
.cmd
.data
[IDIAG_MBXACC_WDCNT_INDX
];
5011 len
+= scnprintf(pbuffer
+len
, LPFC_MBX_ACC_BUF_SIZE
-len
,
5012 "mbx_dump_map: 0x%08x\n", mbx_dump_map
);
5013 len
+= scnprintf(pbuffer
+len
, LPFC_MBX_ACC_BUF_SIZE
-len
,
5014 "mbx_dump_cnt: %04d\n", mbx_dump_cnt
);
5015 len
+= scnprintf(pbuffer
+len
, LPFC_MBX_ACC_BUF_SIZE
-len
,
5016 "mbx_word_cnt: %04d\n", mbx_word_cnt
);
5017 len
+= scnprintf(pbuffer
+len
, LPFC_MBX_ACC_BUF_SIZE
-len
,
5018 "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd
);
5024 * lpfc_idiag_mbxacc_read - idiag debugfs read on mailbox access
5025 * @file: The file pointer to read from.
5026 * @buf: The buffer to copy the data to.
5027 * @nbytes: The number of bytes to read.
5028 * @ppos: The position in the file to start reading from.
5031 * This routine reads data from the @phba driver mailbox access debugfs setup
5035 * This function returns the amount of data that was read (this could be less
5036 * than @nbytes if the end of the file was reached) or a negative error value.
5039 lpfc_idiag_mbxacc_read(struct file
*file
, char __user
*buf
, size_t nbytes
,
5042 struct lpfc_debug
*debug
= file
->private_data
;
5043 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
5047 /* This is a user read operation */
5048 debug
->op
= LPFC_IDIAG_OP_RD
;
5051 debug
->buffer
= kmalloc(LPFC_MBX_ACC_BUF_SIZE
, GFP_KERNEL
);
5054 pbuffer
= debug
->buffer
;
5059 if ((idiag
.cmd
.opcode
!= LPFC_IDIAG_CMD_MBXACC_DP
) &&
5060 (idiag
.cmd
.opcode
!= LPFC_IDIAG_BSG_MBXACC_DP
))
5063 len
= lpfc_idiag_mbxacc_get_setup(phba
, pbuffer
);
5065 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
5069 * lpfc_idiag_mbxacc_write - Syntax check and set up idiag mbxacc commands
5070 * @file: The file pointer to read from.
5071 * @buf: The buffer to copy the user data from.
5072 * @nbytes: The number of bytes to get.
5073 * @ppos: The position in the file to start reading from.
5075 * This routine get the debugfs idiag command struct from user space and then
5076 * perform the syntax check for driver mailbox command (dump) and sets up the
5077 * necessary states in the idiag command struct accordingly.
5079 * It returns the @nbytges passing in from debugfs user space when successful.
5080 * In case of error conditions, it returns proper error code back to the user
5084 lpfc_idiag_mbxacc_write(struct file
*file
, const char __user
*buf
,
5085 size_t nbytes
, loff_t
*ppos
)
5087 struct lpfc_debug
*debug
= file
->private_data
;
5088 uint32_t mbx_dump_map
, mbx_dump_cnt
, mbx_word_cnt
, mbx_mbox_cmd
;
5091 /* This is a user write operation */
5092 debug
->op
= LPFC_IDIAG_OP_WR
;
5094 rc
= lpfc_idiag_cmd_get(buf
, nbytes
, &idiag
.cmd
);
5098 /* Sanity check on command line arguments */
5099 mbx_mbox_cmd
= idiag
.cmd
.data
[IDIAG_MBXACC_MBCMD_INDX
];
5100 mbx_dump_map
= idiag
.cmd
.data
[IDIAG_MBXACC_DPMAP_INDX
];
5101 mbx_dump_cnt
= idiag
.cmd
.data
[IDIAG_MBXACC_DPCNT_INDX
];
5102 mbx_word_cnt
= idiag
.cmd
.data
[IDIAG_MBXACC_WDCNT_INDX
];
5104 if (idiag
.cmd
.opcode
== LPFC_IDIAG_CMD_MBXACC_DP
) {
5105 if (!(mbx_dump_map
& LPFC_MBX_DMP_MBX_ALL
))
5107 if ((mbx_dump_map
& ~LPFC_MBX_DMP_MBX_ALL
) &&
5108 (mbx_dump_map
!= LPFC_MBX_DMP_ALL
))
5110 if (mbx_word_cnt
> sizeof(MAILBOX_t
))
5112 } else if (idiag
.cmd
.opcode
== LPFC_IDIAG_BSG_MBXACC_DP
) {
5113 if (!(mbx_dump_map
& LPFC_BSG_DMP_MBX_ALL
))
5115 if ((mbx_dump_map
& ~LPFC_BSG_DMP_MBX_ALL
) &&
5116 (mbx_dump_map
!= LPFC_MBX_DMP_ALL
))
5118 if (mbx_word_cnt
> (BSG_MBOX_SIZE
)/4)
5120 if (mbx_mbox_cmd
!= 0x9b)
5125 if (mbx_word_cnt
== 0)
5127 if (rc
!= LPFC_MBX_DMP_ARG
)
5129 if (mbx_mbox_cmd
& ~0xff)
5132 /* condition for stop mailbox dump */
5133 if (mbx_dump_cnt
== 0)
5139 /* Clean out command structure on command error out */
5140 memset(&idiag
, 0, sizeof(idiag
));
5144 /* Clean out command structure on command error out */
5145 memset(&idiag
, 0, sizeof(idiag
));
5150 * lpfc_idiag_extacc_avail_get - get the available extents information
5151 * @phba: pointer to lpfc hba data structure.
5152 * @pbuffer: pointer to internal buffer.
5153 * @len: length into the internal buffer data has been copied.
5156 * This routine is to get the available extent information.
5159 * overall length of the data read into the internal buffer.
5162 lpfc_idiag_extacc_avail_get(struct lpfc_hba
*phba
, char *pbuffer
, int len
)
5164 uint16_t ext_cnt
= 0, ext_size
= 0;
5166 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5167 "\nAvailable Extents Information:\n");
5169 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5170 "\tPort Available VPI extents: ");
5171 lpfc_sli4_get_avail_extnt_rsrc(phba
, LPFC_RSC_TYPE_FCOE_VPI
,
5172 &ext_cnt
, &ext_size
);
5173 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5174 "Count %3d, Size %3d\n", ext_cnt
, ext_size
);
5176 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5177 "\tPort Available VFI extents: ");
5178 lpfc_sli4_get_avail_extnt_rsrc(phba
, LPFC_RSC_TYPE_FCOE_VFI
,
5179 &ext_cnt
, &ext_size
);
5180 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5181 "Count %3d, Size %3d\n", ext_cnt
, ext_size
);
5183 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5184 "\tPort Available RPI extents: ");
5185 lpfc_sli4_get_avail_extnt_rsrc(phba
, LPFC_RSC_TYPE_FCOE_RPI
,
5186 &ext_cnt
, &ext_size
);
5187 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5188 "Count %3d, Size %3d\n", ext_cnt
, ext_size
);
5190 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5191 "\tPort Available XRI extents: ");
5192 lpfc_sli4_get_avail_extnt_rsrc(phba
, LPFC_RSC_TYPE_FCOE_XRI
,
5193 &ext_cnt
, &ext_size
);
5194 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5195 "Count %3d, Size %3d\n", ext_cnt
, ext_size
);
5201 * lpfc_idiag_extacc_alloc_get - get the allocated extents information
5202 * @phba: pointer to lpfc hba data structure.
5203 * @pbuffer: pointer to internal buffer.
5204 * @len: length into the internal buffer data has been copied.
5207 * This routine is to get the allocated extent information.
5210 * overall length of the data read into the internal buffer.
5213 lpfc_idiag_extacc_alloc_get(struct lpfc_hba
*phba
, char *pbuffer
, int len
)
5215 uint16_t ext_cnt
, ext_size
;
5218 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5219 "\nAllocated Extents Information:\n");
5221 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5222 "\tHost Allocated VPI extents: ");
5223 rc
= lpfc_sli4_get_allocated_extnts(phba
, LPFC_RSC_TYPE_FCOE_VPI
,
5224 &ext_cnt
, &ext_size
);
5226 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5227 "Port %d Extent %3d, Size %3d\n",
5228 phba
->brd_no
, ext_cnt
, ext_size
);
5230 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5233 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5234 "\tHost Allocated VFI extents: ");
5235 rc
= lpfc_sli4_get_allocated_extnts(phba
, LPFC_RSC_TYPE_FCOE_VFI
,
5236 &ext_cnt
, &ext_size
);
5238 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5239 "Port %d Extent %3d, Size %3d\n",
5240 phba
->brd_no
, ext_cnt
, ext_size
);
5242 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5245 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5246 "\tHost Allocated RPI extents: ");
5247 rc
= lpfc_sli4_get_allocated_extnts(phba
, LPFC_RSC_TYPE_FCOE_RPI
,
5248 &ext_cnt
, &ext_size
);
5250 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5251 "Port %d Extent %3d, Size %3d\n",
5252 phba
->brd_no
, ext_cnt
, ext_size
);
5254 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5257 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5258 "\tHost Allocated XRI extents: ");
5259 rc
= lpfc_sli4_get_allocated_extnts(phba
, LPFC_RSC_TYPE_FCOE_XRI
,
5260 &ext_cnt
, &ext_size
);
5262 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5263 "Port %d Extent %3d, Size %3d\n",
5264 phba
->brd_no
, ext_cnt
, ext_size
);
5266 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5273 * lpfc_idiag_extacc_drivr_get - get driver extent information
5274 * @phba: pointer to lpfc hba data structure.
5275 * @pbuffer: pointer to internal buffer.
5276 * @len: length into the internal buffer data has been copied.
5279 * This routine is to get the driver extent information.
5282 * overall length of the data read into the internal buffer.
5285 lpfc_idiag_extacc_drivr_get(struct lpfc_hba
*phba
, char *pbuffer
, int len
)
5287 struct lpfc_rsrc_blks
*rsrc_blks
;
5290 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5291 "\nDriver Extents Information:\n");
5293 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5294 "\tVPI extents:\n");
5296 list_for_each_entry(rsrc_blks
, &phba
->lpfc_vpi_blk_list
, list
) {
5297 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5298 "\t\tBlock %3d: Start %4d, Count %4d\n",
5299 index
, rsrc_blks
->rsrc_start
,
5300 rsrc_blks
->rsrc_size
);
5303 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5304 "\tVFI extents:\n");
5306 list_for_each_entry(rsrc_blks
, &phba
->sli4_hba
.lpfc_vfi_blk_list
,
5308 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5309 "\t\tBlock %3d: Start %4d, Count %4d\n",
5310 index
, rsrc_blks
->rsrc_start
,
5311 rsrc_blks
->rsrc_size
);
5315 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5316 "\tRPI extents:\n");
5318 list_for_each_entry(rsrc_blks
, &phba
->sli4_hba
.lpfc_rpi_blk_list
,
5320 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5321 "\t\tBlock %3d: Start %4d, Count %4d\n",
5322 index
, rsrc_blks
->rsrc_start
,
5323 rsrc_blks
->rsrc_size
);
5327 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5328 "\tXRI extents:\n");
5330 list_for_each_entry(rsrc_blks
, &phba
->sli4_hba
.lpfc_xri_blk_list
,
5332 len
+= scnprintf(pbuffer
+len
, LPFC_EXT_ACC_BUF_SIZE
-len
,
5333 "\t\tBlock %3d: Start %4d, Count %4d\n",
5334 index
, rsrc_blks
->rsrc_start
,
5335 rsrc_blks
->rsrc_size
);
5343 * lpfc_idiag_extacc_write - Syntax check and set up idiag extacc commands
5344 * @file: The file pointer to read from.
5345 * @buf: The buffer to copy the user data from.
5346 * @nbytes: The number of bytes to get.
5347 * @ppos: The position in the file to start reading from.
5349 * This routine get the debugfs idiag command struct from user space and then
5350 * perform the syntax check for extent information access commands and sets
5351 * up the necessary states in the idiag command struct accordingly.
5353 * It returns the @nbytges passing in from debugfs user space when successful.
5354 * In case of error conditions, it returns proper error code back to the user
5358 lpfc_idiag_extacc_write(struct file
*file
, const char __user
*buf
,
5359 size_t nbytes
, loff_t
*ppos
)
5361 struct lpfc_debug
*debug
= file
->private_data
;
5365 /* This is a user write operation */
5366 debug
->op
= LPFC_IDIAG_OP_WR
;
5368 rc
= lpfc_idiag_cmd_get(buf
, nbytes
, &idiag
.cmd
);
5372 ext_map
= idiag
.cmd
.data
[IDIAG_EXTACC_EXMAP_INDX
];
5374 if (idiag
.cmd
.opcode
!= LPFC_IDIAG_CMD_EXTACC_RD
)
5376 if (rc
!= LPFC_EXT_ACC_CMD_ARG
)
5378 if (!(ext_map
& LPFC_EXT_ACC_ALL
))
5383 /* Clean out command structure on command error out */
5384 memset(&idiag
, 0, sizeof(idiag
));
5389 * lpfc_idiag_extacc_read - idiag debugfs read access to extent information
5390 * @file: The file pointer to read from.
5391 * @buf: The buffer to copy the data to.
5392 * @nbytes: The number of bytes to read.
5393 * @ppos: The position in the file to start reading from.
5396 * This routine reads data from the proper extent information according to
5397 * the idiag command, and copies to user @buf.
5400 * This function returns the amount of data that was read (this could be less
5401 * than @nbytes if the end of the file was reached) or a negative error value.
5404 lpfc_idiag_extacc_read(struct file
*file
, char __user
*buf
, size_t nbytes
,
5407 struct lpfc_debug
*debug
= file
->private_data
;
5408 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
5413 /* This is a user read operation */
5414 debug
->op
= LPFC_IDIAG_OP_RD
;
5417 debug
->buffer
= kmalloc(LPFC_EXT_ACC_BUF_SIZE
, GFP_KERNEL
);
5420 pbuffer
= debug
->buffer
;
5423 if (idiag
.cmd
.opcode
!= LPFC_IDIAG_CMD_EXTACC_RD
)
5426 ext_map
= idiag
.cmd
.data
[IDIAG_EXTACC_EXMAP_INDX
];
5427 if (ext_map
& LPFC_EXT_ACC_AVAIL
)
5428 len
= lpfc_idiag_extacc_avail_get(phba
, pbuffer
, len
);
5429 if (ext_map
& LPFC_EXT_ACC_ALLOC
)
5430 len
= lpfc_idiag_extacc_alloc_get(phba
, pbuffer
, len
);
5431 if (ext_map
& LPFC_EXT_ACC_DRIVR
)
5432 len
= lpfc_idiag_extacc_drivr_get(phba
, pbuffer
, len
);
5434 return simple_read_from_buffer(buf
, nbytes
, ppos
, pbuffer
, len
);
5438 lpfc_cgn_buffer_open(struct inode
*inode
, struct file
*file
)
5440 struct lpfc_debug
*debug
;
5443 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
5447 debug
->buffer
= vmalloc(LPFC_CGN_BUF_SIZE
);
5448 if (!debug
->buffer
) {
5453 debug
->i_private
= inode
->i_private
;
5454 file
->private_data
= debug
;
5462 lpfc_cgn_buffer_read(struct file
*file
, char __user
*buf
, size_t nbytes
,
5465 struct lpfc_debug
*debug
= file
->private_data
;
5466 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
5467 char *buffer
= debug
->buffer
;
5471 if (!phba
->sli4_hba
.pc_sli4_params
.mi_ver
|| !phba
->cgn_i
) {
5472 len
+= scnprintf(buffer
+ len
, LPFC_CGN_BUF_SIZE
- len
,
5473 "Congestion Mgmt is not supported\n");
5476 ptr
= (uint32_t *)phba
->cgn_i
->virt
;
5477 len
+= scnprintf(buffer
+ len
, LPFC_CGN_BUF_SIZE
- len
,
5478 "Congestion Buffer Header\n");
5479 /* Dump the first 32 bytes */
5481 len
+= scnprintf(buffer
+ len
, LPFC_CGN_BUF_SIZE
- len
,
5482 "000: %08x %08x %08x %08x %08x %08x %08x %08x\n",
5483 *ptr
, *(ptr
+ 1), *(ptr
+ 2), *(ptr
+ 3),
5484 *(ptr
+ 4), *(ptr
+ 5), *(ptr
+ 6), *(ptr
+ 7));
5486 len
+= scnprintf(buffer
+ len
, LPFC_CGN_BUF_SIZE
- len
,
5487 "Congestion Buffer Data\n");
5488 while (cnt
< sizeof(struct lpfc_cgn_info
)) {
5489 if (len
> (LPFC_CGN_BUF_SIZE
- LPFC_DEBUG_OUT_LINE_SZ
)) {
5490 len
+= scnprintf(buffer
+ len
, LPFC_CGN_BUF_SIZE
- len
,
5491 "Truncated . . .\n");
5494 len
+= scnprintf(buffer
+ len
, LPFC_CGN_BUF_SIZE
- len
,
5495 "%03x: %08x %08x %08x %08x "
5496 "%08x %08x %08x %08x\n",
5497 cnt
, *ptr
, *(ptr
+ 1), *(ptr
+ 2),
5498 *(ptr
+ 3), *(ptr
+ 4), *(ptr
+ 5),
5499 *(ptr
+ 6), *(ptr
+ 7));
5503 if (len
> (LPFC_CGN_BUF_SIZE
- LPFC_DEBUG_OUT_LINE_SZ
)) {
5504 len
+= scnprintf(buffer
+ len
, LPFC_CGN_BUF_SIZE
- len
,
5505 "Truncated . . .\n");
5508 len
+= scnprintf(buffer
+ len
, LPFC_CGN_BUF_SIZE
- len
,
5509 "Parameter Data\n");
5510 ptr
= (uint32_t *)&phba
->cgn_p
;
5511 len
+= scnprintf(buffer
+ len
, LPFC_CGN_BUF_SIZE
- len
,
5512 "%08x %08x %08x %08x\n",
5513 *ptr
, *(ptr
+ 1), *(ptr
+ 2), *(ptr
+ 3));
5515 return simple_read_from_buffer(buf
, nbytes
, ppos
, buffer
, len
);
5519 lpfc_cgn_buffer_release(struct inode
*inode
, struct file
*file
)
5521 struct lpfc_debug
*debug
= file
->private_data
;
5523 vfree(debug
->buffer
);
5530 lpfc_rx_monitor_open(struct inode
*inode
, struct file
*file
)
5532 struct lpfc_rx_monitor_debug
*debug
;
5535 debug
= kmalloc(sizeof(*debug
), GFP_KERNEL
);
5539 debug
->buffer
= vmalloc(MAX_DEBUGFS_RX_INFO_SIZE
);
5540 if (!debug
->buffer
) {
5545 debug
->i_private
= inode
->i_private
;
5546 file
->private_data
= debug
;
5554 lpfc_rx_monitor_read(struct file
*file
, char __user
*buf
, size_t nbytes
,
5557 struct lpfc_rx_monitor_debug
*debug
= file
->private_data
;
5558 struct lpfc_hba
*phba
= (struct lpfc_hba
*)debug
->i_private
;
5559 char *buffer
= debug
->buffer
;
5561 if (!phba
->rx_monitor
) {
5562 scnprintf(buffer
, MAX_DEBUGFS_RX_INFO_SIZE
,
5563 "Rx Monitor Info is empty.\n");
5565 lpfc_rx_monitor_report(phba
, phba
->rx_monitor
, buffer
,
5566 MAX_DEBUGFS_RX_INFO_SIZE
,
5567 LPFC_MAX_RXMONITOR_ENTRY
);
5570 return simple_read_from_buffer(buf
, nbytes
, ppos
, buffer
,
5575 lpfc_rx_monitor_release(struct inode
*inode
, struct file
*file
)
5577 struct lpfc_rx_monitor_debug
*debug
= file
->private_data
;
5579 vfree(debug
->buffer
);
5585 #undef lpfc_debugfs_op_disc_trc
5586 static const struct file_operations lpfc_debugfs_op_disc_trc
= {
5587 .owner
= THIS_MODULE
,
5588 .open
= lpfc_debugfs_disc_trc_open
,
5589 .llseek
= lpfc_debugfs_lseek
,
5590 .read
= lpfc_debugfs_read
,
5591 .release
= lpfc_debugfs_release
,
5594 #undef lpfc_debugfs_op_nodelist
5595 static const struct file_operations lpfc_debugfs_op_nodelist
= {
5596 .owner
= THIS_MODULE
,
5597 .open
= lpfc_debugfs_nodelist_open
,
5598 .llseek
= lpfc_debugfs_lseek
,
5599 .read
= lpfc_debugfs_read
,
5600 .release
= lpfc_debugfs_release
,
5603 #undef lpfc_debugfs_op_multixripools
5604 static const struct file_operations lpfc_debugfs_op_multixripools
= {
5605 .owner
= THIS_MODULE
,
5606 .open
= lpfc_debugfs_multixripools_open
,
5607 .llseek
= lpfc_debugfs_lseek
,
5608 .read
= lpfc_debugfs_read
,
5609 .write
= lpfc_debugfs_multixripools_write
,
5610 .release
= lpfc_debugfs_release
,
5613 #undef lpfc_debugfs_op_hbqinfo
5614 static const struct file_operations lpfc_debugfs_op_hbqinfo
= {
5615 .owner
= THIS_MODULE
,
5616 .open
= lpfc_debugfs_hbqinfo_open
,
5617 .llseek
= lpfc_debugfs_lseek
,
5618 .read
= lpfc_debugfs_read
,
5619 .release
= lpfc_debugfs_release
,
5622 #ifdef LPFC_HDWQ_LOCK_STAT
5623 #undef lpfc_debugfs_op_lockstat
5624 static const struct file_operations lpfc_debugfs_op_lockstat
= {
5625 .owner
= THIS_MODULE
,
5626 .open
= lpfc_debugfs_lockstat_open
,
5627 .llseek
= lpfc_debugfs_lseek
,
5628 .read
= lpfc_debugfs_read
,
5629 .write
= lpfc_debugfs_lockstat_write
,
5630 .release
= lpfc_debugfs_release
,
5634 #undef lpfc_debugfs_ras_log
5635 static const struct file_operations lpfc_debugfs_ras_log
= {
5636 .owner
= THIS_MODULE
,
5637 .open
= lpfc_debugfs_ras_log_open
,
5638 .llseek
= lpfc_debugfs_lseek
,
5639 .read
= lpfc_debugfs_read
,
5640 .release
= lpfc_debugfs_ras_log_release
,
5643 #undef lpfc_debugfs_op_dumpHBASlim
5644 static const struct file_operations lpfc_debugfs_op_dumpHBASlim
= {
5645 .owner
= THIS_MODULE
,
5646 .open
= lpfc_debugfs_dumpHBASlim_open
,
5647 .llseek
= lpfc_debugfs_lseek
,
5648 .read
= lpfc_debugfs_read
,
5649 .release
= lpfc_debugfs_release
,
5652 #undef lpfc_debugfs_op_dumpHostSlim
5653 static const struct file_operations lpfc_debugfs_op_dumpHostSlim
= {
5654 .owner
= THIS_MODULE
,
5655 .open
= lpfc_debugfs_dumpHostSlim_open
,
5656 .llseek
= lpfc_debugfs_lseek
,
5657 .read
= lpfc_debugfs_read
,
5658 .release
= lpfc_debugfs_release
,
5661 #undef lpfc_debugfs_op_nvmestat
5662 static const struct file_operations lpfc_debugfs_op_nvmestat
= {
5663 .owner
= THIS_MODULE
,
5664 .open
= lpfc_debugfs_nvmestat_open
,
5665 .llseek
= lpfc_debugfs_lseek
,
5666 .read
= lpfc_debugfs_read
,
5667 .write
= lpfc_debugfs_nvmestat_write
,
5668 .release
= lpfc_debugfs_release
,
5671 #undef lpfc_debugfs_op_scsistat
5672 static const struct file_operations lpfc_debugfs_op_scsistat
= {
5673 .owner
= THIS_MODULE
,
5674 .open
= lpfc_debugfs_scsistat_open
,
5675 .llseek
= lpfc_debugfs_lseek
,
5676 .read
= lpfc_debugfs_read
,
5677 .write
= lpfc_debugfs_scsistat_write
,
5678 .release
= lpfc_debugfs_release
,
5681 #undef lpfc_debugfs_op_ioktime
5682 static const struct file_operations lpfc_debugfs_op_ioktime
= {
5683 .owner
= THIS_MODULE
,
5684 .open
= lpfc_debugfs_ioktime_open
,
5685 .llseek
= lpfc_debugfs_lseek
,
5686 .read
= lpfc_debugfs_read
,
5687 .write
= lpfc_debugfs_ioktime_write
,
5688 .release
= lpfc_debugfs_release
,
5691 #undef lpfc_debugfs_op_nvmeio_trc
5692 static const struct file_operations lpfc_debugfs_op_nvmeio_trc
= {
5693 .owner
= THIS_MODULE
,
5694 .open
= lpfc_debugfs_nvmeio_trc_open
,
5695 .llseek
= lpfc_debugfs_lseek
,
5696 .read
= lpfc_debugfs_read
,
5697 .write
= lpfc_debugfs_nvmeio_trc_write
,
5698 .release
= lpfc_debugfs_release
,
5701 #undef lpfc_debugfs_op_hdwqstat
5702 static const struct file_operations lpfc_debugfs_op_hdwqstat
= {
5703 .owner
= THIS_MODULE
,
5704 .open
= lpfc_debugfs_hdwqstat_open
,
5705 .llseek
= lpfc_debugfs_lseek
,
5706 .read
= lpfc_debugfs_read
,
5707 .write
= lpfc_debugfs_hdwqstat_write
,
5708 .release
= lpfc_debugfs_release
,
5711 #undef lpfc_debugfs_op_dif_err
5712 static const struct file_operations lpfc_debugfs_op_dif_err
= {
5713 .owner
= THIS_MODULE
,
5714 .open
= simple_open
,
5715 .llseek
= lpfc_debugfs_lseek
,
5716 .read
= lpfc_debugfs_dif_err_read
,
5717 .write
= lpfc_debugfs_dif_err_write
,
5718 .release
= lpfc_debugfs_dif_err_release
,
5721 #undef lpfc_debugfs_op_slow_ring_trc
5722 static const struct file_operations lpfc_debugfs_op_slow_ring_trc
= {
5723 .owner
= THIS_MODULE
,
5724 .open
= lpfc_debugfs_slow_ring_trc_open
,
5725 .llseek
= lpfc_debugfs_lseek
,
5726 .read
= lpfc_debugfs_read
,
5727 .release
= lpfc_debugfs_release
,
5730 static struct dentry
*lpfc_debugfs_root
= NULL
;
5731 static atomic_t lpfc_debugfs_hba_count
;
5734 * File operations for the iDiag debugfs
5736 #undef lpfc_idiag_op_pciCfg
5737 static const struct file_operations lpfc_idiag_op_pciCfg
= {
5738 .owner
= THIS_MODULE
,
5739 .open
= lpfc_idiag_open
,
5740 .llseek
= lpfc_debugfs_lseek
,
5741 .read
= lpfc_idiag_pcicfg_read
,
5742 .write
= lpfc_idiag_pcicfg_write
,
5743 .release
= lpfc_idiag_cmd_release
,
5746 #undef lpfc_idiag_op_barAcc
5747 static const struct file_operations lpfc_idiag_op_barAcc
= {
5748 .owner
= THIS_MODULE
,
5749 .open
= lpfc_idiag_open
,
5750 .llseek
= lpfc_debugfs_lseek
,
5751 .read
= lpfc_idiag_baracc_read
,
5752 .write
= lpfc_idiag_baracc_write
,
5753 .release
= lpfc_idiag_cmd_release
,
5756 #undef lpfc_idiag_op_queInfo
5757 static const struct file_operations lpfc_idiag_op_queInfo
= {
5758 .owner
= THIS_MODULE
,
5759 .open
= lpfc_idiag_open
,
5760 .read
= lpfc_idiag_queinfo_read
,
5761 .release
= lpfc_idiag_release
,
5764 #undef lpfc_idiag_op_queAcc
5765 static const struct file_operations lpfc_idiag_op_queAcc
= {
5766 .owner
= THIS_MODULE
,
5767 .open
= lpfc_idiag_open
,
5768 .llseek
= lpfc_debugfs_lseek
,
5769 .read
= lpfc_idiag_queacc_read
,
5770 .write
= lpfc_idiag_queacc_write
,
5771 .release
= lpfc_idiag_cmd_release
,
5774 #undef lpfc_idiag_op_drbAcc
5775 static const struct file_operations lpfc_idiag_op_drbAcc
= {
5776 .owner
= THIS_MODULE
,
5777 .open
= lpfc_idiag_open
,
5778 .llseek
= lpfc_debugfs_lseek
,
5779 .read
= lpfc_idiag_drbacc_read
,
5780 .write
= lpfc_idiag_drbacc_write
,
5781 .release
= lpfc_idiag_cmd_release
,
5784 #undef lpfc_idiag_op_ctlAcc
5785 static const struct file_operations lpfc_idiag_op_ctlAcc
= {
5786 .owner
= THIS_MODULE
,
5787 .open
= lpfc_idiag_open
,
5788 .llseek
= lpfc_debugfs_lseek
,
5789 .read
= lpfc_idiag_ctlacc_read
,
5790 .write
= lpfc_idiag_ctlacc_write
,
5791 .release
= lpfc_idiag_cmd_release
,
5794 #undef lpfc_idiag_op_mbxAcc
5795 static const struct file_operations lpfc_idiag_op_mbxAcc
= {
5796 .owner
= THIS_MODULE
,
5797 .open
= lpfc_idiag_open
,
5798 .llseek
= lpfc_debugfs_lseek
,
5799 .read
= lpfc_idiag_mbxacc_read
,
5800 .write
= lpfc_idiag_mbxacc_write
,
5801 .release
= lpfc_idiag_cmd_release
,
5804 #undef lpfc_idiag_op_extAcc
5805 static const struct file_operations lpfc_idiag_op_extAcc
= {
5806 .owner
= THIS_MODULE
,
5807 .open
= lpfc_idiag_open
,
5808 .llseek
= lpfc_debugfs_lseek
,
5809 .read
= lpfc_idiag_extacc_read
,
5810 .write
= lpfc_idiag_extacc_write
,
5811 .release
= lpfc_idiag_cmd_release
,
5813 #undef lpfc_cgn_buffer_op
5814 static const struct file_operations lpfc_cgn_buffer_op
= {
5815 .owner
= THIS_MODULE
,
5816 .open
= lpfc_cgn_buffer_open
,
5817 .llseek
= lpfc_debugfs_lseek
,
5818 .read
= lpfc_cgn_buffer_read
,
5819 .release
= lpfc_cgn_buffer_release
,
5822 #undef lpfc_rx_monitor_op
5823 static const struct file_operations lpfc_rx_monitor_op
= {
5824 .owner
= THIS_MODULE
,
5825 .open
= lpfc_rx_monitor_open
,
5826 .llseek
= lpfc_debugfs_lseek
,
5827 .read
= lpfc_rx_monitor_read
,
5828 .release
= lpfc_rx_monitor_release
,
5832 /* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command
5833 * @phba: Pointer to HBA context object.
5834 * @dmabuf: Pointer to a DMA buffer descriptor.
5837 * This routine dump a bsg pass-through non-embedded mailbox command with
5841 lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba
*phba
, enum nemb_type nemb_tp
,
5842 enum mbox_type mbox_tp
, enum dma_type dma_tp
,
5843 enum sta_type sta_tp
,
5844 struct lpfc_dmabuf
*dmabuf
, uint32_t ext_buf
)
5846 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
5847 uint32_t *mbx_mbox_cmd
, *mbx_dump_map
, *mbx_dump_cnt
, *mbx_word_cnt
;
5848 char line_buf
[LPFC_MBX_ACC_LBUF_SZ
];
5850 uint32_t do_dump
= 0;
5854 if (idiag
.cmd
.opcode
!= LPFC_IDIAG_BSG_MBXACC_DP
)
5857 mbx_mbox_cmd
= &idiag
.cmd
.data
[IDIAG_MBXACC_MBCMD_INDX
];
5858 mbx_dump_map
= &idiag
.cmd
.data
[IDIAG_MBXACC_DPMAP_INDX
];
5859 mbx_dump_cnt
= &idiag
.cmd
.data
[IDIAG_MBXACC_DPCNT_INDX
];
5860 mbx_word_cnt
= &idiag
.cmd
.data
[IDIAG_MBXACC_WDCNT_INDX
];
5862 if (!(*mbx_dump_map
& LPFC_MBX_DMP_ALL
) ||
5863 (*mbx_dump_cnt
== 0) ||
5864 (*mbx_word_cnt
== 0))
5867 if (*mbx_mbox_cmd
!= 0x9B)
5870 if ((mbox_tp
== mbox_rd
) && (dma_tp
== dma_mbox
)) {
5871 if (*mbx_dump_map
& LPFC_BSG_DMP_MBX_RD_MBX
) {
5872 do_dump
|= LPFC_BSG_DMP_MBX_RD_MBX
;
5873 pr_err("\nRead mbox command (x%x), "
5874 "nemb:0x%x, extbuf_cnt:%d:\n",
5875 sta_tp
, nemb_tp
, ext_buf
);
5878 if ((mbox_tp
== mbox_rd
) && (dma_tp
== dma_ebuf
)) {
5879 if (*mbx_dump_map
& LPFC_BSG_DMP_MBX_RD_BUF
) {
5880 do_dump
|= LPFC_BSG_DMP_MBX_RD_BUF
;
5881 pr_err("\nRead mbox buffer (x%x), "
5882 "nemb:0x%x, extbuf_seq:%d:\n",
5883 sta_tp
, nemb_tp
, ext_buf
);
5886 if ((mbox_tp
== mbox_wr
) && (dma_tp
== dma_mbox
)) {
5887 if (*mbx_dump_map
& LPFC_BSG_DMP_MBX_WR_MBX
) {
5888 do_dump
|= LPFC_BSG_DMP_MBX_WR_MBX
;
5889 pr_err("\nWrite mbox command (x%x), "
5890 "nemb:0x%x, extbuf_cnt:%d:\n",
5891 sta_tp
, nemb_tp
, ext_buf
);
5894 if ((mbox_tp
== mbox_wr
) && (dma_tp
== dma_ebuf
)) {
5895 if (*mbx_dump_map
& LPFC_BSG_DMP_MBX_WR_BUF
) {
5896 do_dump
|= LPFC_BSG_DMP_MBX_WR_BUF
;
5897 pr_err("\nWrite mbox buffer (x%x), "
5898 "nemb:0x%x, extbuf_seq:%d:\n",
5899 sta_tp
, nemb_tp
, ext_buf
);
5903 /* dump buffer content */
5905 pword
= (uint32_t *)dmabuf
->virt
;
5906 for (i
= 0; i
< *mbx_word_cnt
; i
++) {
5909 pr_err("%s\n", line_buf
);
5911 len
+= scnprintf(line_buf
+len
,
5912 LPFC_MBX_ACC_LBUF_SZ
-len
,
5915 len
+= scnprintf(line_buf
+len
, LPFC_MBX_ACC_LBUF_SZ
-len
,
5916 "%08x ", (uint32_t)*pword
);
5920 pr_err("%s\n", line_buf
);
5924 /* Clean out command structure on reaching dump count */
5925 if (*mbx_dump_cnt
== 0)
5926 memset(&idiag
, 0, sizeof(idiag
));
5931 /* lpfc_idiag_mbxacc_dump_issue_mbox - idiag debugfs dump issue mailbox command
5932 * @phba: Pointer to HBA context object.
5933 * @dmabuf: Pointer to a DMA buffer descriptor.
5936 * This routine dump a pass-through non-embedded mailbox command from issue
5940 lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba
*phba
, MAILBOX_t
*pmbox
)
5942 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
5943 uint32_t *mbx_dump_map
, *mbx_dump_cnt
, *mbx_word_cnt
, *mbx_mbox_cmd
;
5944 char line_buf
[LPFC_MBX_ACC_LBUF_SZ
];
5950 if (idiag
.cmd
.opcode
!= LPFC_IDIAG_CMD_MBXACC_DP
)
5953 mbx_mbox_cmd
= &idiag
.cmd
.data
[IDIAG_MBXACC_MBCMD_INDX
];
5954 mbx_dump_map
= &idiag
.cmd
.data
[IDIAG_MBXACC_DPMAP_INDX
];
5955 mbx_dump_cnt
= &idiag
.cmd
.data
[IDIAG_MBXACC_DPCNT_INDX
];
5956 mbx_word_cnt
= &idiag
.cmd
.data
[IDIAG_MBXACC_WDCNT_INDX
];
5958 if (!(*mbx_dump_map
& LPFC_MBX_DMP_MBX_ALL
) ||
5959 (*mbx_dump_cnt
== 0) ||
5960 (*mbx_word_cnt
== 0))
5963 if ((*mbx_mbox_cmd
!= LPFC_MBX_ALL_CMD
) &&
5964 (*mbx_mbox_cmd
!= pmbox
->mbxCommand
))
5967 /* dump buffer content */
5968 if (*mbx_dump_map
& LPFC_MBX_DMP_MBX_WORD
) {
5969 pr_err("Mailbox command:0x%x dump by word:\n",
5971 pword
= (uint32_t *)pmbox
;
5972 for (i
= 0; i
< *mbx_word_cnt
; i
++) {
5975 pr_err("%s\n", line_buf
);
5977 memset(line_buf
, 0, LPFC_MBX_ACC_LBUF_SZ
);
5978 len
+= scnprintf(line_buf
+len
,
5979 LPFC_MBX_ACC_LBUF_SZ
-len
,
5982 len
+= scnprintf(line_buf
+len
, LPFC_MBX_ACC_LBUF_SZ
-len
,
5984 ((uint32_t)*pword
) & 0xffffffff);
5988 pr_err("%s\n", line_buf
);
5991 if (*mbx_dump_map
& LPFC_MBX_DMP_MBX_BYTE
) {
5992 pr_err("Mailbox command:0x%x dump by byte:\n",
5994 pbyte
= (uint8_t *)pmbox
;
5995 for (i
= 0; i
< *mbx_word_cnt
; i
++) {
5998 pr_err("%s\n", line_buf
);
6000 memset(line_buf
, 0, LPFC_MBX_ACC_LBUF_SZ
);
6001 len
+= scnprintf(line_buf
+len
,
6002 LPFC_MBX_ACC_LBUF_SZ
-len
,
6005 for (j
= 0; j
< 4; j
++) {
6006 len
+= scnprintf(line_buf
+len
,
6007 LPFC_MBX_ACC_LBUF_SZ
-len
,
6009 ((uint8_t)*pbyte
) & 0xff);
6012 len
+= scnprintf(line_buf
+len
,
6013 LPFC_MBX_ACC_LBUF_SZ
-len
, " ");
6016 pr_err("%s\n", line_buf
);
6021 /* Clean out command structure on reaching dump count */
6022 if (*mbx_dump_cnt
== 0)
6023 memset(&idiag
, 0, sizeof(idiag
));
6029 * lpfc_debugfs_initialize - Initialize debugfs for a vport
6030 * @vport: The vport pointer to initialize.
6033 * When Debugfs is configured this routine sets up the lpfc debugfs file system.
6034 * If not already created, this routine will create the lpfc directory, and
6035 * lpfcX directory (for this HBA), and vportX directory for this vport. It will
6036 * also create each file used to access lpfc specific debugfs information.
6039 lpfc_debugfs_initialize(struct lpfc_vport
*vport
)
6041 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
6042 struct lpfc_hba
*phba
= vport
->phba
;
6045 bool pport_setup
= false;
6047 if (!lpfc_debugfs_enable
)
6050 /* Setup lpfc root directory */
6051 if (!lpfc_debugfs_root
) {
6052 lpfc_debugfs_root
= debugfs_create_dir("lpfc", NULL
);
6053 atomic_set(&lpfc_debugfs_hba_count
, 0);
6055 if (!lpfc_debugfs_start_time
)
6056 lpfc_debugfs_start_time
= jiffies
;
6058 /* Setup funcX directory for specific HBA PCI function */
6059 snprintf(name
, sizeof(name
), "fn%d", phba
->brd_no
);
6060 if (!phba
->hba_debugfs_root
) {
6062 phba
->hba_debugfs_root
=
6063 debugfs_create_dir(name
, lpfc_debugfs_root
);
6064 atomic_inc(&lpfc_debugfs_hba_count
);
6065 atomic_set(&phba
->debugfs_vport_count
, 0);
6067 /* Multi-XRI pools */
6068 snprintf(name
, sizeof(name
), "multixripools");
6069 phba
->debug_multixri_pools
=
6070 debugfs_create_file(name
, S_IFREG
| 0644,
6071 phba
->hba_debugfs_root
,
6073 &lpfc_debugfs_op_multixripools
);
6074 if (IS_ERR(phba
->debug_multixri_pools
)) {
6075 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
6076 "0527 Cannot create debugfs multixripools\n");
6080 /* Congestion Info Buffer */
6081 scnprintf(name
, sizeof(name
), "cgn_buffer");
6082 phba
->debug_cgn_buffer
=
6083 debugfs_create_file(name
, S_IFREG
| 0644,
6084 phba
->hba_debugfs_root
,
6085 phba
, &lpfc_cgn_buffer_op
);
6086 if (IS_ERR(phba
->debug_cgn_buffer
)) {
6087 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
6088 "6527 Cannot create debugfs "
6094 scnprintf(name
, sizeof(name
), "rx_monitor");
6095 phba
->debug_rx_monitor
=
6096 debugfs_create_file(name
, S_IFREG
| 0644,
6097 phba
->hba_debugfs_root
,
6098 phba
, &lpfc_rx_monitor_op
);
6099 if (IS_ERR(phba
->debug_rx_monitor
)) {
6100 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
6101 "6528 Cannot create debugfs "
6107 snprintf(name
, sizeof(name
), "ras_log");
6108 phba
->debug_ras_log
=
6109 debugfs_create_file(name
, 0644,
6110 phba
->hba_debugfs_root
,
6111 phba
, &lpfc_debugfs_ras_log
);
6112 if (IS_ERR(phba
->debug_ras_log
)) {
6113 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
6114 "6148 Cannot create debugfs"
6120 snprintf(name
, sizeof(name
), "hbqinfo");
6121 phba
->debug_hbqinfo
=
6122 debugfs_create_file(name
, S_IFREG
| 0644,
6123 phba
->hba_debugfs_root
,
6124 phba
, &lpfc_debugfs_op_hbqinfo
);
6126 #ifdef LPFC_HDWQ_LOCK_STAT
6127 /* Setup lockstat */
6128 snprintf(name
, sizeof(name
), "lockstat");
6129 phba
->debug_lockstat
=
6130 debugfs_create_file(name
, S_IFREG
| 0644,
6131 phba
->hba_debugfs_root
,
6132 phba
, &lpfc_debugfs_op_lockstat
);
6133 if (IS_ERR(phba
->debug_lockstat
)) {
6134 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
6135 "4610 Can't create debugfs lockstat\n");
6140 /* Setup dumpHBASlim */
6141 if (phba
->sli_rev
< LPFC_SLI_REV4
) {
6142 snprintf(name
, sizeof(name
), "dumpHBASlim");
6143 phba
->debug_dumpHBASlim
=
6144 debugfs_create_file(name
,
6145 S_IFREG
|S_IRUGO
|S_IWUSR
,
6146 phba
->hba_debugfs_root
,
6147 phba
, &lpfc_debugfs_op_dumpHBASlim
);
6149 phba
->debug_dumpHBASlim
= NULL
;
6151 /* Setup dumpHostSlim */
6152 if (phba
->sli_rev
< LPFC_SLI_REV4
) {
6153 snprintf(name
, sizeof(name
), "dumpHostSlim");
6154 phba
->debug_dumpHostSlim
=
6155 debugfs_create_file(name
,
6156 S_IFREG
|S_IRUGO
|S_IWUSR
,
6157 phba
->hba_debugfs_root
,
6158 phba
, &lpfc_debugfs_op_dumpHostSlim
);
6160 phba
->debug_dumpHostSlim
= NULL
;
6162 /* Setup DIF Error Injections */
6163 snprintf(name
, sizeof(name
), "InjErrLBA");
6164 phba
->debug_InjErrLBA
=
6165 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6166 phba
->hba_debugfs_root
,
6167 phba
, &lpfc_debugfs_op_dif_err
);
6168 phba
->lpfc_injerr_lba
= LPFC_INJERR_LBA_OFF
;
6170 snprintf(name
, sizeof(name
), "InjErrNPortID");
6171 phba
->debug_InjErrNPortID
=
6172 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6173 phba
->hba_debugfs_root
,
6174 phba
, &lpfc_debugfs_op_dif_err
);
6176 snprintf(name
, sizeof(name
), "InjErrWWPN");
6177 phba
->debug_InjErrWWPN
=
6178 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6179 phba
->hba_debugfs_root
,
6180 phba
, &lpfc_debugfs_op_dif_err
);
6182 snprintf(name
, sizeof(name
), "writeGuardInjErr");
6183 phba
->debug_writeGuard
=
6184 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6185 phba
->hba_debugfs_root
,
6186 phba
, &lpfc_debugfs_op_dif_err
);
6188 snprintf(name
, sizeof(name
), "writeAppInjErr");
6189 phba
->debug_writeApp
=
6190 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6191 phba
->hba_debugfs_root
,
6192 phba
, &lpfc_debugfs_op_dif_err
);
6194 snprintf(name
, sizeof(name
), "writeRefInjErr");
6195 phba
->debug_writeRef
=
6196 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6197 phba
->hba_debugfs_root
,
6198 phba
, &lpfc_debugfs_op_dif_err
);
6200 snprintf(name
, sizeof(name
), "readGuardInjErr");
6201 phba
->debug_readGuard
=
6202 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6203 phba
->hba_debugfs_root
,
6204 phba
, &lpfc_debugfs_op_dif_err
);
6206 snprintf(name
, sizeof(name
), "readAppInjErr");
6207 phba
->debug_readApp
=
6208 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6209 phba
->hba_debugfs_root
,
6210 phba
, &lpfc_debugfs_op_dif_err
);
6212 snprintf(name
, sizeof(name
), "readRefInjErr");
6213 phba
->debug_readRef
=
6214 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6215 phba
->hba_debugfs_root
,
6216 phba
, &lpfc_debugfs_op_dif_err
);
6218 /* Setup slow ring trace */
6219 if (lpfc_debugfs_max_slow_ring_trc
) {
6220 num
= lpfc_debugfs_max_slow_ring_trc
- 1;
6221 if (num
& lpfc_debugfs_max_slow_ring_trc
) {
6222 /* Change to be a power of 2 */
6223 num
= lpfc_debugfs_max_slow_ring_trc
;
6229 lpfc_debugfs_max_slow_ring_trc
= (1 << i
);
6230 pr_err("lpfc_debugfs_max_disc_trc changed to "
6231 "%d\n", lpfc_debugfs_max_disc_trc
);
6235 snprintf(name
, sizeof(name
), "slow_ring_trace");
6236 phba
->debug_slow_ring_trc
=
6237 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6238 phba
->hba_debugfs_root
,
6239 phba
, &lpfc_debugfs_op_slow_ring_trc
);
6240 if (!phba
->slow_ring_trc
) {
6241 phba
->slow_ring_trc
= kcalloc(
6242 lpfc_debugfs_max_slow_ring_trc
,
6243 sizeof(struct lpfc_debugfs_trc
),
6245 if (!phba
->slow_ring_trc
) {
6246 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
6247 "0416 Cannot create debugfs "
6248 "slow_ring buffer\n");
6251 atomic_set(&phba
->slow_ring_trc_cnt
, 0);
6254 snprintf(name
, sizeof(name
), "nvmeio_trc");
6255 phba
->debug_nvmeio_trc
=
6256 debugfs_create_file(name
, 0644,
6257 phba
->hba_debugfs_root
,
6258 phba
, &lpfc_debugfs_op_nvmeio_trc
);
6260 atomic_set(&phba
->nvmeio_trc_cnt
, 0);
6261 if (lpfc_debugfs_max_nvmeio_trc
) {
6262 num
= lpfc_debugfs_max_nvmeio_trc
- 1;
6263 if (num
& lpfc_debugfs_max_disc_trc
) {
6264 /* Change to be a power of 2 */
6265 num
= lpfc_debugfs_max_nvmeio_trc
;
6271 lpfc_debugfs_max_nvmeio_trc
= (1 << i
);
6272 lpfc_printf_log(phba
, KERN_ERR
, LOG_INIT
,
6273 "0575 lpfc_debugfs_max_nvmeio_trc "
6275 lpfc_debugfs_max_nvmeio_trc
);
6277 phba
->nvmeio_trc_size
= lpfc_debugfs_max_nvmeio_trc
;
6279 /* Allocate trace buffer and initialize */
6280 phba
->nvmeio_trc
= kzalloc(
6281 (sizeof(struct lpfc_debugfs_nvmeio_trc
) *
6282 phba
->nvmeio_trc_size
), GFP_KERNEL
);
6284 if (!phba
->nvmeio_trc
) {
6285 lpfc_printf_log(phba
, KERN_ERR
, LOG_INIT
,
6286 "0576 Cannot create debugfs "
6287 "nvmeio_trc buffer\n");
6290 phba
->nvmeio_trc_on
= 1;
6291 phba
->nvmeio_trc_output_idx
= 0;
6292 phba
->nvmeio_trc
= NULL
;
6295 phba
->nvmeio_trc_size
= 0;
6296 phba
->nvmeio_trc_on
= 0;
6297 phba
->nvmeio_trc_output_idx
= 0;
6298 phba
->nvmeio_trc
= NULL
;
6302 snprintf(name
, sizeof(name
), "vport%d", vport
->vpi
);
6303 if (!vport
->vport_debugfs_root
) {
6304 vport
->vport_debugfs_root
=
6305 debugfs_create_dir(name
, phba
->hba_debugfs_root
);
6306 atomic_inc(&phba
->debugfs_vport_count
);
6309 if (lpfc_debugfs_max_disc_trc
) {
6310 num
= lpfc_debugfs_max_disc_trc
- 1;
6311 if (num
& lpfc_debugfs_max_disc_trc
) {
6312 /* Change to be a power of 2 */
6313 num
= lpfc_debugfs_max_disc_trc
;
6319 lpfc_debugfs_max_disc_trc
= (1 << i
);
6320 pr_err("lpfc_debugfs_max_disc_trc changed to %d\n",
6321 lpfc_debugfs_max_disc_trc
);
6325 vport
->disc_trc
= kzalloc(
6326 (sizeof(struct lpfc_debugfs_trc
) * lpfc_debugfs_max_disc_trc
),
6329 if (!vport
->disc_trc
) {
6330 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
6331 "0418 Cannot create debugfs disc trace "
6335 atomic_set(&vport
->disc_trc_cnt
, 0);
6337 snprintf(name
, sizeof(name
), "discovery_trace");
6338 vport
->debug_disc_trc
=
6339 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6340 vport
->vport_debugfs_root
,
6341 vport
, &lpfc_debugfs_op_disc_trc
);
6342 snprintf(name
, sizeof(name
), "nodelist");
6343 vport
->debug_nodelist
=
6344 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6345 vport
->vport_debugfs_root
,
6346 vport
, &lpfc_debugfs_op_nodelist
);
6348 snprintf(name
, sizeof(name
), "nvmestat");
6349 vport
->debug_nvmestat
=
6350 debugfs_create_file(name
, 0644,
6351 vport
->vport_debugfs_root
,
6352 vport
, &lpfc_debugfs_op_nvmestat
);
6354 snprintf(name
, sizeof(name
), "scsistat");
6355 vport
->debug_scsistat
=
6356 debugfs_create_file(name
, 0644,
6357 vport
->vport_debugfs_root
,
6358 vport
, &lpfc_debugfs_op_scsistat
);
6359 if (IS_ERR(vport
->debug_scsistat
)) {
6360 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
6361 "4611 Cannot create debugfs scsistat\n");
6365 snprintf(name
, sizeof(name
), "ioktime");
6366 vport
->debug_ioktime
=
6367 debugfs_create_file(name
, 0644,
6368 vport
->vport_debugfs_root
,
6369 vport
, &lpfc_debugfs_op_ioktime
);
6370 if (IS_ERR(vport
->debug_ioktime
)) {
6371 lpfc_printf_vlog(vport
, KERN_ERR
, LOG_INIT
,
6372 "0815 Cannot create debugfs ioktime\n");
6376 snprintf(name
, sizeof(name
), "hdwqstat");
6377 vport
->debug_hdwqstat
=
6378 debugfs_create_file(name
, 0644,
6379 vport
->vport_debugfs_root
,
6380 vport
, &lpfc_debugfs_op_hdwqstat
);
6383 * The following section is for additional directories/files for the
6391 * iDiag debugfs root entry points for SLI4 device only
6393 if (phba
->sli_rev
< LPFC_SLI_REV4
)
6396 snprintf(name
, sizeof(name
), "iDiag");
6397 if (!phba
->idiag_root
) {
6399 debugfs_create_dir(name
, phba
->hba_debugfs_root
);
6400 /* Initialize iDiag data structure */
6401 memset(&idiag
, 0, sizeof(idiag
));
6404 /* iDiag read PCI config space */
6405 snprintf(name
, sizeof(name
), "pciCfg");
6406 if (!phba
->idiag_pci_cfg
) {
6407 phba
->idiag_pci_cfg
=
6408 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6409 phba
->idiag_root
, phba
, &lpfc_idiag_op_pciCfg
);
6410 idiag
.offset
.last_rd
= 0;
6413 /* iDiag PCI BAR access */
6414 snprintf(name
, sizeof(name
), "barAcc");
6415 if (!phba
->idiag_bar_acc
) {
6416 phba
->idiag_bar_acc
=
6417 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6418 phba
->idiag_root
, phba
, &lpfc_idiag_op_barAcc
);
6419 idiag
.offset
.last_rd
= 0;
6422 /* iDiag get PCI function queue information */
6423 snprintf(name
, sizeof(name
), "queInfo");
6424 if (!phba
->idiag_que_info
) {
6425 phba
->idiag_que_info
=
6426 debugfs_create_file(name
, S_IFREG
|S_IRUGO
,
6427 phba
->idiag_root
, phba
, &lpfc_idiag_op_queInfo
);
6430 /* iDiag access PCI function queue */
6431 snprintf(name
, sizeof(name
), "queAcc");
6432 if (!phba
->idiag_que_acc
) {
6433 phba
->idiag_que_acc
=
6434 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6435 phba
->idiag_root
, phba
, &lpfc_idiag_op_queAcc
);
6438 /* iDiag access PCI function doorbell registers */
6439 snprintf(name
, sizeof(name
), "drbAcc");
6440 if (!phba
->idiag_drb_acc
) {
6441 phba
->idiag_drb_acc
=
6442 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6443 phba
->idiag_root
, phba
, &lpfc_idiag_op_drbAcc
);
6446 /* iDiag access PCI function control registers */
6447 snprintf(name
, sizeof(name
), "ctlAcc");
6448 if (!phba
->idiag_ctl_acc
) {
6449 phba
->idiag_ctl_acc
=
6450 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6451 phba
->idiag_root
, phba
, &lpfc_idiag_op_ctlAcc
);
6454 /* iDiag access mbox commands */
6455 snprintf(name
, sizeof(name
), "mbxAcc");
6456 if (!phba
->idiag_mbx_acc
) {
6457 phba
->idiag_mbx_acc
=
6458 debugfs_create_file(name
, S_IFREG
|S_IRUGO
|S_IWUSR
,
6459 phba
->idiag_root
, phba
, &lpfc_idiag_op_mbxAcc
);
6462 /* iDiag extents access commands */
6463 if (phba
->sli4_hba
.extents_in_use
) {
6464 snprintf(name
, sizeof(name
), "extAcc");
6465 if (!phba
->idiag_ext_acc
) {
6466 phba
->idiag_ext_acc
=
6467 debugfs_create_file(name
,
6468 S_IFREG
|S_IRUGO
|S_IWUSR
,
6469 phba
->idiag_root
, phba
,
6470 &lpfc_idiag_op_extAcc
);
6480 * lpfc_debugfs_terminate - Tear down debugfs infrastructure for this vport
6481 * @vport: The vport pointer to remove from debugfs.
6484 * When Debugfs is configured this routine removes debugfs file system elements
6485 * that are specific to this vport. It also checks to see if there are any
6486 * users left for the debugfs directories associated with the HBA and driver. If
6487 * this is the last user of the HBA directory or driver directory then it will
6488 * remove those from the debugfs infrastructure as well.
6491 lpfc_debugfs_terminate(struct lpfc_vport
*vport
)
6493 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
6494 struct lpfc_hba
*phba
= vport
->phba
;
6496 kfree(vport
->disc_trc
);
6497 vport
->disc_trc
= NULL
;
6499 debugfs_remove(vport
->debug_disc_trc
); /* discovery_trace */
6500 vport
->debug_disc_trc
= NULL
;
6502 debugfs_remove(vport
->debug_nodelist
); /* nodelist */
6503 vport
->debug_nodelist
= NULL
;
6505 debugfs_remove(vport
->debug_nvmestat
); /* nvmestat */
6506 vport
->debug_nvmestat
= NULL
;
6508 debugfs_remove(vport
->debug_scsistat
); /* scsistat */
6509 vport
->debug_scsistat
= NULL
;
6511 debugfs_remove(vport
->debug_ioktime
); /* ioktime */
6512 vport
->debug_ioktime
= NULL
;
6514 debugfs_remove(vport
->debug_hdwqstat
); /* hdwqstat */
6515 vport
->debug_hdwqstat
= NULL
;
6517 if (vport
->vport_debugfs_root
) {
6518 debugfs_remove(vport
->vport_debugfs_root
); /* vportX */
6519 vport
->vport_debugfs_root
= NULL
;
6520 atomic_dec(&phba
->debugfs_vport_count
);
6523 if (atomic_read(&phba
->debugfs_vport_count
) == 0) {
6525 debugfs_remove(phba
->debug_multixri_pools
); /* multixripools*/
6526 phba
->debug_multixri_pools
= NULL
;
6528 debugfs_remove(phba
->debug_hbqinfo
); /* hbqinfo */
6529 phba
->debug_hbqinfo
= NULL
;
6531 debugfs_remove(phba
->debug_cgn_buffer
);
6532 phba
->debug_cgn_buffer
= NULL
;
6534 debugfs_remove(phba
->debug_rx_monitor
);
6535 phba
->debug_rx_monitor
= NULL
;
6537 debugfs_remove(phba
->debug_ras_log
);
6538 phba
->debug_ras_log
= NULL
;
6540 #ifdef LPFC_HDWQ_LOCK_STAT
6541 debugfs_remove(phba
->debug_lockstat
); /* lockstat */
6542 phba
->debug_lockstat
= NULL
;
6544 debugfs_remove(phba
->debug_dumpHBASlim
); /* HBASlim */
6545 phba
->debug_dumpHBASlim
= NULL
;
6547 debugfs_remove(phba
->debug_dumpHostSlim
); /* HostSlim */
6548 phba
->debug_dumpHostSlim
= NULL
;
6550 debugfs_remove(phba
->debug_InjErrLBA
); /* InjErrLBA */
6551 phba
->debug_InjErrLBA
= NULL
;
6553 debugfs_remove(phba
->debug_InjErrNPortID
);
6554 phba
->debug_InjErrNPortID
= NULL
;
6556 debugfs_remove(phba
->debug_InjErrWWPN
); /* InjErrWWPN */
6557 phba
->debug_InjErrWWPN
= NULL
;
6559 debugfs_remove(phba
->debug_writeGuard
); /* writeGuard */
6560 phba
->debug_writeGuard
= NULL
;
6562 debugfs_remove(phba
->debug_writeApp
); /* writeApp */
6563 phba
->debug_writeApp
= NULL
;
6565 debugfs_remove(phba
->debug_writeRef
); /* writeRef */
6566 phba
->debug_writeRef
= NULL
;
6568 debugfs_remove(phba
->debug_readGuard
); /* readGuard */
6569 phba
->debug_readGuard
= NULL
;
6571 debugfs_remove(phba
->debug_readApp
); /* readApp */
6572 phba
->debug_readApp
= NULL
;
6574 debugfs_remove(phba
->debug_readRef
); /* readRef */
6575 phba
->debug_readRef
= NULL
;
6577 kfree(phba
->slow_ring_trc
);
6578 phba
->slow_ring_trc
= NULL
;
6580 /* slow_ring_trace */
6581 debugfs_remove(phba
->debug_slow_ring_trc
);
6582 phba
->debug_slow_ring_trc
= NULL
;
6584 debugfs_remove(phba
->debug_nvmeio_trc
);
6585 phba
->debug_nvmeio_trc
= NULL
;
6587 kfree(phba
->nvmeio_trc
);
6588 phba
->nvmeio_trc
= NULL
;
6593 if (phba
->sli_rev
== LPFC_SLI_REV4
) {
6595 debugfs_remove(phba
->idiag_ext_acc
);
6596 phba
->idiag_ext_acc
= NULL
;
6599 debugfs_remove(phba
->idiag_mbx_acc
);
6600 phba
->idiag_mbx_acc
= NULL
;
6603 debugfs_remove(phba
->idiag_ctl_acc
);
6604 phba
->idiag_ctl_acc
= NULL
;
6607 debugfs_remove(phba
->idiag_drb_acc
);
6608 phba
->idiag_drb_acc
= NULL
;
6611 debugfs_remove(phba
->idiag_que_acc
);
6612 phba
->idiag_que_acc
= NULL
;
6615 debugfs_remove(phba
->idiag_que_info
);
6616 phba
->idiag_que_info
= NULL
;
6619 debugfs_remove(phba
->idiag_bar_acc
);
6620 phba
->idiag_bar_acc
= NULL
;
6623 debugfs_remove(phba
->idiag_pci_cfg
);
6624 phba
->idiag_pci_cfg
= NULL
;
6626 /* Finally remove the iDiag debugfs root */
6627 debugfs_remove(phba
->idiag_root
);
6628 phba
->idiag_root
= NULL
;
6631 if (phba
->hba_debugfs_root
) {
6632 debugfs_remove(phba
->hba_debugfs_root
); /* fnX */
6633 phba
->hba_debugfs_root
= NULL
;
6634 atomic_dec(&lpfc_debugfs_hba_count
);
6637 if (atomic_read(&lpfc_debugfs_hba_count
) == 0) {
6638 debugfs_remove(lpfc_debugfs_root
); /* lpfc */
6639 lpfc_debugfs_root
= NULL
;
6647 * Driver debug utility routines outside of debugfs. The debug utility
6648 * routines implemented here is intended to be used in the instrumented
6649 * debug driver for debugging host or port issues.
6653 * lpfc_debug_dump_all_queues - dump all the queues with a hba
6654 * @phba: Pointer to HBA context object.
6656 * This function dumps entries of all the queues asociated with the @phba.
6659 lpfc_debug_dump_all_queues(struct lpfc_hba
*phba
)
6664 * Dump Work Queues (WQs)
6666 lpfc_debug_dump_wq(phba
, DUMP_MBX
, 0);
6667 lpfc_debug_dump_wq(phba
, DUMP_ELS
, 0);
6668 lpfc_debug_dump_wq(phba
, DUMP_NVMELS
, 0);
6670 for (idx
= 0; idx
< phba
->cfg_hdw_queue
; idx
++)
6671 lpfc_debug_dump_wq(phba
, DUMP_IO
, idx
);
6673 lpfc_debug_dump_hdr_rq(phba
);
6674 lpfc_debug_dump_dat_rq(phba
);
6676 * Dump Complete Queues (CQs)
6678 lpfc_debug_dump_cq(phba
, DUMP_MBX
, 0);
6679 lpfc_debug_dump_cq(phba
, DUMP_ELS
, 0);
6680 lpfc_debug_dump_cq(phba
, DUMP_NVMELS
, 0);
6682 for (idx
= 0; idx
< phba
->cfg_hdw_queue
; idx
++)
6683 lpfc_debug_dump_cq(phba
, DUMP_IO
, idx
);
6686 * Dump Event Queues (EQs)
6688 for (idx
= 0; idx
< phba
->cfg_hdw_queue
; idx
++)
6689 lpfc_debug_dump_hba_eq(phba
, idx
);