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