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