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