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 cnt, 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 cnt = LPFC_HBQINFO_SIZE;
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=%s\n",
972 __func__, _dump_buf_dif, file->f_dentry->d_name.name);
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_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_dentry;
1056 struct lpfc_hba *phba = file->private_data;
1057 char dstbuf[32];
1058 uint64_t tmp = 0;
1059 int size;
1060
1061 memset(dstbuf, 0, 32);
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 spin_unlock_irq(&phba->hbalock);
2284 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2285
2286too_big:
2287 len += snprintf(pbuffer+len,
2288 LPFC_QUE_INFO_GET_BUF_SIZE-len, "Truncated ...\n");
2289 spin_unlock_irq(&phba->hbalock);
2290 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2291}
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306static int
2307lpfc_idiag_que_param_check(struct lpfc_queue *q, int index, int count)
2308{
2309
2310 if ((count != 1) && (count != LPFC_QUE_ACC_BROWSE))
2311 return -EINVAL;
2312 if (index > q->entry_count - 1)
2313 return -EINVAL;
2314 return 0;
2315}
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331static int
2332lpfc_idiag_queacc_read_qe(char *pbuffer, int len, struct lpfc_queue *pque,
2333 uint32_t index)
2334{
2335 int offset, esize;
2336 uint32_t *pentry;
2337
2338 if (!pbuffer || !pque)
2339 return 0;
2340
2341 esize = pque->entry_size;
2342 len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
2343 "QE-INDEX[%04d]:\n", index);
2344
2345 offset = 0;
2346 pentry = pque->qe[index].address;
2347 while (esize > 0) {
2348 len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
2349 "%08x ", *pentry);
2350 pentry++;
2351 offset += sizeof(uint32_t);
2352 esize -= sizeof(uint32_t);
2353 if (esize > 0 && !(offset % (4 * sizeof(uint32_t))))
2354 len += snprintf(pbuffer+len,
2355 LPFC_QUE_ACC_BUF_SIZE-len, "\n");
2356 }
2357 len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, "\n");
2358
2359 return len;
2360}
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379static ssize_t
2380lpfc_idiag_queacc_read(struct file *file, char __user *buf, size_t nbytes,
2381 loff_t *ppos)
2382{
2383 struct lpfc_debug *debug = file->private_data;
2384 uint32_t last_index, index, count;
2385 struct lpfc_queue *pque = NULL;
2386 char *pbuffer;
2387 int len = 0;
2388
2389
2390 debug->op = LPFC_IDIAG_OP_RD;
2391
2392 if (!debug->buffer)
2393 debug->buffer = kmalloc(LPFC_QUE_ACC_BUF_SIZE, GFP_KERNEL);
2394 if (!debug->buffer)
2395 return 0;
2396 pbuffer = debug->buffer;
2397
2398 if (*ppos)
2399 return 0;
2400
2401 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
2402 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
2403 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
2404 pque = (struct lpfc_queue *)idiag.ptr_private;
2405 } else
2406 return 0;
2407
2408
2409 if (count == LPFC_QUE_ACC_BROWSE)
2410 goto que_browse;
2411
2412
2413 len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
2414
2415 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2416
2417que_browse:
2418
2419
2420 last_index = idiag.offset.last_rd;
2421 index = last_index;
2422
2423 while (len < LPFC_QUE_ACC_SIZE - pque->entry_size) {
2424 len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
2425 index++;
2426 if (index > pque->entry_count - 1)
2427 break;
2428 }
2429
2430
2431 if (index > pque->entry_count - 1)
2432 index = 0;
2433 idiag.offset.last_rd = index;
2434
2435 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2436}
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456static ssize_t
2457lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
2458 size_t nbytes, loff_t *ppos)
2459{
2460 struct lpfc_debug *debug = file->private_data;
2461 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2462 uint32_t qidx, quetp, queid, index, count, offset, value;
2463 uint32_t *pentry;
2464 struct lpfc_queue *pque;
2465 int rc;
2466
2467
2468 debug->op = LPFC_IDIAG_OP_WR;
2469
2470 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
2471 if (rc < 0)
2472 return rc;
2473
2474
2475 quetp = idiag.cmd.data[IDIAG_QUEACC_QUETP_INDX];
2476 queid = idiag.cmd.data[IDIAG_QUEACC_QUEID_INDX];
2477 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
2478 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
2479 offset = idiag.cmd.data[IDIAG_QUEACC_OFFST_INDX];
2480 value = idiag.cmd.data[IDIAG_QUEACC_VALUE_INDX];
2481
2482
2483 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
2484 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
2485 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
2486 if (rc != LPFC_QUE_ACC_WR_CMD_ARG)
2487 goto error_out;
2488 if (count != 1)
2489 goto error_out;
2490 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
2491 if (rc != LPFC_QUE_ACC_RD_CMD_ARG)
2492 goto error_out;
2493 } else
2494 goto error_out;
2495
2496 switch (quetp) {
2497 case LPFC_IDIAG_EQ:
2498
2499 if (phba->sli4_hba.hba_eq) {
2500 for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
2501 qidx++) {
2502 if (phba->sli4_hba.hba_eq[qidx] &&
2503 phba->sli4_hba.hba_eq[qidx]->queue_id ==
2504 queid) {
2505
2506 rc = lpfc_idiag_que_param_check(
2507 phba->sli4_hba.hba_eq[qidx],
2508 index, count);
2509 if (rc)
2510 goto error_out;
2511 idiag.ptr_private =
2512 phba->sli4_hba.hba_eq[qidx];
2513 goto pass_check;
2514 }
2515 }
2516 }
2517 goto error_out;
2518 break;
2519 case LPFC_IDIAG_CQ:
2520
2521 if (phba->sli4_hba.mbx_cq &&
2522 phba->sli4_hba.mbx_cq->queue_id == queid) {
2523
2524 rc = lpfc_idiag_que_param_check(
2525 phba->sli4_hba.mbx_cq, index, count);
2526 if (rc)
2527 goto error_out;
2528 idiag.ptr_private = phba->sli4_hba.mbx_cq;
2529 goto pass_check;
2530 }
2531
2532 if (phba->sli4_hba.els_cq &&
2533 phba->sli4_hba.els_cq->queue_id == queid) {
2534
2535 rc = lpfc_idiag_que_param_check(
2536 phba->sli4_hba.els_cq, index, count);
2537 if (rc)
2538 goto error_out;
2539 idiag.ptr_private = phba->sli4_hba.els_cq;
2540 goto pass_check;
2541 }
2542
2543 if (phba->sli4_hba.fcp_cq) {
2544 qidx = 0;
2545 do {
2546 if (phba->sli4_hba.fcp_cq[qidx] &&
2547 phba->sli4_hba.fcp_cq[qidx]->queue_id ==
2548 queid) {
2549
2550 rc = lpfc_idiag_que_param_check(
2551 phba->sli4_hba.fcp_cq[qidx],
2552 index, count);
2553 if (rc)
2554 goto error_out;
2555 idiag.ptr_private =
2556 phba->sli4_hba.fcp_cq[qidx];
2557 goto pass_check;
2558 }
2559 } while (++qidx < phba->cfg_fcp_io_channel);
2560 }
2561 goto error_out;
2562 break;
2563 case LPFC_IDIAG_MQ:
2564
2565 if (phba->sli4_hba.mbx_wq &&
2566 phba->sli4_hba.mbx_wq->queue_id == queid) {
2567
2568 rc = lpfc_idiag_que_param_check(
2569 phba->sli4_hba.mbx_wq, index, count);
2570 if (rc)
2571 goto error_out;
2572 idiag.ptr_private = phba->sli4_hba.mbx_wq;
2573 goto pass_check;
2574 }
2575 goto error_out;
2576 break;
2577 case LPFC_IDIAG_WQ:
2578
2579 if (phba->sli4_hba.els_wq &&
2580 phba->sli4_hba.els_wq->queue_id == queid) {
2581
2582 rc = lpfc_idiag_que_param_check(
2583 phba->sli4_hba.els_wq, index, count);
2584 if (rc)
2585 goto error_out;
2586 idiag.ptr_private = phba->sli4_hba.els_wq;
2587 goto pass_check;
2588 }
2589
2590 if (phba->sli4_hba.fcp_wq) {
2591 for (qidx = 0; qidx < phba->cfg_fcp_io_channel;
2592 qidx++) {
2593 if (!phba->sli4_hba.fcp_wq[qidx])
2594 continue;
2595 if (phba->sli4_hba.fcp_wq[qidx]->queue_id ==
2596 queid) {
2597
2598 rc = lpfc_idiag_que_param_check(
2599 phba->sli4_hba.fcp_wq[qidx],
2600 index, count);
2601 if (rc)
2602 goto error_out;
2603 idiag.ptr_private =
2604 phba->sli4_hba.fcp_wq[qidx];
2605 goto pass_check;
2606 }
2607 }
2608 }
2609 goto error_out;
2610 break;
2611 case LPFC_IDIAG_RQ:
2612
2613 if (phba->sli4_hba.hdr_rq &&
2614 phba->sli4_hba.hdr_rq->queue_id == queid) {
2615
2616 rc = lpfc_idiag_que_param_check(
2617 phba->sli4_hba.hdr_rq, index, count);
2618 if (rc)
2619 goto error_out;
2620 idiag.ptr_private = phba->sli4_hba.hdr_rq;
2621 goto pass_check;
2622 }
2623
2624 if (phba->sli4_hba.dat_rq &&
2625 phba->sli4_hba.dat_rq->queue_id == queid) {
2626
2627 rc = lpfc_idiag_que_param_check(
2628 phba->sli4_hba.dat_rq, index, count);
2629 if (rc)
2630 goto error_out;
2631 idiag.ptr_private = phba->sli4_hba.dat_rq;
2632 goto pass_check;
2633 }
2634 goto error_out;
2635 break;
2636 default:
2637 goto error_out;
2638 break;
2639 }
2640
2641pass_check:
2642
2643 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
2644 if (count == LPFC_QUE_ACC_BROWSE)
2645 idiag.offset.last_rd = index;
2646 }
2647
2648 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
2649 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
2650 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
2651
2652 pque = (struct lpfc_queue *)idiag.ptr_private;
2653 if (offset > pque->entry_size/sizeof(uint32_t) - 1)
2654 goto error_out;
2655 pentry = pque->qe[index].address;
2656 pentry += offset;
2657 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR)
2658 *pentry = value;
2659 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST)
2660 *pentry |= value;
2661 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL)
2662 *pentry &= ~value;
2663 }
2664 return nbytes;
2665
2666error_out:
2667
2668 memset(&idiag, 0, sizeof(idiag));
2669 return -EINVAL;
2670}
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686static int
2687lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
2688 int len, uint32_t drbregid)
2689{
2690
2691 if (!pbuffer)
2692 return 0;
2693
2694 switch (drbregid) {
2695 case LPFC_DRB_EQCQ:
2696 len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2697 "EQCQ-DRB-REG: 0x%08x\n",
2698 readl(phba->sli4_hba.EQCQDBregaddr));
2699 break;
2700 case LPFC_DRB_MQ:
2701 len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2702 "MQ-DRB-REG: 0x%08x\n",
2703 readl(phba->sli4_hba.MQDBregaddr));
2704 break;
2705 case LPFC_DRB_WQ:
2706 len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2707 "WQ-DRB-REG: 0x%08x\n",
2708 readl(phba->sli4_hba.WQDBregaddr));
2709 break;
2710 case LPFC_DRB_RQ:
2711 len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
2712 "RQ-DRB-REG: 0x%08x\n",
2713 readl(phba->sli4_hba.RQDBregaddr));
2714 break;
2715 default:
2716 break;
2717 }
2718
2719 return len;
2720}
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739static ssize_t
2740lpfc_idiag_drbacc_read(struct file *file, char __user *buf, size_t nbytes,
2741 loff_t *ppos)
2742{
2743 struct lpfc_debug *debug = file->private_data;
2744 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2745 uint32_t drb_reg_id, i;
2746 char *pbuffer;
2747 int len = 0;
2748
2749
2750 debug->op = LPFC_IDIAG_OP_RD;
2751
2752 if (!debug->buffer)
2753 debug->buffer = kmalloc(LPFC_DRB_ACC_BUF_SIZE, GFP_KERNEL);
2754 if (!debug->buffer)
2755 return 0;
2756 pbuffer = debug->buffer;
2757
2758 if (*ppos)
2759 return 0;
2760
2761 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD)
2762 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
2763 else
2764 return 0;
2765
2766 if (drb_reg_id == LPFC_DRB_ACC_ALL)
2767 for (i = 1; i <= LPFC_DRB_MAX; i++)
2768 len = lpfc_idiag_drbacc_read_reg(phba,
2769 pbuffer, len, i);
2770 else
2771 len = lpfc_idiag_drbacc_read_reg(phba,
2772 pbuffer, len, drb_reg_id);
2773
2774 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2775}
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795static ssize_t
2796lpfc_idiag_drbacc_write(struct file *file, const char __user *buf,
2797 size_t nbytes, loff_t *ppos)
2798{
2799 struct lpfc_debug *debug = file->private_data;
2800 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2801 uint32_t drb_reg_id, value, reg_val = 0;
2802 void __iomem *drb_reg;
2803 int rc;
2804
2805
2806 debug->op = LPFC_IDIAG_OP_WR;
2807
2808 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
2809 if (rc < 0)
2810 return rc;
2811
2812
2813 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
2814 value = idiag.cmd.data[IDIAG_DRBACC_VALUE_INDX];
2815
2816 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
2817 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
2818 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
2819 if (rc != LPFC_DRB_ACC_WR_CMD_ARG)
2820 goto error_out;
2821 if (drb_reg_id > LPFC_DRB_MAX)
2822 goto error_out;
2823 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD) {
2824 if (rc != LPFC_DRB_ACC_RD_CMD_ARG)
2825 goto error_out;
2826 if ((drb_reg_id > LPFC_DRB_MAX) &&
2827 (drb_reg_id != LPFC_DRB_ACC_ALL))
2828 goto error_out;
2829 } else
2830 goto error_out;
2831
2832
2833 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
2834 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
2835 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
2836 switch (drb_reg_id) {
2837 case LPFC_DRB_EQCQ:
2838 drb_reg = phba->sli4_hba.EQCQDBregaddr;
2839 break;
2840 case LPFC_DRB_MQ:
2841 drb_reg = phba->sli4_hba.MQDBregaddr;
2842 break;
2843 case LPFC_DRB_WQ:
2844 drb_reg = phba->sli4_hba.WQDBregaddr;
2845 break;
2846 case LPFC_DRB_RQ:
2847 drb_reg = phba->sli4_hba.RQDBregaddr;
2848 break;
2849 default:
2850 goto error_out;
2851 }
2852
2853 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR)
2854 reg_val = value;
2855 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST) {
2856 reg_val = readl(drb_reg);
2857 reg_val |= value;
2858 }
2859 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
2860 reg_val = readl(drb_reg);
2861 reg_val &= ~value;
2862 }
2863 writel(reg_val, drb_reg);
2864 readl(drb_reg);
2865 }
2866 return nbytes;
2867
2868error_out:
2869
2870 memset(&idiag, 0, sizeof(idiag));
2871 return -EINVAL;
2872}
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888static int
2889lpfc_idiag_ctlacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
2890 int len, uint32_t ctlregid)
2891{
2892
2893 if (!pbuffer)
2894 return 0;
2895
2896 switch (ctlregid) {
2897 case LPFC_CTL_PORT_SEM:
2898 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2899 "Port SemReg: 0x%08x\n",
2900 readl(phba->sli4_hba.conf_regs_memmap_p +
2901 LPFC_CTL_PORT_SEM_OFFSET));
2902 break;
2903 case LPFC_CTL_PORT_STA:
2904 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2905 "Port StaReg: 0x%08x\n",
2906 readl(phba->sli4_hba.conf_regs_memmap_p +
2907 LPFC_CTL_PORT_STA_OFFSET));
2908 break;
2909 case LPFC_CTL_PORT_CTL:
2910 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2911 "Port CtlReg: 0x%08x\n",
2912 readl(phba->sli4_hba.conf_regs_memmap_p +
2913 LPFC_CTL_PORT_CTL_OFFSET));
2914 break;
2915 case LPFC_CTL_PORT_ER1:
2916 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2917 "Port Er1Reg: 0x%08x\n",
2918 readl(phba->sli4_hba.conf_regs_memmap_p +
2919 LPFC_CTL_PORT_ER1_OFFSET));
2920 break;
2921 case LPFC_CTL_PORT_ER2:
2922 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2923 "Port Er2Reg: 0x%08x\n",
2924 readl(phba->sli4_hba.conf_regs_memmap_p +
2925 LPFC_CTL_PORT_ER2_OFFSET));
2926 break;
2927 case LPFC_CTL_PDEV_CTL:
2928 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2929 "PDev CtlReg: 0x%08x\n",
2930 readl(phba->sli4_hba.conf_regs_memmap_p +
2931 LPFC_CTL_PDEV_CTL_OFFSET));
2932 break;
2933 default:
2934 break;
2935 }
2936 return len;
2937}
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954static ssize_t
2955lpfc_idiag_ctlacc_read(struct file *file, char __user *buf, size_t nbytes,
2956 loff_t *ppos)
2957{
2958 struct lpfc_debug *debug = file->private_data;
2959 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2960 uint32_t ctl_reg_id, i;
2961 char *pbuffer;
2962 int len = 0;
2963
2964
2965 debug->op = LPFC_IDIAG_OP_RD;
2966
2967 if (!debug->buffer)
2968 debug->buffer = kmalloc(LPFC_CTL_ACC_BUF_SIZE, GFP_KERNEL);
2969 if (!debug->buffer)
2970 return 0;
2971 pbuffer = debug->buffer;
2972
2973 if (*ppos)
2974 return 0;
2975
2976 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD)
2977 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
2978 else
2979 return 0;
2980
2981 if (ctl_reg_id == LPFC_CTL_ACC_ALL)
2982 for (i = 1; i <= LPFC_CTL_MAX; i++)
2983 len = lpfc_idiag_ctlacc_read_reg(phba,
2984 pbuffer, len, i);
2985 else
2986 len = lpfc_idiag_ctlacc_read_reg(phba,
2987 pbuffer, len, ctl_reg_id);
2988
2989 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2990}
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007static ssize_t
3008lpfc_idiag_ctlacc_write(struct file *file, const char __user *buf,
3009 size_t nbytes, loff_t *ppos)
3010{
3011 struct lpfc_debug *debug = file->private_data;
3012 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3013 uint32_t ctl_reg_id, value, reg_val = 0;
3014 void __iomem *ctl_reg;
3015 int rc;
3016
3017
3018 debug->op = LPFC_IDIAG_OP_WR;
3019
3020 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3021 if (rc < 0)
3022 return rc;
3023
3024
3025 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
3026 value = idiag.cmd.data[IDIAG_CTLACC_VALUE_INDX];
3027
3028 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
3029 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
3030 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
3031 if (rc != LPFC_CTL_ACC_WR_CMD_ARG)
3032 goto error_out;
3033 if (ctl_reg_id > LPFC_CTL_MAX)
3034 goto error_out;
3035 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD) {
3036 if (rc != LPFC_CTL_ACC_RD_CMD_ARG)
3037 goto error_out;
3038 if ((ctl_reg_id > LPFC_CTL_MAX) &&
3039 (ctl_reg_id != LPFC_CTL_ACC_ALL))
3040 goto error_out;
3041 } else
3042 goto error_out;
3043
3044
3045 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
3046 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
3047 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
3048 switch (ctl_reg_id) {
3049 case LPFC_CTL_PORT_SEM:
3050 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3051 LPFC_CTL_PORT_SEM_OFFSET;
3052 break;
3053 case LPFC_CTL_PORT_STA:
3054 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3055 LPFC_CTL_PORT_STA_OFFSET;
3056 break;
3057 case LPFC_CTL_PORT_CTL:
3058 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3059 LPFC_CTL_PORT_CTL_OFFSET;
3060 break;
3061 case LPFC_CTL_PORT_ER1:
3062 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3063 LPFC_CTL_PORT_ER1_OFFSET;
3064 break;
3065 case LPFC_CTL_PORT_ER2:
3066 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3067 LPFC_CTL_PORT_ER2_OFFSET;
3068 break;
3069 case LPFC_CTL_PDEV_CTL:
3070 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
3071 LPFC_CTL_PDEV_CTL_OFFSET;
3072 break;
3073 default:
3074 goto error_out;
3075 }
3076
3077 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR)
3078 reg_val = value;
3079 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST) {
3080 reg_val = readl(ctl_reg);
3081 reg_val |= value;
3082 }
3083 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
3084 reg_val = readl(ctl_reg);
3085 reg_val &= ~value;
3086 }
3087 writel(reg_val, ctl_reg);
3088 readl(ctl_reg);
3089 }
3090 return nbytes;
3091
3092error_out:
3093
3094 memset(&idiag, 0, sizeof(idiag));
3095 return -EINVAL;
3096}
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110static int
3111lpfc_idiag_mbxacc_get_setup(struct lpfc_hba *phba, char *pbuffer)
3112{
3113 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
3114 int len = 0;
3115
3116 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3117 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3118 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3119 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3120
3121 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3122 "mbx_dump_map: 0x%08x\n", mbx_dump_map);
3123 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3124 "mbx_dump_cnt: %04d\n", mbx_dump_cnt);
3125 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3126 "mbx_word_cnt: %04d\n", mbx_word_cnt);
3127 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
3128 "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd);
3129
3130 return len;
3131}
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148static ssize_t
3149lpfc_idiag_mbxacc_read(struct file *file, char __user *buf, size_t nbytes,
3150 loff_t *ppos)
3151{
3152 struct lpfc_debug *debug = file->private_data;
3153 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3154 char *pbuffer;
3155 int len = 0;
3156
3157
3158 debug->op = LPFC_IDIAG_OP_RD;
3159
3160 if (!debug->buffer)
3161 debug->buffer = kmalloc(LPFC_MBX_ACC_BUF_SIZE, GFP_KERNEL);
3162 if (!debug->buffer)
3163 return 0;
3164 pbuffer = debug->buffer;
3165
3166 if (*ppos)
3167 return 0;
3168
3169 if ((idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP) &&
3170 (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP))
3171 return 0;
3172
3173 len = lpfc_idiag_mbxacc_get_setup(phba, pbuffer);
3174
3175 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3176}
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193static ssize_t
3194lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf,
3195 size_t nbytes, loff_t *ppos)
3196{
3197 struct lpfc_debug *debug = file->private_data;
3198 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
3199 int rc;
3200
3201
3202 debug->op = LPFC_IDIAG_OP_WR;
3203
3204 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3205 if (rc < 0)
3206 return rc;
3207
3208
3209 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3210 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3211 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3212 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3213
3214 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_MBXACC_DP) {
3215 if (!(mbx_dump_map & LPFC_MBX_DMP_MBX_ALL))
3216 goto error_out;
3217 if ((mbx_dump_map & ~LPFC_MBX_DMP_MBX_ALL) &&
3218 (mbx_dump_map != LPFC_MBX_DMP_ALL))
3219 goto error_out;
3220 if (mbx_word_cnt > sizeof(MAILBOX_t))
3221 goto error_out;
3222 } else if (idiag.cmd.opcode == LPFC_IDIAG_BSG_MBXACC_DP) {
3223 if (!(mbx_dump_map & LPFC_BSG_DMP_MBX_ALL))
3224 goto error_out;
3225 if ((mbx_dump_map & ~LPFC_BSG_DMP_MBX_ALL) &&
3226 (mbx_dump_map != LPFC_MBX_DMP_ALL))
3227 goto error_out;
3228 if (mbx_word_cnt > (BSG_MBOX_SIZE)/4)
3229 goto error_out;
3230 if (mbx_mbox_cmd != 0x9b)
3231 goto error_out;
3232 } else
3233 goto error_out;
3234
3235 if (mbx_word_cnt == 0)
3236 goto error_out;
3237 if (rc != LPFC_MBX_DMP_ARG)
3238 goto error_out;
3239 if (mbx_mbox_cmd & ~0xff)
3240 goto error_out;
3241
3242
3243 if (mbx_dump_cnt == 0)
3244 goto reset_out;
3245
3246 return nbytes;
3247
3248reset_out:
3249
3250 memset(&idiag, 0, sizeof(idiag));
3251 return nbytes;
3252
3253error_out:
3254
3255 memset(&idiag, 0, sizeof(idiag));
3256 return -EINVAL;
3257}
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271static int
3272lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
3273{
3274 uint16_t ext_cnt, ext_size;
3275
3276 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3277 "\nAvailable Extents Information:\n");
3278
3279 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3280 "\tPort Available VPI extents: ");
3281 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI,
3282 &ext_cnt, &ext_size);
3283 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3284 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3285
3286 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3287 "\tPort Available VFI extents: ");
3288 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI,
3289 &ext_cnt, &ext_size);
3290 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3291 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3292
3293 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3294 "\tPort Available RPI extents: ");
3295 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI,
3296 &ext_cnt, &ext_size);
3297 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3298 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3299
3300 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3301 "\tPort Available XRI extents: ");
3302 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI,
3303 &ext_cnt, &ext_size);
3304 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3305 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3306
3307 return len;
3308}
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322static int
3323lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len)
3324{
3325 uint16_t ext_cnt, ext_size;
3326 int rc;
3327
3328 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3329 "\nAllocated Extents Information:\n");
3330
3331 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3332 "\tHost Allocated VPI extents: ");
3333 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI,
3334 &ext_cnt, &ext_size);
3335 if (!rc)
3336 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3337 "Port %d Extent %3d, Size %3d\n",
3338 phba->brd_no, ext_cnt, ext_size);
3339 else
3340 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3341 "N/A\n");
3342
3343 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3344 "\tHost Allocated VFI extents: ");
3345 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI,
3346 &ext_cnt, &ext_size);
3347 if (!rc)
3348 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3349 "Port %d Extent %3d, Size %3d\n",
3350 phba->brd_no, ext_cnt, ext_size);
3351 else
3352 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3353 "N/A\n");
3354
3355 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3356 "\tHost Allocated RPI extents: ");
3357 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI,
3358 &ext_cnt, &ext_size);
3359 if (!rc)
3360 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3361 "Port %d Extent %3d, Size %3d\n",
3362 phba->brd_no, ext_cnt, ext_size);
3363 else
3364 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3365 "N/A\n");
3366
3367 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3368 "\tHost Allocated XRI extents: ");
3369 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI,
3370 &ext_cnt, &ext_size);
3371 if (!rc)
3372 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3373 "Port %d Extent %3d, Size %3d\n",
3374 phba->brd_no, ext_cnt, ext_size);
3375 else
3376 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3377 "N/A\n");
3378
3379 return len;
3380}
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394static int
3395lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len)
3396{
3397 struct lpfc_rsrc_blks *rsrc_blks;
3398 int index;
3399
3400 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3401 "\nDriver Extents Information:\n");
3402
3403 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3404 "\tVPI extents:\n");
3405 index = 0;
3406 list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) {
3407 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3408 "\t\tBlock %3d: Start %4d, Count %4d\n",
3409 index, rsrc_blks->rsrc_start,
3410 rsrc_blks->rsrc_size);
3411 index++;
3412 }
3413 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3414 "\tVFI extents:\n");
3415 index = 0;
3416 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list,
3417 list) {
3418 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3419 "\t\tBlock %3d: Start %4d, Count %4d\n",
3420 index, rsrc_blks->rsrc_start,
3421 rsrc_blks->rsrc_size);
3422 index++;
3423 }
3424
3425 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3426 "\tRPI extents:\n");
3427 index = 0;
3428 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list,
3429 list) {
3430 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3431 "\t\tBlock %3d: Start %4d, Count %4d\n",
3432 index, rsrc_blks->rsrc_start,
3433 rsrc_blks->rsrc_size);
3434 index++;
3435 }
3436
3437 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3438 "\tXRI extents:\n");
3439 index = 0;
3440 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list,
3441 list) {
3442 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3443 "\t\tBlock %3d: Start %4d, Count %4d\n",
3444 index, rsrc_blks->rsrc_start,
3445 rsrc_blks->rsrc_size);
3446 index++;
3447 }
3448
3449 return len;
3450}
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467static ssize_t
3468lpfc_idiag_extacc_write(struct file *file, const char __user *buf,
3469 size_t nbytes, loff_t *ppos)
3470{
3471 struct lpfc_debug *debug = file->private_data;
3472 uint32_t ext_map;
3473 int rc;
3474
3475
3476 debug->op = LPFC_IDIAG_OP_WR;
3477
3478 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3479 if (rc < 0)
3480 return rc;
3481
3482 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
3483
3484 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
3485 goto error_out;
3486 if (rc != LPFC_EXT_ACC_CMD_ARG)
3487 goto error_out;
3488 if (!(ext_map & LPFC_EXT_ACC_ALL))
3489 goto error_out;
3490
3491 return nbytes;
3492error_out:
3493
3494 memset(&idiag, 0, sizeof(idiag));
3495 return -EINVAL;
3496}
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513static ssize_t
3514lpfc_idiag_extacc_read(struct file *file, char __user *buf, size_t nbytes,
3515 loff_t *ppos)
3516{
3517 struct lpfc_debug *debug = file->private_data;
3518 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3519 char *pbuffer;
3520 uint32_t ext_map;
3521 int len = 0;
3522
3523
3524 debug->op = LPFC_IDIAG_OP_RD;
3525
3526 if (!debug->buffer)
3527 debug->buffer = kmalloc(LPFC_EXT_ACC_BUF_SIZE, GFP_KERNEL);
3528 if (!debug->buffer)
3529 return 0;
3530 pbuffer = debug->buffer;
3531 if (*ppos)
3532 return 0;
3533 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
3534 return 0;
3535
3536 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
3537 if (ext_map & LPFC_EXT_ACC_AVAIL)
3538 len = lpfc_idiag_extacc_avail_get(phba, pbuffer, len);
3539 if (ext_map & LPFC_EXT_ACC_ALLOC)
3540 len = lpfc_idiag_extacc_alloc_get(phba, pbuffer, len);
3541 if (ext_map & LPFC_EXT_ACC_DRIVR)
3542 len = lpfc_idiag_extacc_drivr_get(phba, pbuffer, len);
3543
3544 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3545}
3546
3547#undef lpfc_debugfs_op_disc_trc
3548static const struct file_operations lpfc_debugfs_op_disc_trc = {
3549 .owner = THIS_MODULE,
3550 .open = lpfc_debugfs_disc_trc_open,
3551 .llseek = lpfc_debugfs_lseek,
3552 .read = lpfc_debugfs_read,
3553 .release = lpfc_debugfs_release,
3554};
3555
3556#undef lpfc_debugfs_op_nodelist
3557static const struct file_operations lpfc_debugfs_op_nodelist = {
3558 .owner = THIS_MODULE,
3559 .open = lpfc_debugfs_nodelist_open,
3560 .llseek = lpfc_debugfs_lseek,
3561 .read = lpfc_debugfs_read,
3562 .release = lpfc_debugfs_release,
3563};
3564
3565#undef lpfc_debugfs_op_hbqinfo
3566static const struct file_operations lpfc_debugfs_op_hbqinfo = {
3567 .owner = THIS_MODULE,
3568 .open = lpfc_debugfs_hbqinfo_open,
3569 .llseek = lpfc_debugfs_lseek,
3570 .read = lpfc_debugfs_read,
3571 .release = lpfc_debugfs_release,
3572};
3573
3574#undef lpfc_debugfs_op_dumpHBASlim
3575static const struct file_operations lpfc_debugfs_op_dumpHBASlim = {
3576 .owner = THIS_MODULE,
3577 .open = lpfc_debugfs_dumpHBASlim_open,
3578 .llseek = lpfc_debugfs_lseek,
3579 .read = lpfc_debugfs_read,
3580 .release = lpfc_debugfs_release,
3581};
3582
3583#undef lpfc_debugfs_op_dumpHostSlim
3584static const struct file_operations lpfc_debugfs_op_dumpHostSlim = {
3585 .owner = THIS_MODULE,
3586 .open = lpfc_debugfs_dumpHostSlim_open,
3587 .llseek = lpfc_debugfs_lseek,
3588 .read = lpfc_debugfs_read,
3589 .release = lpfc_debugfs_release,
3590};
3591
3592#undef lpfc_debugfs_op_dumpData
3593static const struct file_operations lpfc_debugfs_op_dumpData = {
3594 .owner = THIS_MODULE,
3595 .open = lpfc_debugfs_dumpData_open,
3596 .llseek = lpfc_debugfs_lseek,
3597 .read = lpfc_debugfs_read,
3598 .write = lpfc_debugfs_dumpDataDif_write,
3599 .release = lpfc_debugfs_dumpDataDif_release,
3600};
3601
3602#undef lpfc_debugfs_op_dumpDif
3603static const struct file_operations lpfc_debugfs_op_dumpDif = {
3604 .owner = THIS_MODULE,
3605 .open = lpfc_debugfs_dumpDif_open,
3606 .llseek = lpfc_debugfs_lseek,
3607 .read = lpfc_debugfs_read,
3608 .write = lpfc_debugfs_dumpDataDif_write,
3609 .release = lpfc_debugfs_dumpDataDif_release,
3610};
3611
3612#undef lpfc_debugfs_op_dif_err
3613static const struct file_operations lpfc_debugfs_op_dif_err = {
3614 .owner = THIS_MODULE,
3615 .open = simple_open,
3616 .llseek = lpfc_debugfs_lseek,
3617 .read = lpfc_debugfs_dif_err_read,
3618 .write = lpfc_debugfs_dif_err_write,
3619 .release = lpfc_debugfs_dif_err_release,
3620};
3621
3622#undef lpfc_debugfs_op_slow_ring_trc
3623static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
3624 .owner = THIS_MODULE,
3625 .open = lpfc_debugfs_slow_ring_trc_open,
3626 .llseek = lpfc_debugfs_lseek,
3627 .read = lpfc_debugfs_read,
3628 .release = lpfc_debugfs_release,
3629};
3630
3631static struct dentry *lpfc_debugfs_root = NULL;
3632static atomic_t lpfc_debugfs_hba_count;
3633
3634
3635
3636
3637#undef lpfc_idiag_op_pciCfg
3638static const struct file_operations lpfc_idiag_op_pciCfg = {
3639 .owner = THIS_MODULE,
3640 .open = lpfc_idiag_open,
3641 .llseek = lpfc_debugfs_lseek,
3642 .read = lpfc_idiag_pcicfg_read,
3643 .write = lpfc_idiag_pcicfg_write,
3644 .release = lpfc_idiag_cmd_release,
3645};
3646
3647#undef lpfc_idiag_op_barAcc
3648static const struct file_operations lpfc_idiag_op_barAcc = {
3649 .owner = THIS_MODULE,
3650 .open = lpfc_idiag_open,
3651 .llseek = lpfc_debugfs_lseek,
3652 .read = lpfc_idiag_baracc_read,
3653 .write = lpfc_idiag_baracc_write,
3654 .release = lpfc_idiag_cmd_release,
3655};
3656
3657#undef lpfc_idiag_op_queInfo
3658static const struct file_operations lpfc_idiag_op_queInfo = {
3659 .owner = THIS_MODULE,
3660 .open = lpfc_idiag_open,
3661 .read = lpfc_idiag_queinfo_read,
3662 .release = lpfc_idiag_release,
3663};
3664
3665#undef lpfc_idiag_op_queAcc
3666static const struct file_operations lpfc_idiag_op_queAcc = {
3667 .owner = THIS_MODULE,
3668 .open = lpfc_idiag_open,
3669 .llseek = lpfc_debugfs_lseek,
3670 .read = lpfc_idiag_queacc_read,
3671 .write = lpfc_idiag_queacc_write,
3672 .release = lpfc_idiag_cmd_release,
3673};
3674
3675#undef lpfc_idiag_op_drbAcc
3676static const struct file_operations lpfc_idiag_op_drbAcc = {
3677 .owner = THIS_MODULE,
3678 .open = lpfc_idiag_open,
3679 .llseek = lpfc_debugfs_lseek,
3680 .read = lpfc_idiag_drbacc_read,
3681 .write = lpfc_idiag_drbacc_write,
3682 .release = lpfc_idiag_cmd_release,
3683};
3684
3685#undef lpfc_idiag_op_ctlAcc
3686static const struct file_operations lpfc_idiag_op_ctlAcc = {
3687 .owner = THIS_MODULE,
3688 .open = lpfc_idiag_open,
3689 .llseek = lpfc_debugfs_lseek,
3690 .read = lpfc_idiag_ctlacc_read,
3691 .write = lpfc_idiag_ctlacc_write,
3692 .release = lpfc_idiag_cmd_release,
3693};
3694
3695#undef lpfc_idiag_op_mbxAcc
3696static const struct file_operations lpfc_idiag_op_mbxAcc = {
3697 .owner = THIS_MODULE,
3698 .open = lpfc_idiag_open,
3699 .llseek = lpfc_debugfs_lseek,
3700 .read = lpfc_idiag_mbxacc_read,
3701 .write = lpfc_idiag_mbxacc_write,
3702 .release = lpfc_idiag_cmd_release,
3703};
3704
3705#undef lpfc_idiag_op_extAcc
3706static const struct file_operations lpfc_idiag_op_extAcc = {
3707 .owner = THIS_MODULE,
3708 .open = lpfc_idiag_open,
3709 .llseek = lpfc_debugfs_lseek,
3710 .read = lpfc_idiag_extacc_read,
3711 .write = lpfc_idiag_extacc_write,
3712 .release = lpfc_idiag_cmd_release,
3713};
3714
3715#endif
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725void
3726lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *phba, enum nemb_type nemb_tp,
3727 enum mbox_type mbox_tp, enum dma_type dma_tp,
3728 enum sta_type sta_tp,
3729 struct lpfc_dmabuf *dmabuf, uint32_t ext_buf)
3730{
3731#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
3732 uint32_t *mbx_mbox_cmd, *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt;
3733 char line_buf[LPFC_MBX_ACC_LBUF_SZ];
3734 int len = 0;
3735 uint32_t do_dump = 0;
3736 uint32_t *pword;
3737 uint32_t i;
3738
3739 if (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP)
3740 return;
3741
3742 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3743 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3744 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3745 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3746
3747 if (!(*mbx_dump_map & LPFC_MBX_DMP_ALL) ||
3748 (*mbx_dump_cnt == 0) ||
3749 (*mbx_word_cnt == 0))
3750 return;
3751
3752 if (*mbx_mbox_cmd != 0x9B)
3753 return;
3754
3755 if ((mbox_tp == mbox_rd) && (dma_tp == dma_mbox)) {
3756 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_MBX) {
3757 do_dump |= LPFC_BSG_DMP_MBX_RD_MBX;
3758 printk(KERN_ERR "\nRead mbox command (x%x), "
3759 "nemb:0x%x, extbuf_cnt:%d:\n",
3760 sta_tp, nemb_tp, ext_buf);
3761 }
3762 }
3763 if ((mbox_tp == mbox_rd) && (dma_tp == dma_ebuf)) {
3764 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_BUF) {
3765 do_dump |= LPFC_BSG_DMP_MBX_RD_BUF;
3766 printk(KERN_ERR "\nRead mbox buffer (x%x), "
3767 "nemb:0x%x, extbuf_seq:%d:\n",
3768 sta_tp, nemb_tp, ext_buf);
3769 }
3770 }
3771 if ((mbox_tp == mbox_wr) && (dma_tp == dma_mbox)) {
3772 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_MBX) {
3773 do_dump |= LPFC_BSG_DMP_MBX_WR_MBX;
3774 printk(KERN_ERR "\nWrite mbox command (x%x), "
3775 "nemb:0x%x, extbuf_cnt:%d:\n",
3776 sta_tp, nemb_tp, ext_buf);
3777 }
3778 }
3779 if ((mbox_tp == mbox_wr) && (dma_tp == dma_ebuf)) {
3780 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_BUF) {
3781 do_dump |= LPFC_BSG_DMP_MBX_WR_BUF;
3782 printk(KERN_ERR "\nWrite mbox buffer (x%x), "
3783 "nemb:0x%x, extbuf_seq:%d:\n",
3784 sta_tp, nemb_tp, ext_buf);
3785 }
3786 }
3787
3788
3789 if (do_dump) {
3790 pword = (uint32_t *)dmabuf->virt;
3791 for (i = 0; i < *mbx_word_cnt; i++) {
3792 if (!(i % 8)) {
3793 if (i != 0)
3794 printk(KERN_ERR "%s\n", line_buf);
3795 len = 0;
3796 len += snprintf(line_buf+len,
3797 LPFC_MBX_ACC_LBUF_SZ-len,
3798 "%03d: ", i);
3799 }
3800 len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
3801 "%08x ", (uint32_t)*pword);
3802 pword++;
3803 }
3804 if ((i - 1) % 8)
3805 printk(KERN_ERR "%s\n", line_buf);
3806 (*mbx_dump_cnt)--;
3807 }
3808
3809
3810 if (*mbx_dump_cnt == 0)
3811 memset(&idiag, 0, sizeof(idiag));
3812 return;
3813#endif
3814}
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824void
3825lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox)
3826{
3827#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
3828 uint32_t *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt, *mbx_mbox_cmd;
3829 char line_buf[LPFC_MBX_ACC_LBUF_SZ];
3830 int len = 0;
3831 uint32_t *pword;
3832 uint8_t *pbyte;
3833 uint32_t i, j;
3834
3835 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP)
3836 return;
3837
3838 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3839 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3840 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3841 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3842
3843 if (!(*mbx_dump_map & LPFC_MBX_DMP_MBX_ALL) ||
3844 (*mbx_dump_cnt == 0) ||
3845 (*mbx_word_cnt == 0))
3846 return;
3847
3848 if ((*mbx_mbox_cmd != LPFC_MBX_ALL_CMD) &&
3849 (*mbx_mbox_cmd != pmbox->mbxCommand))
3850 return;
3851
3852
3853 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_WORD) {
3854 printk(KERN_ERR "Mailbox command:0x%x dump by word:\n",
3855 pmbox->mbxCommand);
3856 pword = (uint32_t *)pmbox;
3857 for (i = 0; i < *mbx_word_cnt; i++) {
3858 if (!(i % 8)) {
3859 if (i != 0)
3860 printk(KERN_ERR "%s\n", line_buf);
3861 len = 0;
3862 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
3863 len += snprintf(line_buf+len,
3864 LPFC_MBX_ACC_LBUF_SZ-len,
3865 "%03d: ", i);
3866 }
3867 len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
3868 "%08x ",
3869 ((uint32_t)*pword) & 0xffffffff);
3870 pword++;
3871 }
3872 if ((i - 1) % 8)
3873 printk(KERN_ERR "%s\n", line_buf);
3874 printk(KERN_ERR "\n");
3875 }
3876 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_BYTE) {
3877 printk(KERN_ERR "Mailbox command:0x%x dump by byte:\n",
3878 pmbox->mbxCommand);
3879 pbyte = (uint8_t *)pmbox;
3880 for (i = 0; i < *mbx_word_cnt; i++) {
3881 if (!(i % 8)) {
3882 if (i != 0)
3883 printk(KERN_ERR "%s\n", line_buf);
3884 len = 0;
3885 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
3886 len += snprintf(line_buf+len,
3887 LPFC_MBX_ACC_LBUF_SZ-len,
3888 "%03d: ", i);
3889 }
3890 for (j = 0; j < 4; j++) {
3891 len += snprintf(line_buf+len,
3892 LPFC_MBX_ACC_LBUF_SZ-len,
3893 "%02x",
3894 ((uint8_t)*pbyte) & 0xff);
3895 pbyte++;
3896 }
3897 len += snprintf(line_buf+len,
3898 LPFC_MBX_ACC_LBUF_SZ-len, " ");
3899 }
3900 if ((i - 1) % 8)
3901 printk(KERN_ERR "%s\n", line_buf);
3902 printk(KERN_ERR "\n");
3903 }
3904 (*mbx_dump_cnt)--;
3905
3906
3907 if (*mbx_dump_cnt == 0)
3908 memset(&idiag, 0, sizeof(idiag));
3909 return;
3910#endif
3911}
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923inline void
3924lpfc_debugfs_initialize(struct lpfc_vport *vport)
3925{
3926#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
3927 struct lpfc_hba *phba = vport->phba;
3928 char name[64];
3929 uint32_t num, i;
3930
3931 if (!lpfc_debugfs_enable)
3932 return;
3933
3934
3935 if (!lpfc_debugfs_root) {
3936 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
3937 atomic_set(&lpfc_debugfs_hba_count, 0);
3938 if (!lpfc_debugfs_root) {
3939 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3940 "0408 Cannot create debugfs root\n");
3941 goto debug_failed;
3942 }
3943 }
3944 if (!lpfc_debugfs_start_time)
3945 lpfc_debugfs_start_time = jiffies;
3946
3947
3948 snprintf(name, sizeof(name), "fn%d", phba->brd_no);
3949 if (!phba->hba_debugfs_root) {
3950 phba->hba_debugfs_root =
3951 debugfs_create_dir(name, lpfc_debugfs_root);
3952 if (!phba->hba_debugfs_root) {
3953 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3954 "0412 Cannot create debugfs hba\n");
3955 goto debug_failed;
3956 }
3957 atomic_inc(&lpfc_debugfs_hba_count);
3958 atomic_set(&phba->debugfs_vport_count, 0);
3959
3960
3961 snprintf(name, sizeof(name), "hbqinfo");
3962 phba->debug_hbqinfo =
3963 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
3964 phba->hba_debugfs_root,
3965 phba, &lpfc_debugfs_op_hbqinfo);
3966 if (!phba->debug_hbqinfo) {
3967 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3968 "0411 Cannot create debugfs hbqinfo\n");
3969 goto debug_failed;
3970 }
3971
3972
3973 if (phba->sli_rev < LPFC_SLI_REV4) {
3974 snprintf(name, sizeof(name), "dumpHBASlim");
3975 phba->debug_dumpHBASlim =
3976 debugfs_create_file(name,
3977 S_IFREG|S_IRUGO|S_IWUSR,
3978 phba->hba_debugfs_root,
3979 phba, &lpfc_debugfs_op_dumpHBASlim);
3980 if (!phba->debug_dumpHBASlim) {
3981 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3982 "0413 Cannot create debugfs "
3983 "dumpHBASlim\n");
3984 goto debug_failed;
3985 }
3986 } else
3987 phba->debug_dumpHBASlim = NULL;
3988
3989
3990 if (phba->sli_rev < LPFC_SLI_REV4) {
3991 snprintf(name, sizeof(name), "dumpHostSlim");
3992 phba->debug_dumpHostSlim =
3993 debugfs_create_file(name,
3994 S_IFREG|S_IRUGO|S_IWUSR,
3995 phba->hba_debugfs_root,
3996 phba, &lpfc_debugfs_op_dumpHostSlim);
3997 if (!phba->debug_dumpHostSlim) {
3998 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3999 "0414 Cannot create debugfs "
4000 "dumpHostSlim\n");
4001 goto debug_failed;
4002 }
4003 } else
4004 phba->debug_dumpHBASlim = NULL;
4005
4006
4007 snprintf(name, sizeof(name), "dumpData");
4008 phba->debug_dumpData =
4009 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4010 phba->hba_debugfs_root,
4011 phba, &lpfc_debugfs_op_dumpData);
4012 if (!phba->debug_dumpData) {
4013 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4014 "0800 Cannot create debugfs dumpData\n");
4015 goto debug_failed;
4016 }
4017
4018
4019 snprintf(name, sizeof(name), "dumpDif");
4020 phba->debug_dumpDif =
4021 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4022 phba->hba_debugfs_root,
4023 phba, &lpfc_debugfs_op_dumpDif);
4024 if (!phba->debug_dumpDif) {
4025 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4026 "0801 Cannot create debugfs dumpDif\n");
4027 goto debug_failed;
4028 }
4029
4030
4031 snprintf(name, sizeof(name), "InjErrLBA");
4032 phba->debug_InjErrLBA =
4033 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4034 phba->hba_debugfs_root,
4035 phba, &lpfc_debugfs_op_dif_err);
4036 if (!phba->debug_InjErrLBA) {
4037 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4038 "0807 Cannot create debugfs InjErrLBA\n");
4039 goto debug_failed;
4040 }
4041 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
4042
4043 snprintf(name, sizeof(name), "InjErrNPortID");
4044 phba->debug_InjErrNPortID =
4045 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4046 phba->hba_debugfs_root,
4047 phba, &lpfc_debugfs_op_dif_err);
4048 if (!phba->debug_InjErrNPortID) {
4049 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4050 "0809 Cannot create debugfs InjErrNPortID\n");
4051 goto debug_failed;
4052 }
4053
4054 snprintf(name, sizeof(name), "InjErrWWPN");
4055 phba->debug_InjErrWWPN =
4056 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4057 phba->hba_debugfs_root,
4058 phba, &lpfc_debugfs_op_dif_err);
4059 if (!phba->debug_InjErrWWPN) {
4060 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4061 "0810 Cannot create debugfs InjErrWWPN\n");
4062 goto debug_failed;
4063 }
4064
4065 snprintf(name, sizeof(name), "writeGuardInjErr");
4066 phba->debug_writeGuard =
4067 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4068 phba->hba_debugfs_root,
4069 phba, &lpfc_debugfs_op_dif_err);
4070 if (!phba->debug_writeGuard) {
4071 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4072 "0802 Cannot create debugfs writeGuard\n");
4073 goto debug_failed;
4074 }
4075
4076 snprintf(name, sizeof(name), "writeAppInjErr");
4077 phba->debug_writeApp =
4078 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4079 phba->hba_debugfs_root,
4080 phba, &lpfc_debugfs_op_dif_err);
4081 if (!phba->debug_writeApp) {
4082 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4083 "0803 Cannot create debugfs writeApp\n");
4084 goto debug_failed;
4085 }
4086
4087 snprintf(name, sizeof(name), "writeRefInjErr");
4088 phba->debug_writeRef =
4089 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4090 phba->hba_debugfs_root,
4091 phba, &lpfc_debugfs_op_dif_err);
4092 if (!phba->debug_writeRef) {
4093 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4094 "0804 Cannot create debugfs writeRef\n");
4095 goto debug_failed;
4096 }
4097
4098 snprintf(name, sizeof(name), "readGuardInjErr");
4099 phba->debug_readGuard =
4100 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4101 phba->hba_debugfs_root,
4102 phba, &lpfc_debugfs_op_dif_err);
4103 if (!phba->debug_readGuard) {
4104 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4105 "0808 Cannot create debugfs readGuard\n");
4106 goto debug_failed;
4107 }
4108
4109 snprintf(name, sizeof(name), "readAppInjErr");
4110 phba->debug_readApp =
4111 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4112 phba->hba_debugfs_root,
4113 phba, &lpfc_debugfs_op_dif_err);
4114 if (!phba->debug_readApp) {
4115 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4116 "0805 Cannot create debugfs readApp\n");
4117 goto debug_failed;
4118 }
4119
4120 snprintf(name, sizeof(name), "readRefInjErr");
4121 phba->debug_readRef =
4122 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4123 phba->hba_debugfs_root,
4124 phba, &lpfc_debugfs_op_dif_err);
4125 if (!phba->debug_readRef) {
4126 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4127 "0806 Cannot create debugfs readApp\n");
4128 goto debug_failed;
4129 }
4130
4131
4132 if (lpfc_debugfs_max_slow_ring_trc) {
4133 num = lpfc_debugfs_max_slow_ring_trc - 1;
4134 if (num & lpfc_debugfs_max_slow_ring_trc) {
4135
4136 num = lpfc_debugfs_max_slow_ring_trc;
4137 i = 0;
4138 while (num > 1) {
4139 num = num >> 1;
4140 i++;
4141 }
4142 lpfc_debugfs_max_slow_ring_trc = (1 << i);
4143 printk(KERN_ERR
4144 "lpfc_debugfs_max_disc_trc changed to "
4145 "%d\n", lpfc_debugfs_max_disc_trc);
4146 }
4147 }
4148
4149 snprintf(name, sizeof(name), "slow_ring_trace");
4150 phba->debug_slow_ring_trc =
4151 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4152 phba->hba_debugfs_root,
4153 phba, &lpfc_debugfs_op_slow_ring_trc);
4154 if (!phba->debug_slow_ring_trc) {
4155 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4156 "0415 Cannot create debugfs "
4157 "slow_ring_trace\n");
4158 goto debug_failed;
4159 }
4160 if (!phba->slow_ring_trc) {
4161 phba->slow_ring_trc = kmalloc(
4162 (sizeof(struct lpfc_debugfs_trc) *
4163 lpfc_debugfs_max_slow_ring_trc),
4164 GFP_KERNEL);
4165 if (!phba->slow_ring_trc) {
4166 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4167 "0416 Cannot create debugfs "
4168 "slow_ring buffer\n");
4169 goto debug_failed;
4170 }
4171 atomic_set(&phba->slow_ring_trc_cnt, 0);
4172 memset(phba->slow_ring_trc, 0,
4173 (sizeof(struct lpfc_debugfs_trc) *
4174 lpfc_debugfs_max_slow_ring_trc));
4175 }
4176 }
4177
4178 snprintf(name, sizeof(name), "vport%d", vport->vpi);
4179 if (!vport->vport_debugfs_root) {
4180 vport->vport_debugfs_root =
4181 debugfs_create_dir(name, phba->hba_debugfs_root);
4182 if (!vport->vport_debugfs_root) {
4183 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4184 "0417 Can't create debugfs\n");
4185 goto debug_failed;
4186 }
4187 atomic_inc(&phba->debugfs_vport_count);
4188 }
4189
4190 if (lpfc_debugfs_max_disc_trc) {
4191 num = lpfc_debugfs_max_disc_trc - 1;
4192 if (num & lpfc_debugfs_max_disc_trc) {
4193
4194 num = lpfc_debugfs_max_disc_trc;
4195 i = 0;
4196 while (num > 1) {
4197 num = num >> 1;
4198 i++;
4199 }
4200 lpfc_debugfs_max_disc_trc = (1 << i);
4201 printk(KERN_ERR
4202 "lpfc_debugfs_max_disc_trc changed to %d\n",
4203 lpfc_debugfs_max_disc_trc);
4204 }
4205 }
4206
4207 vport->disc_trc = kzalloc(
4208 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
4209 GFP_KERNEL);
4210
4211 if (!vport->disc_trc) {
4212 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4213 "0418 Cannot create debugfs disc trace "
4214 "buffer\n");
4215 goto debug_failed;
4216 }
4217 atomic_set(&vport->disc_trc_cnt, 0);
4218
4219 snprintf(name, sizeof(name), "discovery_trace");
4220 vport->debug_disc_trc =
4221 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4222 vport->vport_debugfs_root,
4223 vport, &lpfc_debugfs_op_disc_trc);
4224 if (!vport->debug_disc_trc) {
4225 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4226 "0419 Cannot create debugfs "
4227 "discovery_trace\n");
4228 goto debug_failed;
4229 }
4230 snprintf(name, sizeof(name), "nodelist");
4231 vport->debug_nodelist =
4232 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4233 vport->vport_debugfs_root,
4234 vport, &lpfc_debugfs_op_nodelist);
4235 if (!vport->debug_nodelist) {
4236 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4237 "2985 Can't create debugfs nodelist\n");
4238 goto debug_failed;
4239 }
4240
4241
4242
4243
4244 if (phba->sli_rev < LPFC_SLI_REV4)
4245 goto debug_failed;
4246
4247 snprintf(name, sizeof(name), "iDiag");
4248 if (!phba->idiag_root) {
4249 phba->idiag_root =
4250 debugfs_create_dir(name, phba->hba_debugfs_root);
4251 if (!phba->idiag_root) {
4252 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4253 "2922 Can't create idiag debugfs\n");
4254 goto debug_failed;
4255 }
4256
4257 memset(&idiag, 0, sizeof(idiag));
4258 }
4259
4260
4261 snprintf(name, sizeof(name), "pciCfg");
4262 if (!phba->idiag_pci_cfg) {
4263 phba->idiag_pci_cfg =
4264 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4265 phba->idiag_root, phba, &lpfc_idiag_op_pciCfg);
4266 if (!phba->idiag_pci_cfg) {
4267 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4268 "2923 Can't create idiag debugfs\n");
4269 goto debug_failed;
4270 }
4271 idiag.offset.last_rd = 0;
4272 }
4273
4274
4275 snprintf(name, sizeof(name), "barAcc");
4276 if (!phba->idiag_bar_acc) {
4277 phba->idiag_bar_acc =
4278 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4279 phba->idiag_root, phba, &lpfc_idiag_op_barAcc);
4280 if (!phba->idiag_bar_acc) {
4281 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4282 "3056 Can't create idiag debugfs\n");
4283 goto debug_failed;
4284 }
4285 idiag.offset.last_rd = 0;
4286 }
4287
4288
4289 snprintf(name, sizeof(name), "queInfo");
4290 if (!phba->idiag_que_info) {
4291 phba->idiag_que_info =
4292 debugfs_create_file(name, S_IFREG|S_IRUGO,
4293 phba->idiag_root, phba, &lpfc_idiag_op_queInfo);
4294 if (!phba->idiag_que_info) {
4295 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4296 "2924 Can't create idiag debugfs\n");
4297 goto debug_failed;
4298 }
4299 }
4300
4301
4302 snprintf(name, sizeof(name), "queAcc");
4303 if (!phba->idiag_que_acc) {
4304 phba->idiag_que_acc =
4305 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4306 phba->idiag_root, phba, &lpfc_idiag_op_queAcc);
4307 if (!phba->idiag_que_acc) {
4308 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4309 "2926 Can't create idiag debugfs\n");
4310 goto debug_failed;
4311 }
4312 }
4313
4314
4315 snprintf(name, sizeof(name), "drbAcc");
4316 if (!phba->idiag_drb_acc) {
4317 phba->idiag_drb_acc =
4318 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4319 phba->idiag_root, phba, &lpfc_idiag_op_drbAcc);
4320 if (!phba->idiag_drb_acc) {
4321 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4322 "2927 Can't create idiag debugfs\n");
4323 goto debug_failed;
4324 }
4325 }
4326
4327
4328 snprintf(name, sizeof(name), "ctlAcc");
4329 if (!phba->idiag_ctl_acc) {
4330 phba->idiag_ctl_acc =
4331 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4332 phba->idiag_root, phba, &lpfc_idiag_op_ctlAcc);
4333 if (!phba->idiag_ctl_acc) {
4334 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4335 "2981 Can't create idiag debugfs\n");
4336 goto debug_failed;
4337 }
4338 }
4339
4340
4341 snprintf(name, sizeof(name), "mbxAcc");
4342 if (!phba->idiag_mbx_acc) {
4343 phba->idiag_mbx_acc =
4344 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4345 phba->idiag_root, phba, &lpfc_idiag_op_mbxAcc);
4346 if (!phba->idiag_mbx_acc) {
4347 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4348 "2980 Can't create idiag debugfs\n");
4349 goto debug_failed;
4350 }
4351 }
4352
4353
4354 if (phba->sli4_hba.extents_in_use) {
4355 snprintf(name, sizeof(name), "extAcc");
4356 if (!phba->idiag_ext_acc) {
4357 phba->idiag_ext_acc =
4358 debugfs_create_file(name,
4359 S_IFREG|S_IRUGO|S_IWUSR,
4360 phba->idiag_root, phba,
4361 &lpfc_idiag_op_extAcc);
4362 if (!phba->idiag_ext_acc) {
4363 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4364 "2986 Cant create "
4365 "idiag debugfs\n");
4366 goto debug_failed;
4367 }
4368 }
4369 }
4370
4371debug_failed:
4372 return;
4373#endif
4374}
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387inline void
4388lpfc_debugfs_terminate(struct lpfc_vport *vport)
4389{
4390#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
4391 struct lpfc_hba *phba = vport->phba;
4392
4393 if (vport->disc_trc) {
4394 kfree(vport->disc_trc);
4395 vport->disc_trc = NULL;
4396 }
4397 if (vport->debug_disc_trc) {
4398 debugfs_remove(vport->debug_disc_trc);
4399 vport->debug_disc_trc = NULL;
4400 }
4401 if (vport->debug_nodelist) {
4402 debugfs_remove(vport->debug_nodelist);
4403 vport->debug_nodelist = NULL;
4404 }
4405 if (vport->vport_debugfs_root) {
4406 debugfs_remove(vport->vport_debugfs_root);
4407 vport->vport_debugfs_root = NULL;
4408 atomic_dec(&phba->debugfs_vport_count);
4409 }
4410 if (atomic_read(&phba->debugfs_vport_count) == 0) {
4411
4412 if (phba->debug_hbqinfo) {
4413 debugfs_remove(phba->debug_hbqinfo);
4414 phba->debug_hbqinfo = NULL;
4415 }
4416 if (phba->debug_dumpHBASlim) {
4417 debugfs_remove(phba->debug_dumpHBASlim);
4418 phba->debug_dumpHBASlim = NULL;
4419 }
4420 if (phba->debug_dumpHostSlim) {
4421 debugfs_remove(phba->debug_dumpHostSlim);
4422 phba->debug_dumpHostSlim = NULL;
4423 }
4424 if (phba->debug_dumpData) {
4425 debugfs_remove(phba->debug_dumpData);
4426 phba->debug_dumpData = NULL;
4427 }
4428
4429 if (phba->debug_dumpDif) {
4430 debugfs_remove(phba->debug_dumpDif);
4431 phba->debug_dumpDif = NULL;
4432 }
4433 if (phba->debug_InjErrLBA) {
4434 debugfs_remove(phba->debug_InjErrLBA);
4435 phba->debug_InjErrLBA = NULL;
4436 }
4437 if (phba->debug_InjErrNPortID) {
4438 debugfs_remove(phba->debug_InjErrNPortID);
4439 phba->debug_InjErrNPortID = NULL;
4440 }
4441 if (phba->debug_InjErrWWPN) {
4442 debugfs_remove(phba->debug_InjErrWWPN);
4443 phba->debug_InjErrWWPN = NULL;
4444 }
4445 if (phba->debug_writeGuard) {
4446 debugfs_remove(phba->debug_writeGuard);
4447 phba->debug_writeGuard = NULL;
4448 }
4449 if (phba->debug_writeApp) {
4450 debugfs_remove(phba->debug_writeApp);
4451 phba->debug_writeApp = NULL;
4452 }
4453 if (phba->debug_writeRef) {
4454 debugfs_remove(phba->debug_writeRef);
4455 phba->debug_writeRef = NULL;
4456 }
4457 if (phba->debug_readGuard) {
4458 debugfs_remove(phba->debug_readGuard);
4459 phba->debug_readGuard = NULL;
4460 }
4461 if (phba->debug_readApp) {
4462 debugfs_remove(phba->debug_readApp);
4463 phba->debug_readApp = NULL;
4464 }
4465 if (phba->debug_readRef) {
4466 debugfs_remove(phba->debug_readRef);
4467 phba->debug_readRef = NULL;
4468 }
4469
4470 if (phba->slow_ring_trc) {
4471 kfree(phba->slow_ring_trc);
4472 phba->slow_ring_trc = NULL;
4473 }
4474 if (phba->debug_slow_ring_trc) {
4475
4476 debugfs_remove(phba->debug_slow_ring_trc);
4477 phba->debug_slow_ring_trc = NULL;
4478 }
4479
4480
4481
4482
4483 if (phba->sli_rev == LPFC_SLI_REV4) {
4484 if (phba->idiag_ext_acc) {
4485
4486 debugfs_remove(phba->idiag_ext_acc);
4487 phba->idiag_ext_acc = NULL;
4488 }
4489 if (phba->idiag_mbx_acc) {
4490
4491 debugfs_remove(phba->idiag_mbx_acc);
4492 phba->idiag_mbx_acc = NULL;
4493 }
4494 if (phba->idiag_ctl_acc) {
4495
4496 debugfs_remove(phba->idiag_ctl_acc);
4497 phba->idiag_ctl_acc = NULL;
4498 }
4499 if (phba->idiag_drb_acc) {
4500
4501 debugfs_remove(phba->idiag_drb_acc);
4502 phba->idiag_drb_acc = NULL;
4503 }
4504 if (phba->idiag_que_acc) {
4505
4506 debugfs_remove(phba->idiag_que_acc);
4507 phba->idiag_que_acc = NULL;
4508 }
4509 if (phba->idiag_que_info) {
4510
4511 debugfs_remove(phba->idiag_que_info);
4512 phba->idiag_que_info = NULL;
4513 }
4514 if (phba->idiag_bar_acc) {
4515
4516 debugfs_remove(phba->idiag_bar_acc);
4517 phba->idiag_bar_acc = NULL;
4518 }
4519 if (phba->idiag_pci_cfg) {
4520
4521 debugfs_remove(phba->idiag_pci_cfg);
4522 phba->idiag_pci_cfg = NULL;
4523 }
4524
4525
4526 if (phba->idiag_root) {
4527
4528 debugfs_remove(phba->idiag_root);
4529 phba->idiag_root = NULL;
4530 }
4531 }
4532
4533 if (phba->hba_debugfs_root) {
4534 debugfs_remove(phba->hba_debugfs_root);
4535 phba->hba_debugfs_root = NULL;
4536 atomic_dec(&lpfc_debugfs_hba_count);
4537 }
4538
4539 if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
4540 debugfs_remove(lpfc_debugfs_root);
4541 lpfc_debugfs_root = NULL;
4542 }
4543 }
4544#endif
4545 return;
4546}
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560void
4561lpfc_debug_dump_all_queues(struct lpfc_hba *phba)
4562{
4563 int fcp_wqidx;
4564
4565
4566
4567
4568 lpfc_debug_dump_mbx_wq(phba);
4569 lpfc_debug_dump_els_wq(phba);
4570
4571 for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
4572 lpfc_debug_dump_fcp_wq(phba, fcp_wqidx);
4573
4574 lpfc_debug_dump_hdr_rq(phba);
4575 lpfc_debug_dump_dat_rq(phba);
4576
4577
4578
4579 lpfc_debug_dump_mbx_cq(phba);
4580 lpfc_debug_dump_els_cq(phba);
4581
4582 for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
4583 lpfc_debug_dump_fcp_cq(phba, fcp_wqidx);
4584
4585
4586
4587
4588 for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_io_channel; fcp_wqidx++)
4589 lpfc_debug_dump_hba_eq(phba, fcp_wqidx);
4590}
4591