1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/blkdev.h>
22#include <linux/delay.h>
23#include <linux/module.h>
24#include <linux/dma-mapping.h>
25#include <linux/idr.h>
26#include <linux/interrupt.h>
27#include <linux/kthread.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <linux/spinlock.h>
31#include <linux/ctype.h>
32
33#include <scsi/scsi.h>
34#include <scsi/scsi_device.h>
35#include <scsi/scsi_host.h>
36#include <scsi/scsi_transport_fc.h>
37
38#include "lpfc_hw4.h"
39#include "lpfc_hw.h"
40#include "lpfc_sli.h"
41#include "lpfc_sli4.h"
42#include "lpfc_nl.h"
43#include "lpfc_disc.h"
44#include "lpfc_scsi.h"
45#include "lpfc.h"
46#include "lpfc_logmsg.h"
47#include "lpfc_crtn.h"
48#include "lpfc_vport.h"
49#include "lpfc_version.h"
50#include "lpfc_compat.h"
51#include "lpfc_debugfs.h"
52#include "lpfc_bsg.h"
53
54#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86static int lpfc_debugfs_enable = 1;
87module_param(lpfc_debugfs_enable, int, S_IRUGO);
88MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services");
89
90
91static int lpfc_debugfs_max_disc_trc;
92module_param(lpfc_debugfs_max_disc_trc, int, S_IRUGO);
93MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc,
94 "Set debugfs discovery trace depth");
95
96
97static int lpfc_debugfs_max_slow_ring_trc;
98module_param(lpfc_debugfs_max_slow_ring_trc, int, S_IRUGO);
99MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
100 "Set debugfs slow ring trace depth");
101
102static int lpfc_debugfs_mask_disc_trc;
103module_param(lpfc_debugfs_mask_disc_trc, int, S_IRUGO);
104MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
105 "Set debugfs discovery trace mask");
106
107#include <linux/debugfs.h>
108
109static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
110static unsigned long lpfc_debugfs_start_time = 0L;
111
112
113static struct lpfc_idiag idiag;
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134static int
135lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
136{
137 int i, index, len, enable;
138 uint32_t ms;
139 struct lpfc_debugfs_trc *dtp;
140 char *buffer;
141
142 buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
143 if (!buffer)
144 return 0;
145
146 enable = lpfc_debugfs_enable;
147 lpfc_debugfs_enable = 0;
148
149 len = 0;
150 index = (atomic_read(&vport->disc_trc_cnt) + 1) &
151 (lpfc_debugfs_max_disc_trc - 1);
152 for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
153 dtp = vport->disc_trc + i;
154 if (!dtp->fmt)
155 continue;
156 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
157 snprintf(buffer,
158 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
159 dtp->seq_cnt, ms, dtp->fmt);
160 len += snprintf(buf+len, size-len, buffer,
161 dtp->data1, dtp->data2, dtp->data3);
162 }
163 for (i = 0; i < index; i++) {
164 dtp = vport->disc_trc + i;
165 if (!dtp->fmt)
166 continue;
167 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
168 snprintf(buffer,
169 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
170 dtp->seq_cnt, ms, dtp->fmt);
171 len += snprintf(buf+len, size-len, buffer,
172 dtp->data1, dtp->data2, dtp->data3);
173 }
174
175 lpfc_debugfs_enable = enable;
176 kfree(buffer);
177
178 return len;
179}
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200static int
201lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
202{
203 int i, index, len, enable;
204 uint32_t ms;
205 struct lpfc_debugfs_trc *dtp;
206 char *buffer;
207
208 buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
209 if (!buffer)
210 return 0;
211
212 enable = lpfc_debugfs_enable;
213 lpfc_debugfs_enable = 0;
214
215 len = 0;
216 index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
217 (lpfc_debugfs_max_slow_ring_trc - 1);
218 for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
219 dtp = phba->slow_ring_trc + i;
220 if (!dtp->fmt)
221 continue;
222 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
223 snprintf(buffer,
224 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
225 dtp->seq_cnt, ms, dtp->fmt);
226 len += snprintf(buf+len, size-len, buffer,
227 dtp->data1, dtp->data2, dtp->data3);
228 }
229 for (i = 0; i < index; i++) {
230 dtp = phba->slow_ring_trc + i;
231 if (!dtp->fmt)
232 continue;
233 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
234 snprintf(buffer,
235 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
236 dtp->seq_cnt, ms, dtp->fmt);
237 len += snprintf(buf+len, size-len, buffer,
238 dtp->data1, dtp->data2, dtp->data3);
239 }
240
241 lpfc_debugfs_enable = enable;
242 kfree(buffer);
243
244 return len;
245}
246
247static int lpfc_debugfs_last_hbq = -1;
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268static int
269lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
270{
271 int len = 0;
272 int i, j, found, posted, low;
273 uint32_t phys, raw_index, getidx;
274 struct lpfc_hbq_init *hip;
275 struct hbq_s *hbqs;
276 struct lpfc_hbq_entry *hbqe;
277 struct lpfc_dmabuf *d_buf;
278 struct hbq_dmabuf *hbq_buf;
279
280 if (phba->sli_rev != 3)
281 return 0;
282
283 spin_lock_irq(&phba->hbalock);
284
285
286 i = lpfc_sli_hbq_count();
287 if (i > 1) {
288 lpfc_debugfs_last_hbq++;
289 if (lpfc_debugfs_last_hbq >= i)
290 lpfc_debugfs_last_hbq = 0;
291 }
292 else
293 lpfc_debugfs_last_hbq = 0;
294
295 i = lpfc_debugfs_last_hbq;
296
297 len += snprintf(buf+len, size-len, "HBQ %d Info\n", i);
298
299 hbqs = &phba->hbqs[i];
300 posted = 0;
301 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
302 posted++;
303
304 hip = lpfc_hbq_defs[i];
305 len += snprintf(buf+len, size-len,
306 "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
307 hip->hbq_index, hip->profile, hip->rn,
308 hip->buffer_count, hip->init_count, hip->add_count, posted);
309
310 raw_index = phba->hbq_get[i];
311 getidx = le32_to_cpu(raw_index);
312 len += snprintf(buf+len, size-len,
313 "entrys:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
314 hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx,
315 hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx);
316
317 hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
318 for (j=0; j<hbqs->entry_count; j++) {
319 len += snprintf(buf+len, size-len,
320 "%03d: %08x %04x %05x ", j,
321 le32_to_cpu(hbqe->bde.addrLow),
322 le32_to_cpu(hbqe->bde.tus.w),
323 le32_to_cpu(hbqe->buffer_tag));
324 i = 0;
325 found = 0;
326
327
328 low = hbqs->hbqPutIdx - posted;
329 if (low >= 0) {
330 if ((j >= hbqs->hbqPutIdx) || (j < low)) {
331 len += snprintf(buf+len, size-len, "Unused\n");
332 goto skipit;
333 }
334 }
335 else {
336 if ((j >= hbqs->hbqPutIdx) &&
337 (j < (hbqs->entry_count+low))) {
338 len += snprintf(buf+len, size-len, "Unused\n");
339 goto skipit;
340 }
341 }
342
343
344 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
345 hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
346 phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
347 if (phys == le32_to_cpu(hbqe->bde.addrLow)) {
348 len += snprintf(buf+len, size-len,
349 "Buf%d: %p %06x\n", i,
350 hbq_buf->dbuf.virt, hbq_buf->tag);
351 found = 1;
352 break;
353 }
354 i++;
355 }
356 if (!found) {
357 len += snprintf(buf+len, size-len, "No DMAinfo?\n");
358 }
359skipit:
360 hbqe++;
361 if (len > LPFC_HBQINFO_SIZE - 54)
362 break;
363 }
364 spin_unlock_irq(&phba->hbalock);
365 return len;
366}
367
368static int lpfc_debugfs_last_hba_slim_off;
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388static int
389lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
390{
391 int len = 0;
392 int i, off;
393 uint32_t *ptr;
394 char *buffer;
395
396 buffer = kmalloc(1024, GFP_KERNEL);
397 if (!buffer)
398 return 0;
399
400 off = 0;
401 spin_lock_irq(&phba->hbalock);
402
403 len += snprintf(buf+len, size-len, "HBA SLIM\n");
404 lpfc_memcpy_from_slim(buffer,
405 phba->MBslimaddr + lpfc_debugfs_last_hba_slim_off, 1024);
406
407 ptr = (uint32_t *)&buffer[0];
408 off = lpfc_debugfs_last_hba_slim_off;
409
410
411 lpfc_debugfs_last_hba_slim_off += 1024;
412 if (lpfc_debugfs_last_hba_slim_off >= 4096)
413 lpfc_debugfs_last_hba_slim_off = 0;
414
415 i = 1024;
416 while (i > 0) {
417 len += snprintf(buf+len, size-len,
418 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
419 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
420 *(ptr+5), *(ptr+6), *(ptr+7));
421 ptr += 8;
422 i -= (8 * sizeof(uint32_t));
423 off += (8 * sizeof(uint32_t));
424 }
425
426 spin_unlock_irq(&phba->hbalock);
427 kfree(buffer);
428
429 return len;
430}
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447static int
448lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
449{
450 int len = 0;
451 int i, off;
452 uint32_t word0, word1, word2, word3;
453 uint32_t *ptr;
454 struct lpfc_pgp *pgpp;
455 struct lpfc_sli *psli = &phba->sli;
456 struct lpfc_sli_ring *pring;
457
458 off = 0;
459 spin_lock_irq(&phba->hbalock);
460
461 len += snprintf(buf+len, size-len, "SLIM Mailbox\n");
462 ptr = (uint32_t *)phba->slim2p.virt;
463 i = sizeof(MAILBOX_t);
464 while (i > 0) {
465 len += snprintf(buf+len, size-len,
466 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
467 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
468 *(ptr+5), *(ptr+6), *(ptr+7));
469 ptr += 8;
470 i -= (8 * sizeof(uint32_t));
471 off += (8 * sizeof(uint32_t));
472 }
473
474 len += snprintf(buf+len, size-len, "SLIM PCB\n");
475 ptr = (uint32_t *)phba->pcb;
476 i = sizeof(PCB_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 for (i = 0; i < 4; i++) {
488 pgpp = &phba->port_gp[i];
489 pring = &psli->ring[i];
490 len += snprintf(buf+len, size-len,
491 "Ring %d: CMD GetInx:%d (Max:%d Next:%d "
492 "Local:%d flg:x%x) RSP PutInx:%d Max:%d\n",
493 i, pgpp->cmdGetInx, pring->sli.sli3.numCiocb,
494 pring->sli.sli3.next_cmdidx,
495 pring->sli.sli3.local_getidx,
496 pring->flag, pgpp->rspPutInx,
497 pring->sli.sli3.numRiocb);
498 }
499
500 if (phba->sli_rev <= LPFC_SLI_REV3) {
501 word0 = readl(phba->HAregaddr);
502 word1 = readl(phba->CAregaddr);
503 word2 = readl(phba->HSregaddr);
504 word3 = readl(phba->HCregaddr);
505 len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x "
506 "HC:%08x\n", word0, word1, word2, word3);
507 }
508 spin_unlock_irq(&phba->hbalock);
509 return len;
510}
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527static int
528lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
529{
530 int len = 0;
531 int cnt;
532 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
533 struct lpfc_nodelist *ndlp;
534 unsigned char *statep, *name;
535
536 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
537
538 spin_lock_irq(shost->host_lock);
539 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
540 if (!cnt) {
541 len += snprintf(buf+len, size-len,
542 "Missing Nodelist Entries\n");
543 break;
544 }
545 cnt--;
546 switch (ndlp->nlp_state) {
547 case NLP_STE_UNUSED_NODE:
548 statep = "UNUSED";
549 break;
550 case NLP_STE_PLOGI_ISSUE:
551 statep = "PLOGI ";
552 break;
553 case NLP_STE_ADISC_ISSUE:
554 statep = "ADISC ";
555 break;
556 case NLP_STE_REG_LOGIN_ISSUE:
557 statep = "REGLOG";
558 break;
559 case NLP_STE_PRLI_ISSUE:
560 statep = "PRLI ";
561 break;
562 case NLP_STE_LOGO_ISSUE:
563 statep = "LOGO ";
564 break;
565 case NLP_STE_UNMAPPED_NODE:
566 statep = "UNMAP ";
567 break;
568 case NLP_STE_MAPPED_NODE:
569 statep = "MAPPED";
570 break;
571 case NLP_STE_NPR_NODE:
572 statep = "NPR ";
573 break;
574 default:
575 statep = "UNKNOWN";
576 }
577 len += snprintf(buf+len, size-len, "%s DID:x%06x ",
578 statep, ndlp->nlp_DID);
579 name = (unsigned char *)&ndlp->nlp_portname;
580 len += snprintf(buf+len, size-len,
581 "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
582 *name, *(name+1), *(name+2), *(name+3),
583 *(name+4), *(name+5), *(name+6), *(name+7));
584 name = (unsigned char *)&ndlp->nlp_nodename;
585 len += snprintf(buf+len, size-len,
586 "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
587 *name, *(name+1), *(name+2), *(name+3),
588 *(name+4), *(name+5), *(name+6), *(name+7));
589 if (ndlp->nlp_flag & NLP_RPI_REGISTERED)
590 len += snprintf(buf+len, size-len, "RPI:%03d ",
591 ndlp->nlp_rpi);
592 else
593 len += snprintf(buf+len, size-len, "RPI:none ");
594 len += snprintf(buf+len, size-len, "flag:x%08x ",
595 ndlp->nlp_flag);
596 if (!ndlp->nlp_type)
597 len += snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
598 if (ndlp->nlp_type & NLP_FC_NODE)
599 len += snprintf(buf+len, size-len, "FC_NODE ");
600 if (ndlp->nlp_type & NLP_FABRIC)
601 len += snprintf(buf+len, size-len, "FABRIC ");
602 if (ndlp->nlp_type & NLP_FCP_TARGET)
603 len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ",
604 ndlp->nlp_sid);
605 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
606 len += snprintf(buf+len, size-len, "FCP_INITIATOR ");
607 len += snprintf(buf+len, size-len, "usgmap:%x ",
608 ndlp->nlp_usg_map);
609 len += snprintf(buf+len, size-len, "refcnt:%x",
610 atomic_read(&ndlp->kref.refcount));
611 len += snprintf(buf+len, size-len, "\n");
612 }
613 spin_unlock_irq(shost->host_lock);
614 return len;
615}
616#endif
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634inline void
635lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
636 uint32_t data1, uint32_t data2, uint32_t data3)
637{
638#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
639 struct lpfc_debugfs_trc *dtp;
640 int index;
641
642 if (!(lpfc_debugfs_mask_disc_trc & mask))
643 return;
644
645 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
646 !vport || !vport->disc_trc)
647 return;
648
649 index = atomic_inc_return(&vport->disc_trc_cnt) &
650 (lpfc_debugfs_max_disc_trc - 1);
651 dtp = vport->disc_trc + index;
652 dtp->fmt = fmt;
653 dtp->data1 = data1;
654 dtp->data2 = data2;
655 dtp->data3 = data3;
656 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
657 dtp->jif = jiffies;
658#endif
659 return;
660}
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675inline void
676lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
677 uint32_t data1, uint32_t data2, uint32_t data3)
678{
679#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
680 struct lpfc_debugfs_trc *dtp;
681 int index;
682
683 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
684 !phba || !phba->slow_ring_trc)
685 return;
686
687 index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
688 (lpfc_debugfs_max_slow_ring_trc - 1);
689 dtp = phba->slow_ring_trc + index;
690 dtp->fmt = fmt;
691 dtp->data1 = data1;
692 dtp->data2 = data2;
693 dtp->data3 = data3;
694 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
695 dtp->jif = jiffies;
696#endif
697 return;
698}
699
700#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716static int
717lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
718{
719 struct lpfc_vport *vport = inode->i_private;
720 struct lpfc_debug *debug;
721 int size;
722 int rc = -ENOMEM;
723
724 if (!lpfc_debugfs_max_disc_trc) {
725 rc = -ENOSPC;
726 goto out;
727 }
728
729 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
730 if (!debug)
731 goto out;
732
733
734 size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
735 size = PAGE_ALIGN(size);
736
737 debug->buffer = kmalloc(size, GFP_KERNEL);
738 if (!debug->buffer) {
739 kfree(debug);
740 goto out;
741 }
742
743 debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
744 file->private_data = debug;
745
746 rc = 0;
747out:
748 return rc;
749}
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766static int
767lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
768{
769 struct lpfc_hba *phba = inode->i_private;
770 struct lpfc_debug *debug;
771 int size;
772 int rc = -ENOMEM;
773
774 if (!lpfc_debugfs_max_slow_ring_trc) {
775 rc = -ENOSPC;
776 goto out;
777 }
778
779 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
780 if (!debug)
781 goto out;
782
783
784 size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
785 size = PAGE_ALIGN(size);
786
787 debug->buffer = kmalloc(size, GFP_KERNEL);
788 if (!debug->buffer) {
789 kfree(debug);
790 goto out;
791 }
792
793 debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
794 file->private_data = debug;
795
796 rc = 0;
797out:
798 return rc;
799}
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816static int
817lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
818{
819 struct lpfc_hba *phba = inode->i_private;
820 struct lpfc_debug *debug;
821 int rc = -ENOMEM;
822
823 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
824 if (!debug)
825 goto out;
826
827
828 debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
829 if (!debug->buffer) {
830 kfree(debug);
831 goto out;
832 }
833
834 debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
835 LPFC_HBQINFO_SIZE);
836 file->private_data = debug;
837
838 rc = 0;
839out:
840 return rc;
841}
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858static int
859lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file)
860{
861 struct lpfc_hba *phba = inode->i_private;
862 struct lpfc_debug *debug;
863 int rc = -ENOMEM;
864
865 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
866 if (!debug)
867 goto out;
868
869
870 debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL);
871 if (!debug->buffer) {
872 kfree(debug);
873 goto out;
874 }
875
876 debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer,
877 LPFC_DUMPHBASLIM_SIZE);
878 file->private_data = debug;
879
880 rc = 0;
881out:
882 return rc;
883}
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900static int
901lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file)
902{
903 struct lpfc_hba *phba = inode->i_private;
904 struct lpfc_debug *debug;
905 int rc = -ENOMEM;
906
907 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
908 if (!debug)
909 goto out;
910
911
912 debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL);
913 if (!debug->buffer) {
914 kfree(debug);
915 goto out;
916 }
917
918 debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer,
919 LPFC_DUMPHOSTSLIM_SIZE);
920 file->private_data = debug;
921
922 rc = 0;
923out:
924 return rc;
925}
926
927static int
928lpfc_debugfs_dumpData_open(struct inode *inode, struct file *file)
929{
930 struct lpfc_debug *debug;
931 int rc = -ENOMEM;
932
933 if (!_dump_buf_data)
934 return -EBUSY;
935
936 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
937 if (!debug)
938 goto out;
939
940
941 printk(KERN_ERR "9059 BLKGRD: %s: _dump_buf_data=0x%p\n",
942 __func__, _dump_buf_data);
943 debug->buffer = _dump_buf_data;
944 if (!debug->buffer) {
945 kfree(debug);
946 goto out;
947 }
948
949 debug->len = (1 << _dump_buf_data_order) << PAGE_SHIFT;
950 file->private_data = debug;
951
952 rc = 0;
953out:
954 return rc;
955}
956
957static int
958lpfc_debugfs_dumpDif_open(struct inode *inode, struct file *file)
959{
960 struct lpfc_debug *debug;
961 int rc = -ENOMEM;
962
963 if (!_dump_buf_dif)
964 return -EBUSY;
965
966 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
967 if (!debug)
968 goto out;
969
970
971 printk(KERN_ERR "9060 BLKGRD: %s: _dump_buf_dif=0x%p file=%pD\n",
972 __func__, _dump_buf_dif, file);
973 debug->buffer = _dump_buf_dif;
974 if (!debug->buffer) {
975 kfree(debug);
976 goto out;
977 }
978
979 debug->len = (1 << _dump_buf_dif_order) << PAGE_SHIFT;
980 file->private_data = debug;
981
982 rc = 0;
983out:
984 return rc;
985}
986
987static ssize_t
988lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf,
989 size_t nbytes, loff_t *ppos)
990{
991
992
993
994
995
996 spin_lock(&_dump_buf_lock);
997
998 memset((void *)_dump_buf_data, 0,
999 ((1 << PAGE_SHIFT) << _dump_buf_data_order));
1000 memset((void *)_dump_buf_dif, 0,
1001 ((1 << PAGE_SHIFT) << _dump_buf_dif_order));
1002
1003 _dump_buf_done = 0;
1004
1005 spin_unlock(&_dump_buf_lock);
1006
1007 return nbytes;
1008}
1009
1010static ssize_t
1011lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
1012 size_t nbytes, loff_t *ppos)
1013{
1014 struct dentry *dent = file->f_path.dentry;
1015 struct lpfc_hba *phba = file->private_data;
1016 char cbuf[32];
1017 uint64_t tmp = 0;
1018 int cnt = 0;
1019
1020 if (dent == phba->debug_writeGuard)
1021 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt);
1022 else if (dent == phba->debug_writeApp)
1023 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt);
1024 else if (dent == phba->debug_writeRef)
1025 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt);
1026 else if (dent == phba->debug_readGuard)
1027 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt);
1028 else if (dent == phba->debug_readApp)
1029 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt);
1030 else if (dent == phba->debug_readRef)
1031 cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt);
1032 else if (dent == phba->debug_InjErrNPortID)
1033 cnt = snprintf(cbuf, 32, "0x%06x\n", phba->lpfc_injerr_nportid);
1034 else if (dent == phba->debug_InjErrWWPN) {
1035 memcpy(&tmp, &phba->lpfc_injerr_wwpn, sizeof(struct lpfc_name));
1036 tmp = cpu_to_be64(tmp);
1037 cnt = snprintf(cbuf, 32, "0x%016llx\n", tmp);
1038 } else if (dent == phba->debug_InjErrLBA) {
1039 if (phba->lpfc_injerr_lba == (sector_t)(-1))
1040 cnt = snprintf(cbuf, 32, "off\n");
1041 else
1042 cnt = snprintf(cbuf, 32, "0x%llx\n",
1043 (uint64_t) phba->lpfc_injerr_lba);
1044 } else
1045 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1046 "0547 Unknown debugfs error injection entry\n");
1047
1048 return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt);
1049}
1050
1051static ssize_t
1052lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
1053 size_t nbytes, loff_t *ppos)
1054{
1055 struct dentry *dent = file->f_path.dentry;
1056 struct lpfc_hba *phba = file->private_data;
1057 char dstbuf[33];
1058 uint64_t tmp = 0;
1059 int size;
1060
1061 memset(dstbuf, 0, 33);
1062 size = (nbytes < 32) ? nbytes : 32;
1063 if (copy_from_user(dstbuf, buf, size))
1064 return 0;
1065
1066 if (dent == phba->debug_InjErrLBA) {
1067 if ((buf[0] == 'o') && (buf[1] == 'f') && (buf[2] == 'f'))
1068 tmp = (uint64_t)(-1);
1069 }
1070
1071 if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp)))
1072 return 0;
1073
1074 if (dent == phba->debug_writeGuard)
1075 phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
1076 else if (dent == phba->debug_writeApp)
1077 phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
1078 else if (dent == phba->debug_writeRef)
1079 phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
1080 else if (dent == phba->debug_readGuard)
1081 phba->lpfc_injerr_rgrd_cnt = (uint32_t)tmp;
1082 else if (dent == phba->debug_readApp)
1083 phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
1084 else if (dent == phba->debug_readRef)
1085 phba->lpfc_injerr_rref_cnt = (uint32_t)tmp;
1086 else if (dent == phba->debug_InjErrLBA)
1087 phba->lpfc_injerr_lba = (sector_t)tmp;
1088 else if (dent == phba->debug_InjErrNPortID)
1089 phba->lpfc_injerr_nportid = (uint32_t)(tmp & Mask_DID);
1090 else if (dent == phba->debug_InjErrWWPN) {
1091 tmp = cpu_to_be64(tmp);
1092 memcpy(&phba->lpfc_injerr_wwpn, &tmp, sizeof(struct lpfc_name));
1093 } else
1094 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1095 "0548 Unknown debugfs error injection entry\n");
1096
1097 return nbytes;
1098}
1099
1100static int
1101lpfc_debugfs_dif_err_release(struct inode *inode, struct file *file)
1102{
1103 return 0;
1104}
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121static int
1122lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
1123{
1124 struct lpfc_vport *vport = inode->i_private;
1125 struct lpfc_debug *debug;
1126 int rc = -ENOMEM;
1127
1128 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1129 if (!debug)
1130 goto out;
1131
1132
1133 debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
1134 if (!debug->buffer) {
1135 kfree(debug);
1136 goto out;
1137 }
1138
1139 debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
1140 LPFC_NODELIST_SIZE);
1141 file->private_data = debug;
1142
1143 rc = 0;
1144out:
1145 return rc;
1146}
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165static loff_t
1166lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
1167{
1168 struct lpfc_debug *debug = file->private_data;
1169 return fixed_size_llseek(file, off, whence, debug->len);
1170}
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188static ssize_t
1189lpfc_debugfs_read(struct file *file, char __user *buf,
1190 size_t nbytes, loff_t *ppos)
1191{
1192 struct lpfc_debug *debug = file->private_data;
1193
1194 return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
1195 debug->len);
1196}
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210static int
1211lpfc_debugfs_release(struct inode *inode, struct file *file)
1212{
1213 struct lpfc_debug *debug = file->private_data;
1214
1215 kfree(debug->buffer);
1216 kfree(debug);
1217
1218 return 0;
1219}
1220
1221static int
1222lpfc_debugfs_dumpDataDif_release(struct inode *inode, struct file *file)
1223{
1224 struct lpfc_debug *debug = file->private_data;
1225
1226 debug->buffer = NULL;
1227 kfree(debug);
1228
1229 return 0;
1230}
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256static int lpfc_idiag_cmd_get(const char __user *buf, size_t nbytes,
1257 struct lpfc_idiag_cmd *idiag_cmd)
1258{
1259 char mybuf[64];
1260 char *pbuf, *step_str;
1261 int i;
1262 size_t bsize;
1263
1264
1265 if (!access_ok(VERIFY_READ, buf, nbytes))
1266 return -EFAULT;
1267
1268 memset(mybuf, 0, sizeof(mybuf));
1269 memset(idiag_cmd, 0, sizeof(*idiag_cmd));
1270 bsize = min(nbytes, (sizeof(mybuf)-1));
1271
1272 if (copy_from_user(mybuf, buf, bsize))
1273 return -EFAULT;
1274 pbuf = &mybuf[0];
1275 step_str = strsep(&pbuf, "\t ");
1276
1277
1278 if (!step_str)
1279 return -EINVAL;
1280
1281 idiag_cmd->opcode = simple_strtol(step_str, NULL, 0);
1282 if (idiag_cmd->opcode == 0)
1283 return -EINVAL;
1284
1285 for (i = 0; i < LPFC_IDIAG_CMD_DATA_SIZE; i++) {
1286 step_str = strsep(&pbuf, "\t ");
1287 if (!step_str)
1288 return i;
1289 idiag_cmd->data[i] = simple_strtol(step_str, NULL, 0);
1290 }
1291 return i;
1292}
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311static int
1312lpfc_idiag_open(struct inode *inode, struct file *file)
1313{
1314 struct lpfc_debug *debug;
1315
1316 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1317 if (!debug)
1318 return -ENOMEM;
1319
1320 debug->i_private = inode->i_private;
1321 debug->buffer = NULL;
1322 file->private_data = debug;
1323
1324 return 0;
1325}
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340static int
1341lpfc_idiag_release(struct inode *inode, struct file *file)
1342{
1343 struct lpfc_debug *debug = file->private_data;
1344
1345
1346 kfree(debug->buffer);
1347 kfree(debug);
1348
1349 return 0;
1350}
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365static int
1366lpfc_idiag_cmd_release(struct inode *inode, struct file *file)
1367{
1368 struct lpfc_debug *debug = file->private_data;
1369
1370 if (debug->op == LPFC_IDIAG_OP_WR) {
1371 switch (idiag.cmd.opcode) {
1372 case LPFC_IDIAG_CMD_PCICFG_WR:
1373 case LPFC_IDIAG_CMD_PCICFG_ST:
1374 case LPFC_IDIAG_CMD_PCICFG_CL:
1375 case LPFC_IDIAG_CMD_QUEACC_WR:
1376 case LPFC_IDIAG_CMD_QUEACC_ST:
1377 case LPFC_IDIAG_CMD_QUEACC_CL:
1378 memset(&idiag, 0, sizeof(idiag));
1379 break;
1380 default:
1381 break;
1382 }
1383 }
1384
1385
1386 kfree(debug->buffer);
1387 kfree(debug);
1388
1389 return 0;
1390}
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410static ssize_t
1411lpfc_idiag_pcicfg_read(struct file *file, char __user *buf, size_t nbytes,
1412 loff_t *ppos)
1413{
1414 struct lpfc_debug *debug = file->private_data;
1415 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1416 int offset_label, offset, len = 0, index = LPFC_PCI_CFG_RD_SIZE;
1417 int where, count;
1418 char *pbuffer;
1419 struct pci_dev *pdev;
1420 uint32_t u32val;
1421 uint16_t u16val;
1422 uint8_t u8val;
1423
1424 pdev = phba->pcidev;
1425 if (!pdev)
1426 return 0;
1427
1428
1429 debug->op = LPFC_IDIAG_OP_RD;
1430
1431 if (!debug->buffer)
1432 debug->buffer = kmalloc(LPFC_PCI_CFG_SIZE, GFP_KERNEL);
1433 if (!debug->buffer)
1434 return 0;
1435 pbuffer = debug->buffer;
1436
1437 if (*ppos)
1438 return 0;
1439
1440 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
1441 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
1442 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
1443 } else
1444 return 0;
1445
1446
1447 switch (count) {
1448 case SIZE_U8:
1449 pci_read_config_byte(pdev, where, &u8val);
1450 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1451 "%03x: %02x\n", where, u8val);
1452 break;
1453 case SIZE_U16:
1454 pci_read_config_word(pdev, where, &u16val);
1455 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1456 "%03x: %04x\n", where, u16val);
1457 break;
1458 case SIZE_U32:
1459 pci_read_config_dword(pdev, where, &u32val);
1460 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1461 "%03x: %08x\n", where, u32val);
1462 break;
1463 case LPFC_PCI_CFG_BROWSE:
1464 goto pcicfg_browse;
1465 break;
1466 default:
1467
1468 len = 0;
1469 break;
1470 }
1471 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1472
1473pcicfg_browse:
1474
1475
1476 offset_label = idiag.offset.last_rd;
1477 offset = offset_label;
1478
1479
1480 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1481 "%03x: ", offset_label);
1482 while (index > 0) {
1483 pci_read_config_dword(pdev, offset, &u32val);
1484 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1485 "%08x ", u32val);
1486 offset += sizeof(uint32_t);
1487 if (offset >= LPFC_PCI_CFG_SIZE) {
1488 len += snprintf(pbuffer+len,
1489 LPFC_PCI_CFG_SIZE-len, "\n");
1490 break;
1491 }
1492 index -= sizeof(uint32_t);
1493 if (!index)
1494 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1495 "\n");
1496 else if (!(index % (8 * sizeof(uint32_t)))) {
1497 offset_label += (8 * sizeof(uint32_t));
1498 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1499 "\n%03x: ", offset_label);
1500 }
1501 }
1502
1503
1504 if (index == 0) {
1505 idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE;
1506 if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE)
1507 idiag.offset.last_rd = 0;
1508 } else
1509 idiag.offset.last_rd = 0;
1510
1511 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1512}
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532static ssize_t
1533lpfc_idiag_pcicfg_write(struct file *file, const char __user *buf,
1534 size_t nbytes, loff_t *ppos)
1535{
1536 struct lpfc_debug *debug = file->private_data;
1537 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1538 uint32_t where, value, count;
1539 uint32_t u32val;
1540 uint16_t u16val;
1541 uint8_t u8val;
1542 struct pci_dev *pdev;
1543 int rc;
1544
1545 pdev = phba->pcidev;
1546 if (!pdev)
1547 return -EFAULT;
1548
1549
1550 debug->op = LPFC_IDIAG_OP_WR;
1551
1552 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
1553 if (rc < 0)
1554 return rc;
1555
1556 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
1557
1558 if (rc != LPFC_PCI_CFG_RD_CMD_ARG)
1559 goto error_out;
1560
1561 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
1562 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
1563 if (count == LPFC_PCI_CFG_BROWSE) {
1564 if (where % sizeof(uint32_t))
1565 goto error_out;
1566
1567 idiag.offset.last_rd = where;
1568 } else if ((count != sizeof(uint8_t)) &&
1569 (count != sizeof(uint16_t)) &&
1570 (count != sizeof(uint32_t)))
1571 goto error_out;
1572 if (count == sizeof(uint8_t)) {
1573 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
1574 goto error_out;
1575 if (where % sizeof(uint8_t))
1576 goto error_out;
1577 }
1578 if (count == sizeof(uint16_t)) {
1579 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
1580 goto error_out;
1581 if (where % sizeof(uint16_t))
1582 goto error_out;
1583 }
1584 if (count == sizeof(uint32_t)) {
1585 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
1586 goto error_out;
1587 if (where % sizeof(uint32_t))
1588 goto error_out;
1589 }
1590 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR ||
1591 idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST ||
1592 idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1593
1594 if (rc != LPFC_PCI_CFG_WR_CMD_ARG)
1595 goto error_out;
1596
1597 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
1598 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
1599 value = idiag.cmd.data[IDIAG_PCICFG_VALUE_INDX];
1600
1601 if ((count != sizeof(uint8_t)) &&
1602 (count != sizeof(uint16_t)) &&
1603 (count != sizeof(uint32_t)))
1604 goto error_out;
1605 if (count == sizeof(uint8_t)) {
1606 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
1607 goto error_out;
1608 if (where % sizeof(uint8_t))
1609 goto error_out;
1610 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
1611 pci_write_config_byte(pdev, where,
1612 (uint8_t)value);
1613 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
1614 rc = pci_read_config_byte(pdev, where, &u8val);
1615 if (!rc) {
1616 u8val |= (uint8_t)value;
1617 pci_write_config_byte(pdev, where,
1618 u8val);
1619 }
1620 }
1621 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1622 rc = pci_read_config_byte(pdev, where, &u8val);
1623 if (!rc) {
1624 u8val &= (uint8_t)(~value);
1625 pci_write_config_byte(pdev, where,
1626 u8val);
1627 }
1628 }
1629 }
1630 if (count == sizeof(uint16_t)) {
1631 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
1632 goto error_out;
1633 if (where % sizeof(uint16_t))
1634 goto error_out;
1635 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
1636 pci_write_config_word(pdev, where,
1637 (uint16_t)value);
1638 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
1639 rc = pci_read_config_word(pdev, where, &u16val);
1640 if (!rc) {
1641 u16val |= (uint16_t)value;
1642 pci_write_config_word(pdev, where,
1643 u16val);
1644 }
1645 }
1646 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1647 rc = pci_read_config_word(pdev, where, &u16val);
1648 if (!rc) {
1649 u16val &= (uint16_t)(~value);
1650 pci_write_config_word(pdev, where,
1651 u16val);
1652 }
1653 }
1654 }
1655 if (count == sizeof(uint32_t)) {
1656 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
1657 goto error_out;
1658 if (where % sizeof(uint32_t))
1659 goto error_out;
1660 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
1661 pci_write_config_dword(pdev, where, value);
1662 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
1663 rc = pci_read_config_dword(pdev, where,
1664 &u32val);
1665 if (!rc) {
1666 u32val |= value;
1667 pci_write_config_dword(pdev, where,
1668 u32val);
1669 }
1670 }
1671 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1672 rc = pci_read_config_dword(pdev, where,
1673 &u32val);
1674 if (!rc) {
1675 u32val &= ~value;
1676 pci_write_config_dword(pdev, where,
1677 u32val);
1678 }
1679 }
1680 }
1681 } else
1682
1683 goto error_out;
1684
1685 return nbytes;
1686error_out:
1687 memset(&idiag, 0, sizeof(idiag));
1688 return -EINVAL;
1689}
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706static ssize_t
1707lpfc_idiag_baracc_read(struct file *file, char __user *buf, size_t nbytes,
1708 loff_t *ppos)
1709{
1710 struct lpfc_debug *debug = file->private_data;
1711 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1712 int offset_label, offset, offset_run, len = 0, index;
1713 int bar_num, acc_range, bar_size;
1714 char *pbuffer;
1715 void __iomem *mem_mapped_bar;
1716 uint32_t if_type;
1717 struct pci_dev *pdev;
1718 uint32_t u32val;
1719
1720 pdev = phba->pcidev;
1721 if (!pdev)
1722 return 0;
1723
1724
1725 debug->op = LPFC_IDIAG_OP_RD;
1726
1727 if (!debug->buffer)
1728 debug->buffer = kmalloc(LPFC_PCI_BAR_RD_BUF_SIZE, GFP_KERNEL);
1729 if (!debug->buffer)
1730 return 0;
1731 pbuffer = debug->buffer;
1732
1733 if (*ppos)
1734 return 0;
1735
1736 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
1737 bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
1738 offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
1739 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
1740 bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
1741 } else
1742 return 0;
1743
1744 if (acc_range == 0)
1745 return 0;
1746
1747 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
1748 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
1749 if (bar_num == IDIAG_BARACC_BAR_0)
1750 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1751 else if (bar_num == IDIAG_BARACC_BAR_1)
1752 mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
1753 else if (bar_num == IDIAG_BARACC_BAR_2)
1754 mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
1755 else
1756 return 0;
1757 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
1758 if (bar_num == IDIAG_BARACC_BAR_0)
1759 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1760 else
1761 return 0;
1762 } else
1763 return 0;
1764
1765
1766 if (acc_range == SINGLE_WORD) {
1767 offset_run = offset;
1768 u32val = readl(mem_mapped_bar + offset_run);
1769 len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
1770 "%05x: %08x\n", offset_run, u32val);
1771 } else
1772 goto baracc_browse;
1773
1774 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1775
1776baracc_browse:
1777
1778
1779 offset_label = idiag.offset.last_rd;
1780 offset_run = offset_label;
1781
1782
1783 len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
1784 "%05x: ", offset_label);
1785 index = LPFC_PCI_BAR_RD_SIZE;
1786 while (index > 0) {
1787 u32val = readl(mem_mapped_bar + offset_run);
1788 len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
1789 "%08x ", u32val);
1790 offset_run += sizeof(uint32_t);
1791 if (acc_range == LPFC_PCI_BAR_BROWSE) {
1792 if (offset_run >= bar_size) {
1793 len += snprintf(pbuffer+len,
1794 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
1795 break;
1796 }
1797 } else {
1798 if (offset_run >= offset +
1799 (acc_range * sizeof(uint32_t))) {
1800 len += snprintf(pbuffer+len,
1801 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
1802 break;
1803 }
1804 }
1805 index -= sizeof(uint32_t);
1806 if (!index)
1807 len += snprintf(pbuffer+len,
1808 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
1809 else if (!(index % (8 * sizeof(uint32_t)))) {
1810 offset_label += (8 * sizeof(uint32_t));
1811 len += snprintf(pbuffer+len,
1812 LPFC_PCI_BAR_RD_BUF_SIZE-len,
1813 "\n%05x: ", offset_label);
1814 }
1815 }
1816
1817
1818 if (index == 0) {
1819 idiag.offset.last_rd += LPFC_PCI_BAR_RD_SIZE;
1820 if (acc_range == LPFC_PCI_BAR_BROWSE) {
1821 if (idiag.offset.last_rd >= bar_size)
1822 idiag.offset.last_rd = 0;
1823 } else {
1824 if (offset_run >= offset +
1825 (acc_range * sizeof(uint32_t)))
1826 idiag.offset.last_rd = offset;
1827 }
1828 } else {
1829 if (acc_range == LPFC_PCI_BAR_BROWSE)
1830 idiag.offset.last_rd = 0;
1831 else
1832 idiag.offset.last_rd = offset;
1833 }
1834
1835 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1836}
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857static ssize_t
1858lpfc_idiag_baracc_write(struct file *file, const char __user *buf,
1859 size_t nbytes, loff_t *ppos)
1860{
1861 struct lpfc_debug *debug = file->private_data;
1862 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1863 uint32_t bar_num, bar_size, offset, value, acc_range;
1864 struct pci_dev *pdev;
1865 void __iomem *mem_mapped_bar;
1866 uint32_t if_type;
1867 uint32_t u32val;
1868 int rc;
1869
1870 pdev = phba->pcidev;
1871 if (!pdev)
1872 return -EFAULT;
1873
1874
1875 debug->op = LPFC_IDIAG_OP_WR;
1876
1877 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
1878 if (rc < 0)
1879 return rc;
1880
1881 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
1882 bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
1883
1884 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
1885 if ((bar_num != IDIAG_BARACC_BAR_0) &&
1886 (bar_num != IDIAG_BARACC_BAR_1) &&
1887 (bar_num != IDIAG_BARACC_BAR_2))
1888 goto error_out;
1889 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
1890 if (bar_num != IDIAG_BARACC_BAR_0)
1891 goto error_out;
1892 } else
1893 goto error_out;
1894
1895 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
1896 if (bar_num == IDIAG_BARACC_BAR_0) {
1897 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1898 LPFC_PCI_IF0_BAR0_SIZE;
1899 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1900 } else if (bar_num == IDIAG_BARACC_BAR_1) {
1901 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1902 LPFC_PCI_IF0_BAR1_SIZE;
1903 mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
1904 } else if (bar_num == IDIAG_BARACC_BAR_2) {
1905 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1906 LPFC_PCI_IF0_BAR2_SIZE;
1907 mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
1908 } else
1909 goto error_out;
1910 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
1911 if (bar_num == IDIAG_BARACC_BAR_0) {
1912 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1913 LPFC_PCI_IF2_BAR0_SIZE;
1914 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1915 } else
1916 goto error_out;
1917 } else
1918 goto error_out;
1919
1920 offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
1921 if (offset % sizeof(uint32_t))
1922 goto error_out;
1923
1924 bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
1925 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
1926
1927 if (rc != LPFC_PCI_BAR_RD_CMD_ARG)
1928 goto error_out;
1929 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
1930 if (acc_range == LPFC_PCI_BAR_BROWSE) {
1931 if (offset > bar_size - sizeof(uint32_t))
1932 goto error_out;
1933
1934 idiag.offset.last_rd = offset;
1935 } else if (acc_range > SINGLE_WORD) {
1936 if (offset + acc_range * sizeof(uint32_t) > bar_size)
1937 goto error_out;
1938
1939 idiag.offset.last_rd = offset;
1940 } else if (acc_range != SINGLE_WORD)
1941 goto error_out;
1942 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR ||
1943 idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST ||
1944 idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
1945
1946 if (rc != LPFC_PCI_BAR_WR_CMD_ARG)
1947 goto error_out;
1948
1949 acc_range = SINGLE_WORD;
1950 value = idiag.cmd.data[IDIAG_BARACC_REG_VAL_INDX];
1951 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR) {
1952 writel(value, mem_mapped_bar + offset);
1953 readl(mem_mapped_bar + offset);
1954 }
1955 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST) {
1956 u32val = readl(mem_mapped_bar + offset);
1957 u32val |= value;
1958 writel(u32val, mem_mapped_bar + offset);
1959 readl(mem_mapped_bar + offset);
1960 }
1961 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
1962 u32val = readl(mem_mapped_bar + offset);
1963 u32val &= ~value;
1964 writel(u32val, mem_mapped_bar + offset);
1965 readl(mem_mapped_bar + offset);
1966 }
1967 } else
1968
1969 goto error_out;
1970
1971 return nbytes;
1972error_out:
1973 memset(&idiag, 0, sizeof(idiag));
1974 return -EINVAL;
1975}
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992static ssize_t
1993lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
1994 loff_t *ppos)
1995{
1996 struct lpfc_debug *debug = file->private_data;
1997 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1998 int len = 0;
1999 char *pbuffer;
2000 int x, cnt;
2001 int max_cnt;
2002 struct lpfc_queue *qp = NULL;
2003
2004
2005 if (!debug->buffer)
2006 debug->buffer = kmalloc(LPFC_QUE_INFO_GET_BUF_SIZE, GFP_KERNEL);
2007 if (!debug->buffer)
2008 return 0;
2009 pbuffer = debug->buffer;
2010 max_cnt = LPFC_QUE_INFO_GET_BUF_SIZE - 128;
2011
2012 if (*ppos)
2013 return 0;
2014
2015 spin_lock_irq(&phba->hbalock);
2016
2017
2018 if (phba->sli4_hba.hba_eq && phba->cfg_fcp_io_channel) {
2019 cnt = phba->cfg_fcp_io_channel;
2020
2021 for (x = 0; x < cnt; x++) {
2022
2023
2024 qp = phba->sli4_hba.hba_eq[x];
2025 if (!qp)
2026 goto proc_cq;
2027
2028 len += snprintf(pbuffer+len,
2029 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2030 "\nHBA EQ info: "
2031 "EQ-STAT[max:x%x noE:x%x "
2032 "bs:x%x proc:x%llx]\n",
2033 qp->q_cnt_1, qp->q_cnt_2,
2034 qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
2035
2036 len += snprintf(pbuffer+len,
2037 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2038 "EQID[%02d], "
2039 "QE-CNT[%04d], QE-SIZE[%04d], "
2040 "HOST-IDX[%04d], PORT-IDX[%04d]",
2041 qp->queue_id,
2042 qp->entry_count,
2043 qp->entry_size,
2044 qp->host_index,
2045 qp->hba_index);
2046
2047
2048
2049 qp->EQ_max_eqe = 0;
2050
2051 len += snprintf(pbuffer+len,
2052 LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2053 if (len >= max_cnt)
2054 goto too_big;
2055proc_cq:
2056
2057 qp = phba->sli4_hba.fcp_cq[x];
2058 len += snprintf(pbuffer+len,
2059 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2060 "\tFCP CQ info: ");
2061 len += snprintf(pbuffer+len,
2062 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2063 "AssocEQID[%02d]: "
2064 "CQ STAT[max:x%x relw:x%x "
2065 "xabt:x%x wq:x%llx]\n",
2066 qp->assoc_qid,
2067 qp->q_cnt_1, qp->q_cnt_2,
2068 qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
2069 len += snprintf(pbuffer+len,
2070 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2071 "\tCQID[%02d], "
2072 "QE-CNT[%04d], QE-SIZE[%04d], "
2073 "HOST-IDX[%04d], PORT-IDX[%04d]",
2074 qp->queue_id, qp->entry_count,
2075 qp->entry_size, qp->host_index,
2076 qp->hba_index);
2077
2078
2079
2080 qp->CQ_max_cqe = 0;
2081
2082 len += snprintf(pbuffer+len,
2083 LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2084 if (len >= max_cnt)
2085 goto too_big;
2086
2087
2088 qp = phba->sli4_hba.fcp_wq[x];
2089
2090 len += snprintf(pbuffer+len,
2091 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2092 "\t\tFCP WQ info: ");
2093 len += snprintf(pbuffer+len,
2094 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2095 "AssocCQID[%02d]: "
2096 "WQ-STAT[oflow:x%x posted:x%llx]\n",
2097 qp->assoc_qid,
2098 qp->q_cnt_1, (unsigned long long)qp->q_cnt_4);
2099 len += snprintf(pbuffer+len,
2100 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2101 "\t\tWQID[%02d], "
2102 "QE-CNT[%04d], QE-SIZE[%04d], "
2103 "HOST-IDX[%04d], PORT-IDX[%04d]",
2104 qp->queue_id,
2105 qp->entry_count,
2106 qp->entry_size,
2107 qp->host_index,
2108 qp->hba_index);
2109
2110 len += snprintf(pbuffer+len,
2111 LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2112 if (len >= max_cnt)
2113 goto too_big;
2114
2115 if (x)
2116 continue;
2117
2118
2119
2120
2121 qp = phba->sli4_hba.mbx_cq;
2122 if (qp) {
2123 len += snprintf(pbuffer+len,
2124 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2125 "\tMBX CQ info: ");
2126 len += snprintf(pbuffer+len,
2127 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2128 "AssocEQID[%02d]: "
2129 "CQ-STAT[mbox:x%x relw:x%x "
2130 "xabt:x%x wq:x%llx]\n",
2131 qp->assoc_qid,
2132 qp->q_cnt_1, qp->q_cnt_2,
2133 qp->q_cnt_3,
2134 (unsigned long long)qp->q_cnt_4);
2135 len += snprintf(pbuffer+len,
2136 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2137 "\tCQID[%02d], "
2138 "QE-CNT[%04d], QE-SIZE[%04d], "
2139 "HOST-IDX[%04d], PORT-IDX[%04d]",
2140 qp->queue_id, qp->entry_count,
2141 qp->entry_size, qp->host_index,
2142 qp->hba_index);
2143
2144 len += snprintf(pbuffer+len,
2145 LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2146 if (len >= max_cnt)
2147 goto too_big;
2148 }
2149
2150
2151 qp = phba->sli4_hba.mbx_wq;
2152 if (qp) {
2153 len += snprintf(pbuffer+len,
2154 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2155 "\t\tMBX MQ info: ");
2156 len += snprintf(pbuffer+len,
2157 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2158 "AssocCQID[%02d]:\n",
2159 phba->sli4_hba.mbx_wq->assoc_qid);
2160 len += snprintf(pbuffer+len,
2161 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2162 "\t\tWQID[%02d], "
2163 "QE-CNT[%04d], QE-SIZE[%04d], "
2164 "HOST-IDX[%04d], PORT-IDX[%04d]",
2165 qp->queue_id, qp->entry_count,
2166 qp->entry_size, qp->host_index,
2167 qp->hba_index);
2168
2169 len += snprintf(pbuffer+len,
2170 LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2171 if (len >= max_cnt)
2172 goto too_big;
2173 }
2174
2175
2176 qp = phba->sli4_hba.els_cq;
2177 if (qp) {
2178 len += snprintf(pbuffer+len,
2179 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2180 "\tELS CQ info: ");
2181 len += snprintf(pbuffer+len,
2182 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2183 "AssocEQID[%02d]: "
2184 "CQ-STAT[max:x%x relw:x%x "
2185 "xabt:x%x wq:x%llx]\n",
2186 qp->assoc_qid,
2187 qp->q_cnt_1, qp->q_cnt_2,
2188 qp->q_cnt_3,
2189 (unsigned long long)qp->q_cnt_4);
2190 len += snprintf(pbuffer+len,
2191 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2192 "\tCQID [%02d], "
2193 "QE-CNT[%04d], QE-SIZE[%04d], "
2194 "HOST-IDX[%04d], PORT-IDX[%04d]",
2195 qp->queue_id, qp->entry_count,
2196 qp->entry_size, qp->host_index,
2197 qp->hba_index);
2198
2199
2200 qp->CQ_max_cqe = 0;
2201
2202 len += snprintf(pbuffer+len,
2203 LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2204 if (len >= max_cnt)
2205 goto too_big;
2206 }
2207
2208
2209 qp = phba->sli4_hba.els_wq;
2210 if (qp) {
2211 len += snprintf(pbuffer+len,
2212 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2213 "\t\tELS WQ info: ");
2214 len += snprintf(pbuffer+len,
2215 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2216 "AssocCQID[%02d]: "
2217 " WQ-STAT[oflow:x%x "
2218 "posted:x%llx]\n",
2219 qp->assoc_qid,
2220 qp->q_cnt_1,
2221 (unsigned long long)qp->q_cnt_4);
2222 len += snprintf(pbuffer+len,
2223 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2224 "\t\tWQID[%02d], "
2225 "QE-CNT[%04d], QE-SIZE[%04d], "
2226 "HOST-IDX[%04d], PORT-IDX[%04d]",
2227 qp->queue_id, qp->entry_count,
2228 qp->entry_size, qp->host_index,
2229 qp->hba_index);
2230
2231 len += snprintf(pbuffer+len,
2232 LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2233 if (len >= max_cnt)
2234 goto too_big;
2235 }
2236
2237 if (phba->sli4_hba.hdr_rq && phba->sli4_hba.dat_rq) {
2238
2239 qp = phba->sli4_hba.hdr_rq;
2240
2241 len += snprintf(pbuffer+len,
2242 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2243 "\t\tRQ info: ");
2244 len += snprintf(pbuffer+len,
2245 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2246 "AssocCQID[%02d]: "
2247 "RQ-STAT[nopost:x%x nobuf:x%x "
2248 "trunc:x%x rcv:x%llx]\n",
2249 qp->assoc_qid,
2250 qp->q_cnt_1, qp->q_cnt_2,
2251 qp->q_cnt_3,
2252 (unsigned long long)qp->q_cnt_4);
2253 len += snprintf(pbuffer+len,
2254 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2255 "\t\tHQID[%02d], "
2256 "QE-CNT[%04d], QE-SIZE[%04d], "
2257 "HOST-IDX[%04d], PORT-IDX[%04d]\n",
2258 qp->queue_id,
2259 qp->entry_count,
2260 qp->entry_size,
2261 qp->host_index,
2262 qp->hba_index);
2263
2264
2265 qp = phba->sli4_hba.dat_rq;
2266 len += snprintf(pbuffer+len,
2267 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2268 "\t\tDQID[%02d], "
2269 "QE-CNT[%04d], QE-SIZE[%04d], "
2270 "HOST-IDX[%04d], PORT-IDX[%04d]\n",
2271 qp->queue_id,
2272 qp->entry_count,
2273 qp->entry_size,
2274 qp->host_index,
2275 qp->hba_index);
2276
2277 len += snprintf(pbuffer+len,
2278 LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2279 }
2280 }
2281 }
2282
2283 if (phba->cfg_fof) {
2284
2285 qp = phba->sli4_hba.fof_eq;
2286 if (!qp)
2287 goto out;
2288
2289 len += snprintf(pbuffer+len,
2290 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2291 "\nFOF EQ info: "
2292 "EQ-STAT[max:x%x noE:x%x "
2293 "bs:x%x proc:x%llx]\n",
2294 qp->q_cnt_1, qp->q_cnt_2,
2295 qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
2296
2297 len += snprintf(pbuffer+len,
2298 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2299 "EQID[%02d], "
2300 "QE-CNT[%04d], QE-SIZE[%04d], "
2301 "HOST-IDX[%04d], PORT-IDX[%04d]",
2302 qp->queue_id,
2303 qp->entry_count,
2304 qp->entry_size,
2305 qp->host_index,
2306 qp->hba_index);
2307
2308
2309 qp->EQ_max_eqe = 0;
2310
2311 len += snprintf(pbuffer+len,
2312 LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2313 if (len >= max_cnt)
2314 goto too_big;
2315 }
2316
2317 if (phba->cfg_fof) {
2318
2319
2320 qp = phba->sli4_hba.oas_cq;
2321 if (qp) {
2322 len += snprintf(pbuffer+len,
2323 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2324 "\tOAS CQ info: ");
2325 len += snprintf(pbuffer+len,
2326 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2327 "AssocEQID[%02d]: "
2328 "CQ STAT[max:x%x relw:x%x "
2329 "xabt:x%x wq:x%llx]\n",
2330 qp->assoc_qid,
2331 qp->q_cnt_1, qp->q_cnt_2,
2332 qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
2333 len += snprintf(pbuffer+len,
2334 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2335 "\tCQID[%02d], "
2336 "QE-CNT[%04d], QE-SIZE[%04d], "
2337 "HOST-IDX[%04d], PORT-IDX[%04d]",
2338 qp->queue_id, qp->entry_count,
2339 qp->entry_size, qp->host_index,
2340 qp->hba_index);
2341
2342
2343 qp->CQ_max_cqe = 0;
2344
2345 len += snprintf(pbuffer+len,
2346 LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2347 if (len >= max_cnt)
2348 goto too_big;
2349 }
2350
2351
2352 qp = phba->sli4_hba.oas_wq;
2353 if (qp) {
2354 len += snprintf(pbuffer+len,
2355 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2356 "\t\tOAS WQ info: ");
2357 len += snprintf(pbuffer+len,
2358 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2359 "AssocCQID[%02d]: "
2360 "WQ-STAT[oflow:x%x posted:x%llx]\n",
2361 qp->assoc_qid,
2362 qp->q_cnt_1, (unsigned long long)qp->q_cnt_4);
2363 len += snprintf(pbuffer+len,
2364 LPFC_QUE_INFO_GET_BUF_SIZE-len,
2365 "\t\tWQID[%02d], "
2366 "QE-CNT[%04d], QE-SIZE[%04d], "
2367 "HOST-IDX[%04d], PORT-IDX[%04d]",
2368 qp->queue_id,
2369 qp->entry_count,
2370 qp->entry_size,
2371 qp->host_index,
2372 qp->hba_index);
2373
2374 len += snprintf(pbuffer+len,
2375 LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
2376 if (len >= max_cnt)
2377 goto too_big;
2378 }
2379 }
2380out:
2381 spin_unlock_irq(&phba->hbalock);
2382 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2383
2384too_big:
2385 len += snprintf(pbuffer+len,
2386 LPFC_QUE_INFO_GET_BUF_SIZE-len, "Truncated ...\n");
2387 spin_unlock_irq(&phba->hbalock);
2388 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2389}
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404static int
2405lpfc_idiag_que_param_check(struct lpfc_queue *q, int index, int count)
2406{
2407
2408 if ((count != 1) && (count != LPFC_QUE_ACC_BROWSE))
2409 return -EINVAL;
2410 if (index > q->entry_count - 1)
2411 return -EINVAL;
2412 return 0;
2413}
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429static int
2430lpfc_idiag_queacc_read_qe(char *pbuffer, int len, struct lpfc_queue *pque,
2431 uint32_t index)
2432{
2433 int offset, esize;
2434 uint32_t *pentry;
2435
2436 if (!pbuffer || !pque)
2437 return 0;
2438
2439 esize = pque->entry_size;
2440 len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
2441 "QE-INDEX[%04d]:\n", index);
2442
2443 offset = 0;
2444 pentry = pque->qe[index].address;
2445 while (esize > 0) {
2446 len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
2447 "%08x ", *pentry);
2448 pentry++;
2449 offset += sizeof(uint32_t);
2450 esize -= sizeof(uint32_t);
2451 if (esize > 0 && !(offset % (4 * sizeof(uint32_t))))
2452 len += snprintf(pbuffer+len,
2453 LPFC_QUE_ACC_BUF_SIZE-len, "\n");
2454 }
2455 len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, "\n");
2456
2457 return len;
2458}
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477static ssize_t
2478lpfc_idiag_queacc_read(struct file *file, char __user *buf, size_t nbytes,
2479 loff_t *ppos)
2480{
2481 struct lpfc_debug *debug = file->private_data;
2482 uint32_t last_index, index, count;
2483 struct lpfc_queue *pque = NULL;
2484 char *pbuffer;
2485 int len = 0;
2486
2487
2488 debug->op = LPFC_IDIAG_OP_RD;
2489
2490 if (!debug->buffer)
2491 debug->buffer = kmalloc(LPFC_QUE_ACC_BUF_SIZE, GFP_KERNEL);
2492 if (!debug->buffer)
2493 return 0;
2494 pbuffer = debug->buffer;
2495
2496 if (*ppos)
2497 return 0;
2498
2499 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
2500 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
2501 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
2502 pque = (struct lpfc_queue *)idiag.ptr_private;
2503 } else
2504 return 0;
2505
2506
2507 if (count == LPFC_QUE_ACC_BROWSE)
2508 goto que_browse;
2509
2510
2511 len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
2512
2513 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2514
2515que_browse:
2516
2517
2518 last_index = idiag.offset.last_rd;
2519 index = last_index;
2520
2521 while (len < LPFC_QUE_ACC_SIZE - pque->entry_size) {
2522 len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
2523 index++;
2524 if (index > pque->entry_count - 1)
2525 break;
2526 }
2527
2528
2529 if (index > pque->entry_count - 1)
2530 index = 0;
2531 idiag.offset.last_rd = index;
2532
2533 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2534}
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554static ssize_t
2555lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
2556 size_t nbytes, loff_t *ppos)
2557{
2558 struct lpfc_debug *debug = file->private_data;
2559 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2560 uint32_t qidx, quetp, queid, index, count, offset, value;
2561 uint32_t *pentry;
2562 struct lpfc_queue *pque;
2563 int rc;
2564
2565
2566 debug->op = LPFC_IDIAG_OP_WR;
2567
2568 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
2569 if (rc < 0)
2570 return rc;
2571
2572
2573 quetp = idiag.cmd.data[IDIAG_QUEACC_QUETP_INDX];
2574 queid = idiag.cmd.data[IDIAG_QUEACC_QUEID_INDX];
2575 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
2576 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
2577 offset = idiag.cmd.data[IDIAG_QUEACC_OFFST_INDX];
2578 value = idiag.cmd.data[IDIAG_QUEACC_VALUE_INDX];
2579
2580
2581 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
2582 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
2583 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
2584 if (rc != LPFC_QUE_ACC_WR_CMD_ARG)
2585 goto error_out;
2586 if (count != 1)
2587 goto error_out;
2588 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
2589 if (rc != LPFC_QUE_ACC_RD_CMD_ARG)
2590 goto error_out;
2591 } else
2592 goto error_out;
2593
2594 switch (quetp) {
2595 case LPFC_IDIAG_EQ:
2596
2597 if (phba->sli4_hba.hba_eq) {
2598 for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
2599 qidx++) {
2600 if (phba->sli4_hba.hba_eq[qidx] &&
2601 phba->sli4_hba.hba_eq[qidx]->queue_id ==
2602 queid) {
2603
2604 rc = lpfc_idiag_que_param_check(
2605 phba->sli4_hba.hba_eq[qidx],
2606 index, count);
2607 if (rc)
2608 goto error_out;
2609 idiag.ptr_private =
2610 phba->sli4_hba.hba_eq[qidx];
2611 goto pass_check;
2612 }
2613 }
2614 }
2615 goto error_out;
2616 break;
2617 case LPFC_IDIAG_CQ:
2618
2619 if (phba->sli4_hba.mbx_cq &&
2620 phba->sli4_hba.mbx_cq->queue_id == queid) {
2621
2622 rc = lpfc_idiag_que_param_check(
2623 phba->sli4_hba.mbx_cq, index, count);
2624 if (rc)
2625 goto error_out;
2626 idiag.ptr_private = phba->sli4_hba.mbx_cq;
2627 goto pass_check;
2628 }
2629
2630 if (phba->sli4_hba.els_cq &&
2631 phba->sli4_hba.els_cq->queue_id == queid) {
2632
2633 rc = lpfc_idiag_que_param_check(
2634 phba->sli4_hba.els_cq, index, count);
2635 if (rc)
2636 goto error_out;
2637 idiag.ptr_private = phba->sli4_hba.els_cq;
2638 goto pass_check;
2639 }
2640
2641 if (phba->sli4_hba.fcp_cq) {
2642 qidx = 0;
2643 do {
2644 if (phba->sli4_hba.fcp_cq[qidx] &&
2645 phba->sli4_hba.fcp_cq[qidx]->queue_id ==
2646 queid) {
2647
2648 rc = lpfc_idiag_que_param_check(
2649 phba->sli4_hba.fcp_cq[qidx],
2650 index, count);
2651 if (rc)
2652 goto error_out;
2653 idiag.ptr_private =
2654 phba->sli4_hba.fcp_cq[qidx];
2655 goto pass_check;
2656 }
2657 } while (++qidx < phba->cfg_fcp_io_channel);
2658 }
2659 goto error_out;
2660 break;
2661 case LPFC_IDIAG_MQ:
2662
2663 if (phba->sli4_hba.mbx_wq &&
2664 phba->sli4_hba.mbx_wq->queue_id == queid) {
2665
2666 rc = lpfc_idiag_que_param_check(
2667 phba->sli4_hba.mbx_wq, index, count);
2668 if (rc)
2669 goto error_out;
2670 idiag.ptr_private = phba->sli4_hba.mbx_wq;
2671 goto pass_check;
2672 }
2673 goto error_out;
2674 break;
2675 case LPFC_IDIAG_WQ:
2676
2677 if (phba->sli4_hba.els_wq &&
2678 phba->sli4_hba.els_wq->queue_id == queid) {
2679
2680 rc = lpfc_idiag_que_param_check(
2681 phba->sli4_hba.els_wq, index, count);
2682 if (rc)
2683 goto error_out;
2684 idiag.ptr_private = phba->sli4_hba.els_wq;
2685 goto pass_check;
2686 }
2687
2688 if (phba->sli4_hba.fcp_wq) {
2689 for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
2690 qidx++) {
2691 if (!phba->sli4_hba.fcp_wq[qidx])
2692 continue;
2693 if (phba->sli4_hba.fcp_wq[qidx]->queue_id ==
2694 queid) {
2695
2696 rc = lpfc_idiag_que_param_check(
2697 phba->sli4_hba.fcp_wq[qidx],
2698 index, count);
2699 if (rc)
2700 goto error_out;
2701 idiag.ptr_private =
2702 phba->sli4_hba.fcp_wq[qidx];
2703 goto pass_check;
2704 }
2705 }
2706 }
2707 goto error_out;
2708 break;
2709 case LPFC_IDIAG_RQ:
2710
2711 if (phba->sli4_hba.hdr_rq &&
2712 phba->sli4_hba.hdr_rq->queue_id == queid) {
2713
2714 rc = lpfc_idiag_que_param_check(
2715 phba->sli4_hba.hdr_rq, index, count);
2716 if (rc)
2717 goto error_out;
2718 idiag.ptr_private = phba->sli4_hba.hdr_rq;
2719 goto pass_check;
2720 }
2721
2722 if (phba->sli4_hba.dat_rq &&
2723 phba->sli4_hba.dat_rq->queue_id == queid) {
2724
2725 rc = lpfc_idiag_que_param_check(
2726 phba->sli4_hba.dat_rq, index, count);
2727 if (rc)
2728 goto error_out;
2729 idiag.ptr_private = phba->sli4_hba.dat_rq;
2730 goto pass_check;
2731 }
2732 goto error_out;
2733 break;
2734 default:
2735 goto error_out;
2736 break;
2737 }
2738
2739pass_check:
2740
2741 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
2742 if (count == LPFC_QUE_ACC_BROWSE)
2743 idiag.offset.last_rd = index;
2744 }
2745
2746 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
2747 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
2748 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
2749
2750 pque = (struct lpfc_queue *)idiag.ptr_private;
2751 if (offset > pque->entry_size/sizeof(uint32_t) - 1)
2752 goto error_out;
2753 pentry = pque->qe[index].address;
2754 pentry += offset;
2755 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR)
2756 *pentry = value;
2757 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST)
2758 *pentry |= value;
2759 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL)
2760 *pentry &= ~value;
2761 }
2762 return nbytes;
2763
2764error_out:
2765
2766 memset(&idiag, 0, sizeof(idiag));
2767 return -EINVAL;
2768}
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784static int
2785lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
2786 int len, uint32_t drbregid)
2787{
2788
2789 if (!pbuffer)
2790 return 0;
2791
2792 switch (drbregid) {
2793 case LPFC_DRB_EQCQ:
2794 len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2795 "EQCQ-DRB-REG: 0x%08x\n",
2796 readl(phba->sli4_hba.EQCQDBregaddr));
2797 break;
2798 case LPFC_DRB_MQ:
2799 len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2800 "MQ-DRB-REG: 0x%08x\n",
2801 readl(phba->sli4_hba.MQDBregaddr));
2802 break;
2803 case LPFC_DRB_WQ:
2804 len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2805 "WQ-DRB-REG: 0x%08x\n",
2806 readl(phba->sli4_hba.WQDBregaddr));
2807 break;
2808 case LPFC_DRB_RQ:
2809 len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2810 "RQ-DRB-REG: 0x%08x\n",
2811 readl(phba->sli4_hba.RQDBregaddr));
2812 break;
2813 default:
2814 break;
2815 }
2816
2817 return len;
2818}
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837static ssize_t
2838lpfc_idiag_drbacc_read(struct file *file, char __user *buf, size_t nbytes,
2839 loff_t *ppos)
2840{
2841 struct lpfc_debug *debug = file->private_data;
2842 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2843 uint32_t drb_reg_id, i;
2844 char *pbuffer;
2845 int len = 0;
2846
2847
2848 debug->op = LPFC_IDIAG_OP_RD;
2849
2850 if (!debug->buffer)
2851 debug->buffer = kmalloc(LPFC_DRB_ACC_BUF_SIZE, GFP_KERNEL);
2852 if (!debug->buffer)
2853 return 0;
2854 pbuffer = debug->buffer;
2855
2856 if (*ppos)
2857 return 0;
2858
2859 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD)
2860 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
2861 else
2862 return 0;
2863
2864 if (drb_reg_id == LPFC_DRB_ACC_ALL)
2865 for (i = 1; i <= LPFC_DRB_MAX; i++)
2866 len = lpfc_idiag_drbacc_read_reg(phba,
2867 pbuffer, len, i);
2868 else
2869 len = lpfc_idiag_drbacc_read_reg(phba,
2870 pbuffer, len, drb_reg_id);
2871
2872 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2873}
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893static ssize_t
2894lpfc_idiag_drbacc_write(struct file *file, const char __user *buf,
2895 size_t nbytes, loff_t *ppos)
2896{
2897 struct lpfc_debug *debug = file->private_data;
2898 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2899 uint32_t drb_reg_id, value, reg_val = 0;
2900 void __iomem *drb_reg;
2901 int rc;
2902
2903
2904 debug->op = LPFC_IDIAG_OP_WR;
2905
2906 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
2907 if (rc < 0)
2908 return rc;
2909
2910
2911 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
2912 value = idiag.cmd.data[IDIAG_DRBACC_VALUE_INDX];
2913
2914 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
2915 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
2916 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
2917 if (rc != LPFC_DRB_ACC_WR_CMD_ARG)
2918 goto error_out;
2919 if (drb_reg_id > LPFC_DRB_MAX)
2920 goto error_out;
2921 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD) {
2922 if (rc != LPFC_DRB_ACC_RD_CMD_ARG)
2923 goto error_out;
2924 if ((drb_reg_id > LPFC_DRB_MAX) &&
2925 (drb_reg_id != LPFC_DRB_ACC_ALL))
2926 goto error_out;
2927 } else
2928 goto error_out;
2929
2930
2931 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
2932 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
2933 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
2934 switch (drb_reg_id) {
2935 case LPFC_DRB_EQCQ:
2936 drb_reg = phba->sli4_hba.EQCQDBregaddr;
2937 break;
2938 case LPFC_DRB_MQ:
2939 drb_reg = phba->sli4_hba.MQDBregaddr;
2940 break;
2941 case LPFC_DRB_WQ:
2942 drb_reg = phba->sli4_hba.WQDBregaddr;
2943 break;
2944 case LPFC_DRB_RQ:
2945 drb_reg = phba->sli4_hba.RQDBregaddr;
2946 break;
2947 default:
2948 goto error_out;
2949 }
2950
2951 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR)
2952 reg_val = value;
2953 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST) {
2954 reg_val = readl(drb_reg);
2955 reg_val |= value;
2956 }
2957 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
2958 reg_val = readl(drb_reg);
2959 reg_val &= ~value;
2960 }
2961 writel(reg_val, drb_reg);
2962 readl(drb_reg);
2963 }
2964 return nbytes;
2965
2966error_out:
2967
2968 memset(&idiag, 0, sizeof(idiag));
2969 return -EINVAL;
2970}
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986static int
2987lpfc_idiag_ctlacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
2988 int len, uint32_t ctlregid)
2989{
2990
2991 if (!pbuffer)
2992 return 0;
2993
2994 switch (ctlregid) {
2995 case LPFC_CTL_PORT_SEM:
2996 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2997 "Port SemReg: 0x%08x\n",
2998 readl(phba->sli4_hba.conf_regs_memmap_p +
2999 LPFC_CTL_PORT_SEM_OFFSET));
3000 break;
3001 case LPFC_CTL_PORT_STA:
3002 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
3003 "Port StaReg: 0x%08x\n",
3004 readl(phba->sli4_hba.conf_regs_memmap_p +
3005 LPFC_CTL_PORT_STA_OFFSET));
3006 break;
3007 case LPFC_CTL_PORT_CTL:
3008 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
3009 "Port CtlReg: 0x%08x\n",
3010 readl(phba->sli4_hba.conf_regs_memmap_p +
3011 LPFC_CTL_PORT_CTL_OFFSET));
3012 break;
3013 case LPFC_CTL_PORT_ER1:
3014 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
3015 "Port Er1Reg: 0x%08x\n",
3016 readl(phba->sli4_hba.conf_regs_memmap_p +
3017 LPFC_CTL_PORT_ER1_OFFSET));
3018 break;
3019 case LPFC_CTL_PORT_ER2:
3020 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
3021 "Port Er2Reg: 0x%08x\n",
3022 readl(phba->sli4_hba.conf_regs_memmap_p +
3023 LPFC_CTL_PORT_ER2_OFFSET));
3024 break;
3025 case LPFC_CTL_PDEV_CTL:
3026 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
3027 "PDev CtlReg: 0x%08x\n",
3028 readl(phba->sli4_hba.conf_regs_memmap_p +
3029 LPFC_CTL_PDEV_CTL_OFFSET));
3030 break;
3031 default:
3032 break;
3033 }
3034 return len;
3035}
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052static ssize_t
3053lpfc_idiag_ctlacc_read(struct file *file, char __user *buf, size_t nbytes,
3054 loff_t *ppos)
3055{
3056 struct lpfc_debug *debug = file->private_data;
3057 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3058 uint32_t ctl_reg_id, i;
3059 char *pbuffer;
3060 int len = 0;
3061
3062
3063 debug->op = LPFC_IDIAG_OP_RD;
3064
3065 if (!debug->buffer)
3066 debug->buffer = kmalloc(LPFC_CTL_ACC_BUF_SIZE, GFP_KERNEL);
3067 if (!debug->buffer)
3068 return 0;
3069 pbuffer = debug->buffer;
3070
3071 if (*ppos)
3072 return 0;
3073
3074 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD)
3075 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
3076 else
3077 return 0;
3078
3079 if (ctl_reg_id == LPFC_CTL_ACC_ALL)
3080 for (i = 1; i <= LPFC_CTL_MAX; i++)
3081 len = lpfc_idiag_ctlacc_read_reg(phba,
3082 pbuffer, len, i);
3083 else
3084 len = lpfc_idiag_ctlacc_read_reg(phba,
3085 pbuffer, len, ctl_reg_id);
3086
3087 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3088}
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105static ssize_t
3106lpfc_idiag_ctlacc_write(struct file *file, const char __user *buf,
3107 size_t nbytes, loff_t *ppos)
3108{
3109 struct lpfc_debug *debug = file->private_data;
3110 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3111 uint32_t ctl_reg_id, value, reg_val = 0;
3112 void __iomem *ctl_reg;
3113 int rc;
3114
3115
3116 debug->op = LPFC_IDIAG_OP_WR;
3117
3118 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3119 if (rc < 0)
3120 return rc;
3121
3122
3123 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
3124 value = idiag.cmd.data[IDIAG_CTLACC_VALUE_INDX];
3125
3126 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
3127 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
3128 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
3129 if (rc != LPFC_CTL_ACC_WR_CMD_ARG)
3130 goto error_out;
3131 if (ctl_reg_id > LPFC_CTL_MAX)
3132 goto error_out;
3133 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD) {
3134 if (rc != LPFC_CTL_ACC_RD_CMD_ARG)
3135 goto error_out;
3136 if ((ctl_reg_id > LPFC_CTL_MAX) &&
3137 (ctl_reg_id != LPFC_CTL_ACC_ALL))
3138 goto error_out;
3139 } else
3140 goto error_out;
3141
3142
3143 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
3144 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
3145 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
3146 switch (ctl_reg_id) {
3147 case LPFC_CTL_PORT_SEM:
3148 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3149 LPFC_CTL_PORT_SEM_OFFSET;
3150 break;
3151 case LPFC_CTL_PORT_STA:
3152 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3153 LPFC_CTL_PORT_STA_OFFSET;
3154 break;
3155 case LPFC_CTL_PORT_CTL:
3156 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3157 LPFC_CTL_PORT_CTL_OFFSET;
3158 break;
3159 case LPFC_CTL_PORT_ER1:
3160 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3161 LPFC_CTL_PORT_ER1_OFFSET;
3162 break;
3163 case LPFC_CTL_PORT_ER2:
3164 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3165 LPFC_CTL_PORT_ER2_OFFSET;
3166 break;
3167 case LPFC_CTL_PDEV_CTL:
3168 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3169 LPFC_CTL_PDEV_CTL_OFFSET;
3170 break;
3171 default:
3172 goto error_out;
3173 }
3174
3175 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR)
3176 reg_val = value;
3177 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST) {
3178 reg_val = readl(ctl_reg);
3179 reg_val |= value;
3180 }
3181 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
3182 reg_val = readl(ctl_reg);
3183 reg_val &= ~value;
3184 }
3185 writel(reg_val, ctl_reg);
3186 readl(ctl_reg);
3187 }
3188 return nbytes;
3189
3190error_out:
3191
3192 memset(&idiag, 0, sizeof(idiag));
3193 return -EINVAL;
3194}
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208static int
3209lpfc_idiag_mbxacc_get_setup(struct lpfc_hba *phba, char *pbuffer)
3210{
3211 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
3212 int len = 0;
3213
3214 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3215 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3216 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3217 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3218
3219 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3220 "mbx_dump_map: 0x%08x\n", mbx_dump_map);
3221 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3222 "mbx_dump_cnt: %04d\n", mbx_dump_cnt);
3223 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3224 "mbx_word_cnt: %04d\n", mbx_word_cnt);
3225 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3226 "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd);
3227
3228 return len;
3229}
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246static ssize_t
3247lpfc_idiag_mbxacc_read(struct file *file, char __user *buf, size_t nbytes,
3248 loff_t *ppos)
3249{
3250 struct lpfc_debug *debug = file->private_data;
3251 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3252 char *pbuffer;
3253 int len = 0;
3254
3255
3256 debug->op = LPFC_IDIAG_OP_RD;
3257
3258 if (!debug->buffer)
3259 debug->buffer = kmalloc(LPFC_MBX_ACC_BUF_SIZE, GFP_KERNEL);
3260 if (!debug->buffer)
3261 return 0;
3262 pbuffer = debug->buffer;
3263
3264 if (*ppos)
3265 return 0;
3266
3267 if ((idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP) &&
3268 (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP))
3269 return 0;
3270
3271 len = lpfc_idiag_mbxacc_get_setup(phba, pbuffer);
3272
3273 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3274}
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291static ssize_t
3292lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf,
3293 size_t nbytes, loff_t *ppos)
3294{
3295 struct lpfc_debug *debug = file->private_data;
3296 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
3297 int rc;
3298
3299
3300 debug->op = LPFC_IDIAG_OP_WR;
3301
3302 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3303 if (rc < 0)
3304 return rc;
3305
3306
3307 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3308 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3309 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3310 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3311
3312 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_MBXACC_DP) {
3313 if (!(mbx_dump_map & LPFC_MBX_DMP_MBX_ALL))
3314 goto error_out;
3315 if ((mbx_dump_map & ~LPFC_MBX_DMP_MBX_ALL) &&
3316 (mbx_dump_map != LPFC_MBX_DMP_ALL))
3317 goto error_out;
3318 if (mbx_word_cnt > sizeof(MAILBOX_t))
3319 goto error_out;
3320 } else if (idiag.cmd.opcode == LPFC_IDIAG_BSG_MBXACC_DP) {
3321 if (!(mbx_dump_map & LPFC_BSG_DMP_MBX_ALL))
3322 goto error_out;
3323 if ((mbx_dump_map & ~LPFC_BSG_DMP_MBX_ALL) &&
3324 (mbx_dump_map != LPFC_MBX_DMP_ALL))
3325 goto error_out;
3326 if (mbx_word_cnt > (BSG_MBOX_SIZE)/4)
3327 goto error_out;
3328 if (mbx_mbox_cmd != 0x9b)
3329 goto error_out;
3330 } else
3331 goto error_out;
3332
3333 if (mbx_word_cnt == 0)
3334 goto error_out;
3335 if (rc != LPFC_MBX_DMP_ARG)
3336 goto error_out;
3337 if (mbx_mbox_cmd & ~0xff)
3338 goto error_out;
3339
3340
3341 if (mbx_dump_cnt == 0)
3342 goto reset_out;
3343
3344 return nbytes;
3345
3346reset_out:
3347
3348 memset(&idiag, 0, sizeof(idiag));
3349 return nbytes;
3350
3351error_out:
3352
3353 memset(&idiag, 0, sizeof(idiag));
3354 return -EINVAL;
3355}
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369static int
3370lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
3371{
3372 uint16_t ext_cnt, ext_size;
3373
3374 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3375 "\nAvailable Extents Information:\n");
3376
3377 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3378 "\tPort Available VPI extents: ");
3379 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI,
3380 &ext_cnt, &ext_size);
3381 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3382 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3383
3384 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3385 "\tPort Available VFI extents: ");
3386 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI,
3387 &ext_cnt, &ext_size);
3388 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3389 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3390
3391 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3392 "\tPort Available RPI extents: ");
3393 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI,
3394 &ext_cnt, &ext_size);
3395 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3396 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3397
3398 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3399 "\tPort Available XRI extents: ");
3400 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI,
3401 &ext_cnt, &ext_size);
3402 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3403 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3404
3405 return len;
3406}
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420static int
3421lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len)
3422{
3423 uint16_t ext_cnt, ext_size;
3424 int rc;
3425
3426 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3427 "\nAllocated Extents Information:\n");
3428
3429 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3430 "\tHost Allocated VPI extents: ");
3431 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI,
3432 &ext_cnt, &ext_size);
3433 if (!rc)
3434 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3435 "Port %d Extent %3d, Size %3d\n",
3436 phba->brd_no, ext_cnt, ext_size);
3437 else
3438 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3439 "N/A\n");
3440
3441 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3442 "\tHost Allocated VFI extents: ");
3443 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI,
3444 &ext_cnt, &ext_size);
3445 if (!rc)
3446 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3447 "Port %d Extent %3d, Size %3d\n",
3448 phba->brd_no, ext_cnt, ext_size);
3449 else
3450 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3451 "N/A\n");
3452
3453 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3454 "\tHost Allocated RPI extents: ");
3455 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI,
3456 &ext_cnt, &ext_size);
3457 if (!rc)
3458 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3459 "Port %d Extent %3d, Size %3d\n",
3460 phba->brd_no, ext_cnt, ext_size);
3461 else
3462 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3463 "N/A\n");
3464
3465 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3466 "\tHost Allocated XRI extents: ");
3467 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI,
3468 &ext_cnt, &ext_size);
3469 if (!rc)
3470 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3471 "Port %d Extent %3d, Size %3d\n",
3472 phba->brd_no, ext_cnt, ext_size);
3473 else
3474 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3475 "N/A\n");
3476
3477 return len;
3478}
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492static int
3493lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len)
3494{
3495 struct lpfc_rsrc_blks *rsrc_blks;
3496 int index;
3497
3498 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3499 "\nDriver Extents Information:\n");
3500
3501 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3502 "\tVPI extents:\n");
3503 index = 0;
3504 list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) {
3505 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3506 "\t\tBlock %3d: Start %4d, Count %4d\n",
3507 index, rsrc_blks->rsrc_start,
3508 rsrc_blks->rsrc_size);
3509 index++;
3510 }
3511 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3512 "\tVFI extents:\n");
3513 index = 0;
3514 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list,
3515 list) {
3516 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3517 "\t\tBlock %3d: Start %4d, Count %4d\n",
3518 index, rsrc_blks->rsrc_start,
3519 rsrc_blks->rsrc_size);
3520 index++;
3521 }
3522
3523 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3524 "\tRPI extents:\n");
3525 index = 0;
3526 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list,
3527 list) {
3528 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3529 "\t\tBlock %3d: Start %4d, Count %4d\n",
3530 index, rsrc_blks->rsrc_start,
3531 rsrc_blks->rsrc_size);
3532 index++;
3533 }
3534
3535 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3536 "\tXRI extents:\n");
3537 index = 0;
3538 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list,
3539 list) {
3540 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3541 "\t\tBlock %3d: Start %4d, Count %4d\n",
3542 index, rsrc_blks->rsrc_start,
3543 rsrc_blks->rsrc_size);
3544 index++;
3545 }
3546
3547 return len;
3548}
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565static ssize_t
3566lpfc_idiag_extacc_write(struct file *file, const char __user *buf,
3567 size_t nbytes, loff_t *ppos)
3568{
3569 struct lpfc_debug *debug = file->private_data;
3570 uint32_t ext_map;
3571 int rc;
3572
3573
3574 debug->op = LPFC_IDIAG_OP_WR;
3575
3576 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3577 if (rc < 0)
3578 return rc;
3579
3580 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
3581
3582 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
3583 goto error_out;
3584 if (rc != LPFC_EXT_ACC_CMD_ARG)
3585 goto error_out;
3586 if (!(ext_map & LPFC_EXT_ACC_ALL))
3587 goto error_out;
3588
3589 return nbytes;
3590error_out:
3591
3592 memset(&idiag, 0, sizeof(idiag));
3593 return -EINVAL;
3594}
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611static ssize_t
3612lpfc_idiag_extacc_read(struct file *file, char __user *buf, size_t nbytes,
3613 loff_t *ppos)
3614{
3615 struct lpfc_debug *debug = file->private_data;
3616 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3617 char *pbuffer;
3618 uint32_t ext_map;
3619 int len = 0;
3620
3621
3622 debug->op = LPFC_IDIAG_OP_RD;
3623
3624 if (!debug->buffer)
3625 debug->buffer = kmalloc(LPFC_EXT_ACC_BUF_SIZE, GFP_KERNEL);
3626 if (!debug->buffer)
3627 return 0;
3628 pbuffer = debug->buffer;
3629 if (*ppos)
3630 return 0;
3631 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
3632 return 0;
3633
3634 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
3635 if (ext_map & LPFC_EXT_ACC_AVAIL)
3636 len = lpfc_idiag_extacc_avail_get(phba, pbuffer, len);
3637 if (ext_map & LPFC_EXT_ACC_ALLOC)
3638 len = lpfc_idiag_extacc_alloc_get(phba, pbuffer, len);
3639 if (ext_map & LPFC_EXT_ACC_DRIVR)
3640 len = lpfc_idiag_extacc_drivr_get(phba, pbuffer, len);
3641
3642 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3643}
3644
3645#undef lpfc_debugfs_op_disc_trc
3646static const struct file_operations lpfc_debugfs_op_disc_trc = {
3647 .owner = THIS_MODULE,
3648 .open = lpfc_debugfs_disc_trc_open,
3649 .llseek = lpfc_debugfs_lseek,
3650 .read = lpfc_debugfs_read,
3651 .release = lpfc_debugfs_release,
3652};
3653
3654#undef lpfc_debugfs_op_nodelist
3655static const struct file_operations lpfc_debugfs_op_nodelist = {
3656 .owner = THIS_MODULE,
3657 .open = lpfc_debugfs_nodelist_open,
3658 .llseek = lpfc_debugfs_lseek,
3659 .read = lpfc_debugfs_read,
3660 .release = lpfc_debugfs_release,
3661};
3662
3663#undef lpfc_debugfs_op_hbqinfo
3664static const struct file_operations lpfc_debugfs_op_hbqinfo = {
3665 .owner = THIS_MODULE,
3666 .open = lpfc_debugfs_hbqinfo_open,
3667 .llseek = lpfc_debugfs_lseek,
3668 .read = lpfc_debugfs_read,
3669 .release = lpfc_debugfs_release,
3670};
3671
3672#undef lpfc_debugfs_op_dumpHBASlim
3673static const struct file_operations lpfc_debugfs_op_dumpHBASlim = {
3674 .owner = THIS_MODULE,
3675 .open = lpfc_debugfs_dumpHBASlim_open,
3676 .llseek = lpfc_debugfs_lseek,
3677 .read = lpfc_debugfs_read,
3678 .release = lpfc_debugfs_release,
3679};
3680
3681#undef lpfc_debugfs_op_dumpHostSlim
3682static const struct file_operations lpfc_debugfs_op_dumpHostSlim = {
3683 .owner = THIS_MODULE,
3684 .open = lpfc_debugfs_dumpHostSlim_open,
3685 .llseek = lpfc_debugfs_lseek,
3686 .read = lpfc_debugfs_read,
3687 .release = lpfc_debugfs_release,
3688};
3689
3690#undef lpfc_debugfs_op_dumpData
3691static const struct file_operations lpfc_debugfs_op_dumpData = {
3692 .owner = THIS_MODULE,
3693 .open = lpfc_debugfs_dumpData_open,
3694 .llseek = lpfc_debugfs_lseek,
3695 .read = lpfc_debugfs_read,
3696 .write = lpfc_debugfs_dumpDataDif_write,
3697 .release = lpfc_debugfs_dumpDataDif_release,
3698};
3699
3700#undef lpfc_debugfs_op_dumpDif
3701static const struct file_operations lpfc_debugfs_op_dumpDif = {
3702 .owner = THIS_MODULE,
3703 .open = lpfc_debugfs_dumpDif_open,
3704 .llseek = lpfc_debugfs_lseek,
3705 .read = lpfc_debugfs_read,
3706 .write = lpfc_debugfs_dumpDataDif_write,
3707 .release = lpfc_debugfs_dumpDataDif_release,
3708};
3709
3710#undef lpfc_debugfs_op_dif_err
3711static const struct file_operations lpfc_debugfs_op_dif_err = {
3712 .owner = THIS_MODULE,
3713 .open = simple_open,
3714 .llseek = lpfc_debugfs_lseek,
3715 .read = lpfc_debugfs_dif_err_read,
3716 .write = lpfc_debugfs_dif_err_write,
3717 .release = lpfc_debugfs_dif_err_release,
3718};
3719
3720#undef lpfc_debugfs_op_slow_ring_trc
3721static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
3722 .owner = THIS_MODULE,
3723 .open = lpfc_debugfs_slow_ring_trc_open,
3724 .llseek = lpfc_debugfs_lseek,
3725 .read = lpfc_debugfs_read,
3726 .release = lpfc_debugfs_release,
3727};
3728
3729static struct dentry *lpfc_debugfs_root = NULL;
3730static atomic_t lpfc_debugfs_hba_count;
3731
3732
3733
3734
3735#undef lpfc_idiag_op_pciCfg
3736static const struct file_operations lpfc_idiag_op_pciCfg = {
3737 .owner = THIS_MODULE,
3738 .open = lpfc_idiag_open,
3739 .llseek = lpfc_debugfs_lseek,
3740 .read = lpfc_idiag_pcicfg_read,
3741 .write = lpfc_idiag_pcicfg_write,
3742 .release = lpfc_idiag_cmd_release,
3743};
3744
3745#undef lpfc_idiag_op_barAcc
3746static const struct file_operations lpfc_idiag_op_barAcc = {
3747 .owner = THIS_MODULE,
3748 .open = lpfc_idiag_open,
3749 .llseek = lpfc_debugfs_lseek,
3750 .read = lpfc_idiag_baracc_read,
3751 .write = lpfc_idiag_baracc_write,
3752 .release = lpfc_idiag_cmd_release,
3753};
3754
3755#undef lpfc_idiag_op_queInfo
3756static const struct file_operations lpfc_idiag_op_queInfo = {
3757 .owner = THIS_MODULE,
3758 .open = lpfc_idiag_open,
3759 .read = lpfc_idiag_queinfo_read,
3760 .release = lpfc_idiag_release,
3761};
3762
3763#undef lpfc_idiag_op_queAcc
3764static const struct file_operations lpfc_idiag_op_queAcc = {
3765 .owner = THIS_MODULE,
3766 .open = lpfc_idiag_open,
3767 .llseek = lpfc_debugfs_lseek,
3768 .read = lpfc_idiag_queacc_read,
3769 .write = lpfc_idiag_queacc_write,
3770 .release = lpfc_idiag_cmd_release,
3771};
3772
3773#undef lpfc_idiag_op_drbAcc
3774static const struct file_operations lpfc_idiag_op_drbAcc = {
3775 .owner = THIS_MODULE,
3776 .open = lpfc_idiag_open,
3777 .llseek = lpfc_debugfs_lseek,
3778 .read = lpfc_idiag_drbacc_read,
3779 .write = lpfc_idiag_drbacc_write,
3780 .release = lpfc_idiag_cmd_release,
3781};
3782
3783#undef lpfc_idiag_op_ctlAcc
3784static const struct file_operations lpfc_idiag_op_ctlAcc = {
3785 .owner = THIS_MODULE,
3786 .open = lpfc_idiag_open,
3787 .llseek = lpfc_debugfs_lseek,
3788 .read = lpfc_idiag_ctlacc_read,
3789 .write = lpfc_idiag_ctlacc_write,
3790 .release = lpfc_idiag_cmd_release,
3791};
3792
3793#undef lpfc_idiag_op_mbxAcc
3794static const struct file_operations lpfc_idiag_op_mbxAcc = {
3795 .owner = THIS_MODULE,
3796 .open = lpfc_idiag_open,
3797 .llseek = lpfc_debugfs_lseek,
3798 .read = lpfc_idiag_mbxacc_read,
3799 .write = lpfc_idiag_mbxacc_write,
3800 .release = lpfc_idiag_cmd_release,
3801};
3802
3803#undef lpfc_idiag_op_extAcc
3804static const struct file_operations lpfc_idiag_op_extAcc = {
3805 .owner = THIS_MODULE,
3806 .open = lpfc_idiag_open,
3807 .llseek = lpfc_debugfs_lseek,
3808 .read = lpfc_idiag_extacc_read,
3809 .write = lpfc_idiag_extacc_write,
3810 .release = lpfc_idiag_cmd_release,
3811};
3812
3813#endif
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823void
3824lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *phba, enum nemb_type nemb_tp,
3825 enum mbox_type mbox_tp, enum dma_type dma_tp,
3826 enum sta_type sta_tp,
3827 struct lpfc_dmabuf *dmabuf, uint32_t ext_buf)
3828{
3829#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
3830 uint32_t *mbx_mbox_cmd, *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt;
3831 char line_buf[LPFC_MBX_ACC_LBUF_SZ];
3832 int len = 0;
3833 uint32_t do_dump = 0;
3834 uint32_t *pword;
3835 uint32_t i;
3836
3837 if (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP)
3838 return;
3839
3840 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3841 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3842 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3843 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3844
3845 if (!(*mbx_dump_map & LPFC_MBX_DMP_ALL) ||
3846 (*mbx_dump_cnt == 0) ||
3847 (*mbx_word_cnt == 0))
3848 return;
3849
3850 if (*mbx_mbox_cmd != 0x9B)
3851 return;
3852
3853 if ((mbox_tp == mbox_rd) && (dma_tp == dma_mbox)) {
3854 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_MBX) {
3855 do_dump |= LPFC_BSG_DMP_MBX_RD_MBX;
3856 printk(KERN_ERR "\nRead mbox command (x%x), "
3857 "nemb:0x%x, extbuf_cnt:%d:\n",
3858 sta_tp, nemb_tp, ext_buf);
3859 }
3860 }
3861 if ((mbox_tp == mbox_rd) && (dma_tp == dma_ebuf)) {
3862 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_BUF) {
3863 do_dump |= LPFC_BSG_DMP_MBX_RD_BUF;
3864 printk(KERN_ERR "\nRead mbox buffer (x%x), "
3865 "nemb:0x%x, extbuf_seq:%d:\n",
3866 sta_tp, nemb_tp, ext_buf);
3867 }
3868 }
3869 if ((mbox_tp == mbox_wr) && (dma_tp == dma_mbox)) {
3870 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_MBX) {
3871 do_dump |= LPFC_BSG_DMP_MBX_WR_MBX;
3872 printk(KERN_ERR "\nWrite mbox command (x%x), "
3873 "nemb:0x%x, extbuf_cnt:%d:\n",
3874 sta_tp, nemb_tp, ext_buf);
3875 }
3876 }
3877 if ((mbox_tp == mbox_wr) && (dma_tp == dma_ebuf)) {
3878 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_BUF) {
3879 do_dump |= LPFC_BSG_DMP_MBX_WR_BUF;
3880 printk(KERN_ERR "\nWrite mbox buffer (x%x), "
3881 "nemb:0x%x, extbuf_seq:%d:\n",
3882 sta_tp, nemb_tp, ext_buf);
3883 }
3884 }
3885
3886
3887 if (do_dump) {
3888 pword = (uint32_t *)dmabuf->virt;
3889 for (i = 0; i < *mbx_word_cnt; i++) {
3890 if (!(i % 8)) {
3891 if (i != 0)
3892 printk(KERN_ERR "%s\n", line_buf);
3893 len = 0;
3894 len += snprintf(line_buf+len,
3895 LPFC_MBX_ACC_LBUF_SZ-len,
3896 "%03d: ", i);
3897 }
3898 len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
3899 "%08x ", (uint32_t)*pword);
3900 pword++;
3901 }
3902 if ((i - 1) % 8)
3903 printk(KERN_ERR "%s\n", line_buf);
3904 (*mbx_dump_cnt)--;
3905 }
3906
3907
3908 if (*mbx_dump_cnt == 0)
3909 memset(&idiag, 0, sizeof(idiag));
3910 return;
3911#endif
3912}
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922void
3923lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox)
3924{
3925#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
3926 uint32_t *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt, *mbx_mbox_cmd;
3927 char line_buf[LPFC_MBX_ACC_LBUF_SZ];
3928 int len = 0;
3929 uint32_t *pword;
3930 uint8_t *pbyte;
3931 uint32_t i, j;
3932
3933 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP)
3934 return;
3935
3936 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3937 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3938 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3939 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3940
3941 if (!(*mbx_dump_map & LPFC_MBX_DMP_MBX_ALL) ||
3942 (*mbx_dump_cnt == 0) ||
3943 (*mbx_word_cnt == 0))
3944 return;
3945
3946 if ((*mbx_mbox_cmd != LPFC_MBX_ALL_CMD) &&
3947 (*mbx_mbox_cmd != pmbox->mbxCommand))
3948 return;
3949
3950
3951 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_WORD) {
3952 printk(KERN_ERR "Mailbox command:0x%x dump by word:\n",
3953 pmbox->mbxCommand);
3954 pword = (uint32_t *)pmbox;
3955 for (i = 0; i < *mbx_word_cnt; i++) {
3956 if (!(i % 8)) {
3957 if (i != 0)
3958 printk(KERN_ERR "%s\n", line_buf);
3959 len = 0;
3960 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
3961 len += snprintf(line_buf+len,
3962 LPFC_MBX_ACC_LBUF_SZ-len,
3963 "%03d: ", i);
3964 }
3965 len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
3966 "%08x ",
3967 ((uint32_t)*pword) & 0xffffffff);
3968 pword++;
3969 }
3970 if ((i - 1) % 8)
3971 printk(KERN_ERR "%s\n", line_buf);
3972 printk(KERN_ERR "\n");
3973 }
3974 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_BYTE) {
3975 printk(KERN_ERR "Mailbox command:0x%x dump by byte:\n",
3976 pmbox->mbxCommand);
3977 pbyte = (uint8_t *)pmbox;
3978 for (i = 0; i < *mbx_word_cnt; i++) {
3979 if (!(i % 8)) {
3980 if (i != 0)
3981 printk(KERN_ERR "%s\n", line_buf);
3982 len = 0;
3983 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
3984 len += snprintf(line_buf+len,
3985 LPFC_MBX_ACC_LBUF_SZ-len,
3986 "%03d: ", i);
3987 }
3988 for (j = 0; j < 4; j++) {
3989 len += snprintf(line_buf+len,
3990 LPFC_MBX_ACC_LBUF_SZ-len,
3991 "%02x",
3992 ((uint8_t)*pbyte) & 0xff);
3993 pbyte++;
3994 }
3995 len += snprintf(line_buf+len,
3996 LPFC_MBX_ACC_LBUF_SZ-len, " ");
3997 }
3998 if ((i - 1) % 8)
3999 printk(KERN_ERR "%s\n", line_buf);
4000 printk(KERN_ERR "\n");
4001 }
4002 (*mbx_dump_cnt)--;
4003
4004
4005 if (*mbx_dump_cnt == 0)
4006 memset(&idiag, 0, sizeof(idiag));
4007 return;
4008#endif
4009}
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021inline void
4022lpfc_debugfs_initialize(struct lpfc_vport *vport)
4023{
4024#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
4025 struct lpfc_hba *phba = vport->phba;
4026 char name[64];
4027 uint32_t num, i;
4028 bool pport_setup = false;
4029
4030 if (!lpfc_debugfs_enable)
4031 return;
4032
4033
4034 if (!lpfc_debugfs_root) {
4035 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
4036 atomic_set(&lpfc_debugfs_hba_count, 0);
4037 if (!lpfc_debugfs_root) {
4038 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4039 "0408 Cannot create debugfs root\n");
4040 goto debug_failed;
4041 }
4042 }
4043 if (!lpfc_debugfs_start_time)
4044 lpfc_debugfs_start_time = jiffies;
4045
4046
4047 snprintf(name, sizeof(name), "fn%d", phba->brd_no);
4048 if (!phba->hba_debugfs_root) {
4049 pport_setup = true;
4050 phba->hba_debugfs_root =
4051 debugfs_create_dir(name, lpfc_debugfs_root);
4052 if (!phba->hba_debugfs_root) {
4053 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4054 "0412 Cannot create debugfs hba\n");
4055 goto debug_failed;
4056 }
4057 atomic_inc(&lpfc_debugfs_hba_count);
4058 atomic_set(&phba->debugfs_vport_count, 0);
4059
4060
4061 snprintf(name, sizeof(name), "hbqinfo");
4062 phba->debug_hbqinfo =
4063 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4064 phba->hba_debugfs_root,
4065 phba, &lpfc_debugfs_op_hbqinfo);
4066 if (!phba->debug_hbqinfo) {
4067 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4068 "0411 Cannot create debugfs hbqinfo\n");
4069 goto debug_failed;
4070 }
4071
4072
4073 if (phba->sli_rev < LPFC_SLI_REV4) {
4074 snprintf(name, sizeof(name), "dumpHBASlim");
4075 phba->debug_dumpHBASlim =
4076 debugfs_create_file(name,
4077 S_IFREG|S_IRUGO|S_IWUSR,
4078 phba->hba_debugfs_root,
4079 phba, &lpfc_debugfs_op_dumpHBASlim);
4080 if (!phba->debug_dumpHBASlim) {
4081 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4082 "0413 Cannot create debugfs "
4083 "dumpHBASlim\n");
4084 goto debug_failed;
4085 }
4086 } else
4087 phba->debug_dumpHBASlim = NULL;
4088
4089
4090 if (phba->sli_rev < LPFC_SLI_REV4) {
4091 snprintf(name, sizeof(name), "dumpHostSlim");
4092 phba->debug_dumpHostSlim =
4093 debugfs_create_file(name,
4094 S_IFREG|S_IRUGO|S_IWUSR,
4095 phba->hba_debugfs_root,
4096 phba, &lpfc_debugfs_op_dumpHostSlim);
4097 if (!phba->debug_dumpHostSlim) {
4098 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4099 "0414 Cannot create debugfs "
4100 "dumpHostSlim\n");
4101 goto debug_failed;
4102 }
4103 } else
4104 phba->debug_dumpHostSlim = NULL;
4105
4106
4107 snprintf(name, sizeof(name), "dumpData");
4108 phba->debug_dumpData =
4109 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4110 phba->hba_debugfs_root,
4111 phba, &lpfc_debugfs_op_dumpData);
4112 if (!phba->debug_dumpData) {
4113 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4114 "0800 Cannot create debugfs dumpData\n");
4115 goto debug_failed;
4116 }
4117
4118
4119 snprintf(name, sizeof(name), "dumpDif");
4120 phba->debug_dumpDif =
4121 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4122 phba->hba_debugfs_root,
4123 phba, &lpfc_debugfs_op_dumpDif);
4124 if (!phba->debug_dumpDif) {
4125 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4126 "0801 Cannot create debugfs dumpDif\n");
4127 goto debug_failed;
4128 }
4129
4130
4131 snprintf(name, sizeof(name), "InjErrLBA");
4132 phba->debug_InjErrLBA =
4133 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4134 phba->hba_debugfs_root,
4135 phba, &lpfc_debugfs_op_dif_err);
4136 if (!phba->debug_InjErrLBA) {
4137 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4138 "0807 Cannot create debugfs InjErrLBA\n");
4139 goto debug_failed;
4140 }
4141 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
4142
4143 snprintf(name, sizeof(name), "InjErrNPortID");
4144 phba->debug_InjErrNPortID =
4145 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4146 phba->hba_debugfs_root,
4147 phba, &lpfc_debugfs_op_dif_err);
4148 if (!phba->debug_InjErrNPortID) {
4149 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4150 "0809 Cannot create debugfs InjErrNPortID\n");
4151 goto debug_failed;
4152 }
4153
4154 snprintf(name, sizeof(name), "InjErrWWPN");
4155 phba->debug_InjErrWWPN =
4156 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4157 phba->hba_debugfs_root,
4158 phba, &lpfc_debugfs_op_dif_err);
4159 if (!phba->debug_InjErrWWPN) {
4160 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4161 "0810 Cannot create debugfs InjErrWWPN\n");
4162 goto debug_failed;
4163 }
4164
4165 snprintf(name, sizeof(name), "writeGuardInjErr");
4166 phba->debug_writeGuard =
4167 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4168 phba->hba_debugfs_root,
4169 phba, &lpfc_debugfs_op_dif_err);
4170 if (!phba->debug_writeGuard) {
4171 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4172 "0802 Cannot create debugfs writeGuard\n");
4173 goto debug_failed;
4174 }
4175
4176 snprintf(name, sizeof(name), "writeAppInjErr");
4177 phba->debug_writeApp =
4178 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4179 phba->hba_debugfs_root,
4180 phba, &lpfc_debugfs_op_dif_err);
4181 if (!phba->debug_writeApp) {
4182 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4183 "0803 Cannot create debugfs writeApp\n");
4184 goto debug_failed;
4185 }
4186
4187 snprintf(name, sizeof(name), "writeRefInjErr");
4188 phba->debug_writeRef =
4189 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4190 phba->hba_debugfs_root,
4191 phba, &lpfc_debugfs_op_dif_err);
4192 if (!phba->debug_writeRef) {
4193 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4194 "0804 Cannot create debugfs writeRef\n");
4195 goto debug_failed;
4196 }
4197
4198 snprintf(name, sizeof(name), "readGuardInjErr");
4199 phba->debug_readGuard =
4200 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4201 phba->hba_debugfs_root,
4202 phba, &lpfc_debugfs_op_dif_err);
4203 if (!phba->debug_readGuard) {
4204 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4205 "0808 Cannot create debugfs readGuard\n");
4206 goto debug_failed;
4207 }
4208
4209 snprintf(name, sizeof(name), "readAppInjErr");
4210 phba->debug_readApp =
4211 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4212 phba->hba_debugfs_root,
4213 phba, &lpfc_debugfs_op_dif_err);
4214 if (!phba->debug_readApp) {
4215 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4216 "0805 Cannot create debugfs readApp\n");
4217 goto debug_failed;
4218 }
4219
4220 snprintf(name, sizeof(name), "readRefInjErr");
4221 phba->debug_readRef =
4222 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4223 phba->hba_debugfs_root,
4224 phba, &lpfc_debugfs_op_dif_err);
4225 if (!phba->debug_readRef) {
4226 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4227 "0806 Cannot create debugfs readApp\n");
4228 goto debug_failed;
4229 }
4230
4231
4232 if (lpfc_debugfs_max_slow_ring_trc) {
4233 num = lpfc_debugfs_max_slow_ring_trc - 1;
4234 if (num & lpfc_debugfs_max_slow_ring_trc) {
4235
4236 num = lpfc_debugfs_max_slow_ring_trc;
4237 i = 0;
4238 while (num > 1) {
4239 num = num >> 1;
4240 i++;
4241 }
4242 lpfc_debugfs_max_slow_ring_trc = (1 << i);
4243 printk(KERN_ERR
4244 "lpfc_debugfs_max_disc_trc changed to "
4245 "%d\n", lpfc_debugfs_max_disc_trc);
4246 }
4247 }
4248
4249 snprintf(name, sizeof(name), "slow_ring_trace");
4250 phba->debug_slow_ring_trc =
4251 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4252 phba->hba_debugfs_root,
4253 phba, &lpfc_debugfs_op_slow_ring_trc);
4254 if (!phba->debug_slow_ring_trc) {
4255 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4256 "0415 Cannot create debugfs "
4257 "slow_ring_trace\n");
4258 goto debug_failed;
4259 }
4260 if (!phba->slow_ring_trc) {
4261 phba->slow_ring_trc = kmalloc(
4262 (sizeof(struct lpfc_debugfs_trc) *
4263 lpfc_debugfs_max_slow_ring_trc),
4264 GFP_KERNEL);
4265 if (!phba->slow_ring_trc) {
4266 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4267 "0416 Cannot create debugfs "
4268 "slow_ring buffer\n");
4269 goto debug_failed;
4270 }
4271 atomic_set(&phba->slow_ring_trc_cnt, 0);
4272 memset(phba->slow_ring_trc, 0,
4273 (sizeof(struct lpfc_debugfs_trc) *
4274 lpfc_debugfs_max_slow_ring_trc));
4275 }
4276 }
4277
4278 snprintf(name, sizeof(name), "vport%d", vport->vpi);
4279 if (!vport->vport_debugfs_root) {
4280 vport->vport_debugfs_root =
4281 debugfs_create_dir(name, phba->hba_debugfs_root);
4282 if (!vport->vport_debugfs_root) {
4283 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4284 "0417 Can't create debugfs\n");
4285 goto debug_failed;
4286 }
4287 atomic_inc(&phba->debugfs_vport_count);
4288 }
4289
4290 if (lpfc_debugfs_max_disc_trc) {
4291 num = lpfc_debugfs_max_disc_trc - 1;
4292 if (num & lpfc_debugfs_max_disc_trc) {
4293
4294 num = lpfc_debugfs_max_disc_trc;
4295 i = 0;
4296 while (num > 1) {
4297 num = num >> 1;
4298 i++;
4299 }
4300 lpfc_debugfs_max_disc_trc = (1 << i);
4301 printk(KERN_ERR
4302 "lpfc_debugfs_max_disc_trc changed to %d\n",
4303 lpfc_debugfs_max_disc_trc);
4304 }
4305 }
4306
4307 vport->disc_trc = kzalloc(
4308 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
4309 GFP_KERNEL);
4310
4311 if (!vport->disc_trc) {
4312 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4313 "0418 Cannot create debugfs disc trace "
4314 "buffer\n");
4315 goto debug_failed;
4316 }
4317 atomic_set(&vport->disc_trc_cnt, 0);
4318
4319 snprintf(name, sizeof(name), "discovery_trace");
4320 vport->debug_disc_trc =
4321 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4322 vport->vport_debugfs_root,
4323 vport, &lpfc_debugfs_op_disc_trc);
4324 if (!vport->debug_disc_trc) {
4325 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4326 "0419 Cannot create debugfs "
4327 "discovery_trace\n");
4328 goto debug_failed;
4329 }
4330 snprintf(name, sizeof(name), "nodelist");
4331 vport->debug_nodelist =
4332 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4333 vport->vport_debugfs_root,
4334 vport, &lpfc_debugfs_op_nodelist);
4335 if (!vport->debug_nodelist) {
4336 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4337 "2985 Can't create debugfs nodelist\n");
4338 goto debug_failed;
4339 }
4340
4341
4342
4343
4344
4345
4346 if (!pport_setup)
4347 goto debug_failed;
4348
4349
4350
4351
4352 if (phba->sli_rev < LPFC_SLI_REV4)
4353 goto debug_failed;
4354
4355 snprintf(name, sizeof(name), "iDiag");
4356 if (!phba->idiag_root) {
4357 phba->idiag_root =
4358 debugfs_create_dir(name, phba->hba_debugfs_root);
4359 if (!phba->idiag_root) {
4360 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4361 "2922 Can't create idiag debugfs\n");
4362 goto debug_failed;
4363 }
4364
4365 memset(&idiag, 0, sizeof(idiag));
4366 }
4367
4368
4369 snprintf(name, sizeof(name), "pciCfg");
4370 if (!phba->idiag_pci_cfg) {
4371 phba->idiag_pci_cfg =
4372 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4373 phba->idiag_root, phba, &lpfc_idiag_op_pciCfg);
4374 if (!phba->idiag_pci_cfg) {
4375 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4376 "2923 Can't create idiag debugfs\n");
4377 goto debug_failed;
4378 }
4379 idiag.offset.last_rd = 0;
4380 }
4381
4382
4383 snprintf(name, sizeof(name), "barAcc");
4384 if (!phba->idiag_bar_acc) {
4385 phba->idiag_bar_acc =
4386 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4387 phba->idiag_root, phba, &lpfc_idiag_op_barAcc);
4388 if (!phba->idiag_bar_acc) {
4389 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4390 "3056 Can't create idiag debugfs\n");
4391 goto debug_failed;
4392 }
4393 idiag.offset.last_rd = 0;
4394 }
4395
4396
4397 snprintf(name, sizeof(name), "queInfo");
4398 if (!phba->idiag_que_info) {
4399 phba->idiag_que_info =
4400 debugfs_create_file(name, S_IFREG|S_IRUGO,
4401 phba->idiag_root, phba, &lpfc_idiag_op_queInfo);
4402 if (!phba->idiag_que_info) {
4403 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4404 "2924 Can't create idiag debugfs\n");
4405 goto debug_failed;
4406 }
4407 }
4408
4409
4410 snprintf(name, sizeof(name), "queAcc");
4411 if (!phba->idiag_que_acc) {
4412 phba->idiag_que_acc =
4413 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4414 phba->idiag_root, phba, &lpfc_idiag_op_queAcc);
4415 if (!phba->idiag_que_acc) {
4416 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4417 "2926 Can't create idiag debugfs\n");
4418 goto debug_failed;
4419 }
4420 }
4421
4422
4423 snprintf(name, sizeof(name), "drbAcc");
4424 if (!phba->idiag_drb_acc) {
4425 phba->idiag_drb_acc =
4426 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4427 phba->idiag_root, phba, &lpfc_idiag_op_drbAcc);
4428 if (!phba->idiag_drb_acc) {
4429 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4430 "2927 Can't create idiag debugfs\n");
4431 goto debug_failed;
4432 }
4433 }
4434
4435
4436 snprintf(name, sizeof(name), "ctlAcc");
4437 if (!phba->idiag_ctl_acc) {
4438 phba->idiag_ctl_acc =
4439 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4440 phba->idiag_root, phba, &lpfc_idiag_op_ctlAcc);
4441 if (!phba->idiag_ctl_acc) {
4442 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4443 "2981 Can't create idiag debugfs\n");
4444 goto debug_failed;
4445 }
4446 }
4447
4448
4449 snprintf(name, sizeof(name), "mbxAcc");
4450 if (!phba->idiag_mbx_acc) {
4451 phba->idiag_mbx_acc =
4452 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4453 phba->idiag_root, phba, &lpfc_idiag_op_mbxAcc);
4454 if (!phba->idiag_mbx_acc) {
4455 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4456 "2980 Can't create idiag debugfs\n");
4457 goto debug_failed;
4458 }
4459 }
4460
4461
4462 if (phba->sli4_hba.extents_in_use) {
4463 snprintf(name, sizeof(name), "extAcc");
4464 if (!phba->idiag_ext_acc) {
4465 phba->idiag_ext_acc =
4466 debugfs_create_file(name,
4467 S_IFREG|S_IRUGO|S_IWUSR,
4468 phba->idiag_root, phba,
4469 &lpfc_idiag_op_extAcc);
4470 if (!phba->idiag_ext_acc) {
4471 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4472 "2986 Cant create "
4473 "idiag debugfs\n");
4474 goto debug_failed;
4475 }
4476 }
4477 }
4478
4479debug_failed:
4480 return;
4481#endif
4482}
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495inline void
4496lpfc_debugfs_terminate(struct lpfc_vport *vport)
4497{
4498#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
4499 struct lpfc_hba *phba = vport->phba;
4500
4501 if (vport->disc_trc) {
4502 kfree(vport->disc_trc);
4503 vport->disc_trc = NULL;
4504 }
4505 if (vport->debug_disc_trc) {
4506 debugfs_remove(vport->debug_disc_trc);
4507 vport->debug_disc_trc = NULL;
4508 }
4509 if (vport->debug_nodelist) {
4510 debugfs_remove(vport->debug_nodelist);
4511 vport->debug_nodelist = NULL;
4512 }
4513 if (vport->vport_debugfs_root) {
4514 debugfs_remove(vport->vport_debugfs_root);
4515 vport->vport_debugfs_root = NULL;
4516 atomic_dec(&phba->debugfs_vport_count);
4517 }
4518 if (atomic_read(&phba->debugfs_vport_count) == 0) {
4519
4520 if (phba->debug_hbqinfo) {
4521 debugfs_remove(phba->debug_hbqinfo);
4522 phba->debug_hbqinfo = NULL;
4523 }
4524 if (phba->debug_dumpHBASlim) {
4525 debugfs_remove(phba->debug_dumpHBASlim);
4526 phba->debug_dumpHBASlim = NULL;
4527 }
4528 if (phba->debug_dumpHostSlim) {
4529 debugfs_remove(phba->debug_dumpHostSlim);
4530 phba->debug_dumpHostSlim = NULL;
4531 }
4532 if (phba->debug_dumpData) {
4533 debugfs_remove(phba->debug_dumpData);
4534 phba->debug_dumpData = NULL;
4535 }
4536
4537 if (phba->debug_dumpDif) {
4538 debugfs_remove(phba->debug_dumpDif);
4539 phba->debug_dumpDif = NULL;
4540 }
4541 if (phba->debug_InjErrLBA) {
4542 debugfs_remove(phba->debug_InjErrLBA);
4543 phba->debug_InjErrLBA = NULL;
4544 }
4545 if (phba->debug_InjErrNPortID) {
4546 debugfs_remove(phba->debug_InjErrNPortID);
4547 phba->debug_InjErrNPortID = NULL;
4548 }
4549 if (phba->debug_InjErrWWPN) {
4550 debugfs_remove(phba->debug_InjErrWWPN);
4551 phba->debug_InjErrWWPN = NULL;
4552 }
4553 if (phba->debug_writeGuard) {
4554 debugfs_remove(phba->debug_writeGuard);
4555 phba->debug_writeGuard = NULL;
4556 }
4557 if (phba->debug_writeApp) {
4558 debugfs_remove(phba->debug_writeApp);
4559 phba->debug_writeApp = NULL;
4560 }
4561 if (phba->debug_writeRef) {
4562 debugfs_remove(phba->debug_writeRef);
4563 phba->debug_writeRef = NULL;
4564 }
4565 if (phba->debug_readGuard) {
4566 debugfs_remove(phba->debug_readGuard);
4567 phba->debug_readGuard = NULL;
4568 }
4569 if (phba->debug_readApp) {
4570 debugfs_remove(phba->debug_readApp);
4571 phba->debug_readApp = NULL;
4572 }
4573 if (phba->debug_readRef) {
4574 debugfs_remove(phba->debug_readRef);
4575 phba->debug_readRef = NULL;
4576 }
4577
4578 if (phba->slow_ring_trc) {
4579 kfree(phba->slow_ring_trc);
4580 phba->slow_ring_trc = NULL;
4581 }
4582 if (phba->debug_slow_ring_trc) {
4583
4584 debugfs_remove(phba->debug_slow_ring_trc);
4585 phba->debug_slow_ring_trc = NULL;
4586 }
4587
4588
4589
4590
4591 if (phba->sli_rev == LPFC_SLI_REV4) {
4592 if (phba->idiag_ext_acc) {
4593
4594 debugfs_remove(phba->idiag_ext_acc);
4595 phba->idiag_ext_acc = NULL;
4596 }
4597 if (phba->idiag_mbx_acc) {
4598
4599 debugfs_remove(phba->idiag_mbx_acc);
4600 phba->idiag_mbx_acc = NULL;
4601 }
4602 if (phba->idiag_ctl_acc) {
4603
4604 debugfs_remove(phba->idiag_ctl_acc);
4605 phba->idiag_ctl_acc = NULL;
4606 }
4607 if (phba->idiag_drb_acc) {
4608
4609 debugfs_remove(phba->idiag_drb_acc);
4610 phba->idiag_drb_acc = NULL;
4611 }
4612 if (phba->idiag_que_acc) {
4613
4614 debugfs_remove(phba->idiag_que_acc);
4615 phba->idiag_que_acc = NULL;
4616 }
4617 if (phba->idiag_que_info) {
4618
4619 debugfs_remove(phba->idiag_que_info);
4620 phba->idiag_que_info = NULL;
4621 }
4622 if (phba->idiag_bar_acc) {
4623
4624 debugfs_remove(phba->idiag_bar_acc);
4625 phba->idiag_bar_acc = NULL;
4626 }
4627 if (phba->idiag_pci_cfg) {
4628
4629 debugfs_remove(phba->idiag_pci_cfg);
4630 phba->idiag_pci_cfg = NULL;
4631 }
4632
4633
4634 if (phba->idiag_root) {
4635
4636 debugfs_remove(phba->idiag_root);
4637 phba->idiag_root = NULL;
4638 }
4639 }
4640
4641 if (phba->hba_debugfs_root) {
4642 debugfs_remove(phba->hba_debugfs_root);
4643 phba->hba_debugfs_root = NULL;
4644 atomic_dec(&lpfc_debugfs_hba_count);
4645 }
4646
4647 if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
4648 debugfs_remove(lpfc_debugfs_root);
4649 lpfc_debugfs_root = NULL;
4650 }
4651 }
4652#endif
4653 return;
4654}
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668void
4669lpfc_debug_dump_all_queues(struct lpfc_hba *phba)
4670{
4671 int fcp_wqidx;
4672
4673
4674
4675
4676 lpfc_debug_dump_mbx_wq(phba);
4677 lpfc_debug_dump_els_wq(phba);
4678
4679 for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
4680 lpfc_debug_dump_fcp_wq(phba, fcp_wqidx);
4681
4682 lpfc_debug_dump_hdr_rq(phba);
4683 lpfc_debug_dump_dat_rq(phba);
4684
4685
4686
4687 lpfc_debug_dump_mbx_cq(phba);
4688 lpfc_debug_dump_els_cq(phba);
4689
4690 for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
4691 lpfc_debug_dump_fcp_cq(phba, fcp_wqidx);
4692
4693
4694
4695
4696 for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
4697 lpfc_debug_dump_hba_eq(phba, fcp_wqidx);
4698}
4699