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