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