0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <linux/blkdev.h>
0024 #include <linux/delay.h>
0025 #include <linux/module.h>
0026 #include <linux/dma-mapping.h>
0027 #include <linux/idr.h>
0028 #include <linux/interrupt.h>
0029 #include <linux/kthread.h>
0030 #include <linux/slab.h>
0031 #include <linux/pci.h>
0032 #include <linux/spinlock.h>
0033 #include <linux/ctype.h>
0034 #include <linux/vmalloc.h>
0035
0036 #include <scsi/scsi.h>
0037 #include <scsi/scsi_device.h>
0038 #include <scsi/scsi_host.h>
0039 #include <scsi/scsi_transport_fc.h>
0040 #include <scsi/fc/fc_fs.h>
0041
0042 #include "lpfc_hw4.h"
0043 #include "lpfc_hw.h"
0044 #include "lpfc_sli.h"
0045 #include "lpfc_sli4.h"
0046 #include "lpfc_nl.h"
0047 #include "lpfc_disc.h"
0048 #include "lpfc.h"
0049 #include "lpfc_scsi.h"
0050 #include "lpfc_nvme.h"
0051 #include "lpfc_logmsg.h"
0052 #include "lpfc_crtn.h"
0053 #include "lpfc_vport.h"
0054 #include "lpfc_version.h"
0055 #include "lpfc_compat.h"
0056 #include "lpfc_debugfs.h"
0057 #include "lpfc_bsg.h"
0058
0059 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 static int lpfc_debugfs_enable = 1;
0092 module_param(lpfc_debugfs_enable, int, S_IRUGO);
0093 MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services");
0094
0095
0096 static int lpfc_debugfs_max_disc_trc;
0097 module_param(lpfc_debugfs_max_disc_trc, int, S_IRUGO);
0098 MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc,
0099 "Set debugfs discovery trace depth");
0100
0101
0102 static int lpfc_debugfs_max_slow_ring_trc;
0103 module_param(lpfc_debugfs_max_slow_ring_trc, int, S_IRUGO);
0104 MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
0105 "Set debugfs slow ring trace depth");
0106
0107
0108 static int lpfc_debugfs_max_nvmeio_trc;
0109 module_param(lpfc_debugfs_max_nvmeio_trc, int, 0444);
0110 MODULE_PARM_DESC(lpfc_debugfs_max_nvmeio_trc,
0111 "Set debugfs NVME IO trace depth");
0112
0113 static int lpfc_debugfs_mask_disc_trc;
0114 module_param(lpfc_debugfs_mask_disc_trc, int, S_IRUGO);
0115 MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
0116 "Set debugfs discovery trace mask");
0117
0118 #include <linux/debugfs.h>
0119
0120 static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
0121 static unsigned long lpfc_debugfs_start_time = 0L;
0122
0123
0124 static struct lpfc_idiag idiag;
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 static int
0146 lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
0147 {
0148 int i, index, len, enable;
0149 uint32_t ms;
0150 struct lpfc_debugfs_trc *dtp;
0151 char *buffer;
0152
0153 buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
0154 if (!buffer)
0155 return 0;
0156
0157 enable = lpfc_debugfs_enable;
0158 lpfc_debugfs_enable = 0;
0159
0160 len = 0;
0161 index = (atomic_read(&vport->disc_trc_cnt) + 1) &
0162 (lpfc_debugfs_max_disc_trc - 1);
0163 for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
0164 dtp = vport->disc_trc + i;
0165 if (!dtp->fmt)
0166 continue;
0167 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
0168 snprintf(buffer,
0169 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
0170 dtp->seq_cnt, ms, dtp->fmt);
0171 len += scnprintf(buf+len, size-len, buffer,
0172 dtp->data1, dtp->data2, dtp->data3);
0173 }
0174 for (i = 0; i < index; i++) {
0175 dtp = vport->disc_trc + i;
0176 if (!dtp->fmt)
0177 continue;
0178 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
0179 snprintf(buffer,
0180 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
0181 dtp->seq_cnt, ms, dtp->fmt);
0182 len += scnprintf(buf+len, size-len, buffer,
0183 dtp->data1, dtp->data2, dtp->data3);
0184 }
0185
0186 lpfc_debugfs_enable = enable;
0187 kfree(buffer);
0188
0189 return len;
0190 }
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 static int
0212 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
0213 {
0214 int i, index, len, enable;
0215 uint32_t ms;
0216 struct lpfc_debugfs_trc *dtp;
0217 char *buffer;
0218
0219 buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
0220 if (!buffer)
0221 return 0;
0222
0223 enable = lpfc_debugfs_enable;
0224 lpfc_debugfs_enable = 0;
0225
0226 len = 0;
0227 index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
0228 (lpfc_debugfs_max_slow_ring_trc - 1);
0229 for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
0230 dtp = phba->slow_ring_trc + i;
0231 if (!dtp->fmt)
0232 continue;
0233 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
0234 snprintf(buffer,
0235 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
0236 dtp->seq_cnt, ms, dtp->fmt);
0237 len += scnprintf(buf+len, size-len, buffer,
0238 dtp->data1, dtp->data2, dtp->data3);
0239 }
0240 for (i = 0; i < index; i++) {
0241 dtp = phba->slow_ring_trc + i;
0242 if (!dtp->fmt)
0243 continue;
0244 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
0245 snprintf(buffer,
0246 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
0247 dtp->seq_cnt, ms, dtp->fmt);
0248 len += scnprintf(buf+len, size-len, buffer,
0249 dtp->data1, dtp->data2, dtp->data3);
0250 }
0251
0252 lpfc_debugfs_enable = enable;
0253 kfree(buffer);
0254
0255 return len;
0256 }
0257
0258 static int lpfc_debugfs_last_hbq = -1;
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279 static int
0280 lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
0281 {
0282 int len = 0;
0283 int i, j, found, posted, low;
0284 uint32_t phys, raw_index, getidx;
0285 struct lpfc_hbq_init *hip;
0286 struct hbq_s *hbqs;
0287 struct lpfc_hbq_entry *hbqe;
0288 struct lpfc_dmabuf *d_buf;
0289 struct hbq_dmabuf *hbq_buf;
0290
0291 if (phba->sli_rev != 3)
0292 return 0;
0293
0294 spin_lock_irq(&phba->hbalock);
0295
0296
0297 i = lpfc_sli_hbq_count();
0298 if (i > 1) {
0299 lpfc_debugfs_last_hbq++;
0300 if (lpfc_debugfs_last_hbq >= i)
0301 lpfc_debugfs_last_hbq = 0;
0302 }
0303 else
0304 lpfc_debugfs_last_hbq = 0;
0305
0306 i = lpfc_debugfs_last_hbq;
0307
0308 len += scnprintf(buf+len, size-len, "HBQ %d Info\n", i);
0309
0310 hbqs = &phba->hbqs[i];
0311 posted = 0;
0312 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
0313 posted++;
0314
0315 hip = lpfc_hbq_defs[i];
0316 len += scnprintf(buf+len, size-len,
0317 "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
0318 hip->hbq_index, hip->profile, hip->rn,
0319 hip->buffer_count, hip->init_count, hip->add_count, posted);
0320
0321 raw_index = phba->hbq_get[i];
0322 getidx = le32_to_cpu(raw_index);
0323 len += scnprintf(buf+len, size-len,
0324 "entries:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
0325 hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx,
0326 hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx);
0327
0328 hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
0329 for (j=0; j<hbqs->entry_count; j++) {
0330 len += scnprintf(buf+len, size-len,
0331 "%03d: %08x %04x %05x ", j,
0332 le32_to_cpu(hbqe->bde.addrLow),
0333 le32_to_cpu(hbqe->bde.tus.w),
0334 le32_to_cpu(hbqe->buffer_tag));
0335 i = 0;
0336 found = 0;
0337
0338
0339 low = hbqs->hbqPutIdx - posted;
0340 if (low >= 0) {
0341 if ((j >= hbqs->hbqPutIdx) || (j < low)) {
0342 len += scnprintf(buf + len, size - len,
0343 "Unused\n");
0344 goto skipit;
0345 }
0346 }
0347 else {
0348 if ((j >= hbqs->hbqPutIdx) &&
0349 (j < (hbqs->entry_count+low))) {
0350 len += scnprintf(buf + len, size - len,
0351 "Unused\n");
0352 goto skipit;
0353 }
0354 }
0355
0356
0357 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
0358 hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
0359 phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
0360 if (phys == le32_to_cpu(hbqe->bde.addrLow)) {
0361 len += scnprintf(buf+len, size-len,
0362 "Buf%d: x%px %06x\n", i,
0363 hbq_buf->dbuf.virt, hbq_buf->tag);
0364 found = 1;
0365 break;
0366 }
0367 i++;
0368 }
0369 if (!found) {
0370 len += scnprintf(buf+len, size-len, "No DMAinfo?\n");
0371 }
0372 skipit:
0373 hbqe++;
0374 if (len > LPFC_HBQINFO_SIZE - 54)
0375 break;
0376 }
0377 spin_unlock_irq(&phba->hbalock);
0378 return len;
0379 }
0380
0381 static int lpfc_debugfs_last_xripool;
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403 static int
0404 lpfc_debugfs_commonxripools_data(struct lpfc_hba *phba, char *buf, int size)
0405 {
0406 struct lpfc_sli4_hdw_queue *qp;
0407 int len = 0;
0408 int i, out;
0409 unsigned long iflag;
0410
0411 for (i = 0; i < phba->cfg_hdw_queue; i++) {
0412 if (len > (LPFC_DUMP_MULTIXRIPOOL_SIZE - 80))
0413 break;
0414 qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_xripool];
0415
0416 len += scnprintf(buf + len, size - len, "HdwQ %d Info ", i);
0417 spin_lock_irqsave(&qp->abts_io_buf_list_lock, iflag);
0418 spin_lock(&qp->io_buf_list_get_lock);
0419 spin_lock(&qp->io_buf_list_put_lock);
0420 out = qp->total_io_bufs - (qp->get_io_bufs + qp->put_io_bufs +
0421 qp->abts_scsi_io_bufs + qp->abts_nvme_io_bufs);
0422 len += scnprintf(buf + len, size - len,
0423 "tot:%d get:%d put:%d mt:%d "
0424 "ABTS scsi:%d nvme:%d Out:%d\n",
0425 qp->total_io_bufs, qp->get_io_bufs, qp->put_io_bufs,
0426 qp->empty_io_bufs, qp->abts_scsi_io_bufs,
0427 qp->abts_nvme_io_bufs, out);
0428 spin_unlock(&qp->io_buf_list_put_lock);
0429 spin_unlock(&qp->io_buf_list_get_lock);
0430 spin_unlock_irqrestore(&qp->abts_io_buf_list_lock, iflag);
0431
0432 lpfc_debugfs_last_xripool++;
0433 if (lpfc_debugfs_last_xripool >= phba->cfg_hdw_queue)
0434 lpfc_debugfs_last_xripool = 0;
0435 }
0436
0437 return len;
0438 }
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455 static int
0456 lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size)
0457 {
0458 u32 i;
0459 u32 hwq_count;
0460 struct lpfc_sli4_hdw_queue *qp;
0461 struct lpfc_multixri_pool *multixri_pool;
0462 struct lpfc_pvt_pool *pvt_pool;
0463 struct lpfc_pbl_pool *pbl_pool;
0464 u32 txcmplq_cnt;
0465 char tmp[LPFC_DEBUG_OUT_LINE_SZ] = {0};
0466
0467 if (phba->sli_rev != LPFC_SLI_REV4)
0468 return 0;
0469
0470 if (!phba->sli4_hba.hdwq)
0471 return 0;
0472
0473 if (!phba->cfg_xri_rebalancing) {
0474 i = lpfc_debugfs_commonxripools_data(phba, buf, size);
0475 return i;
0476 }
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487 scnprintf(tmp, sizeof(tmp),
0488 "HWQ: Pbl Pvt Busy HWM | pvt_empty pbl_empty ");
0489 if (strlcat(buf, tmp, size) >= size)
0490 return strnlen(buf, size);
0491
0492 #ifdef LPFC_MXP_STAT
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504 scnprintf(tmp, sizeof(tmp),
0505 "MAXH above_lmt below_lmt locPbl_hit othPbl_hit");
0506 if (strlcat(buf, tmp, size) >= size)
0507 return strnlen(buf, size);
0508
0509
0510
0511
0512
0513
0514 scnprintf(tmp, sizeof(tmp),
0515 " | sPbl sPvt sBusy");
0516 if (strlcat(buf, tmp, size) >= size)
0517 return strnlen(buf, size);
0518 #endif
0519
0520 scnprintf(tmp, sizeof(tmp), "\n");
0521 if (strlcat(buf, tmp, size) >= size)
0522 return strnlen(buf, size);
0523
0524 hwq_count = phba->cfg_hdw_queue;
0525 for (i = 0; i < hwq_count; i++) {
0526 qp = &phba->sli4_hba.hdwq[i];
0527 multixri_pool = qp->p_multixri_pool;
0528 if (!multixri_pool)
0529 continue;
0530 pbl_pool = &multixri_pool->pbl_pool;
0531 pvt_pool = &multixri_pool->pvt_pool;
0532 txcmplq_cnt = qp->io_wq->pring->txcmplq_cnt;
0533
0534 scnprintf(tmp, sizeof(tmp),
0535 "%03d: %4d %4d %4d %4d | %10d %10d ",
0536 i, pbl_pool->count, pvt_pool->count,
0537 txcmplq_cnt, pvt_pool->high_watermark,
0538 qp->empty_io_bufs, multixri_pool->pbl_empty_count);
0539 if (strlcat(buf, tmp, size) >= size)
0540 break;
0541
0542 #ifdef LPFC_MXP_STAT
0543 scnprintf(tmp, sizeof(tmp),
0544 "%4d %10d %10d %10d %10d",
0545 multixri_pool->stat_max_hwm,
0546 multixri_pool->above_limit_count,
0547 multixri_pool->below_limit_count,
0548 multixri_pool->local_pbl_hit_count,
0549 multixri_pool->other_pbl_hit_count);
0550 if (strlcat(buf, tmp, size) >= size)
0551 break;
0552
0553 scnprintf(tmp, sizeof(tmp),
0554 " | %4d %4d %5d",
0555 multixri_pool->stat_pbl_count,
0556 multixri_pool->stat_pvt_count,
0557 multixri_pool->stat_busy_count);
0558 if (strlcat(buf, tmp, size) >= size)
0559 break;
0560 #endif
0561
0562 scnprintf(tmp, sizeof(tmp), "\n");
0563 if (strlcat(buf, tmp, size) >= size)
0564 break;
0565 }
0566 return strnlen(buf, size);
0567 }
0568
0569
0570 #ifdef LPFC_HDWQ_LOCK_STAT
0571 static int lpfc_debugfs_last_lock;
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593 static int
0594 lpfc_debugfs_lockstat_data(struct lpfc_hba *phba, char *buf, int size)
0595 {
0596 struct lpfc_sli4_hdw_queue *qp;
0597 int len = 0;
0598 int i;
0599
0600 if (phba->sli_rev != LPFC_SLI_REV4)
0601 return 0;
0602
0603 if (!phba->sli4_hba.hdwq)
0604 return 0;
0605
0606 for (i = 0; i < phba->cfg_hdw_queue; i++) {
0607 if (len > (LPFC_HDWQINFO_SIZE - 100))
0608 break;
0609 qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_lock];
0610
0611 len += scnprintf(buf + len, size - len, "HdwQ %03d Lock ", i);
0612 if (phba->cfg_xri_rebalancing) {
0613 len += scnprintf(buf + len, size - len,
0614 "get_pvt:%d mv_pvt:%d "
0615 "mv2pub:%d mv2pvt:%d "
0616 "put_pvt:%d put_pub:%d wq:%d\n",
0617 qp->lock_conflict.alloc_pvt_pool,
0618 qp->lock_conflict.mv_from_pvt_pool,
0619 qp->lock_conflict.mv_to_pub_pool,
0620 qp->lock_conflict.mv_to_pvt_pool,
0621 qp->lock_conflict.free_pvt_pool,
0622 qp->lock_conflict.free_pub_pool,
0623 qp->lock_conflict.wq_access);
0624 } else {
0625 len += scnprintf(buf + len, size - len,
0626 "get:%d put:%d free:%d wq:%d\n",
0627 qp->lock_conflict.alloc_xri_get,
0628 qp->lock_conflict.alloc_xri_put,
0629 qp->lock_conflict.free_xri,
0630 qp->lock_conflict.wq_access);
0631 }
0632
0633 lpfc_debugfs_last_lock++;
0634 if (lpfc_debugfs_last_lock >= phba->cfg_hdw_queue)
0635 lpfc_debugfs_last_lock = 0;
0636 }
0637
0638 return len;
0639 }
0640 #endif
0641
0642 static int lpfc_debugfs_last_hba_slim_off;
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662 static int
0663 lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
0664 {
0665 int len = 0;
0666 int i, off;
0667 uint32_t *ptr;
0668 char *buffer;
0669
0670 buffer = kmalloc(1024, GFP_KERNEL);
0671 if (!buffer)
0672 return 0;
0673
0674 off = 0;
0675 spin_lock_irq(&phba->hbalock);
0676
0677 len += scnprintf(buf+len, size-len, "HBA SLIM\n");
0678 lpfc_memcpy_from_slim(buffer,
0679 phba->MBslimaddr + lpfc_debugfs_last_hba_slim_off, 1024);
0680
0681 ptr = (uint32_t *)&buffer[0];
0682 off = lpfc_debugfs_last_hba_slim_off;
0683
0684
0685 lpfc_debugfs_last_hba_slim_off += 1024;
0686 if (lpfc_debugfs_last_hba_slim_off >= 4096)
0687 lpfc_debugfs_last_hba_slim_off = 0;
0688
0689 i = 1024;
0690 while (i > 0) {
0691 len += scnprintf(buf+len, size-len,
0692 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
0693 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
0694 *(ptr+5), *(ptr+6), *(ptr+7));
0695 ptr += 8;
0696 i -= (8 * sizeof(uint32_t));
0697 off += (8 * sizeof(uint32_t));
0698 }
0699
0700 spin_unlock_irq(&phba->hbalock);
0701 kfree(buffer);
0702
0703 return len;
0704 }
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721 static int
0722 lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
0723 {
0724 int len = 0;
0725 int i, off;
0726 uint32_t word0, word1, word2, word3;
0727 uint32_t *ptr;
0728 struct lpfc_pgp *pgpp;
0729 struct lpfc_sli *psli = &phba->sli;
0730 struct lpfc_sli_ring *pring;
0731
0732 off = 0;
0733 spin_lock_irq(&phba->hbalock);
0734
0735 len += scnprintf(buf+len, size-len, "SLIM Mailbox\n");
0736 ptr = (uint32_t *)phba->slim2p.virt;
0737 i = sizeof(MAILBOX_t);
0738 while (i > 0) {
0739 len += scnprintf(buf+len, size-len,
0740 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
0741 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
0742 *(ptr+5), *(ptr+6), *(ptr+7));
0743 ptr += 8;
0744 i -= (8 * sizeof(uint32_t));
0745 off += (8 * sizeof(uint32_t));
0746 }
0747
0748 len += scnprintf(buf+len, size-len, "SLIM PCB\n");
0749 ptr = (uint32_t *)phba->pcb;
0750 i = sizeof(PCB_t);
0751 while (i > 0) {
0752 len += scnprintf(buf+len, size-len,
0753 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
0754 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
0755 *(ptr+5), *(ptr+6), *(ptr+7));
0756 ptr += 8;
0757 i -= (8 * sizeof(uint32_t));
0758 off += (8 * sizeof(uint32_t));
0759 }
0760
0761 if (phba->sli_rev <= LPFC_SLI_REV3) {
0762 for (i = 0; i < 4; i++) {
0763 pgpp = &phba->port_gp[i];
0764 pring = &psli->sli3_ring[i];
0765 len += scnprintf(buf+len, size-len,
0766 "Ring %d: CMD GetInx:%d "
0767 "(Max:%d Next:%d "
0768 "Local:%d flg:x%x) "
0769 "RSP PutInx:%d Max:%d\n",
0770 i, pgpp->cmdGetInx,
0771 pring->sli.sli3.numCiocb,
0772 pring->sli.sli3.next_cmdidx,
0773 pring->sli.sli3.local_getidx,
0774 pring->flag, pgpp->rspPutInx,
0775 pring->sli.sli3.numRiocb);
0776 }
0777
0778 word0 = readl(phba->HAregaddr);
0779 word1 = readl(phba->CAregaddr);
0780 word2 = readl(phba->HSregaddr);
0781 word3 = readl(phba->HCregaddr);
0782 len += scnprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x "
0783 "HC:%08x\n", word0, word1, word2, word3);
0784 }
0785 spin_unlock_irq(&phba->hbalock);
0786 return len;
0787 }
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804 static int
0805 lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
0806 {
0807 int len = 0;
0808 int i, iocnt, outio, cnt;
0809 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
0810 struct lpfc_hba *phba = vport->phba;
0811 struct lpfc_nodelist *ndlp;
0812 unsigned char *statep;
0813 struct nvme_fc_local_port *localport;
0814 struct nvme_fc_remote_port *nrport = NULL;
0815 struct lpfc_nvme_rport *rport;
0816
0817 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
0818 outio = 0;
0819
0820 len += scnprintf(buf+len, size-len, "\nFCP Nodelist Entries ...\n");
0821 spin_lock_irq(shost->host_lock);
0822 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
0823 iocnt = 0;
0824 if (!cnt) {
0825 len += scnprintf(buf+len, size-len,
0826 "Missing Nodelist Entries\n");
0827 break;
0828 }
0829 cnt--;
0830 switch (ndlp->nlp_state) {
0831 case NLP_STE_UNUSED_NODE:
0832 statep = "UNUSED";
0833 break;
0834 case NLP_STE_PLOGI_ISSUE:
0835 statep = "PLOGI ";
0836 break;
0837 case NLP_STE_ADISC_ISSUE:
0838 statep = "ADISC ";
0839 break;
0840 case NLP_STE_REG_LOGIN_ISSUE:
0841 statep = "REGLOG";
0842 break;
0843 case NLP_STE_PRLI_ISSUE:
0844 statep = "PRLI ";
0845 break;
0846 case NLP_STE_LOGO_ISSUE:
0847 statep = "LOGO ";
0848 break;
0849 case NLP_STE_UNMAPPED_NODE:
0850 statep = "UNMAP ";
0851 iocnt = 1;
0852 break;
0853 case NLP_STE_MAPPED_NODE:
0854 statep = "MAPPED";
0855 iocnt = 1;
0856 break;
0857 case NLP_STE_NPR_NODE:
0858 statep = "NPR ";
0859 break;
0860 default:
0861 statep = "UNKNOWN";
0862 }
0863 len += scnprintf(buf+len, size-len, "%s DID:x%06x ",
0864 statep, ndlp->nlp_DID);
0865 len += scnprintf(buf+len, size-len,
0866 "WWPN x%016llx ",
0867 wwn_to_u64(ndlp->nlp_portname.u.wwn));
0868 len += scnprintf(buf+len, size-len,
0869 "WWNN x%016llx ",
0870 wwn_to_u64(ndlp->nlp_nodename.u.wwn));
0871 len += scnprintf(buf+len, size-len, "RPI:x%04x ",
0872 ndlp->nlp_rpi);
0873 len += scnprintf(buf+len, size-len, "flag:x%08x ",
0874 ndlp->nlp_flag);
0875 if (!ndlp->nlp_type)
0876 len += scnprintf(buf+len, size-len, "UNKNOWN_TYPE ");
0877 if (ndlp->nlp_type & NLP_FC_NODE)
0878 len += scnprintf(buf+len, size-len, "FC_NODE ");
0879 if (ndlp->nlp_type & NLP_FABRIC) {
0880 len += scnprintf(buf+len, size-len, "FABRIC ");
0881 iocnt = 0;
0882 }
0883 if (ndlp->nlp_type & NLP_FCP_TARGET)
0884 len += scnprintf(buf+len, size-len, "FCP_TGT sid:%d ",
0885 ndlp->nlp_sid);
0886 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
0887 len += scnprintf(buf+len, size-len, "FCP_INITIATOR ");
0888 if (ndlp->nlp_type & NLP_NVME_TARGET)
0889 len += scnprintf(buf + len,
0890 size - len, "NVME_TGT sid:%d ",
0891 NLP_NO_SID);
0892 if (ndlp->nlp_type & NLP_NVME_INITIATOR)
0893 len += scnprintf(buf + len,
0894 size - len, "NVME_INITIATOR ");
0895 len += scnprintf(buf+len, size-len, "refcnt:%d",
0896 kref_read(&ndlp->kref));
0897 if (iocnt) {
0898 i = atomic_read(&ndlp->cmd_pending);
0899 len += scnprintf(buf + len, size - len,
0900 " OutIO:x%x Qdepth x%x",
0901 i, ndlp->cmd_qdepth);
0902 outio += i;
0903 }
0904 len += scnprintf(buf+len, size-len, " xpt:x%x",
0905 ndlp->fc4_xpt_flags);
0906 if (ndlp->nlp_defer_did != NLP_EVT_NOTHING_PENDING)
0907 len += scnprintf(buf+len, size-len, " defer:%x",
0908 ndlp->nlp_defer_did);
0909 len += scnprintf(buf+len, size-len, "\n");
0910 }
0911 spin_unlock_irq(shost->host_lock);
0912
0913 len += scnprintf(buf + len, size - len,
0914 "\nOutstanding IO x%x\n", outio);
0915
0916 if (phba->nvmet_support && phba->targetport && (vport == phba->pport)) {
0917 len += scnprintf(buf + len, size - len,
0918 "\nNVME Targetport Entry ...\n");
0919
0920
0921 if (phba->targetport->port_id)
0922 statep = "REGISTERED";
0923 else
0924 statep = "INIT";
0925 len += scnprintf(buf + len, size - len,
0926 "TGT WWNN x%llx WWPN x%llx State %s\n",
0927 wwn_to_u64(vport->fc_nodename.u.wwn),
0928 wwn_to_u64(vport->fc_portname.u.wwn),
0929 statep);
0930 len += scnprintf(buf + len, size - len,
0931 " Targetport DID x%06x\n",
0932 phba->targetport->port_id);
0933 goto out_exit;
0934 }
0935
0936 len += scnprintf(buf + len, size - len,
0937 "\nNVME Lport/Rport Entries ...\n");
0938
0939 localport = vport->localport;
0940 if (!localport)
0941 goto out_exit;
0942
0943 spin_lock_irq(shost->host_lock);
0944
0945
0946 if (localport->port_id)
0947 statep = "ONLINE";
0948 else
0949 statep = "UNKNOWN ";
0950
0951 len += scnprintf(buf + len, size - len,
0952 "Lport DID x%06x PortState %s\n",
0953 localport->port_id, statep);
0954
0955 len += scnprintf(buf + len, size - len, "\tRport List:\n");
0956 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
0957
0958 spin_lock(&ndlp->lock);
0959 rport = lpfc_ndlp_get_nrport(ndlp);
0960 if (rport)
0961 nrport = rport->remoteport;
0962 else
0963 nrport = NULL;
0964 spin_unlock(&ndlp->lock);
0965 if (!nrport)
0966 continue;
0967
0968
0969 switch (nrport->port_state) {
0970 case FC_OBJSTATE_ONLINE:
0971 statep = "ONLINE";
0972 break;
0973 case FC_OBJSTATE_UNKNOWN:
0974 statep = "UNKNOWN ";
0975 break;
0976 default:
0977 statep = "UNSUPPORTED";
0978 break;
0979 }
0980
0981
0982 len += scnprintf(buf + len, size - len,
0983 "\t%s Port ID:x%06x ",
0984 statep, nrport->port_id);
0985 len += scnprintf(buf + len, size - len, "WWPN x%llx ",
0986 nrport->port_name);
0987 len += scnprintf(buf + len, size - len, "WWNN x%llx ",
0988 nrport->node_name);
0989
0990
0991 if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR)
0992 len += scnprintf(buf + len, size - len,
0993 "INITIATOR ");
0994 if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET)
0995 len += scnprintf(buf + len, size - len,
0996 "TARGET ");
0997 if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY)
0998 len += scnprintf(buf + len, size - len,
0999 "DISCSRVC ");
1000 if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
1001 FC_PORT_ROLE_NVME_TARGET |
1002 FC_PORT_ROLE_NVME_DISCOVERY))
1003 len += scnprintf(buf + len, size - len,
1004 "UNKNOWN ROLE x%x",
1005 nrport->port_role);
1006
1007 len += scnprintf(buf + len, size - len, "\n");
1008 }
1009
1010 spin_unlock_irq(shost->host_lock);
1011 out_exit:
1012 return len;
1013 }
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 static int
1029 lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size)
1030 {
1031 struct lpfc_hba *phba = vport->phba;
1032 struct lpfc_nvmet_tgtport *tgtp;
1033 struct lpfc_async_xchg_ctx *ctxp, *next_ctxp;
1034 struct nvme_fc_local_port *localport;
1035 struct lpfc_fc4_ctrl_stat *cstat;
1036 struct lpfc_nvme_lport *lport;
1037 uint64_t data1, data2, data3;
1038 uint64_t tot, totin, totout;
1039 int cnt, i;
1040 int len = 0;
1041
1042 if (phba->nvmet_support) {
1043 if (!phba->targetport)
1044 return len;
1045 tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
1046 len += scnprintf(buf + len, size - len,
1047 "\nNVME Targetport Statistics\n");
1048
1049 len += scnprintf(buf + len, size - len,
1050 "LS: Rcv %08x Drop %08x Abort %08x\n",
1051 atomic_read(&tgtp->rcv_ls_req_in),
1052 atomic_read(&tgtp->rcv_ls_req_drop),
1053 atomic_read(&tgtp->xmt_ls_abort));
1054 if (atomic_read(&tgtp->rcv_ls_req_in) !=
1055 atomic_read(&tgtp->rcv_ls_req_out)) {
1056 len += scnprintf(buf + len, size - len,
1057 "Rcv LS: in %08x != out %08x\n",
1058 atomic_read(&tgtp->rcv_ls_req_in),
1059 atomic_read(&tgtp->rcv_ls_req_out));
1060 }
1061
1062 len += scnprintf(buf + len, size - len,
1063 "LS: Xmt %08x Drop %08x Cmpl %08x\n",
1064 atomic_read(&tgtp->xmt_ls_rsp),
1065 atomic_read(&tgtp->xmt_ls_drop),
1066 atomic_read(&tgtp->xmt_ls_rsp_cmpl));
1067
1068 len += scnprintf(buf + len, size - len,
1069 "LS: RSP Abort %08x xb %08x Err %08x\n",
1070 atomic_read(&tgtp->xmt_ls_rsp_aborted),
1071 atomic_read(&tgtp->xmt_ls_rsp_xb_set),
1072 atomic_read(&tgtp->xmt_ls_rsp_error));
1073
1074 len += scnprintf(buf + len, size - len,
1075 "FCP: Rcv %08x Defer %08x Release %08x "
1076 "Drop %08x\n",
1077 atomic_read(&tgtp->rcv_fcp_cmd_in),
1078 atomic_read(&tgtp->rcv_fcp_cmd_defer),
1079 atomic_read(&tgtp->xmt_fcp_release),
1080 atomic_read(&tgtp->rcv_fcp_cmd_drop));
1081
1082 if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
1083 atomic_read(&tgtp->rcv_fcp_cmd_out)) {
1084 len += scnprintf(buf + len, size - len,
1085 "Rcv FCP: in %08x != out %08x\n",
1086 atomic_read(&tgtp->rcv_fcp_cmd_in),
1087 atomic_read(&tgtp->rcv_fcp_cmd_out));
1088 }
1089
1090 len += scnprintf(buf + len, size - len,
1091 "FCP Rsp: read %08x readrsp %08x "
1092 "write %08x rsp %08x\n",
1093 atomic_read(&tgtp->xmt_fcp_read),
1094 atomic_read(&tgtp->xmt_fcp_read_rsp),
1095 atomic_read(&tgtp->xmt_fcp_write),
1096 atomic_read(&tgtp->xmt_fcp_rsp));
1097
1098 len += scnprintf(buf + len, size - len,
1099 "FCP Rsp Cmpl: %08x err %08x drop %08x\n",
1100 atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
1101 atomic_read(&tgtp->xmt_fcp_rsp_error),
1102 atomic_read(&tgtp->xmt_fcp_rsp_drop));
1103
1104 len += scnprintf(buf + len, size - len,
1105 "FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
1106 atomic_read(&tgtp->xmt_fcp_rsp_aborted),
1107 atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
1108 atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
1109
1110 len += scnprintf(buf + len, size - len,
1111 "ABORT: Xmt %08x Cmpl %08x\n",
1112 atomic_read(&tgtp->xmt_fcp_abort),
1113 atomic_read(&tgtp->xmt_fcp_abort_cmpl));
1114
1115 len += scnprintf(buf + len, size - len,
1116 "ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x",
1117 atomic_read(&tgtp->xmt_abort_sol),
1118 atomic_read(&tgtp->xmt_abort_unsol),
1119 atomic_read(&tgtp->xmt_abort_rsp),
1120 atomic_read(&tgtp->xmt_abort_rsp_error));
1121
1122 len += scnprintf(buf + len, size - len, "\n");
1123
1124 cnt = 0;
1125 spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1126 list_for_each_entry_safe(ctxp, next_ctxp,
1127 &phba->sli4_hba.lpfc_abts_nvmet_ctx_list,
1128 list) {
1129 cnt++;
1130 }
1131 spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1132 if (cnt) {
1133 len += scnprintf(buf + len, size - len,
1134 "ABORT: %d ctx entries\n", cnt);
1135 spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1136 list_for_each_entry_safe(ctxp, next_ctxp,
1137 &phba->sli4_hba.lpfc_abts_nvmet_ctx_list,
1138 list) {
1139 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ))
1140 break;
1141 len += scnprintf(buf + len, size - len,
1142 "Entry: oxid %x state %x "
1143 "flag %x\n",
1144 ctxp->oxid, ctxp->state,
1145 ctxp->flag);
1146 }
1147 spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
1148 }
1149
1150
1151 tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
1152 tot += atomic_read(&tgtp->xmt_fcp_release);
1153 tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot;
1154
1155 len += scnprintf(buf + len, size - len,
1156 "IO_CTX: %08x WAIT: cur %08x tot %08x\n"
1157 "CTX Outstanding %08llx\n",
1158 phba->sli4_hba.nvmet_xri_cnt,
1159 phba->sli4_hba.nvmet_io_wait_cnt,
1160 phba->sli4_hba.nvmet_io_wait_total,
1161 tot);
1162 } else {
1163 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME))
1164 return len;
1165
1166 localport = vport->localport;
1167 if (!localport)
1168 return len;
1169 lport = (struct lpfc_nvme_lport *)localport->private;
1170 if (!lport)
1171 return len;
1172
1173 len += scnprintf(buf + len, size - len,
1174 "\nNVME HDWQ Statistics\n");
1175
1176 len += scnprintf(buf + len, size - len,
1177 "LS: Xmt %016x Cmpl %016x\n",
1178 atomic_read(&lport->fc4NvmeLsRequests),
1179 atomic_read(&lport->fc4NvmeLsCmpls));
1180
1181 totin = 0;
1182 totout = 0;
1183 for (i = 0; i < phba->cfg_hdw_queue; i++) {
1184 cstat = &phba->sli4_hba.hdwq[i].nvme_cstat;
1185 tot = cstat->io_cmpls;
1186 totin += tot;
1187 data1 = cstat->input_requests;
1188 data2 = cstat->output_requests;
1189 data3 = cstat->control_requests;
1190 totout += (data1 + data2 + data3);
1191
1192
1193 if (i >= 32)
1194 continue;
1195
1196 len += scnprintf(buf + len, PAGE_SIZE - len,
1197 "HDWQ (%d): Rd %016llx Wr %016llx "
1198 "IO %016llx ",
1199 i, data1, data2, data3);
1200 len += scnprintf(buf + len, PAGE_SIZE - len,
1201 "Cmpl %016llx OutIO %016llx\n",
1202 tot, ((data1 + data2 + data3) - tot));
1203 }
1204 len += scnprintf(buf + len, PAGE_SIZE - len,
1205 "Total FCP Cmpl %016llx Issue %016llx "
1206 "OutIO %016llx\n",
1207 totin, totout, totout - totin);
1208
1209 len += scnprintf(buf + len, size - len,
1210 "LS Xmt Err: Abrt %08x Err %08x "
1211 "Cmpl Err: xb %08x Err %08x\n",
1212 atomic_read(&lport->xmt_ls_abort),
1213 atomic_read(&lport->xmt_ls_err),
1214 atomic_read(&lport->cmpl_ls_xb),
1215 atomic_read(&lport->cmpl_ls_err));
1216
1217 len += scnprintf(buf + len, size - len,
1218 "FCP Xmt Err: noxri %06x nondlp %06x "
1219 "qdepth %06x wqerr %06x err %06x Abrt %06x\n",
1220 atomic_read(&lport->xmt_fcp_noxri),
1221 atomic_read(&lport->xmt_fcp_bad_ndlp),
1222 atomic_read(&lport->xmt_fcp_qdepth),
1223 atomic_read(&lport->xmt_fcp_wqerr),
1224 atomic_read(&lport->xmt_fcp_err),
1225 atomic_read(&lport->xmt_fcp_abort));
1226
1227 len += scnprintf(buf + len, size - len,
1228 "FCP Cmpl Err: xb %08x Err %08x\n",
1229 atomic_read(&lport->cmpl_fcp_xb),
1230 atomic_read(&lport->cmpl_fcp_err));
1231
1232 }
1233
1234 return len;
1235 }
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250 static int
1251 lpfc_debugfs_scsistat_data(struct lpfc_vport *vport, char *buf, int size)
1252 {
1253 int len;
1254 struct lpfc_hba *phba = vport->phba;
1255 struct lpfc_fc4_ctrl_stat *cstat;
1256 u64 data1, data2, data3;
1257 u64 tot, totin, totout;
1258 int i;
1259 char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
1260
1261 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
1262 (phba->sli_rev != LPFC_SLI_REV4))
1263 return 0;
1264
1265 scnprintf(buf, size, "SCSI HDWQ Statistics\n");
1266
1267 totin = 0;
1268 totout = 0;
1269 for (i = 0; i < phba->cfg_hdw_queue; i++) {
1270 cstat = &phba->sli4_hba.hdwq[i].scsi_cstat;
1271 tot = cstat->io_cmpls;
1272 totin += tot;
1273 data1 = cstat->input_requests;
1274 data2 = cstat->output_requests;
1275 data3 = cstat->control_requests;
1276 totout += (data1 + data2 + data3);
1277
1278 scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx "
1279 "IO %016llx ", i, data1, data2, data3);
1280 if (strlcat(buf, tmp, size) >= size)
1281 goto buffer_done;
1282
1283 scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n",
1284 tot, ((data1 + data2 + data3) - tot));
1285 if (strlcat(buf, tmp, size) >= size)
1286 goto buffer_done;
1287 }
1288 scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx "
1289 "OutIO %016llx\n", totin, totout, totout - totin);
1290 strlcat(buf, tmp, size);
1291
1292 buffer_done:
1293 len = strnlen(buf, size);
1294
1295 return len;
1296 }
1297
1298 void
1299 lpfc_io_ktime(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
1300 {
1301 uint64_t seg1, seg2, seg3, seg4;
1302 uint64_t segsum;
1303
1304 if (!lpfc_cmd->ts_last_cmd ||
1305 !lpfc_cmd->ts_cmd_start ||
1306 !lpfc_cmd->ts_cmd_wqput ||
1307 !lpfc_cmd->ts_isr_cmpl ||
1308 !lpfc_cmd->ts_data_io)
1309 return;
1310
1311 if (lpfc_cmd->ts_data_io < lpfc_cmd->ts_cmd_start)
1312 return;
1313 if (lpfc_cmd->ts_cmd_start < lpfc_cmd->ts_last_cmd)
1314 return;
1315 if (lpfc_cmd->ts_cmd_wqput < lpfc_cmd->ts_cmd_start)
1316 return;
1317 if (lpfc_cmd->ts_isr_cmpl < lpfc_cmd->ts_cmd_wqput)
1318 return;
1319 if (lpfc_cmd->ts_data_io < lpfc_cmd->ts_isr_cmpl)
1320 return;
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331 seg1 = lpfc_cmd->ts_cmd_start - lpfc_cmd->ts_last_cmd;
1332 if (seg1 > 5000000)
1333 seg1 = 0;
1334
1335
1336 seg2 = (lpfc_cmd->ts_cmd_wqput - lpfc_cmd->ts_cmd_start);
1337 segsum = seg2;
1338 seg3 = lpfc_cmd->ts_isr_cmpl - lpfc_cmd->ts_cmd_start;
1339 if (segsum > seg3)
1340 return;
1341 seg3 -= segsum;
1342 segsum += seg3;
1343
1344 seg4 = lpfc_cmd->ts_data_io - lpfc_cmd->ts_cmd_start;
1345 if (segsum > seg4)
1346 return;
1347 seg4 -= segsum;
1348
1349 phba->ktime_data_samples++;
1350 phba->ktime_seg1_total += seg1;
1351 if (seg1 < phba->ktime_seg1_min)
1352 phba->ktime_seg1_min = seg1;
1353 else if (seg1 > phba->ktime_seg1_max)
1354 phba->ktime_seg1_max = seg1;
1355 phba->ktime_seg2_total += seg2;
1356 if (seg2 < phba->ktime_seg2_min)
1357 phba->ktime_seg2_min = seg2;
1358 else if (seg2 > phba->ktime_seg2_max)
1359 phba->ktime_seg2_max = seg2;
1360 phba->ktime_seg3_total += seg3;
1361 if (seg3 < phba->ktime_seg3_min)
1362 phba->ktime_seg3_min = seg3;
1363 else if (seg3 > phba->ktime_seg3_max)
1364 phba->ktime_seg3_max = seg3;
1365 phba->ktime_seg4_total += seg4;
1366 if (seg4 < phba->ktime_seg4_min)
1367 phba->ktime_seg4_min = seg4;
1368 else if (seg4 > phba->ktime_seg4_max)
1369 phba->ktime_seg4_max = seg4;
1370
1371 lpfc_cmd->ts_last_cmd = 0;
1372 lpfc_cmd->ts_cmd_start = 0;
1373 lpfc_cmd->ts_cmd_wqput = 0;
1374 lpfc_cmd->ts_isr_cmpl = 0;
1375 lpfc_cmd->ts_data_io = 0;
1376 }
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391 static int
1392 lpfc_debugfs_ioktime_data(struct lpfc_vport *vport, char *buf, int size)
1393 {
1394 struct lpfc_hba *phba = vport->phba;
1395 int len = 0;
1396
1397 if (phba->nvmet_support == 0) {
1398
1399 len += scnprintf(buf + len, PAGE_SIZE - len,
1400 "ktime %s: Total Samples: %lld\n",
1401 (phba->ktime_on ? "Enabled" : "Disabled"),
1402 phba->ktime_data_samples);
1403 if (phba->ktime_data_samples == 0)
1404 return len;
1405
1406 len += scnprintf(
1407 buf + len, PAGE_SIZE - len,
1408 "Segment 1: Last Cmd cmpl "
1409 "done -to- Start of next Cmd (in driver)\n");
1410 len += scnprintf(
1411 buf + len, PAGE_SIZE - len,
1412 "avg:%08lld min:%08lld max %08lld\n",
1413 div_u64(phba->ktime_seg1_total,
1414 phba->ktime_data_samples),
1415 phba->ktime_seg1_min,
1416 phba->ktime_seg1_max);
1417 len += scnprintf(
1418 buf + len, PAGE_SIZE - len,
1419 "Segment 2: Driver start of Cmd "
1420 "-to- Firmware WQ doorbell\n");
1421 len += scnprintf(
1422 buf + len, PAGE_SIZE - len,
1423 "avg:%08lld min:%08lld max %08lld\n",
1424 div_u64(phba->ktime_seg2_total,
1425 phba->ktime_data_samples),
1426 phba->ktime_seg2_min,
1427 phba->ktime_seg2_max);
1428 len += scnprintf(
1429 buf + len, PAGE_SIZE - len,
1430 "Segment 3: Firmware WQ doorbell -to- "
1431 "MSI-X ISR cmpl\n");
1432 len += scnprintf(
1433 buf + len, PAGE_SIZE - len,
1434 "avg:%08lld min:%08lld max %08lld\n",
1435 div_u64(phba->ktime_seg3_total,
1436 phba->ktime_data_samples),
1437 phba->ktime_seg3_min,
1438 phba->ktime_seg3_max);
1439 len += scnprintf(
1440 buf + len, PAGE_SIZE - len,
1441 "Segment 4: MSI-X ISR cmpl -to- "
1442 "Cmd cmpl done\n");
1443 len += scnprintf(
1444 buf + len, PAGE_SIZE - len,
1445 "avg:%08lld min:%08lld max %08lld\n",
1446 div_u64(phba->ktime_seg4_total,
1447 phba->ktime_data_samples),
1448 phba->ktime_seg4_min,
1449 phba->ktime_seg4_max);
1450 len += scnprintf(
1451 buf + len, PAGE_SIZE - len,
1452 "Total IO avg time: %08lld\n",
1453 div_u64(phba->ktime_seg1_total +
1454 phba->ktime_seg2_total +
1455 phba->ktime_seg3_total +
1456 phba->ktime_seg4_total,
1457 phba->ktime_data_samples));
1458 return len;
1459 }
1460
1461
1462 len += scnprintf(buf + len, PAGE_SIZE-len,
1463 "ktime %s: Total Samples: %lld %lld\n",
1464 (phba->ktime_on ? "Enabled" : "Disabled"),
1465 phba->ktime_data_samples,
1466 phba->ktime_status_samples);
1467 if (phba->ktime_data_samples == 0)
1468 return len;
1469
1470 len += scnprintf(buf + len, PAGE_SIZE-len,
1471 "Segment 1: MSI-X ISR Rcv cmd -to- "
1472 "cmd pass to NVME Layer\n");
1473 len += scnprintf(buf + len, PAGE_SIZE-len,
1474 "avg:%08lld min:%08lld max %08lld\n",
1475 div_u64(phba->ktime_seg1_total,
1476 phba->ktime_data_samples),
1477 phba->ktime_seg1_min,
1478 phba->ktime_seg1_max);
1479 len += scnprintf(buf + len, PAGE_SIZE-len,
1480 "Segment 2: cmd pass to NVME Layer- "
1481 "-to- Driver rcv cmd OP (action)\n");
1482 len += scnprintf(buf + len, PAGE_SIZE-len,
1483 "avg:%08lld min:%08lld max %08lld\n",
1484 div_u64(phba->ktime_seg2_total,
1485 phba->ktime_data_samples),
1486 phba->ktime_seg2_min,
1487 phba->ktime_seg2_max);
1488 len += scnprintf(buf + len, PAGE_SIZE-len,
1489 "Segment 3: Driver rcv cmd OP -to- "
1490 "Firmware WQ doorbell: cmd\n");
1491 len += scnprintf(buf + len, PAGE_SIZE-len,
1492 "avg:%08lld min:%08lld max %08lld\n",
1493 div_u64(phba->ktime_seg3_total,
1494 phba->ktime_data_samples),
1495 phba->ktime_seg3_min,
1496 phba->ktime_seg3_max);
1497 len += scnprintf(buf + len, PAGE_SIZE-len,
1498 "Segment 4: Firmware WQ doorbell: cmd "
1499 "-to- MSI-X ISR for cmd cmpl\n");
1500 len += scnprintf(buf + len, PAGE_SIZE-len,
1501 "avg:%08lld min:%08lld max %08lld\n",
1502 div_u64(phba->ktime_seg4_total,
1503 phba->ktime_data_samples),
1504 phba->ktime_seg4_min,
1505 phba->ktime_seg4_max);
1506 len += scnprintf(buf + len, PAGE_SIZE-len,
1507 "Segment 5: MSI-X ISR for cmd cmpl "
1508 "-to- NVME layer passed cmd done\n");
1509 len += scnprintf(buf + len, PAGE_SIZE-len,
1510 "avg:%08lld min:%08lld max %08lld\n",
1511 div_u64(phba->ktime_seg5_total,
1512 phba->ktime_data_samples),
1513 phba->ktime_seg5_min,
1514 phba->ktime_seg5_max);
1515
1516 if (phba->ktime_status_samples == 0) {
1517 len += scnprintf(buf + len, PAGE_SIZE-len,
1518 "Total: cmd received by MSI-X ISR "
1519 "-to- cmd completed on wire\n");
1520 len += scnprintf(buf + len, PAGE_SIZE-len,
1521 "avg:%08lld min:%08lld "
1522 "max %08lld\n",
1523 div_u64(phba->ktime_seg10_total,
1524 phba->ktime_data_samples),
1525 phba->ktime_seg10_min,
1526 phba->ktime_seg10_max);
1527 return len;
1528 }
1529
1530 len += scnprintf(buf + len, PAGE_SIZE-len,
1531 "Segment 6: NVME layer passed cmd done "
1532 "-to- Driver rcv rsp status OP\n");
1533 len += scnprintf(buf + len, PAGE_SIZE-len,
1534 "avg:%08lld min:%08lld max %08lld\n",
1535 div_u64(phba->ktime_seg6_total,
1536 phba->ktime_status_samples),
1537 phba->ktime_seg6_min,
1538 phba->ktime_seg6_max);
1539 len += scnprintf(buf + len, PAGE_SIZE-len,
1540 "Segment 7: Driver rcv rsp status OP "
1541 "-to- Firmware WQ doorbell: status\n");
1542 len += scnprintf(buf + len, PAGE_SIZE-len,
1543 "avg:%08lld min:%08lld max %08lld\n",
1544 div_u64(phba->ktime_seg7_total,
1545 phba->ktime_status_samples),
1546 phba->ktime_seg7_min,
1547 phba->ktime_seg7_max);
1548 len += scnprintf(buf + len, PAGE_SIZE-len,
1549 "Segment 8: Firmware WQ doorbell: status"
1550 " -to- MSI-X ISR for status cmpl\n");
1551 len += scnprintf(buf + len, PAGE_SIZE-len,
1552 "avg:%08lld min:%08lld max %08lld\n",
1553 div_u64(phba->ktime_seg8_total,
1554 phba->ktime_status_samples),
1555 phba->ktime_seg8_min,
1556 phba->ktime_seg8_max);
1557 len += scnprintf(buf + len, PAGE_SIZE-len,
1558 "Segment 9: MSI-X ISR for status cmpl "
1559 "-to- NVME layer passed status done\n");
1560 len += scnprintf(buf + len, PAGE_SIZE-len,
1561 "avg:%08lld min:%08lld max %08lld\n",
1562 div_u64(phba->ktime_seg9_total,
1563 phba->ktime_status_samples),
1564 phba->ktime_seg9_min,
1565 phba->ktime_seg9_max);
1566 len += scnprintf(buf + len, PAGE_SIZE-len,
1567 "Total: cmd received by MSI-X ISR -to- "
1568 "cmd completed on wire\n");
1569 len += scnprintf(buf + len, PAGE_SIZE-len,
1570 "avg:%08lld min:%08lld max %08lld\n",
1571 div_u64(phba->ktime_seg10_total,
1572 phba->ktime_status_samples),
1573 phba->ktime_seg10_min,
1574 phba->ktime_seg10_max);
1575 return len;
1576 }
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591 static int
1592 lpfc_debugfs_nvmeio_trc_data(struct lpfc_hba *phba, char *buf, int size)
1593 {
1594 struct lpfc_debugfs_nvmeio_trc *dtp;
1595 int i, state, index, skip;
1596 int len = 0;
1597
1598 state = phba->nvmeio_trc_on;
1599
1600 index = (atomic_read(&phba->nvmeio_trc_cnt) + 1) &
1601 (phba->nvmeio_trc_size - 1);
1602 skip = phba->nvmeio_trc_output_idx;
1603
1604 len += scnprintf(buf + len, size - len,
1605 "%s IO Trace %s: next_idx %d skip %d size %d\n",
1606 (phba->nvmet_support ? "NVME" : "NVMET"),
1607 (state ? "Enabled" : "Disabled"),
1608 index, skip, phba->nvmeio_trc_size);
1609
1610 if (!phba->nvmeio_trc || state)
1611 return len;
1612
1613
1614
1615 for (i = index; i < phba->nvmeio_trc_size; i++) {
1616 if (skip) {
1617 skip--;
1618 continue;
1619 }
1620 dtp = phba->nvmeio_trc + i;
1621 phba->nvmeio_trc_output_idx++;
1622
1623 if (!dtp->fmt)
1624 continue;
1625
1626 len += scnprintf(buf + len, size - len, dtp->fmt,
1627 dtp->data1, dtp->data2, dtp->data3);
1628
1629 if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) {
1630 phba->nvmeio_trc_output_idx = 0;
1631 len += scnprintf(buf + len, size - len,
1632 "Trace Complete\n");
1633 goto out;
1634 }
1635
1636 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) {
1637 len += scnprintf(buf + len, size - len,
1638 "Trace Continue (%d of %d)\n",
1639 phba->nvmeio_trc_output_idx,
1640 phba->nvmeio_trc_size);
1641 goto out;
1642 }
1643 }
1644 for (i = 0; i < index; i++) {
1645 if (skip) {
1646 skip--;
1647 continue;
1648 }
1649 dtp = phba->nvmeio_trc + i;
1650 phba->nvmeio_trc_output_idx++;
1651
1652 if (!dtp->fmt)
1653 continue;
1654
1655 len += scnprintf(buf + len, size - len, dtp->fmt,
1656 dtp->data1, dtp->data2, dtp->data3);
1657
1658 if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) {
1659 phba->nvmeio_trc_output_idx = 0;
1660 len += scnprintf(buf + len, size - len,
1661 "Trace Complete\n");
1662 goto out;
1663 }
1664
1665 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) {
1666 len += scnprintf(buf + len, size - len,
1667 "Trace Continue (%d of %d)\n",
1668 phba->nvmeio_trc_output_idx,
1669 phba->nvmeio_trc_size);
1670 goto out;
1671 }
1672 }
1673
1674 len += scnprintf(buf + len, size - len,
1675 "Trace Done\n");
1676 out:
1677 return len;
1678 }
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693 static int
1694 lpfc_debugfs_hdwqstat_data(struct lpfc_vport *vport, char *buf, int size)
1695 {
1696 struct lpfc_hba *phba = vport->phba;
1697 struct lpfc_hdwq_stat *c_stat;
1698 int i, j, len;
1699 uint32_t tot_xmt;
1700 uint32_t tot_rcv;
1701 uint32_t tot_cmpl;
1702 char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
1703
1704 scnprintf(tmp, sizeof(tmp), "HDWQ Stats:\n\n");
1705 if (strlcat(buf, tmp, size) >= size)
1706 goto buffer_done;
1707
1708 scnprintf(tmp, sizeof(tmp), "(NVME Accounting: %s) ",
1709 (phba->hdwqstat_on &
1710 (LPFC_CHECK_NVME_IO | LPFC_CHECK_NVMET_IO) ?
1711 "Enabled" : "Disabled"));
1712 if (strlcat(buf, tmp, size) >= size)
1713 goto buffer_done;
1714
1715 scnprintf(tmp, sizeof(tmp), "(SCSI Accounting: %s) ",
1716 (phba->hdwqstat_on & LPFC_CHECK_SCSI_IO ?
1717 "Enabled" : "Disabled"));
1718 if (strlcat(buf, tmp, size) >= size)
1719 goto buffer_done;
1720
1721 scnprintf(tmp, sizeof(tmp), "\n\n");
1722 if (strlcat(buf, tmp, size) >= size)
1723 goto buffer_done;
1724
1725 for (i = 0; i < phba->cfg_hdw_queue; i++) {
1726 tot_rcv = 0;
1727 tot_xmt = 0;
1728 tot_cmpl = 0;
1729
1730 for_each_present_cpu(j) {
1731 c_stat = per_cpu_ptr(phba->sli4_hba.c_stat, j);
1732
1733
1734 if (i != c_stat->hdwq_no)
1735 continue;
1736
1737
1738 if (!c_stat->xmt_io && !c_stat->cmpl_io &&
1739 !c_stat->rcv_io)
1740 continue;
1741
1742 if (!tot_xmt && !tot_cmpl && !tot_rcv) {
1743
1744 scnprintf(tmp, sizeof(tmp), "[HDWQ %d]:\t", i);
1745 if (strlcat(buf, tmp, size) >= size)
1746 goto buffer_done;
1747 }
1748
1749 tot_xmt += c_stat->xmt_io;
1750 tot_cmpl += c_stat->cmpl_io;
1751 if (phba->nvmet_support)
1752 tot_rcv += c_stat->rcv_io;
1753
1754 scnprintf(tmp, sizeof(tmp), "| [CPU %d]: ", j);
1755 if (strlcat(buf, tmp, size) >= size)
1756 goto buffer_done;
1757
1758 if (phba->nvmet_support) {
1759 scnprintf(tmp, sizeof(tmp),
1760 "XMT 0x%x CMPL 0x%x RCV 0x%x |",
1761 c_stat->xmt_io, c_stat->cmpl_io,
1762 c_stat->rcv_io);
1763 if (strlcat(buf, tmp, size) >= size)
1764 goto buffer_done;
1765 } else {
1766 scnprintf(tmp, sizeof(tmp),
1767 "XMT 0x%x CMPL 0x%x |",
1768 c_stat->xmt_io, c_stat->cmpl_io);
1769 if (strlcat(buf, tmp, size) >= size)
1770 goto buffer_done;
1771 }
1772 }
1773
1774
1775 if (!tot_xmt && !tot_cmpl && !tot_rcv)
1776 continue;
1777
1778 scnprintf(tmp, sizeof(tmp), "\t->\t[HDWQ Total: ");
1779 if (strlcat(buf, tmp, size) >= size)
1780 goto buffer_done;
1781
1782 if (phba->nvmet_support) {
1783 scnprintf(tmp, sizeof(tmp),
1784 "XMT 0x%x CMPL 0x%x RCV 0x%x]\n\n",
1785 tot_xmt, tot_cmpl, tot_rcv);
1786 if (strlcat(buf, tmp, size) >= size)
1787 goto buffer_done;
1788 } else {
1789 scnprintf(tmp, sizeof(tmp),
1790 "XMT 0x%x CMPL 0x%x]\n\n",
1791 tot_xmt, tot_cmpl);
1792 if (strlcat(buf, tmp, size) >= size)
1793 goto buffer_done;
1794 }
1795 }
1796
1797 buffer_done:
1798 len = strnlen(buf, size);
1799 return len;
1800 }
1801
1802 #endif
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820 inline void
1821 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
1822 uint32_t data1, uint32_t data2, uint32_t data3)
1823 {
1824 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1825 struct lpfc_debugfs_trc *dtp;
1826 int index;
1827
1828 if (!(lpfc_debugfs_mask_disc_trc & mask))
1829 return;
1830
1831 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
1832 !vport || !vport->disc_trc)
1833 return;
1834
1835 index = atomic_inc_return(&vport->disc_trc_cnt) &
1836 (lpfc_debugfs_max_disc_trc - 1);
1837 dtp = vport->disc_trc + index;
1838 dtp->fmt = fmt;
1839 dtp->data1 = data1;
1840 dtp->data2 = data2;
1841 dtp->data3 = data3;
1842 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
1843 dtp->jif = jiffies;
1844 #endif
1845 return;
1846 }
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861 inline void
1862 lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
1863 uint32_t data1, uint32_t data2, uint32_t data3)
1864 {
1865 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1866 struct lpfc_debugfs_trc *dtp;
1867 int index;
1868
1869 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
1870 !phba || !phba->slow_ring_trc)
1871 return;
1872
1873 index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
1874 (lpfc_debugfs_max_slow_ring_trc - 1);
1875 dtp = phba->slow_ring_trc + index;
1876 dtp->fmt = fmt;
1877 dtp->data1 = data1;
1878 dtp->data2 = data2;
1879 dtp->data3 = data3;
1880 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
1881 dtp->jif = jiffies;
1882 #endif
1883 return;
1884 }
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899 inline void
1900 lpfc_debugfs_nvme_trc(struct lpfc_hba *phba, char *fmt,
1901 uint16_t data1, uint16_t data2, uint32_t data3)
1902 {
1903 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1904 struct lpfc_debugfs_nvmeio_trc *dtp;
1905 int index;
1906
1907 if (!phba->nvmeio_trc_on || !phba->nvmeio_trc)
1908 return;
1909
1910 index = atomic_inc_return(&phba->nvmeio_trc_cnt) &
1911 (phba->nvmeio_trc_size - 1);
1912 dtp = phba->nvmeio_trc + index;
1913 dtp->fmt = fmt;
1914 dtp->data1 = data1;
1915 dtp->data2 = data2;
1916 dtp->data3 = data3;
1917 #endif
1918 }
1919
1920 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936 static int
1937 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
1938 {
1939 struct lpfc_vport *vport = inode->i_private;
1940 struct lpfc_debug *debug;
1941 int size;
1942 int rc = -ENOMEM;
1943
1944 if (!lpfc_debugfs_max_disc_trc) {
1945 rc = -ENOSPC;
1946 goto out;
1947 }
1948
1949 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1950 if (!debug)
1951 goto out;
1952
1953
1954 size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
1955 size = PAGE_ALIGN(size);
1956
1957 debug->buffer = kmalloc(size, GFP_KERNEL);
1958 if (!debug->buffer) {
1959 kfree(debug);
1960 goto out;
1961 }
1962
1963 debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
1964 file->private_data = debug;
1965
1966 rc = 0;
1967 out:
1968 return rc;
1969 }
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986 static int
1987 lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
1988 {
1989 struct lpfc_hba *phba = inode->i_private;
1990 struct lpfc_debug *debug;
1991 int size;
1992 int rc = -ENOMEM;
1993
1994 if (!lpfc_debugfs_max_slow_ring_trc) {
1995 rc = -ENOSPC;
1996 goto out;
1997 }
1998
1999 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2000 if (!debug)
2001 goto out;
2002
2003
2004 size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
2005 size = PAGE_ALIGN(size);
2006
2007 debug->buffer = kmalloc(size, GFP_KERNEL);
2008 if (!debug->buffer) {
2009 kfree(debug);
2010 goto out;
2011 }
2012
2013 debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
2014 file->private_data = debug;
2015
2016 rc = 0;
2017 out:
2018 return rc;
2019 }
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036 static int
2037 lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
2038 {
2039 struct lpfc_hba *phba = inode->i_private;
2040 struct lpfc_debug *debug;
2041 int rc = -ENOMEM;
2042
2043 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2044 if (!debug)
2045 goto out;
2046
2047
2048 debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
2049 if (!debug->buffer) {
2050 kfree(debug);
2051 goto out;
2052 }
2053
2054 debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
2055 LPFC_HBQINFO_SIZE);
2056 file->private_data = debug;
2057
2058 rc = 0;
2059 out:
2060 return rc;
2061 }
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078 static int
2079 lpfc_debugfs_multixripools_open(struct inode *inode, struct file *file)
2080 {
2081 struct lpfc_hba *phba = inode->i_private;
2082 struct lpfc_debug *debug;
2083 int rc = -ENOMEM;
2084
2085 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2086 if (!debug)
2087 goto out;
2088
2089
2090 debug->buffer = kzalloc(LPFC_DUMP_MULTIXRIPOOL_SIZE, GFP_KERNEL);
2091 if (!debug->buffer) {
2092 kfree(debug);
2093 goto out;
2094 }
2095
2096 debug->len = lpfc_debugfs_multixripools_data(
2097 phba, debug->buffer, LPFC_DUMP_MULTIXRIPOOL_SIZE);
2098
2099 debug->i_private = inode->i_private;
2100 file->private_data = debug;
2101
2102 rc = 0;
2103 out:
2104 return rc;
2105 }
2106
2107 #ifdef LPFC_HDWQ_LOCK_STAT
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123 static int
2124 lpfc_debugfs_lockstat_open(struct inode *inode, struct file *file)
2125 {
2126 struct lpfc_hba *phba = inode->i_private;
2127 struct lpfc_debug *debug;
2128 int rc = -ENOMEM;
2129
2130 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2131 if (!debug)
2132 goto out;
2133
2134
2135 debug->buffer = kmalloc(LPFC_HDWQINFO_SIZE, GFP_KERNEL);
2136 if (!debug->buffer) {
2137 kfree(debug);
2138 goto out;
2139 }
2140
2141 debug->len = lpfc_debugfs_lockstat_data(phba, debug->buffer,
2142 LPFC_HBQINFO_SIZE);
2143 file->private_data = debug;
2144
2145 rc = 0;
2146 out:
2147 return rc;
2148 }
2149
2150 static ssize_t
2151 lpfc_debugfs_lockstat_write(struct file *file, const char __user *buf,
2152 size_t nbytes, loff_t *ppos)
2153 {
2154 struct lpfc_debug *debug = file->private_data;
2155 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2156 struct lpfc_sli4_hdw_queue *qp;
2157 char mybuf[64];
2158 char *pbuf;
2159 int i;
2160
2161 memset(mybuf, 0, sizeof(mybuf));
2162
2163 if (copy_from_user(mybuf, buf, nbytes))
2164 return -EFAULT;
2165 pbuf = &mybuf[0];
2166
2167 if ((strncmp(pbuf, "reset", strlen("reset")) == 0) ||
2168 (strncmp(pbuf, "zero", strlen("zero")) == 0)) {
2169 for (i = 0; i < phba->cfg_hdw_queue; i++) {
2170 qp = &phba->sli4_hba.hdwq[i];
2171 qp->lock_conflict.alloc_xri_get = 0;
2172 qp->lock_conflict.alloc_xri_put = 0;
2173 qp->lock_conflict.free_xri = 0;
2174 qp->lock_conflict.wq_access = 0;
2175 qp->lock_conflict.alloc_pvt_pool = 0;
2176 qp->lock_conflict.mv_from_pvt_pool = 0;
2177 qp->lock_conflict.mv_to_pub_pool = 0;
2178 qp->lock_conflict.mv_to_pvt_pool = 0;
2179 qp->lock_conflict.free_pvt_pool = 0;
2180 qp->lock_conflict.free_pub_pool = 0;
2181 qp->lock_conflict.wq_access = 0;
2182 }
2183 }
2184 return nbytes;
2185 }
2186 #endif
2187
2188 static int lpfc_debugfs_ras_log_data(struct lpfc_hba *phba,
2189 char *buffer, int size)
2190 {
2191 int copied = 0;
2192 struct lpfc_dmabuf *dmabuf, *next;
2193
2194 memset(buffer, 0, size);
2195
2196 spin_lock_irq(&phba->hbalock);
2197 if (phba->ras_fwlog.state != ACTIVE) {
2198 spin_unlock_irq(&phba->hbalock);
2199 return -EINVAL;
2200 }
2201 spin_unlock_irq(&phba->hbalock);
2202
2203 list_for_each_entry_safe(dmabuf, next,
2204 &phba->ras_fwlog.fwlog_buff_list, list) {
2205
2206 if ((copied + LPFC_RAS_MAX_ENTRY_SIZE) >= (size - 1)) {
2207 memcpy(buffer + copied, dmabuf->virt,
2208 size - copied - 1);
2209 copied += size - copied - 1;
2210 break;
2211 }
2212 memcpy(buffer + copied, dmabuf->virt, LPFC_RAS_MAX_ENTRY_SIZE);
2213 copied += LPFC_RAS_MAX_ENTRY_SIZE;
2214 }
2215 return copied;
2216 }
2217
2218 static int
2219 lpfc_debugfs_ras_log_release(struct inode *inode, struct file *file)
2220 {
2221 struct lpfc_debug *debug = file->private_data;
2222
2223 vfree(debug->buffer);
2224 kfree(debug);
2225
2226 return 0;
2227 }
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244 static int
2245 lpfc_debugfs_ras_log_open(struct inode *inode, struct file *file)
2246 {
2247 struct lpfc_hba *phba = inode->i_private;
2248 struct lpfc_debug *debug;
2249 int size;
2250 int rc = -ENOMEM;
2251
2252 spin_lock_irq(&phba->hbalock);
2253 if (phba->ras_fwlog.state != ACTIVE) {
2254 spin_unlock_irq(&phba->hbalock);
2255 rc = -EINVAL;
2256 goto out;
2257 }
2258 spin_unlock_irq(&phba->hbalock);
2259 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2260 if (!debug)
2261 goto out;
2262
2263 size = LPFC_RAS_MIN_BUFF_POST_SIZE * phba->cfg_ras_fwlog_buffsize;
2264 debug->buffer = vmalloc(size);
2265 if (!debug->buffer)
2266 goto free_debug;
2267
2268 debug->len = lpfc_debugfs_ras_log_data(phba, debug->buffer, size);
2269 if (debug->len < 0) {
2270 rc = -EINVAL;
2271 goto free_buffer;
2272 }
2273 file->private_data = debug;
2274
2275 return 0;
2276
2277 free_buffer:
2278 vfree(debug->buffer);
2279 free_debug:
2280 kfree(debug);
2281 out:
2282 return rc;
2283 }
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300 static int
2301 lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file)
2302 {
2303 struct lpfc_hba *phba = inode->i_private;
2304 struct lpfc_debug *debug;
2305 int rc = -ENOMEM;
2306
2307 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2308 if (!debug)
2309 goto out;
2310
2311
2312 debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL);
2313 if (!debug->buffer) {
2314 kfree(debug);
2315 goto out;
2316 }
2317
2318 debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer,
2319 LPFC_DUMPHBASLIM_SIZE);
2320 file->private_data = debug;
2321
2322 rc = 0;
2323 out:
2324 return rc;
2325 }
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342 static int
2343 lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file)
2344 {
2345 struct lpfc_hba *phba = inode->i_private;
2346 struct lpfc_debug *debug;
2347 int rc = -ENOMEM;
2348
2349 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2350 if (!debug)
2351 goto out;
2352
2353
2354 debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL);
2355 if (!debug->buffer) {
2356 kfree(debug);
2357 goto out;
2358 }
2359
2360 debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer,
2361 LPFC_DUMPHOSTSLIM_SIZE);
2362 file->private_data = debug;
2363
2364 rc = 0;
2365 out:
2366 return rc;
2367 }
2368
2369 static ssize_t
2370 lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
2371 size_t nbytes, loff_t *ppos)
2372 {
2373 struct dentry *dent = file->f_path.dentry;
2374 struct lpfc_hba *phba = file->private_data;
2375 char cbuf[32];
2376 uint64_t tmp = 0;
2377 int cnt = 0;
2378
2379 if (dent == phba->debug_writeGuard)
2380 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt);
2381 else if (dent == phba->debug_writeApp)
2382 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt);
2383 else if (dent == phba->debug_writeRef)
2384 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt);
2385 else if (dent == phba->debug_readGuard)
2386 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt);
2387 else if (dent == phba->debug_readApp)
2388 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt);
2389 else if (dent == phba->debug_readRef)
2390 cnt = scnprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt);
2391 else if (dent == phba->debug_InjErrNPortID)
2392 cnt = scnprintf(cbuf, 32, "0x%06x\n",
2393 phba->lpfc_injerr_nportid);
2394 else if (dent == phba->debug_InjErrWWPN) {
2395 memcpy(&tmp, &phba->lpfc_injerr_wwpn, sizeof(struct lpfc_name));
2396 tmp = cpu_to_be64(tmp);
2397 cnt = scnprintf(cbuf, 32, "0x%016llx\n", tmp);
2398 } else if (dent == phba->debug_InjErrLBA) {
2399 if (phba->lpfc_injerr_lba == (sector_t)(-1))
2400 cnt = scnprintf(cbuf, 32, "off\n");
2401 else
2402 cnt = scnprintf(cbuf, 32, "0x%llx\n",
2403 (uint64_t) phba->lpfc_injerr_lba);
2404 } else
2405 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2406 "0547 Unknown debugfs error injection entry\n");
2407
2408 return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt);
2409 }
2410
2411 static ssize_t
2412 lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
2413 size_t nbytes, loff_t *ppos)
2414 {
2415 struct dentry *dent = file->f_path.dentry;
2416 struct lpfc_hba *phba = file->private_data;
2417 char dstbuf[33];
2418 uint64_t tmp = 0;
2419 int size;
2420
2421 memset(dstbuf, 0, 33);
2422 size = (nbytes < 32) ? nbytes : 32;
2423 if (copy_from_user(dstbuf, buf, size))
2424 return -EFAULT;
2425
2426 if (dent == phba->debug_InjErrLBA) {
2427 if ((dstbuf[0] == 'o') && (dstbuf[1] == 'f') &&
2428 (dstbuf[2] == 'f'))
2429 tmp = (uint64_t)(-1);
2430 }
2431
2432 if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp)))
2433 return -EINVAL;
2434
2435 if (dent == phba->debug_writeGuard)
2436 phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
2437 else if (dent == phba->debug_writeApp)
2438 phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
2439 else if (dent == phba->debug_writeRef)
2440 phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
2441 else if (dent == phba->debug_readGuard)
2442 phba->lpfc_injerr_rgrd_cnt = (uint32_t)tmp;
2443 else if (dent == phba->debug_readApp)
2444 phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
2445 else if (dent == phba->debug_readRef)
2446 phba->lpfc_injerr_rref_cnt = (uint32_t)tmp;
2447 else if (dent == phba->debug_InjErrLBA)
2448 phba->lpfc_injerr_lba = (sector_t)tmp;
2449 else if (dent == phba->debug_InjErrNPortID)
2450 phba->lpfc_injerr_nportid = (uint32_t)(tmp & Mask_DID);
2451 else if (dent == phba->debug_InjErrWWPN) {
2452 tmp = cpu_to_be64(tmp);
2453 memcpy(&phba->lpfc_injerr_wwpn, &tmp, sizeof(struct lpfc_name));
2454 } else
2455 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2456 "0548 Unknown debugfs error injection entry\n");
2457
2458 return nbytes;
2459 }
2460
2461 static int
2462 lpfc_debugfs_dif_err_release(struct inode *inode, struct file *file)
2463 {
2464 return 0;
2465 }
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482 static int
2483 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
2484 {
2485 struct lpfc_vport *vport = inode->i_private;
2486 struct lpfc_debug *debug;
2487 int rc = -ENOMEM;
2488
2489 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2490 if (!debug)
2491 goto out;
2492
2493
2494 debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
2495 if (!debug->buffer) {
2496 kfree(debug);
2497 goto out;
2498 }
2499
2500 debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
2501 LPFC_NODELIST_SIZE);
2502 file->private_data = debug;
2503
2504 rc = 0;
2505 out:
2506 return rc;
2507 }
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526 static loff_t
2527 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
2528 {
2529 struct lpfc_debug *debug = file->private_data;
2530 return fixed_size_llseek(file, off, whence, debug->len);
2531 }
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549 static ssize_t
2550 lpfc_debugfs_read(struct file *file, char __user *buf,
2551 size_t nbytes, loff_t *ppos)
2552 {
2553 struct lpfc_debug *debug = file->private_data;
2554
2555 return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
2556 debug->len);
2557 }
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571 static int
2572 lpfc_debugfs_release(struct inode *inode, struct file *file)
2573 {
2574 struct lpfc_debug *debug = file->private_data;
2575
2576 kfree(debug->buffer);
2577 kfree(debug);
2578
2579 return 0;
2580 }
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597 static ssize_t
2598 lpfc_debugfs_multixripools_write(struct file *file, const char __user *buf,
2599 size_t nbytes, loff_t *ppos)
2600 {
2601 struct lpfc_debug *debug = file->private_data;
2602 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2603 char mybuf[64];
2604 char *pbuf;
2605 u32 i;
2606 u32 hwq_count;
2607 struct lpfc_sli4_hdw_queue *qp;
2608 struct lpfc_multixri_pool *multixri_pool;
2609
2610 if (nbytes > sizeof(mybuf) - 1)
2611 nbytes = sizeof(mybuf) - 1;
2612
2613 memset(mybuf, 0, sizeof(mybuf));
2614
2615 if (copy_from_user(mybuf, buf, nbytes))
2616 return -EFAULT;
2617 pbuf = &mybuf[0];
2618
2619 if ((strncmp(pbuf, "clear", strlen("clear"))) == 0) {
2620 hwq_count = phba->cfg_hdw_queue;
2621 for (i = 0; i < hwq_count; i++) {
2622 qp = &phba->sli4_hba.hdwq[i];
2623 multixri_pool = qp->p_multixri_pool;
2624 if (!multixri_pool)
2625 continue;
2626
2627 qp->empty_io_bufs = 0;
2628 multixri_pool->pbl_empty_count = 0;
2629 #ifdef LPFC_MXP_STAT
2630 multixri_pool->above_limit_count = 0;
2631 multixri_pool->below_limit_count = 0;
2632 multixri_pool->stat_max_hwm = 0;
2633 multixri_pool->local_pbl_hit_count = 0;
2634 multixri_pool->other_pbl_hit_count = 0;
2635
2636 multixri_pool->stat_pbl_count = 0;
2637 multixri_pool->stat_pvt_count = 0;
2638 multixri_pool->stat_busy_count = 0;
2639 multixri_pool->stat_snapshot_taken = 0;
2640 #endif
2641 }
2642 return strlen(pbuf);
2643 }
2644
2645 return -EINVAL;
2646 }
2647
2648 static int
2649 lpfc_debugfs_nvmestat_open(struct inode *inode, struct file *file)
2650 {
2651 struct lpfc_vport *vport = inode->i_private;
2652 struct lpfc_debug *debug;
2653 int rc = -ENOMEM;
2654
2655 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2656 if (!debug)
2657 goto out;
2658
2659
2660 debug->buffer = kmalloc(LPFC_NVMESTAT_SIZE, GFP_KERNEL);
2661 if (!debug->buffer) {
2662 kfree(debug);
2663 goto out;
2664 }
2665
2666 debug->len = lpfc_debugfs_nvmestat_data(vport, debug->buffer,
2667 LPFC_NVMESTAT_SIZE);
2668
2669 debug->i_private = inode->i_private;
2670 file->private_data = debug;
2671
2672 rc = 0;
2673 out:
2674 return rc;
2675 }
2676
2677 static ssize_t
2678 lpfc_debugfs_nvmestat_write(struct file *file, const char __user *buf,
2679 size_t nbytes, loff_t *ppos)
2680 {
2681 struct lpfc_debug *debug = file->private_data;
2682 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
2683 struct lpfc_hba *phba = vport->phba;
2684 struct lpfc_nvmet_tgtport *tgtp;
2685 char mybuf[64];
2686 char *pbuf;
2687
2688 if (!phba->targetport)
2689 return -ENXIO;
2690
2691 if (nbytes > sizeof(mybuf) - 1)
2692 nbytes = sizeof(mybuf) - 1;
2693
2694 memset(mybuf, 0, sizeof(mybuf));
2695
2696 if (copy_from_user(mybuf, buf, nbytes))
2697 return -EFAULT;
2698 pbuf = &mybuf[0];
2699
2700 tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
2701 if ((strncmp(pbuf, "reset", strlen("reset")) == 0) ||
2702 (strncmp(pbuf, "zero", strlen("zero")) == 0)) {
2703 atomic_set(&tgtp->rcv_ls_req_in, 0);
2704 atomic_set(&tgtp->rcv_ls_req_out, 0);
2705 atomic_set(&tgtp->rcv_ls_req_drop, 0);
2706 atomic_set(&tgtp->xmt_ls_abort, 0);
2707 atomic_set(&tgtp->xmt_ls_abort_cmpl, 0);
2708 atomic_set(&tgtp->xmt_ls_rsp, 0);
2709 atomic_set(&tgtp->xmt_ls_drop, 0);
2710 atomic_set(&tgtp->xmt_ls_rsp_error, 0);
2711 atomic_set(&tgtp->xmt_ls_rsp_cmpl, 0);
2712
2713 atomic_set(&tgtp->rcv_fcp_cmd_in, 0);
2714 atomic_set(&tgtp->rcv_fcp_cmd_out, 0);
2715 atomic_set(&tgtp->rcv_fcp_cmd_drop, 0);
2716 atomic_set(&tgtp->xmt_fcp_drop, 0);
2717 atomic_set(&tgtp->xmt_fcp_read_rsp, 0);
2718 atomic_set(&tgtp->xmt_fcp_read, 0);
2719 atomic_set(&tgtp->xmt_fcp_write, 0);
2720 atomic_set(&tgtp->xmt_fcp_rsp, 0);
2721 atomic_set(&tgtp->xmt_fcp_release, 0);
2722 atomic_set(&tgtp->xmt_fcp_rsp_cmpl, 0);
2723 atomic_set(&tgtp->xmt_fcp_rsp_error, 0);
2724 atomic_set(&tgtp->xmt_fcp_rsp_drop, 0);
2725
2726 atomic_set(&tgtp->xmt_fcp_abort, 0);
2727 atomic_set(&tgtp->xmt_fcp_abort_cmpl, 0);
2728 atomic_set(&tgtp->xmt_abort_sol, 0);
2729 atomic_set(&tgtp->xmt_abort_unsol, 0);
2730 atomic_set(&tgtp->xmt_abort_rsp, 0);
2731 atomic_set(&tgtp->xmt_abort_rsp_error, 0);
2732 }
2733 return nbytes;
2734 }
2735
2736 static int
2737 lpfc_debugfs_scsistat_open(struct inode *inode, struct file *file)
2738 {
2739 struct lpfc_vport *vport = inode->i_private;
2740 struct lpfc_debug *debug;
2741 int rc = -ENOMEM;
2742
2743 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2744 if (!debug)
2745 goto out;
2746
2747
2748 debug->buffer = kzalloc(LPFC_SCSISTAT_SIZE, GFP_KERNEL);
2749 if (!debug->buffer) {
2750 kfree(debug);
2751 goto out;
2752 }
2753
2754 debug->len = lpfc_debugfs_scsistat_data(vport, debug->buffer,
2755 LPFC_SCSISTAT_SIZE);
2756
2757 debug->i_private = inode->i_private;
2758 file->private_data = debug;
2759
2760 rc = 0;
2761 out:
2762 return rc;
2763 }
2764
2765 static ssize_t
2766 lpfc_debugfs_scsistat_write(struct file *file, const char __user *buf,
2767 size_t nbytes, loff_t *ppos)
2768 {
2769 struct lpfc_debug *debug = file->private_data;
2770 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
2771 struct lpfc_hba *phba = vport->phba;
2772 char mybuf[6] = {0};
2773 int i;
2774
2775 if (copy_from_user(mybuf, buf, (nbytes >= sizeof(mybuf)) ?
2776 (sizeof(mybuf) - 1) : nbytes))
2777 return -EFAULT;
2778
2779 if ((strncmp(&mybuf[0], "reset", strlen("reset")) == 0) ||
2780 (strncmp(&mybuf[0], "zero", strlen("zero")) == 0)) {
2781 for (i = 0; i < phba->cfg_hdw_queue; i++) {
2782 memset(&phba->sli4_hba.hdwq[i].scsi_cstat, 0,
2783 sizeof(phba->sli4_hba.hdwq[i].scsi_cstat));
2784 }
2785 }
2786
2787 return nbytes;
2788 }
2789
2790 static int
2791 lpfc_debugfs_ioktime_open(struct inode *inode, struct file *file)
2792 {
2793 struct lpfc_vport *vport = inode->i_private;
2794 struct lpfc_debug *debug;
2795 int rc = -ENOMEM;
2796
2797 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2798 if (!debug)
2799 goto out;
2800
2801
2802 debug->buffer = kmalloc(LPFC_IOKTIME_SIZE, GFP_KERNEL);
2803 if (!debug->buffer) {
2804 kfree(debug);
2805 goto out;
2806 }
2807
2808 debug->len = lpfc_debugfs_ioktime_data(vport, debug->buffer,
2809 LPFC_IOKTIME_SIZE);
2810
2811 debug->i_private = inode->i_private;
2812 file->private_data = debug;
2813
2814 rc = 0;
2815 out:
2816 return rc;
2817 }
2818
2819 static ssize_t
2820 lpfc_debugfs_ioktime_write(struct file *file, const char __user *buf,
2821 size_t nbytes, loff_t *ppos)
2822 {
2823 struct lpfc_debug *debug = file->private_data;
2824 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
2825 struct lpfc_hba *phba = vport->phba;
2826 char mybuf[64];
2827 char *pbuf;
2828
2829 if (nbytes > sizeof(mybuf) - 1)
2830 nbytes = sizeof(mybuf) - 1;
2831
2832 memset(mybuf, 0, sizeof(mybuf));
2833
2834 if (copy_from_user(mybuf, buf, nbytes))
2835 return -EFAULT;
2836 pbuf = &mybuf[0];
2837
2838 if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
2839 phba->ktime_data_samples = 0;
2840 phba->ktime_status_samples = 0;
2841 phba->ktime_seg1_total = 0;
2842 phba->ktime_seg1_max = 0;
2843 phba->ktime_seg1_min = 0xffffffff;
2844 phba->ktime_seg2_total = 0;
2845 phba->ktime_seg2_max = 0;
2846 phba->ktime_seg2_min = 0xffffffff;
2847 phba->ktime_seg3_total = 0;
2848 phba->ktime_seg3_max = 0;
2849 phba->ktime_seg3_min = 0xffffffff;
2850 phba->ktime_seg4_total = 0;
2851 phba->ktime_seg4_max = 0;
2852 phba->ktime_seg4_min = 0xffffffff;
2853 phba->ktime_seg5_total = 0;
2854 phba->ktime_seg5_max = 0;
2855 phba->ktime_seg5_min = 0xffffffff;
2856 phba->ktime_seg6_total = 0;
2857 phba->ktime_seg6_max = 0;
2858 phba->ktime_seg6_min = 0xffffffff;
2859 phba->ktime_seg7_total = 0;
2860 phba->ktime_seg7_max = 0;
2861 phba->ktime_seg7_min = 0xffffffff;
2862 phba->ktime_seg8_total = 0;
2863 phba->ktime_seg8_max = 0;
2864 phba->ktime_seg8_min = 0xffffffff;
2865 phba->ktime_seg9_total = 0;
2866 phba->ktime_seg9_max = 0;
2867 phba->ktime_seg9_min = 0xffffffff;
2868 phba->ktime_seg10_total = 0;
2869 phba->ktime_seg10_max = 0;
2870 phba->ktime_seg10_min = 0xffffffff;
2871
2872 phba->ktime_on = 1;
2873 return strlen(pbuf);
2874 } else if ((strncmp(pbuf, "off",
2875 sizeof("off") - 1) == 0)) {
2876 phba->ktime_on = 0;
2877 return strlen(pbuf);
2878 } else if ((strncmp(pbuf, "zero",
2879 sizeof("zero") - 1) == 0)) {
2880 phba->ktime_data_samples = 0;
2881 phba->ktime_status_samples = 0;
2882 phba->ktime_seg1_total = 0;
2883 phba->ktime_seg1_max = 0;
2884 phba->ktime_seg1_min = 0xffffffff;
2885 phba->ktime_seg2_total = 0;
2886 phba->ktime_seg2_max = 0;
2887 phba->ktime_seg2_min = 0xffffffff;
2888 phba->ktime_seg3_total = 0;
2889 phba->ktime_seg3_max = 0;
2890 phba->ktime_seg3_min = 0xffffffff;
2891 phba->ktime_seg4_total = 0;
2892 phba->ktime_seg4_max = 0;
2893 phba->ktime_seg4_min = 0xffffffff;
2894 phba->ktime_seg5_total = 0;
2895 phba->ktime_seg5_max = 0;
2896 phba->ktime_seg5_min = 0xffffffff;
2897 phba->ktime_seg6_total = 0;
2898 phba->ktime_seg6_max = 0;
2899 phba->ktime_seg6_min = 0xffffffff;
2900 phba->ktime_seg7_total = 0;
2901 phba->ktime_seg7_max = 0;
2902 phba->ktime_seg7_min = 0xffffffff;
2903 phba->ktime_seg8_total = 0;
2904 phba->ktime_seg8_max = 0;
2905 phba->ktime_seg8_min = 0xffffffff;
2906 phba->ktime_seg9_total = 0;
2907 phba->ktime_seg9_max = 0;
2908 phba->ktime_seg9_min = 0xffffffff;
2909 phba->ktime_seg10_total = 0;
2910 phba->ktime_seg10_max = 0;
2911 phba->ktime_seg10_min = 0xffffffff;
2912 return strlen(pbuf);
2913 }
2914 return -EINVAL;
2915 }
2916
2917 static int
2918 lpfc_debugfs_nvmeio_trc_open(struct inode *inode, struct file *file)
2919 {
2920 struct lpfc_hba *phba = inode->i_private;
2921 struct lpfc_debug *debug;
2922 int rc = -ENOMEM;
2923
2924 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
2925 if (!debug)
2926 goto out;
2927
2928
2929 debug->buffer = kmalloc(LPFC_NVMEIO_TRC_SIZE, GFP_KERNEL);
2930 if (!debug->buffer) {
2931 kfree(debug);
2932 goto out;
2933 }
2934
2935 debug->len = lpfc_debugfs_nvmeio_trc_data(phba, debug->buffer,
2936 LPFC_NVMEIO_TRC_SIZE);
2937
2938 debug->i_private = inode->i_private;
2939 file->private_data = debug;
2940
2941 rc = 0;
2942 out:
2943 return rc;
2944 }
2945
2946 static ssize_t
2947 lpfc_debugfs_nvmeio_trc_write(struct file *file, const char __user *buf,
2948 size_t nbytes, loff_t *ppos)
2949 {
2950 struct lpfc_debug *debug = file->private_data;
2951 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2952 int i;
2953 unsigned long sz;
2954 char mybuf[64];
2955 char *pbuf;
2956
2957 if (nbytes > sizeof(mybuf) - 1)
2958 nbytes = sizeof(mybuf) - 1;
2959
2960 memset(mybuf, 0, sizeof(mybuf));
2961
2962 if (copy_from_user(mybuf, buf, nbytes))
2963 return -EFAULT;
2964 pbuf = &mybuf[0];
2965
2966 if ((strncmp(pbuf, "off", sizeof("off") - 1) == 0)) {
2967 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2968 "0570 nvmeio_trc_off\n");
2969 phba->nvmeio_trc_output_idx = 0;
2970 phba->nvmeio_trc_on = 0;
2971 return strlen(pbuf);
2972 } else if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
2973 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2974 "0571 nvmeio_trc_on\n");
2975 phba->nvmeio_trc_output_idx = 0;
2976 phba->nvmeio_trc_on = 1;
2977 return strlen(pbuf);
2978 }
2979
2980
2981 if (phba->nvmeio_trc_on != 0)
2982 return -EINVAL;
2983
2984
2985 i = kstrtoul(pbuf, 0, &sz);
2986 if (i)
2987 return -EINVAL;
2988 phba->nvmeio_trc_size = (uint32_t)sz;
2989
2990
2991 i = 0;
2992 while (sz > 1) {
2993 sz = sz >> 1;
2994 i++;
2995 }
2996 sz = (1 << i);
2997 if (phba->nvmeio_trc_size != sz)
2998 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2999 "0572 nvmeio_trc_size changed to %ld\n",
3000 sz);
3001 phba->nvmeio_trc_size = (uint32_t)sz;
3002
3003
3004 kfree(phba->nvmeio_trc);
3005
3006
3007 phba->nvmeio_trc = kzalloc((sizeof(struct lpfc_debugfs_nvmeio_trc) *
3008 sz), GFP_KERNEL);
3009 if (!phba->nvmeio_trc) {
3010 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
3011 "0573 Cannot create debugfs "
3012 "nvmeio_trc buffer\n");
3013 return -ENOMEM;
3014 }
3015 atomic_set(&phba->nvmeio_trc_cnt, 0);
3016 phba->nvmeio_trc_on = 0;
3017 phba->nvmeio_trc_output_idx = 0;
3018
3019 return strlen(pbuf);
3020 }
3021
3022 static int
3023 lpfc_debugfs_hdwqstat_open(struct inode *inode, struct file *file)
3024 {
3025 struct lpfc_vport *vport = inode->i_private;
3026 struct lpfc_debug *debug;
3027 int rc = -ENOMEM;
3028
3029 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
3030 if (!debug)
3031 goto out;
3032
3033
3034 debug->buffer = kcalloc(1, LPFC_SCSISTAT_SIZE, GFP_KERNEL);
3035 if (!debug->buffer) {
3036 kfree(debug);
3037 goto out;
3038 }
3039
3040 debug->len = lpfc_debugfs_hdwqstat_data(vport, debug->buffer,
3041 LPFC_SCSISTAT_SIZE);
3042
3043 debug->i_private = inode->i_private;
3044 file->private_data = debug;
3045
3046 rc = 0;
3047 out:
3048 return rc;
3049 }
3050
3051 static ssize_t
3052 lpfc_debugfs_hdwqstat_write(struct file *file, const char __user *buf,
3053 size_t nbytes, loff_t *ppos)
3054 {
3055 struct lpfc_debug *debug = file->private_data;
3056 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private;
3057 struct lpfc_hba *phba = vport->phba;
3058 struct lpfc_hdwq_stat *c_stat;
3059 char mybuf[64];
3060 char *pbuf;
3061 int i;
3062
3063 if (nbytes > sizeof(mybuf) - 1)
3064 nbytes = sizeof(mybuf) - 1;
3065
3066 memset(mybuf, 0, sizeof(mybuf));
3067
3068 if (copy_from_user(mybuf, buf, nbytes))
3069 return -EFAULT;
3070 pbuf = &mybuf[0];
3071
3072 if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) {
3073 if (phba->nvmet_support)
3074 phba->hdwqstat_on |= LPFC_CHECK_NVMET_IO;
3075 else
3076 phba->hdwqstat_on |= (LPFC_CHECK_NVME_IO |
3077 LPFC_CHECK_SCSI_IO);
3078 return strlen(pbuf);
3079 } else if ((strncmp(pbuf, "nvme_on", sizeof("nvme_on") - 1) == 0)) {
3080 if (phba->nvmet_support)
3081 phba->hdwqstat_on |= LPFC_CHECK_NVMET_IO;
3082 else
3083 phba->hdwqstat_on |= LPFC_CHECK_NVME_IO;
3084 return strlen(pbuf);
3085 } else if ((strncmp(pbuf, "scsi_on", sizeof("scsi_on") - 1) == 0)) {
3086 if (!phba->nvmet_support)
3087 phba->hdwqstat_on |= LPFC_CHECK_SCSI_IO;
3088 return strlen(pbuf);
3089 } else if ((strncmp(pbuf, "nvme_off", sizeof("nvme_off") - 1) == 0)) {
3090 phba->hdwqstat_on &= ~(LPFC_CHECK_NVME_IO |
3091 LPFC_CHECK_NVMET_IO);
3092 return strlen(pbuf);
3093 } else if ((strncmp(pbuf, "scsi_off", sizeof("scsi_off") - 1) == 0)) {
3094 phba->hdwqstat_on &= ~LPFC_CHECK_SCSI_IO;
3095 return strlen(pbuf);
3096 } else if ((strncmp(pbuf, "off",
3097 sizeof("off") - 1) == 0)) {
3098 phba->hdwqstat_on = LPFC_CHECK_OFF;
3099 return strlen(pbuf);
3100 } else if ((strncmp(pbuf, "zero",
3101 sizeof("zero") - 1) == 0)) {
3102 for_each_present_cpu(i) {
3103 c_stat = per_cpu_ptr(phba->sli4_hba.c_stat, i);
3104 c_stat->xmt_io = 0;
3105 c_stat->cmpl_io = 0;
3106 c_stat->rcv_io = 0;
3107 }
3108 return strlen(pbuf);
3109 }
3110 return -EINVAL;
3111 }
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137 static int lpfc_idiag_cmd_get(const char __user *buf, size_t nbytes,
3138 struct lpfc_idiag_cmd *idiag_cmd)
3139 {
3140 char mybuf[64];
3141 char *pbuf, *step_str;
3142 int i;
3143 size_t bsize;
3144
3145 memset(mybuf, 0, sizeof(mybuf));
3146 memset(idiag_cmd, 0, sizeof(*idiag_cmd));
3147 bsize = min(nbytes, (sizeof(mybuf)-1));
3148
3149 if (copy_from_user(mybuf, buf, bsize))
3150 return -EFAULT;
3151 pbuf = &mybuf[0];
3152 step_str = strsep(&pbuf, "\t ");
3153
3154
3155 if (!step_str)
3156 return -EINVAL;
3157
3158 idiag_cmd->opcode = simple_strtol(step_str, NULL, 0);
3159 if (idiag_cmd->opcode == 0)
3160 return -EINVAL;
3161
3162 for (i = 0; i < LPFC_IDIAG_CMD_DATA_SIZE; i++) {
3163 step_str = strsep(&pbuf, "\t ");
3164 if (!step_str)
3165 return i;
3166 idiag_cmd->data[i] = simple_strtol(step_str, NULL, 0);
3167 }
3168 return i;
3169 }
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188 static int
3189 lpfc_idiag_open(struct inode *inode, struct file *file)
3190 {
3191 struct lpfc_debug *debug;
3192
3193 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
3194 if (!debug)
3195 return -ENOMEM;
3196
3197 debug->i_private = inode->i_private;
3198 debug->buffer = NULL;
3199 file->private_data = debug;
3200
3201 return 0;
3202 }
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217 static int
3218 lpfc_idiag_release(struct inode *inode, struct file *file)
3219 {
3220 struct lpfc_debug *debug = file->private_data;
3221
3222
3223 kfree(debug->buffer);
3224 kfree(debug);
3225
3226 return 0;
3227 }
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242 static int
3243 lpfc_idiag_cmd_release(struct inode *inode, struct file *file)
3244 {
3245 struct lpfc_debug *debug = file->private_data;
3246
3247 if (debug->op == LPFC_IDIAG_OP_WR) {
3248 switch (idiag.cmd.opcode) {
3249 case LPFC_IDIAG_CMD_PCICFG_WR:
3250 case LPFC_IDIAG_CMD_PCICFG_ST:
3251 case LPFC_IDIAG_CMD_PCICFG_CL:
3252 case LPFC_IDIAG_CMD_QUEACC_WR:
3253 case LPFC_IDIAG_CMD_QUEACC_ST:
3254 case LPFC_IDIAG_CMD_QUEACC_CL:
3255 memset(&idiag, 0, sizeof(idiag));
3256 break;
3257 default:
3258 break;
3259 }
3260 }
3261
3262
3263 kfree(debug->buffer);
3264 kfree(debug);
3265
3266 return 0;
3267 }
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287 static ssize_t
3288 lpfc_idiag_pcicfg_read(struct file *file, char __user *buf, size_t nbytes,
3289 loff_t *ppos)
3290 {
3291 struct lpfc_debug *debug = file->private_data;
3292 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3293 int offset_label, offset, len = 0, index = LPFC_PCI_CFG_RD_SIZE;
3294 int where, count;
3295 char *pbuffer;
3296 struct pci_dev *pdev;
3297 uint32_t u32val;
3298 uint16_t u16val;
3299 uint8_t u8val;
3300
3301 pdev = phba->pcidev;
3302 if (!pdev)
3303 return 0;
3304
3305
3306 debug->op = LPFC_IDIAG_OP_RD;
3307
3308 if (!debug->buffer)
3309 debug->buffer = kmalloc(LPFC_PCI_CFG_SIZE, GFP_KERNEL);
3310 if (!debug->buffer)
3311 return 0;
3312 pbuffer = debug->buffer;
3313
3314 if (*ppos)
3315 return 0;
3316
3317 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
3318 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
3319 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
3320 } else
3321 return 0;
3322
3323
3324 switch (count) {
3325 case SIZE_U8:
3326 pci_read_config_byte(pdev, where, &u8val);
3327 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3328 "%03x: %02x\n", where, u8val);
3329 break;
3330 case SIZE_U16:
3331 pci_read_config_word(pdev, where, &u16val);
3332 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3333 "%03x: %04x\n", where, u16val);
3334 break;
3335 case SIZE_U32:
3336 pci_read_config_dword(pdev, where, &u32val);
3337 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3338 "%03x: %08x\n", where, u32val);
3339 break;
3340 case LPFC_PCI_CFG_BROWSE:
3341 goto pcicfg_browse;
3342 default:
3343
3344 len = 0;
3345 break;
3346 }
3347 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3348
3349 pcicfg_browse:
3350
3351
3352 offset_label = idiag.offset.last_rd;
3353 offset = offset_label;
3354
3355
3356 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3357 "%03x: ", offset_label);
3358 while (index > 0) {
3359 pci_read_config_dword(pdev, offset, &u32val);
3360 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3361 "%08x ", u32val);
3362 offset += sizeof(uint32_t);
3363 if (offset >= LPFC_PCI_CFG_SIZE) {
3364 len += scnprintf(pbuffer+len,
3365 LPFC_PCI_CFG_SIZE-len, "\n");
3366 break;
3367 }
3368 index -= sizeof(uint32_t);
3369 if (!index)
3370 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3371 "\n");
3372 else if (!(index % (8 * sizeof(uint32_t)))) {
3373 offset_label += (8 * sizeof(uint32_t));
3374 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
3375 "\n%03x: ", offset_label);
3376 }
3377 }
3378
3379
3380 if (index == 0) {
3381 idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE;
3382 if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE)
3383 idiag.offset.last_rd = 0;
3384 } else
3385 idiag.offset.last_rd = 0;
3386
3387 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3388 }
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408 static ssize_t
3409 lpfc_idiag_pcicfg_write(struct file *file, const char __user *buf,
3410 size_t nbytes, loff_t *ppos)
3411 {
3412 struct lpfc_debug *debug = file->private_data;
3413 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3414 uint32_t where, value, count;
3415 uint32_t u32val;
3416 uint16_t u16val;
3417 uint8_t u8val;
3418 struct pci_dev *pdev;
3419 int rc;
3420
3421 pdev = phba->pcidev;
3422 if (!pdev)
3423 return -EFAULT;
3424
3425
3426 debug->op = LPFC_IDIAG_OP_WR;
3427
3428 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3429 if (rc < 0)
3430 return rc;
3431
3432 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
3433
3434 if (rc != LPFC_PCI_CFG_RD_CMD_ARG)
3435 goto error_out;
3436
3437 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
3438 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
3439 if (count == LPFC_PCI_CFG_BROWSE) {
3440 if (where % sizeof(uint32_t))
3441 goto error_out;
3442
3443 idiag.offset.last_rd = where;
3444 } else if ((count != sizeof(uint8_t)) &&
3445 (count != sizeof(uint16_t)) &&
3446 (count != sizeof(uint32_t)))
3447 goto error_out;
3448 if (count == sizeof(uint8_t)) {
3449 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
3450 goto error_out;
3451 if (where % sizeof(uint8_t))
3452 goto error_out;
3453 }
3454 if (count == sizeof(uint16_t)) {
3455 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
3456 goto error_out;
3457 if (where % sizeof(uint16_t))
3458 goto error_out;
3459 }
3460 if (count == sizeof(uint32_t)) {
3461 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
3462 goto error_out;
3463 if (where % sizeof(uint32_t))
3464 goto error_out;
3465 }
3466 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR ||
3467 idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST ||
3468 idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3469
3470 if (rc != LPFC_PCI_CFG_WR_CMD_ARG)
3471 goto error_out;
3472
3473 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
3474 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
3475 value = idiag.cmd.data[IDIAG_PCICFG_VALUE_INDX];
3476
3477 if ((count != sizeof(uint8_t)) &&
3478 (count != sizeof(uint16_t)) &&
3479 (count != sizeof(uint32_t)))
3480 goto error_out;
3481 if (count == sizeof(uint8_t)) {
3482 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
3483 goto error_out;
3484 if (where % sizeof(uint8_t))
3485 goto error_out;
3486 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
3487 pci_write_config_byte(pdev, where,
3488 (uint8_t)value);
3489 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
3490 rc = pci_read_config_byte(pdev, where, &u8val);
3491 if (!rc) {
3492 u8val |= (uint8_t)value;
3493 pci_write_config_byte(pdev, where,
3494 u8val);
3495 }
3496 }
3497 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3498 rc = pci_read_config_byte(pdev, where, &u8val);
3499 if (!rc) {
3500 u8val &= (uint8_t)(~value);
3501 pci_write_config_byte(pdev, where,
3502 u8val);
3503 }
3504 }
3505 }
3506 if (count == sizeof(uint16_t)) {
3507 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
3508 goto error_out;
3509 if (where % sizeof(uint16_t))
3510 goto error_out;
3511 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
3512 pci_write_config_word(pdev, where,
3513 (uint16_t)value);
3514 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
3515 rc = pci_read_config_word(pdev, where, &u16val);
3516 if (!rc) {
3517 u16val |= (uint16_t)value;
3518 pci_write_config_word(pdev, where,
3519 u16val);
3520 }
3521 }
3522 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3523 rc = pci_read_config_word(pdev, where, &u16val);
3524 if (!rc) {
3525 u16val &= (uint16_t)(~value);
3526 pci_write_config_word(pdev, where,
3527 u16val);
3528 }
3529 }
3530 }
3531 if (count == sizeof(uint32_t)) {
3532 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
3533 goto error_out;
3534 if (where % sizeof(uint32_t))
3535 goto error_out;
3536 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
3537 pci_write_config_dword(pdev, where, value);
3538 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
3539 rc = pci_read_config_dword(pdev, where,
3540 &u32val);
3541 if (!rc) {
3542 u32val |= value;
3543 pci_write_config_dword(pdev, where,
3544 u32val);
3545 }
3546 }
3547 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
3548 rc = pci_read_config_dword(pdev, where,
3549 &u32val);
3550 if (!rc) {
3551 u32val &= ~value;
3552 pci_write_config_dword(pdev, where,
3553 u32val);
3554 }
3555 }
3556 }
3557 } else
3558
3559 goto error_out;
3560
3561 return nbytes;
3562 error_out:
3563 memset(&idiag, 0, sizeof(idiag));
3564 return -EINVAL;
3565 }
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582 static ssize_t
3583 lpfc_idiag_baracc_read(struct file *file, char __user *buf, size_t nbytes,
3584 loff_t *ppos)
3585 {
3586 struct lpfc_debug *debug = file->private_data;
3587 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3588 int offset_label, offset, offset_run, len = 0, index;
3589 int bar_num, acc_range, bar_size;
3590 char *pbuffer;
3591 void __iomem *mem_mapped_bar;
3592 uint32_t if_type;
3593 struct pci_dev *pdev;
3594 uint32_t u32val;
3595
3596 pdev = phba->pcidev;
3597 if (!pdev)
3598 return 0;
3599
3600
3601 debug->op = LPFC_IDIAG_OP_RD;
3602
3603 if (!debug->buffer)
3604 debug->buffer = kmalloc(LPFC_PCI_BAR_RD_BUF_SIZE, GFP_KERNEL);
3605 if (!debug->buffer)
3606 return 0;
3607 pbuffer = debug->buffer;
3608
3609 if (*ppos)
3610 return 0;
3611
3612 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
3613 bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
3614 offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
3615 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
3616 bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
3617 } else
3618 return 0;
3619
3620 if (acc_range == 0)
3621 return 0;
3622
3623 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
3624 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
3625 if (bar_num == IDIAG_BARACC_BAR_0)
3626 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3627 else if (bar_num == IDIAG_BARACC_BAR_1)
3628 mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
3629 else if (bar_num == IDIAG_BARACC_BAR_2)
3630 mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
3631 else
3632 return 0;
3633 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
3634 if (bar_num == IDIAG_BARACC_BAR_0)
3635 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3636 else
3637 return 0;
3638 } else
3639 return 0;
3640
3641
3642 if (acc_range == SINGLE_WORD) {
3643 offset_run = offset;
3644 u32val = readl(mem_mapped_bar + offset_run);
3645 len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
3646 "%05x: %08x\n", offset_run, u32val);
3647 } else
3648 goto baracc_browse;
3649
3650 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3651
3652 baracc_browse:
3653
3654
3655 offset_label = idiag.offset.last_rd;
3656 offset_run = offset_label;
3657
3658
3659 len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
3660 "%05x: ", offset_label);
3661 index = LPFC_PCI_BAR_RD_SIZE;
3662 while (index > 0) {
3663 u32val = readl(mem_mapped_bar + offset_run);
3664 len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
3665 "%08x ", u32val);
3666 offset_run += sizeof(uint32_t);
3667 if (acc_range == LPFC_PCI_BAR_BROWSE) {
3668 if (offset_run >= bar_size) {
3669 len += scnprintf(pbuffer+len,
3670 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
3671 break;
3672 }
3673 } else {
3674 if (offset_run >= offset +
3675 (acc_range * sizeof(uint32_t))) {
3676 len += scnprintf(pbuffer+len,
3677 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
3678 break;
3679 }
3680 }
3681 index -= sizeof(uint32_t);
3682 if (!index)
3683 len += scnprintf(pbuffer+len,
3684 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
3685 else if (!(index % (8 * sizeof(uint32_t)))) {
3686 offset_label += (8 * sizeof(uint32_t));
3687 len += scnprintf(pbuffer+len,
3688 LPFC_PCI_BAR_RD_BUF_SIZE-len,
3689 "\n%05x: ", offset_label);
3690 }
3691 }
3692
3693
3694 if (index == 0) {
3695 idiag.offset.last_rd += LPFC_PCI_BAR_RD_SIZE;
3696 if (acc_range == LPFC_PCI_BAR_BROWSE) {
3697 if (idiag.offset.last_rd >= bar_size)
3698 idiag.offset.last_rd = 0;
3699 } else {
3700 if (offset_run >= offset +
3701 (acc_range * sizeof(uint32_t)))
3702 idiag.offset.last_rd = offset;
3703 }
3704 } else {
3705 if (acc_range == LPFC_PCI_BAR_BROWSE)
3706 idiag.offset.last_rd = 0;
3707 else
3708 idiag.offset.last_rd = offset;
3709 }
3710
3711 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3712 }
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733 static ssize_t
3734 lpfc_idiag_baracc_write(struct file *file, const char __user *buf,
3735 size_t nbytes, loff_t *ppos)
3736 {
3737 struct lpfc_debug *debug = file->private_data;
3738 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3739 uint32_t bar_num, bar_size, offset, value, acc_range;
3740 struct pci_dev *pdev;
3741 void __iomem *mem_mapped_bar;
3742 uint32_t if_type;
3743 uint32_t u32val;
3744 int rc;
3745
3746 pdev = phba->pcidev;
3747 if (!pdev)
3748 return -EFAULT;
3749
3750
3751 debug->op = LPFC_IDIAG_OP_WR;
3752
3753 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3754 if (rc < 0)
3755 return rc;
3756
3757 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
3758 bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
3759
3760 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
3761 if ((bar_num != IDIAG_BARACC_BAR_0) &&
3762 (bar_num != IDIAG_BARACC_BAR_1) &&
3763 (bar_num != IDIAG_BARACC_BAR_2))
3764 goto error_out;
3765 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
3766 if (bar_num != IDIAG_BARACC_BAR_0)
3767 goto error_out;
3768 } else
3769 goto error_out;
3770
3771 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
3772 if (bar_num == IDIAG_BARACC_BAR_0) {
3773 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3774 LPFC_PCI_IF0_BAR0_SIZE;
3775 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3776 } else if (bar_num == IDIAG_BARACC_BAR_1) {
3777 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3778 LPFC_PCI_IF0_BAR1_SIZE;
3779 mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
3780 } else if (bar_num == IDIAG_BARACC_BAR_2) {
3781 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3782 LPFC_PCI_IF0_BAR2_SIZE;
3783 mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
3784 } else
3785 goto error_out;
3786 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
3787 if (bar_num == IDIAG_BARACC_BAR_0) {
3788 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
3789 LPFC_PCI_IF2_BAR0_SIZE;
3790 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
3791 } else
3792 goto error_out;
3793 } else
3794 goto error_out;
3795
3796 offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
3797 if (offset % sizeof(uint32_t))
3798 goto error_out;
3799
3800 bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
3801 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
3802
3803 if (rc != LPFC_PCI_BAR_RD_CMD_ARG)
3804 goto error_out;
3805 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
3806 if (acc_range == LPFC_PCI_BAR_BROWSE) {
3807 if (offset > bar_size - sizeof(uint32_t))
3808 goto error_out;
3809
3810 idiag.offset.last_rd = offset;
3811 } else if (acc_range > SINGLE_WORD) {
3812 if (offset + acc_range * sizeof(uint32_t) > bar_size)
3813 goto error_out;
3814
3815 idiag.offset.last_rd = offset;
3816 } else if (acc_range != SINGLE_WORD)
3817 goto error_out;
3818 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR ||
3819 idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST ||
3820 idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
3821
3822 if (rc != LPFC_PCI_BAR_WR_CMD_ARG)
3823 goto error_out;
3824
3825 acc_range = SINGLE_WORD;
3826 value = idiag.cmd.data[IDIAG_BARACC_REG_VAL_INDX];
3827 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR) {
3828 writel(value, mem_mapped_bar + offset);
3829 readl(mem_mapped_bar + offset);
3830 }
3831 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST) {
3832 u32val = readl(mem_mapped_bar + offset);
3833 u32val |= value;
3834 writel(u32val, mem_mapped_bar + offset);
3835 readl(mem_mapped_bar + offset);
3836 }
3837 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
3838 u32val = readl(mem_mapped_bar + offset);
3839 u32val &= ~value;
3840 writel(u32val, mem_mapped_bar + offset);
3841 readl(mem_mapped_bar + offset);
3842 }
3843 } else
3844
3845 goto error_out;
3846
3847 return nbytes;
3848 error_out:
3849 memset(&idiag, 0, sizeof(idiag));
3850 return -EINVAL;
3851 }
3852
3853 static int
3854 __lpfc_idiag_print_wq(struct lpfc_queue *qp, char *wqtype,
3855 char *pbuffer, int len)
3856 {
3857 if (!qp)
3858 return len;
3859
3860 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3861 "\t\t%s WQ info: ", wqtype);
3862 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3863 "AssocCQID[%04d]: WQ-STAT[oflow:x%x posted:x%llx]\n",
3864 qp->assoc_qid, qp->q_cnt_1,
3865 (unsigned long long)qp->q_cnt_4);
3866 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3867 "\t\tWQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3868 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]",
3869 qp->queue_id, qp->entry_count,
3870 qp->entry_size, qp->host_index,
3871 qp->hba_index, qp->notify_interval);
3872 len += scnprintf(pbuffer + len,
3873 LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n");
3874 return len;
3875 }
3876
3877 static int
3878 lpfc_idiag_wqs_for_cq(struct lpfc_hba *phba, char *wqtype, char *pbuffer,
3879 int *len, int max_cnt, int cq_id)
3880 {
3881 struct lpfc_queue *qp;
3882 int qidx;
3883
3884 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
3885 qp = phba->sli4_hba.hdwq[qidx].io_wq;
3886 if (qp->assoc_qid != cq_id)
3887 continue;
3888 *len = __lpfc_idiag_print_wq(qp, wqtype, pbuffer, *len);
3889 if (*len >= max_cnt)
3890 return 1;
3891 }
3892 return 0;
3893 }
3894
3895 static int
3896 __lpfc_idiag_print_cq(struct lpfc_queue *qp, char *cqtype,
3897 char *pbuffer, int len)
3898 {
3899 if (!qp)
3900 return len;
3901
3902 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3903 "\t%s CQ info: ", cqtype);
3904 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3905 "AssocEQID[%02d]: CQ STAT[max:x%x relw:x%x "
3906 "xabt:x%x wq:x%llx]\n",
3907 qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2,
3908 qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
3909 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3910 "\tCQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3911 "HST-IDX[%04d], NTFI[%03d], PLMT[%03d]",
3912 qp->queue_id, qp->entry_count,
3913 qp->entry_size, qp->host_index,
3914 qp->notify_interval, qp->max_proc_limit);
3915
3916 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3917 "\n");
3918
3919 return len;
3920 }
3921
3922 static int
3923 __lpfc_idiag_print_rqpair(struct lpfc_queue *qp, struct lpfc_queue *datqp,
3924 char *rqtype, char *pbuffer, int len)
3925 {
3926 if (!qp || !datqp)
3927 return len;
3928
3929 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3930 "\t\t%s RQ info: ", rqtype);
3931 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3932 "AssocCQID[%02d]: RQ-STAT[nopost:x%x nobuf:x%x "
3933 "posted:x%x rcv:x%llx]\n",
3934 qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2,
3935 qp->q_cnt_3, (unsigned long long)qp->q_cnt_4);
3936 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3937 "\t\tHQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3938 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n",
3939 qp->queue_id, qp->entry_count, qp->entry_size,
3940 qp->host_index, qp->hba_index, qp->notify_interval);
3941 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
3942 "\t\tDQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
3943 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n",
3944 datqp->queue_id, datqp->entry_count,
3945 datqp->entry_size, datqp->host_index,
3946 datqp->hba_index, datqp->notify_interval);
3947 return len;
3948 }
3949
3950 static int
3951 lpfc_idiag_cqs_for_eq(struct lpfc_hba *phba, char *pbuffer,
3952 int *len, int max_cnt, int eqidx, int eq_id)
3953 {
3954 struct lpfc_queue *qp;
3955 int rc;
3956
3957 qp = phba->sli4_hba.hdwq[eqidx].io_cq;
3958
3959 *len = __lpfc_idiag_print_cq(qp, "IO", pbuffer, *len);
3960
3961
3962 qp->CQ_max_cqe = 0;
3963
3964 if (*len >= max_cnt)
3965 return 1;
3966
3967 rc = lpfc_idiag_wqs_for_cq(phba, "IO", pbuffer, len,
3968 max_cnt, qp->queue_id);
3969 if (rc)
3970 return 1;
3971
3972 if ((eqidx < phba->cfg_nvmet_mrq) && phba->nvmet_support) {
3973
3974 qp = phba->sli4_hba.nvmet_cqset[eqidx];
3975 *len = __lpfc_idiag_print_cq(qp, "NVMET CQset", pbuffer, *len);
3976
3977
3978 qp->CQ_max_cqe = 0;
3979
3980 if (*len >= max_cnt)
3981 return 1;
3982
3983
3984 qp = phba->sli4_hba.nvmet_mrq_hdr[eqidx];
3985 *len = __lpfc_idiag_print_rqpair(qp,
3986 phba->sli4_hba.nvmet_mrq_data[eqidx],
3987 "NVMET MRQ", pbuffer, *len);
3988
3989 if (*len >= max_cnt)
3990 return 1;
3991 }
3992
3993 return 0;
3994 }
3995
3996 static int
3997 __lpfc_idiag_print_eq(struct lpfc_queue *qp, char *eqtype,
3998 char *pbuffer, int len)
3999 {
4000 if (!qp)
4001 return len;
4002
4003 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
4004 "\n%s EQ info: EQ-STAT[max:x%x noE:x%x "
4005 "cqe_proc:x%x eqe_proc:x%llx eqd %d]\n",
4006 eqtype, qp->q_cnt_1, qp->q_cnt_2, qp->q_cnt_3,
4007 (unsigned long long)qp->q_cnt_4, qp->q_mode);
4008 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
4009 "EQID[%02d], QE-CNT[%04d], QE-SZ[%04d], "
4010 "HST-IDX[%04d], NTFI[%03d], PLMT[%03d], AFFIN[%03d]",
4011 qp->queue_id, qp->entry_count, qp->entry_size,
4012 qp->host_index, qp->notify_interval,
4013 qp->max_proc_limit, qp->chann);
4014 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len,
4015 "\n");
4016
4017 return len;
4018 }
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038 static ssize_t
4039 lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
4040 loff_t *ppos)
4041 {
4042 struct lpfc_debug *debug = file->private_data;
4043 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4044 char *pbuffer;
4045 int max_cnt, rc, x, len = 0;
4046 struct lpfc_queue *qp = NULL;
4047
4048 if (!debug->buffer)
4049 debug->buffer = kmalloc(LPFC_QUE_INFO_GET_BUF_SIZE, GFP_KERNEL);
4050 if (!debug->buffer)
4051 return 0;
4052 pbuffer = debug->buffer;
4053 max_cnt = LPFC_QUE_INFO_GET_BUF_SIZE - 256;
4054
4055 if (*ppos)
4056 return 0;
4057
4058 spin_lock_irq(&phba->hbalock);
4059
4060
4061 if (phba->sli4_hba.hdwq && phba->cfg_hdw_queue) {
4062
4063 x = phba->lpfc_idiag_last_eq;
4064 phba->lpfc_idiag_last_eq++;
4065 if (phba->lpfc_idiag_last_eq >= phba->cfg_hdw_queue)
4066 phba->lpfc_idiag_last_eq = 0;
4067
4068 len += scnprintf(pbuffer + len,
4069 LPFC_QUE_INFO_GET_BUF_SIZE - len,
4070 "HDWQ %d out of %d HBA HDWQs\n",
4071 x, phba->cfg_hdw_queue);
4072
4073
4074 qp = phba->sli4_hba.hdwq[x].hba_eq;
4075 if (!qp)
4076 goto out;
4077
4078 len = __lpfc_idiag_print_eq(qp, "HBA", pbuffer, len);
4079
4080
4081 qp->EQ_max_eqe = 0;
4082
4083 if (len >= max_cnt)
4084 goto too_big;
4085
4086
4087 rc = lpfc_idiag_cqs_for_eq(phba, pbuffer, &len,
4088 max_cnt, x, qp->queue_id);
4089 if (rc)
4090 goto too_big;
4091
4092
4093 if (x)
4094 goto out;
4095
4096
4097 qp = phba->sli4_hba.mbx_cq;
4098 len = __lpfc_idiag_print_cq(qp, "MBX", pbuffer, len);
4099 if (len >= max_cnt)
4100 goto too_big;
4101
4102
4103 qp = phba->sli4_hba.mbx_wq;
4104 len = __lpfc_idiag_print_wq(qp, "MBX", pbuffer, len);
4105 if (len >= max_cnt)
4106 goto too_big;
4107
4108
4109 qp = phba->sli4_hba.els_cq;
4110 len = __lpfc_idiag_print_cq(qp, "ELS", pbuffer, len);
4111
4112 if (qp)
4113 qp->CQ_max_cqe = 0;
4114 if (len >= max_cnt)
4115 goto too_big;
4116
4117
4118 qp = phba->sli4_hba.els_wq;
4119 len = __lpfc_idiag_print_wq(qp, "ELS", pbuffer, len);
4120 if (len >= max_cnt)
4121 goto too_big;
4122
4123 qp = phba->sli4_hba.hdr_rq;
4124 len = __lpfc_idiag_print_rqpair(qp, phba->sli4_hba.dat_rq,
4125 "ELS RQpair", pbuffer, len);
4126 if (len >= max_cnt)
4127 goto too_big;
4128
4129
4130 qp = phba->sli4_hba.nvmels_cq;
4131 len = __lpfc_idiag_print_cq(qp, "NVME LS",
4132 pbuffer, len);
4133
4134 if (qp)
4135 qp->CQ_max_cqe = 0;
4136 if (len >= max_cnt)
4137 goto too_big;
4138
4139
4140 qp = phba->sli4_hba.nvmels_wq;
4141 len = __lpfc_idiag_print_wq(qp, "NVME LS",
4142 pbuffer, len);
4143 if (len >= max_cnt)
4144 goto too_big;
4145
4146 goto out;
4147 }
4148
4149 spin_unlock_irq(&phba->hbalock);
4150 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4151
4152 too_big:
4153 len += scnprintf(pbuffer + len,
4154 LPFC_QUE_INFO_GET_BUF_SIZE - len, "Truncated ...\n");
4155 out:
4156 spin_unlock_irq(&phba->hbalock);
4157 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4158 }
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173 static int
4174 lpfc_idiag_que_param_check(struct lpfc_queue *q, int index, int count)
4175 {
4176
4177 if ((count != 1) && (count != LPFC_QUE_ACC_BROWSE))
4178 return -EINVAL;
4179 if (index > q->entry_count - 1)
4180 return -EINVAL;
4181 return 0;
4182 }
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199 static int
4200 lpfc_idiag_queacc_read_qe(char *pbuffer, int len, struct lpfc_queue *pque,
4201 uint32_t index)
4202 {
4203 int offset, esize;
4204 uint32_t *pentry;
4205
4206 if (!pbuffer || !pque)
4207 return 0;
4208
4209 esize = pque->entry_size;
4210 len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
4211 "QE-INDEX[%04d]:\n", index);
4212
4213 offset = 0;
4214 pentry = lpfc_sli4_qe(pque, index);
4215 while (esize > 0) {
4216 len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
4217 "%08x ", *pentry);
4218 pentry++;
4219 offset += sizeof(uint32_t);
4220 esize -= sizeof(uint32_t);
4221 if (esize > 0 && !(offset % (4 * sizeof(uint32_t))))
4222 len += scnprintf(pbuffer+len,
4223 LPFC_QUE_ACC_BUF_SIZE-len, "\n");
4224 }
4225 len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, "\n");
4226
4227 return len;
4228 }
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247 static ssize_t
4248 lpfc_idiag_queacc_read(struct file *file, char __user *buf, size_t nbytes,
4249 loff_t *ppos)
4250 {
4251 struct lpfc_debug *debug = file->private_data;
4252 uint32_t last_index, index, count;
4253 struct lpfc_queue *pque = NULL;
4254 char *pbuffer;
4255 int len = 0;
4256
4257
4258 debug->op = LPFC_IDIAG_OP_RD;
4259
4260 if (!debug->buffer)
4261 debug->buffer = kmalloc(LPFC_QUE_ACC_BUF_SIZE, GFP_KERNEL);
4262 if (!debug->buffer)
4263 return 0;
4264 pbuffer = debug->buffer;
4265
4266 if (*ppos)
4267 return 0;
4268
4269 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
4270 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
4271 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
4272 pque = (struct lpfc_queue *)idiag.ptr_private;
4273 } else
4274 return 0;
4275
4276
4277 if (count == LPFC_QUE_ACC_BROWSE)
4278 goto que_browse;
4279
4280
4281 len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
4282
4283 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4284
4285 que_browse:
4286
4287
4288 last_index = idiag.offset.last_rd;
4289 index = last_index;
4290
4291 while (len < LPFC_QUE_ACC_SIZE - pque->entry_size) {
4292 len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
4293 index++;
4294 if (index > pque->entry_count - 1)
4295 break;
4296 }
4297
4298
4299 if (index > pque->entry_count - 1)
4300 index = 0;
4301 idiag.offset.last_rd = index;
4302
4303 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4304 }
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324 static ssize_t
4325 lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
4326 size_t nbytes, loff_t *ppos)
4327 {
4328 struct lpfc_debug *debug = file->private_data;
4329 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4330 uint32_t qidx, quetp, queid, index, count, offset, value;
4331 uint32_t *pentry;
4332 struct lpfc_queue *pque, *qp;
4333 int rc;
4334
4335
4336 debug->op = LPFC_IDIAG_OP_WR;
4337
4338 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
4339 if (rc < 0)
4340 return rc;
4341
4342
4343 quetp = idiag.cmd.data[IDIAG_QUEACC_QUETP_INDX];
4344 queid = idiag.cmd.data[IDIAG_QUEACC_QUEID_INDX];
4345 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
4346 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
4347 offset = idiag.cmd.data[IDIAG_QUEACC_OFFST_INDX];
4348 value = idiag.cmd.data[IDIAG_QUEACC_VALUE_INDX];
4349
4350
4351 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
4352 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
4353 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
4354 if (rc != LPFC_QUE_ACC_WR_CMD_ARG)
4355 goto error_out;
4356 if (count != 1)
4357 goto error_out;
4358 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
4359 if (rc != LPFC_QUE_ACC_RD_CMD_ARG)
4360 goto error_out;
4361 } else
4362 goto error_out;
4363
4364 switch (quetp) {
4365 case LPFC_IDIAG_EQ:
4366
4367 if (phba->sli4_hba.hdwq) {
4368 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
4369 qp = phba->sli4_hba.hdwq[qidx].hba_eq;
4370 if (qp && qp->queue_id == queid) {
4371
4372 rc = lpfc_idiag_que_param_check(qp,
4373 index, count);
4374 if (rc)
4375 goto error_out;
4376 idiag.ptr_private = qp;
4377 goto pass_check;
4378 }
4379 }
4380 }
4381 goto error_out;
4382
4383 case LPFC_IDIAG_CQ:
4384
4385 if (phba->sli4_hba.mbx_cq &&
4386 phba->sli4_hba.mbx_cq->queue_id == queid) {
4387
4388 rc = lpfc_idiag_que_param_check(
4389 phba->sli4_hba.mbx_cq, index, count);
4390 if (rc)
4391 goto error_out;
4392 idiag.ptr_private = phba->sli4_hba.mbx_cq;
4393 goto pass_check;
4394 }
4395
4396 if (phba->sli4_hba.els_cq &&
4397 phba->sli4_hba.els_cq->queue_id == queid) {
4398
4399 rc = lpfc_idiag_que_param_check(
4400 phba->sli4_hba.els_cq, index, count);
4401 if (rc)
4402 goto error_out;
4403 idiag.ptr_private = phba->sli4_hba.els_cq;
4404 goto pass_check;
4405 }
4406
4407 if (phba->sli4_hba.nvmels_cq &&
4408 phba->sli4_hba.nvmels_cq->queue_id == queid) {
4409
4410 rc = lpfc_idiag_que_param_check(
4411 phba->sli4_hba.nvmels_cq, index, count);
4412 if (rc)
4413 goto error_out;
4414 idiag.ptr_private = phba->sli4_hba.nvmels_cq;
4415 goto pass_check;
4416 }
4417
4418 if (phba->sli4_hba.hdwq) {
4419 for (qidx = 0; qidx < phba->cfg_hdw_queue;
4420 qidx++) {
4421 qp = phba->sli4_hba.hdwq[qidx].io_cq;
4422 if (qp && qp->queue_id == queid) {
4423
4424 rc = lpfc_idiag_que_param_check(
4425 qp, index, count);
4426 if (rc)
4427 goto error_out;
4428 idiag.ptr_private = qp;
4429 goto pass_check;
4430 }
4431 }
4432 }
4433 goto error_out;
4434
4435 case LPFC_IDIAG_MQ:
4436
4437 if (phba->sli4_hba.mbx_wq &&
4438 phba->sli4_hba.mbx_wq->queue_id == queid) {
4439
4440 rc = lpfc_idiag_que_param_check(
4441 phba->sli4_hba.mbx_wq, index, count);
4442 if (rc)
4443 goto error_out;
4444 idiag.ptr_private = phba->sli4_hba.mbx_wq;
4445 goto pass_check;
4446 }
4447 goto error_out;
4448
4449 case LPFC_IDIAG_WQ:
4450
4451 if (phba->sli4_hba.els_wq &&
4452 phba->sli4_hba.els_wq->queue_id == queid) {
4453
4454 rc = lpfc_idiag_que_param_check(
4455 phba->sli4_hba.els_wq, index, count);
4456 if (rc)
4457 goto error_out;
4458 idiag.ptr_private = phba->sli4_hba.els_wq;
4459 goto pass_check;
4460 }
4461
4462 if (phba->sli4_hba.nvmels_wq &&
4463 phba->sli4_hba.nvmels_wq->queue_id == queid) {
4464
4465 rc = lpfc_idiag_que_param_check(
4466 phba->sli4_hba.nvmels_wq, index, count);
4467 if (rc)
4468 goto error_out;
4469 idiag.ptr_private = phba->sli4_hba.nvmels_wq;
4470 goto pass_check;
4471 }
4472
4473 if (phba->sli4_hba.hdwq) {
4474
4475 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) {
4476 qp = phba->sli4_hba.hdwq[qidx].io_wq;
4477 if (qp && qp->queue_id == queid) {
4478
4479 rc = lpfc_idiag_que_param_check(
4480 qp, index, count);
4481 if (rc)
4482 goto error_out;
4483 idiag.ptr_private = qp;
4484 goto pass_check;
4485 }
4486 }
4487 }
4488 goto error_out;
4489
4490 case LPFC_IDIAG_RQ:
4491
4492 if (phba->sli4_hba.hdr_rq &&
4493 phba->sli4_hba.hdr_rq->queue_id == queid) {
4494
4495 rc = lpfc_idiag_que_param_check(
4496 phba->sli4_hba.hdr_rq, index, count);
4497 if (rc)
4498 goto error_out;
4499 idiag.ptr_private = phba->sli4_hba.hdr_rq;
4500 goto pass_check;
4501 }
4502
4503 if (phba->sli4_hba.dat_rq &&
4504 phba->sli4_hba.dat_rq->queue_id == queid) {
4505
4506 rc = lpfc_idiag_que_param_check(
4507 phba->sli4_hba.dat_rq, index, count);
4508 if (rc)
4509 goto error_out;
4510 idiag.ptr_private = phba->sli4_hba.dat_rq;
4511 goto pass_check;
4512 }
4513 goto error_out;
4514 default:
4515 goto error_out;
4516 }
4517
4518 pass_check:
4519
4520 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
4521 if (count == LPFC_QUE_ACC_BROWSE)
4522 idiag.offset.last_rd = index;
4523 }
4524
4525 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
4526 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
4527 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
4528
4529 pque = (struct lpfc_queue *)idiag.ptr_private;
4530 if (offset > pque->entry_size/sizeof(uint32_t) - 1)
4531 goto error_out;
4532 pentry = lpfc_sli4_qe(pque, index);
4533 pentry += offset;
4534 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR)
4535 *pentry = value;
4536 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST)
4537 *pentry |= value;
4538 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL)
4539 *pentry &= ~value;
4540 }
4541 return nbytes;
4542
4543 error_out:
4544
4545 memset(&idiag, 0, sizeof(idiag));
4546 return -EINVAL;
4547 }
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563 static int
4564 lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
4565 int len, uint32_t drbregid)
4566 {
4567
4568 if (!pbuffer)
4569 return 0;
4570
4571 switch (drbregid) {
4572 case LPFC_DRB_EQ:
4573 len += scnprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len,
4574 "EQ-DRB-REG: 0x%08x\n",
4575 readl(phba->sli4_hba.EQDBregaddr));
4576 break;
4577 case LPFC_DRB_CQ:
4578 len += scnprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len,
4579 "CQ-DRB-REG: 0x%08x\n",
4580 readl(phba->sli4_hba.CQDBregaddr));
4581 break;
4582 case LPFC_DRB_MQ:
4583 len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
4584 "MQ-DRB-REG: 0x%08x\n",
4585 readl(phba->sli4_hba.MQDBregaddr));
4586 break;
4587 case LPFC_DRB_WQ:
4588 len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
4589 "WQ-DRB-REG: 0x%08x\n",
4590 readl(phba->sli4_hba.WQDBregaddr));
4591 break;
4592 case LPFC_DRB_RQ:
4593 len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
4594 "RQ-DRB-REG: 0x%08x\n",
4595 readl(phba->sli4_hba.RQDBregaddr));
4596 break;
4597 default:
4598 break;
4599 }
4600
4601 return len;
4602 }
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621 static ssize_t
4622 lpfc_idiag_drbacc_read(struct file *file, char __user *buf, size_t nbytes,
4623 loff_t *ppos)
4624 {
4625 struct lpfc_debug *debug = file->private_data;
4626 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4627 uint32_t drb_reg_id, i;
4628 char *pbuffer;
4629 int len = 0;
4630
4631
4632 debug->op = LPFC_IDIAG_OP_RD;
4633
4634 if (!debug->buffer)
4635 debug->buffer = kmalloc(LPFC_DRB_ACC_BUF_SIZE, GFP_KERNEL);
4636 if (!debug->buffer)
4637 return 0;
4638 pbuffer = debug->buffer;
4639
4640 if (*ppos)
4641 return 0;
4642
4643 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD)
4644 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
4645 else
4646 return 0;
4647
4648 if (drb_reg_id == LPFC_DRB_ACC_ALL)
4649 for (i = 1; i <= LPFC_DRB_MAX; i++)
4650 len = lpfc_idiag_drbacc_read_reg(phba,
4651 pbuffer, len, i);
4652 else
4653 len = lpfc_idiag_drbacc_read_reg(phba,
4654 pbuffer, len, drb_reg_id);
4655
4656 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4657 }
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677 static ssize_t
4678 lpfc_idiag_drbacc_write(struct file *file, const char __user *buf,
4679 size_t nbytes, loff_t *ppos)
4680 {
4681 struct lpfc_debug *debug = file->private_data;
4682 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4683 uint32_t drb_reg_id, value, reg_val = 0;
4684 void __iomem *drb_reg;
4685 int rc;
4686
4687
4688 debug->op = LPFC_IDIAG_OP_WR;
4689
4690 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
4691 if (rc < 0)
4692 return rc;
4693
4694
4695 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
4696 value = idiag.cmd.data[IDIAG_DRBACC_VALUE_INDX];
4697
4698 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
4699 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
4700 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
4701 if (rc != LPFC_DRB_ACC_WR_CMD_ARG)
4702 goto error_out;
4703 if (drb_reg_id > LPFC_DRB_MAX)
4704 goto error_out;
4705 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD) {
4706 if (rc != LPFC_DRB_ACC_RD_CMD_ARG)
4707 goto error_out;
4708 if ((drb_reg_id > LPFC_DRB_MAX) &&
4709 (drb_reg_id != LPFC_DRB_ACC_ALL))
4710 goto error_out;
4711 } else
4712 goto error_out;
4713
4714
4715 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
4716 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
4717 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
4718 switch (drb_reg_id) {
4719 case LPFC_DRB_EQ:
4720 drb_reg = phba->sli4_hba.EQDBregaddr;
4721 break;
4722 case LPFC_DRB_CQ:
4723 drb_reg = phba->sli4_hba.CQDBregaddr;
4724 break;
4725 case LPFC_DRB_MQ:
4726 drb_reg = phba->sli4_hba.MQDBregaddr;
4727 break;
4728 case LPFC_DRB_WQ:
4729 drb_reg = phba->sli4_hba.WQDBregaddr;
4730 break;
4731 case LPFC_DRB_RQ:
4732 drb_reg = phba->sli4_hba.RQDBregaddr;
4733 break;
4734 default:
4735 goto error_out;
4736 }
4737
4738 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR)
4739 reg_val = value;
4740 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST) {
4741 reg_val = readl(drb_reg);
4742 reg_val |= value;
4743 }
4744 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
4745 reg_val = readl(drb_reg);
4746 reg_val &= ~value;
4747 }
4748 writel(reg_val, drb_reg);
4749 readl(drb_reg);
4750 }
4751 return nbytes;
4752
4753 error_out:
4754
4755 memset(&idiag, 0, sizeof(idiag));
4756 return -EINVAL;
4757 }
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773 static int
4774 lpfc_idiag_ctlacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
4775 int len, uint32_t ctlregid)
4776 {
4777
4778 if (!pbuffer)
4779 return 0;
4780
4781 switch (ctlregid) {
4782 case LPFC_CTL_PORT_SEM:
4783 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4784 "Port SemReg: 0x%08x\n",
4785 readl(phba->sli4_hba.conf_regs_memmap_p +
4786 LPFC_CTL_PORT_SEM_OFFSET));
4787 break;
4788 case LPFC_CTL_PORT_STA:
4789 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4790 "Port StaReg: 0x%08x\n",
4791 readl(phba->sli4_hba.conf_regs_memmap_p +
4792 LPFC_CTL_PORT_STA_OFFSET));
4793 break;
4794 case LPFC_CTL_PORT_CTL:
4795 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4796 "Port CtlReg: 0x%08x\n",
4797 readl(phba->sli4_hba.conf_regs_memmap_p +
4798 LPFC_CTL_PORT_CTL_OFFSET));
4799 break;
4800 case LPFC_CTL_PORT_ER1:
4801 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4802 "Port Er1Reg: 0x%08x\n",
4803 readl(phba->sli4_hba.conf_regs_memmap_p +
4804 LPFC_CTL_PORT_ER1_OFFSET));
4805 break;
4806 case LPFC_CTL_PORT_ER2:
4807 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4808 "Port Er2Reg: 0x%08x\n",
4809 readl(phba->sli4_hba.conf_regs_memmap_p +
4810 LPFC_CTL_PORT_ER2_OFFSET));
4811 break;
4812 case LPFC_CTL_PDEV_CTL:
4813 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
4814 "PDev CtlReg: 0x%08x\n",
4815 readl(phba->sli4_hba.conf_regs_memmap_p +
4816 LPFC_CTL_PDEV_CTL_OFFSET));
4817 break;
4818 default:
4819 break;
4820 }
4821 return len;
4822 }
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839 static ssize_t
4840 lpfc_idiag_ctlacc_read(struct file *file, char __user *buf, size_t nbytes,
4841 loff_t *ppos)
4842 {
4843 struct lpfc_debug *debug = file->private_data;
4844 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4845 uint32_t ctl_reg_id, i;
4846 char *pbuffer;
4847 int len = 0;
4848
4849
4850 debug->op = LPFC_IDIAG_OP_RD;
4851
4852 if (!debug->buffer)
4853 debug->buffer = kmalloc(LPFC_CTL_ACC_BUF_SIZE, GFP_KERNEL);
4854 if (!debug->buffer)
4855 return 0;
4856 pbuffer = debug->buffer;
4857
4858 if (*ppos)
4859 return 0;
4860
4861 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD)
4862 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
4863 else
4864 return 0;
4865
4866 if (ctl_reg_id == LPFC_CTL_ACC_ALL)
4867 for (i = 1; i <= LPFC_CTL_MAX; i++)
4868 len = lpfc_idiag_ctlacc_read_reg(phba,
4869 pbuffer, len, i);
4870 else
4871 len = lpfc_idiag_ctlacc_read_reg(phba,
4872 pbuffer, len, ctl_reg_id);
4873
4874 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
4875 }
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892 static ssize_t
4893 lpfc_idiag_ctlacc_write(struct file *file, const char __user *buf,
4894 size_t nbytes, loff_t *ppos)
4895 {
4896 struct lpfc_debug *debug = file->private_data;
4897 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
4898 uint32_t ctl_reg_id, value, reg_val = 0;
4899 void __iomem *ctl_reg;
4900 int rc;
4901
4902
4903 debug->op = LPFC_IDIAG_OP_WR;
4904
4905 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
4906 if (rc < 0)
4907 return rc;
4908
4909
4910 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
4911 value = idiag.cmd.data[IDIAG_CTLACC_VALUE_INDX];
4912
4913 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
4914 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
4915 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
4916 if (rc != LPFC_CTL_ACC_WR_CMD_ARG)
4917 goto error_out;
4918 if (ctl_reg_id > LPFC_CTL_MAX)
4919 goto error_out;
4920 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD) {
4921 if (rc != LPFC_CTL_ACC_RD_CMD_ARG)
4922 goto error_out;
4923 if ((ctl_reg_id > LPFC_CTL_MAX) &&
4924 (ctl_reg_id != LPFC_CTL_ACC_ALL))
4925 goto error_out;
4926 } else
4927 goto error_out;
4928
4929
4930 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
4931 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
4932 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
4933 switch (ctl_reg_id) {
4934 case LPFC_CTL_PORT_SEM:
4935 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4936 LPFC_CTL_PORT_SEM_OFFSET;
4937 break;
4938 case LPFC_CTL_PORT_STA:
4939 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4940 LPFC_CTL_PORT_STA_OFFSET;
4941 break;
4942 case LPFC_CTL_PORT_CTL:
4943 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4944 LPFC_CTL_PORT_CTL_OFFSET;
4945 break;
4946 case LPFC_CTL_PORT_ER1:
4947 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4948 LPFC_CTL_PORT_ER1_OFFSET;
4949 break;
4950 case LPFC_CTL_PORT_ER2:
4951 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4952 LPFC_CTL_PORT_ER2_OFFSET;
4953 break;
4954 case LPFC_CTL_PDEV_CTL:
4955 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
4956 LPFC_CTL_PDEV_CTL_OFFSET;
4957 break;
4958 default:
4959 goto error_out;
4960 }
4961
4962 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR)
4963 reg_val = value;
4964 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST) {
4965 reg_val = readl(ctl_reg);
4966 reg_val |= value;
4967 }
4968 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
4969 reg_val = readl(ctl_reg);
4970 reg_val &= ~value;
4971 }
4972 writel(reg_val, ctl_reg);
4973 readl(ctl_reg);
4974 }
4975 return nbytes;
4976
4977 error_out:
4978
4979 memset(&idiag, 0, sizeof(idiag));
4980 return -EINVAL;
4981 }
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995 static int
4996 lpfc_idiag_mbxacc_get_setup(struct lpfc_hba *phba, char *pbuffer)
4997 {
4998 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
4999 int len = 0;
5000
5001 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
5002 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
5003 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
5004 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
5005
5006 len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
5007 "mbx_dump_map: 0x%08x\n", mbx_dump_map);
5008 len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
5009 "mbx_dump_cnt: %04d\n", mbx_dump_cnt);
5010 len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
5011 "mbx_word_cnt: %04d\n", mbx_word_cnt);
5012 len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
5013 "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd);
5014
5015 return len;
5016 }
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033 static ssize_t
5034 lpfc_idiag_mbxacc_read(struct file *file, char __user *buf, size_t nbytes,
5035 loff_t *ppos)
5036 {
5037 struct lpfc_debug *debug = file->private_data;
5038 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
5039 char *pbuffer;
5040 int len = 0;
5041
5042
5043 debug->op = LPFC_IDIAG_OP_RD;
5044
5045 if (!debug->buffer)
5046 debug->buffer = kmalloc(LPFC_MBX_ACC_BUF_SIZE, GFP_KERNEL);
5047 if (!debug->buffer)
5048 return 0;
5049 pbuffer = debug->buffer;
5050
5051 if (*ppos)
5052 return 0;
5053
5054 if ((idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP) &&
5055 (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP))
5056 return 0;
5057
5058 len = lpfc_idiag_mbxacc_get_setup(phba, pbuffer);
5059
5060 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
5061 }
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078 static ssize_t
5079 lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf,
5080 size_t nbytes, loff_t *ppos)
5081 {
5082 struct lpfc_debug *debug = file->private_data;
5083 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
5084 int rc;
5085
5086
5087 debug->op = LPFC_IDIAG_OP_WR;
5088
5089 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
5090 if (rc < 0)
5091 return rc;
5092
5093
5094 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
5095 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
5096 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
5097 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
5098
5099 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_MBXACC_DP) {
5100 if (!(mbx_dump_map & LPFC_MBX_DMP_MBX_ALL))
5101 goto error_out;
5102 if ((mbx_dump_map & ~LPFC_MBX_DMP_MBX_ALL) &&
5103 (mbx_dump_map != LPFC_MBX_DMP_ALL))
5104 goto error_out;
5105 if (mbx_word_cnt > sizeof(MAILBOX_t))
5106 goto error_out;
5107 } else if (idiag.cmd.opcode == LPFC_IDIAG_BSG_MBXACC_DP) {
5108 if (!(mbx_dump_map & LPFC_BSG_DMP_MBX_ALL))
5109 goto error_out;
5110 if ((mbx_dump_map & ~LPFC_BSG_DMP_MBX_ALL) &&
5111 (mbx_dump_map != LPFC_MBX_DMP_ALL))
5112 goto error_out;
5113 if (mbx_word_cnt > (BSG_MBOX_SIZE)/4)
5114 goto error_out;
5115 if (mbx_mbox_cmd != 0x9b)
5116 goto error_out;
5117 } else
5118 goto error_out;
5119
5120 if (mbx_word_cnt == 0)
5121 goto error_out;
5122 if (rc != LPFC_MBX_DMP_ARG)
5123 goto error_out;
5124 if (mbx_mbox_cmd & ~0xff)
5125 goto error_out;
5126
5127
5128 if (mbx_dump_cnt == 0)
5129 goto reset_out;
5130
5131 return nbytes;
5132
5133 reset_out:
5134
5135 memset(&idiag, 0, sizeof(idiag));
5136 return nbytes;
5137
5138 error_out:
5139
5140 memset(&idiag, 0, sizeof(idiag));
5141 return -EINVAL;
5142 }
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156 static int
5157 lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
5158 {
5159 uint16_t ext_cnt, ext_size;
5160
5161 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5162 "\nAvailable Extents Information:\n");
5163
5164 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5165 "\tPort Available VPI extents: ");
5166 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI,
5167 &ext_cnt, &ext_size);
5168 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5169 "Count %3d, Size %3d\n", ext_cnt, ext_size);
5170
5171 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5172 "\tPort Available VFI extents: ");
5173 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI,
5174 &ext_cnt, &ext_size);
5175 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5176 "Count %3d, Size %3d\n", ext_cnt, ext_size);
5177
5178 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5179 "\tPort Available RPI extents: ");
5180 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI,
5181 &ext_cnt, &ext_size);
5182 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5183 "Count %3d, Size %3d\n", ext_cnt, ext_size);
5184
5185 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5186 "\tPort Available XRI extents: ");
5187 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI,
5188 &ext_cnt, &ext_size);
5189 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5190 "Count %3d, Size %3d\n", ext_cnt, ext_size);
5191
5192 return len;
5193 }
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207 static int
5208 lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len)
5209 {
5210 uint16_t ext_cnt, ext_size;
5211 int rc;
5212
5213 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5214 "\nAllocated Extents Information:\n");
5215
5216 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5217 "\tHost Allocated VPI extents: ");
5218 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI,
5219 &ext_cnt, &ext_size);
5220 if (!rc)
5221 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5222 "Port %d Extent %3d, Size %3d\n",
5223 phba->brd_no, ext_cnt, ext_size);
5224 else
5225 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5226 "N/A\n");
5227
5228 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5229 "\tHost Allocated VFI extents: ");
5230 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI,
5231 &ext_cnt, &ext_size);
5232 if (!rc)
5233 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5234 "Port %d Extent %3d, Size %3d\n",
5235 phba->brd_no, ext_cnt, ext_size);
5236 else
5237 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5238 "N/A\n");
5239
5240 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5241 "\tHost Allocated RPI extents: ");
5242 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI,
5243 &ext_cnt, &ext_size);
5244 if (!rc)
5245 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5246 "Port %d Extent %3d, Size %3d\n",
5247 phba->brd_no, ext_cnt, ext_size);
5248 else
5249 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5250 "N/A\n");
5251
5252 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5253 "\tHost Allocated XRI extents: ");
5254 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI,
5255 &ext_cnt, &ext_size);
5256 if (!rc)
5257 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5258 "Port %d Extent %3d, Size %3d\n",
5259 phba->brd_no, ext_cnt, ext_size);
5260 else
5261 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5262 "N/A\n");
5263
5264 return len;
5265 }
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279 static int
5280 lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len)
5281 {
5282 struct lpfc_rsrc_blks *rsrc_blks;
5283 int index;
5284
5285 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5286 "\nDriver Extents Information:\n");
5287
5288 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5289 "\tVPI extents:\n");
5290 index = 0;
5291 list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) {
5292 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5293 "\t\tBlock %3d: Start %4d, Count %4d\n",
5294 index, rsrc_blks->rsrc_start,
5295 rsrc_blks->rsrc_size);
5296 index++;
5297 }
5298 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5299 "\tVFI extents:\n");
5300 index = 0;
5301 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list,
5302 list) {
5303 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5304 "\t\tBlock %3d: Start %4d, Count %4d\n",
5305 index, rsrc_blks->rsrc_start,
5306 rsrc_blks->rsrc_size);
5307 index++;
5308 }
5309
5310 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5311 "\tRPI extents:\n");
5312 index = 0;
5313 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list,
5314 list) {
5315 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5316 "\t\tBlock %3d: Start %4d, Count %4d\n",
5317 index, rsrc_blks->rsrc_start,
5318 rsrc_blks->rsrc_size);
5319 index++;
5320 }
5321
5322 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5323 "\tXRI extents:\n");
5324 index = 0;
5325 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list,
5326 list) {
5327 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
5328 "\t\tBlock %3d: Start %4d, Count %4d\n",
5329 index, rsrc_blks->rsrc_start,
5330 rsrc_blks->rsrc_size);
5331 index++;
5332 }
5333
5334 return len;
5335 }
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352 static ssize_t
5353 lpfc_idiag_extacc_write(struct file *file, const char __user *buf,
5354 size_t nbytes, loff_t *ppos)
5355 {
5356 struct lpfc_debug *debug = file->private_data;
5357 uint32_t ext_map;
5358 int rc;
5359
5360
5361 debug->op = LPFC_IDIAG_OP_WR;
5362
5363 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
5364 if (rc < 0)
5365 return rc;
5366
5367 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
5368
5369 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
5370 goto error_out;
5371 if (rc != LPFC_EXT_ACC_CMD_ARG)
5372 goto error_out;
5373 if (!(ext_map & LPFC_EXT_ACC_ALL))
5374 goto error_out;
5375
5376 return nbytes;
5377 error_out:
5378
5379 memset(&idiag, 0, sizeof(idiag));
5380 return -EINVAL;
5381 }
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398 static ssize_t
5399 lpfc_idiag_extacc_read(struct file *file, char __user *buf, size_t nbytes,
5400 loff_t *ppos)
5401 {
5402 struct lpfc_debug *debug = file->private_data;
5403 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
5404 char *pbuffer;
5405 uint32_t ext_map;
5406 int len = 0;
5407
5408
5409 debug->op = LPFC_IDIAG_OP_RD;
5410
5411 if (!debug->buffer)
5412 debug->buffer = kmalloc(LPFC_EXT_ACC_BUF_SIZE, GFP_KERNEL);
5413 if (!debug->buffer)
5414 return 0;
5415 pbuffer = debug->buffer;
5416 if (*ppos)
5417 return 0;
5418 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
5419 return 0;
5420
5421 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
5422 if (ext_map & LPFC_EXT_ACC_AVAIL)
5423 len = lpfc_idiag_extacc_avail_get(phba, pbuffer, len);
5424 if (ext_map & LPFC_EXT_ACC_ALLOC)
5425 len = lpfc_idiag_extacc_alloc_get(phba, pbuffer, len);
5426 if (ext_map & LPFC_EXT_ACC_DRIVR)
5427 len = lpfc_idiag_extacc_drivr_get(phba, pbuffer, len);
5428
5429 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
5430 }
5431
5432 static int
5433 lpfc_cgn_buffer_open(struct inode *inode, struct file *file)
5434 {
5435 struct lpfc_debug *debug;
5436 int rc = -ENOMEM;
5437
5438 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
5439 if (!debug)
5440 goto out;
5441
5442 debug->buffer = vmalloc(LPFC_CGN_BUF_SIZE);
5443 if (!debug->buffer) {
5444 kfree(debug);
5445 goto out;
5446 }
5447
5448 debug->i_private = inode->i_private;
5449 file->private_data = debug;
5450
5451 rc = 0;
5452 out:
5453 return rc;
5454 }
5455
5456 static ssize_t
5457 lpfc_cgn_buffer_read(struct file *file, char __user *buf, size_t nbytes,
5458 loff_t *ppos)
5459 {
5460 struct lpfc_debug *debug = file->private_data;
5461 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
5462 char *buffer = debug->buffer;
5463 uint32_t *ptr;
5464 int cnt, len = 0;
5465
5466 if (!phba->sli4_hba.pc_sli4_params.mi_ver || !phba->cgn_i) {
5467 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len,
5468 "Congestion Mgmt is not supported\n");
5469 goto out;
5470 }
5471 ptr = (uint32_t *)phba->cgn_i->virt;
5472 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len,
5473 "Congestion Buffer Header\n");
5474
5475 cnt = 32;
5476 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len,
5477 "000: %08x %08x %08x %08x %08x %08x %08x %08x\n",
5478 *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3),
5479 *(ptr + 4), *(ptr + 5), *(ptr + 6), *(ptr + 7));
5480 ptr += 8;
5481 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len,
5482 "Congestion Buffer Data\n");
5483 while (cnt < sizeof(struct lpfc_cgn_info)) {
5484 if (len > (LPFC_CGN_BUF_SIZE - LPFC_DEBUG_OUT_LINE_SZ)) {
5485 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len,
5486 "Truncated . . .\n");
5487 goto out;
5488 }
5489 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len,
5490 "%03x: %08x %08x %08x %08x "
5491 "%08x %08x %08x %08x\n",
5492 cnt, *ptr, *(ptr + 1), *(ptr + 2),
5493 *(ptr + 3), *(ptr + 4), *(ptr + 5),
5494 *(ptr + 6), *(ptr + 7));
5495 cnt += 32;
5496 ptr += 8;
5497 }
5498 if (len > (LPFC_CGN_BUF_SIZE - LPFC_DEBUG_OUT_LINE_SZ)) {
5499 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len,
5500 "Truncated . . .\n");
5501 goto out;
5502 }
5503 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len,
5504 "Parameter Data\n");
5505 ptr = (uint32_t *)&phba->cgn_p;
5506 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len,
5507 "%08x %08x %08x %08x\n",
5508 *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3));
5509 out:
5510 return simple_read_from_buffer(buf, nbytes, ppos, buffer, len);
5511 }
5512
5513 static int
5514 lpfc_cgn_buffer_release(struct inode *inode, struct file *file)
5515 {
5516 struct lpfc_debug *debug = file->private_data;
5517
5518 vfree(debug->buffer);
5519 kfree(debug);
5520
5521 return 0;
5522 }
5523
5524 static int
5525 lpfc_rx_monitor_open(struct inode *inode, struct file *file)
5526 {
5527 struct lpfc_rx_monitor_debug *debug;
5528 int rc = -ENOMEM;
5529
5530 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
5531 if (!debug)
5532 goto out;
5533
5534 debug->buffer = vmalloc(MAX_DEBUGFS_RX_TABLE_SIZE);
5535 if (!debug->buffer) {
5536 kfree(debug);
5537 goto out;
5538 }
5539
5540 debug->i_private = inode->i_private;
5541 file->private_data = debug;
5542
5543 rc = 0;
5544 out:
5545 return rc;
5546 }
5547
5548 static ssize_t
5549 lpfc_rx_monitor_read(struct file *file, char __user *buf, size_t nbytes,
5550 loff_t *ppos)
5551 {
5552 struct lpfc_rx_monitor_debug *debug = file->private_data;
5553 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
5554 char *buffer = debug->buffer;
5555 struct rxtable_entry *entry;
5556 int i, len = 0, head, tail, last, start;
5557
5558 head = atomic_read(&phba->rxtable_idx_head);
5559 while (head == LPFC_RXMONITOR_TABLE_IN_USE) {
5560
5561 msleep(20);
5562 head = atomic_read(&phba->rxtable_idx_head);
5563 }
5564
5565 tail = atomic_xchg(&phba->rxtable_idx_tail, head);
5566 if (!phba->rxtable || head == tail) {
5567 len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
5568 "Rxtable is empty\n");
5569 goto out;
5570 }
5571 last = (head > tail) ? head : LPFC_MAX_RXMONITOR_ENTRY;
5572 start = tail;
5573
5574 len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
5575 " MaxBPI Tot_Data_CMF Tot_Data_Cmd "
5576 "Tot_Data_Cmpl Lat(us) Avg_IO Max_IO "
5577 "Bsy IO_cnt Info BWutil(ms)\n");
5578 get_table:
5579 for (i = start; i < last; i++) {
5580 entry = &phba->rxtable[i];
5581 len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
5582 "%3d:%12lld %12lld %12lld %12lld "
5583 "%7lldus %8lld %7lld "
5584 "%2d %4d %2d %2d(%2d)\n",
5585 i, entry->max_bytes_per_interval,
5586 entry->cmf_bytes,
5587 entry->total_bytes,
5588 entry->rcv_bytes,
5589 entry->avg_io_latency,
5590 entry->avg_io_size,
5591 entry->max_read_cnt,
5592 entry->cmf_busy,
5593 entry->io_cnt,
5594 entry->cmf_info,
5595 entry->timer_utilization,
5596 entry->timer_interval);
5597 }
5598
5599 if (head != last) {
5600 start = 0;
5601 last = head;
5602 goto get_table;
5603 }
5604 out:
5605 return simple_read_from_buffer(buf, nbytes, ppos, buffer, len);
5606 }
5607
5608 static int
5609 lpfc_rx_monitor_release(struct inode *inode, struct file *file)
5610 {
5611 struct lpfc_rx_monitor_debug *debug = file->private_data;
5612
5613 vfree(debug->buffer);
5614 kfree(debug);
5615
5616 return 0;
5617 }
5618
5619 #undef lpfc_debugfs_op_disc_trc
5620 static const struct file_operations lpfc_debugfs_op_disc_trc = {
5621 .owner = THIS_MODULE,
5622 .open = lpfc_debugfs_disc_trc_open,
5623 .llseek = lpfc_debugfs_lseek,
5624 .read = lpfc_debugfs_read,
5625 .release = lpfc_debugfs_release,
5626 };
5627
5628 #undef lpfc_debugfs_op_nodelist
5629 static const struct file_operations lpfc_debugfs_op_nodelist = {
5630 .owner = THIS_MODULE,
5631 .open = lpfc_debugfs_nodelist_open,
5632 .llseek = lpfc_debugfs_lseek,
5633 .read = lpfc_debugfs_read,
5634 .release = lpfc_debugfs_release,
5635 };
5636
5637 #undef lpfc_debugfs_op_multixripools
5638 static const struct file_operations lpfc_debugfs_op_multixripools = {
5639 .owner = THIS_MODULE,
5640 .open = lpfc_debugfs_multixripools_open,
5641 .llseek = lpfc_debugfs_lseek,
5642 .read = lpfc_debugfs_read,
5643 .write = lpfc_debugfs_multixripools_write,
5644 .release = lpfc_debugfs_release,
5645 };
5646
5647 #undef lpfc_debugfs_op_hbqinfo
5648 static const struct file_operations lpfc_debugfs_op_hbqinfo = {
5649 .owner = THIS_MODULE,
5650 .open = lpfc_debugfs_hbqinfo_open,
5651 .llseek = lpfc_debugfs_lseek,
5652 .read = lpfc_debugfs_read,
5653 .release = lpfc_debugfs_release,
5654 };
5655
5656 #ifdef LPFC_HDWQ_LOCK_STAT
5657 #undef lpfc_debugfs_op_lockstat
5658 static const struct file_operations lpfc_debugfs_op_lockstat = {
5659 .owner = THIS_MODULE,
5660 .open = lpfc_debugfs_lockstat_open,
5661 .llseek = lpfc_debugfs_lseek,
5662 .read = lpfc_debugfs_read,
5663 .write = lpfc_debugfs_lockstat_write,
5664 .release = lpfc_debugfs_release,
5665 };
5666 #endif
5667
5668 #undef lpfc_debugfs_ras_log
5669 static const struct file_operations lpfc_debugfs_ras_log = {
5670 .owner = THIS_MODULE,
5671 .open = lpfc_debugfs_ras_log_open,
5672 .llseek = lpfc_debugfs_lseek,
5673 .read = lpfc_debugfs_read,
5674 .release = lpfc_debugfs_ras_log_release,
5675 };
5676
5677 #undef lpfc_debugfs_op_dumpHBASlim
5678 static const struct file_operations lpfc_debugfs_op_dumpHBASlim = {
5679 .owner = THIS_MODULE,
5680 .open = lpfc_debugfs_dumpHBASlim_open,
5681 .llseek = lpfc_debugfs_lseek,
5682 .read = lpfc_debugfs_read,
5683 .release = lpfc_debugfs_release,
5684 };
5685
5686 #undef lpfc_debugfs_op_dumpHostSlim
5687 static const struct file_operations lpfc_debugfs_op_dumpHostSlim = {
5688 .owner = THIS_MODULE,
5689 .open = lpfc_debugfs_dumpHostSlim_open,
5690 .llseek = lpfc_debugfs_lseek,
5691 .read = lpfc_debugfs_read,
5692 .release = lpfc_debugfs_release,
5693 };
5694
5695 #undef lpfc_debugfs_op_nvmestat
5696 static const struct file_operations lpfc_debugfs_op_nvmestat = {
5697 .owner = THIS_MODULE,
5698 .open = lpfc_debugfs_nvmestat_open,
5699 .llseek = lpfc_debugfs_lseek,
5700 .read = lpfc_debugfs_read,
5701 .write = lpfc_debugfs_nvmestat_write,
5702 .release = lpfc_debugfs_release,
5703 };
5704
5705 #undef lpfc_debugfs_op_scsistat
5706 static const struct file_operations lpfc_debugfs_op_scsistat = {
5707 .owner = THIS_MODULE,
5708 .open = lpfc_debugfs_scsistat_open,
5709 .llseek = lpfc_debugfs_lseek,
5710 .read = lpfc_debugfs_read,
5711 .write = lpfc_debugfs_scsistat_write,
5712 .release = lpfc_debugfs_release,
5713 };
5714
5715 #undef lpfc_debugfs_op_ioktime
5716 static const struct file_operations lpfc_debugfs_op_ioktime = {
5717 .owner = THIS_MODULE,
5718 .open = lpfc_debugfs_ioktime_open,
5719 .llseek = lpfc_debugfs_lseek,
5720 .read = lpfc_debugfs_read,
5721 .write = lpfc_debugfs_ioktime_write,
5722 .release = lpfc_debugfs_release,
5723 };
5724
5725 #undef lpfc_debugfs_op_nvmeio_trc
5726 static const struct file_operations lpfc_debugfs_op_nvmeio_trc = {
5727 .owner = THIS_MODULE,
5728 .open = lpfc_debugfs_nvmeio_trc_open,
5729 .llseek = lpfc_debugfs_lseek,
5730 .read = lpfc_debugfs_read,
5731 .write = lpfc_debugfs_nvmeio_trc_write,
5732 .release = lpfc_debugfs_release,
5733 };
5734
5735 #undef lpfc_debugfs_op_hdwqstat
5736 static const struct file_operations lpfc_debugfs_op_hdwqstat = {
5737 .owner = THIS_MODULE,
5738 .open = lpfc_debugfs_hdwqstat_open,
5739 .llseek = lpfc_debugfs_lseek,
5740 .read = lpfc_debugfs_read,
5741 .write = lpfc_debugfs_hdwqstat_write,
5742 .release = lpfc_debugfs_release,
5743 };
5744
5745 #undef lpfc_debugfs_op_dif_err
5746 static const struct file_operations lpfc_debugfs_op_dif_err = {
5747 .owner = THIS_MODULE,
5748 .open = simple_open,
5749 .llseek = lpfc_debugfs_lseek,
5750 .read = lpfc_debugfs_dif_err_read,
5751 .write = lpfc_debugfs_dif_err_write,
5752 .release = lpfc_debugfs_dif_err_release,
5753 };
5754
5755 #undef lpfc_debugfs_op_slow_ring_trc
5756 static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
5757 .owner = THIS_MODULE,
5758 .open = lpfc_debugfs_slow_ring_trc_open,
5759 .llseek = lpfc_debugfs_lseek,
5760 .read = lpfc_debugfs_read,
5761 .release = lpfc_debugfs_release,
5762 };
5763
5764 static struct dentry *lpfc_debugfs_root = NULL;
5765 static atomic_t lpfc_debugfs_hba_count;
5766
5767
5768
5769
5770 #undef lpfc_idiag_op_pciCfg
5771 static const struct file_operations lpfc_idiag_op_pciCfg = {
5772 .owner = THIS_MODULE,
5773 .open = lpfc_idiag_open,
5774 .llseek = lpfc_debugfs_lseek,
5775 .read = lpfc_idiag_pcicfg_read,
5776 .write = lpfc_idiag_pcicfg_write,
5777 .release = lpfc_idiag_cmd_release,
5778 };
5779
5780 #undef lpfc_idiag_op_barAcc
5781 static const struct file_operations lpfc_idiag_op_barAcc = {
5782 .owner = THIS_MODULE,
5783 .open = lpfc_idiag_open,
5784 .llseek = lpfc_debugfs_lseek,
5785 .read = lpfc_idiag_baracc_read,
5786 .write = lpfc_idiag_baracc_write,
5787 .release = lpfc_idiag_cmd_release,
5788 };
5789
5790 #undef lpfc_idiag_op_queInfo
5791 static const struct file_operations lpfc_idiag_op_queInfo = {
5792 .owner = THIS_MODULE,
5793 .open = lpfc_idiag_open,
5794 .read = lpfc_idiag_queinfo_read,
5795 .release = lpfc_idiag_release,
5796 };
5797
5798 #undef lpfc_idiag_op_queAcc
5799 static const struct file_operations lpfc_idiag_op_queAcc = {
5800 .owner = THIS_MODULE,
5801 .open = lpfc_idiag_open,
5802 .llseek = lpfc_debugfs_lseek,
5803 .read = lpfc_idiag_queacc_read,
5804 .write = lpfc_idiag_queacc_write,
5805 .release = lpfc_idiag_cmd_release,
5806 };
5807
5808 #undef lpfc_idiag_op_drbAcc
5809 static const struct file_operations lpfc_idiag_op_drbAcc = {
5810 .owner = THIS_MODULE,
5811 .open = lpfc_idiag_open,
5812 .llseek = lpfc_debugfs_lseek,
5813 .read = lpfc_idiag_drbacc_read,
5814 .write = lpfc_idiag_drbacc_write,
5815 .release = lpfc_idiag_cmd_release,
5816 };
5817
5818 #undef lpfc_idiag_op_ctlAcc
5819 static const struct file_operations lpfc_idiag_op_ctlAcc = {
5820 .owner = THIS_MODULE,
5821 .open = lpfc_idiag_open,
5822 .llseek = lpfc_debugfs_lseek,
5823 .read = lpfc_idiag_ctlacc_read,
5824 .write = lpfc_idiag_ctlacc_write,
5825 .release = lpfc_idiag_cmd_release,
5826 };
5827
5828 #undef lpfc_idiag_op_mbxAcc
5829 static const struct file_operations lpfc_idiag_op_mbxAcc = {
5830 .owner = THIS_MODULE,
5831 .open = lpfc_idiag_open,
5832 .llseek = lpfc_debugfs_lseek,
5833 .read = lpfc_idiag_mbxacc_read,
5834 .write = lpfc_idiag_mbxacc_write,
5835 .release = lpfc_idiag_cmd_release,
5836 };
5837
5838 #undef lpfc_idiag_op_extAcc
5839 static const struct file_operations lpfc_idiag_op_extAcc = {
5840 .owner = THIS_MODULE,
5841 .open = lpfc_idiag_open,
5842 .llseek = lpfc_debugfs_lseek,
5843 .read = lpfc_idiag_extacc_read,
5844 .write = lpfc_idiag_extacc_write,
5845 .release = lpfc_idiag_cmd_release,
5846 };
5847 #undef lpfc_cgn_buffer_op
5848 static const struct file_operations lpfc_cgn_buffer_op = {
5849 .owner = THIS_MODULE,
5850 .open = lpfc_cgn_buffer_open,
5851 .llseek = lpfc_debugfs_lseek,
5852 .read = lpfc_cgn_buffer_read,
5853 .release = lpfc_cgn_buffer_release,
5854 };
5855
5856 #undef lpfc_rx_monitor_op
5857 static const struct file_operations lpfc_rx_monitor_op = {
5858 .owner = THIS_MODULE,
5859 .open = lpfc_rx_monitor_open,
5860 .llseek = lpfc_debugfs_lseek,
5861 .read = lpfc_rx_monitor_read,
5862 .release = lpfc_rx_monitor_release,
5863 };
5864 #endif
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874 void
5875 lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *phba, enum nemb_type nemb_tp,
5876 enum mbox_type mbox_tp, enum dma_type dma_tp,
5877 enum sta_type sta_tp,
5878 struct lpfc_dmabuf *dmabuf, uint32_t ext_buf)
5879 {
5880 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
5881 uint32_t *mbx_mbox_cmd, *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt;
5882 char line_buf[LPFC_MBX_ACC_LBUF_SZ];
5883 int len = 0;
5884 uint32_t do_dump = 0;
5885 uint32_t *pword;
5886 uint32_t i;
5887
5888 if (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP)
5889 return;
5890
5891 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
5892 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
5893 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
5894 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
5895
5896 if (!(*mbx_dump_map & LPFC_MBX_DMP_ALL) ||
5897 (*mbx_dump_cnt == 0) ||
5898 (*mbx_word_cnt == 0))
5899 return;
5900
5901 if (*mbx_mbox_cmd != 0x9B)
5902 return;
5903
5904 if ((mbox_tp == mbox_rd) && (dma_tp == dma_mbox)) {
5905 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_MBX) {
5906 do_dump |= LPFC_BSG_DMP_MBX_RD_MBX;
5907 pr_err("\nRead mbox command (x%x), "
5908 "nemb:0x%x, extbuf_cnt:%d:\n",
5909 sta_tp, nemb_tp, ext_buf);
5910 }
5911 }
5912 if ((mbox_tp == mbox_rd) && (dma_tp == dma_ebuf)) {
5913 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_BUF) {
5914 do_dump |= LPFC_BSG_DMP_MBX_RD_BUF;
5915 pr_err("\nRead mbox buffer (x%x), "
5916 "nemb:0x%x, extbuf_seq:%d:\n",
5917 sta_tp, nemb_tp, ext_buf);
5918 }
5919 }
5920 if ((mbox_tp == mbox_wr) && (dma_tp == dma_mbox)) {
5921 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_MBX) {
5922 do_dump |= LPFC_BSG_DMP_MBX_WR_MBX;
5923 pr_err("\nWrite mbox command (x%x), "
5924 "nemb:0x%x, extbuf_cnt:%d:\n",
5925 sta_tp, nemb_tp, ext_buf);
5926 }
5927 }
5928 if ((mbox_tp == mbox_wr) && (dma_tp == dma_ebuf)) {
5929 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_BUF) {
5930 do_dump |= LPFC_BSG_DMP_MBX_WR_BUF;
5931 pr_err("\nWrite mbox buffer (x%x), "
5932 "nemb:0x%x, extbuf_seq:%d:\n",
5933 sta_tp, nemb_tp, ext_buf);
5934 }
5935 }
5936
5937
5938 if (do_dump) {
5939 pword = (uint32_t *)dmabuf->virt;
5940 for (i = 0; i < *mbx_word_cnt; i++) {
5941 if (!(i % 8)) {
5942 if (i != 0)
5943 pr_err("%s\n", line_buf);
5944 len = 0;
5945 len += scnprintf(line_buf+len,
5946 LPFC_MBX_ACC_LBUF_SZ-len,
5947 "%03d: ", i);
5948 }
5949 len += scnprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
5950 "%08x ", (uint32_t)*pword);
5951 pword++;
5952 }
5953 if ((i - 1) % 8)
5954 pr_err("%s\n", line_buf);
5955 (*mbx_dump_cnt)--;
5956 }
5957
5958
5959 if (*mbx_dump_cnt == 0)
5960 memset(&idiag, 0, sizeof(idiag));
5961 return;
5962 #endif
5963 }
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973 void
5974 lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox)
5975 {
5976 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
5977 uint32_t *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt, *mbx_mbox_cmd;
5978 char line_buf[LPFC_MBX_ACC_LBUF_SZ];
5979 int len = 0;
5980 uint32_t *pword;
5981 uint8_t *pbyte;
5982 uint32_t i, j;
5983
5984 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP)
5985 return;
5986
5987 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
5988 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
5989 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
5990 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
5991
5992 if (!(*mbx_dump_map & LPFC_MBX_DMP_MBX_ALL) ||
5993 (*mbx_dump_cnt == 0) ||
5994 (*mbx_word_cnt == 0))
5995 return;
5996
5997 if ((*mbx_mbox_cmd != LPFC_MBX_ALL_CMD) &&
5998 (*mbx_mbox_cmd != pmbox->mbxCommand))
5999 return;
6000
6001
6002 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_WORD) {
6003 pr_err("Mailbox command:0x%x dump by word:\n",
6004 pmbox->mbxCommand);
6005 pword = (uint32_t *)pmbox;
6006 for (i = 0; i < *mbx_word_cnt; i++) {
6007 if (!(i % 8)) {
6008 if (i != 0)
6009 pr_err("%s\n", line_buf);
6010 len = 0;
6011 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
6012 len += scnprintf(line_buf+len,
6013 LPFC_MBX_ACC_LBUF_SZ-len,
6014 "%03d: ", i);
6015 }
6016 len += scnprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
6017 "%08x ",
6018 ((uint32_t)*pword) & 0xffffffff);
6019 pword++;
6020 }
6021 if ((i - 1) % 8)
6022 pr_err("%s\n", line_buf);
6023 pr_err("\n");
6024 }
6025 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_BYTE) {
6026 pr_err("Mailbox command:0x%x dump by byte:\n",
6027 pmbox->mbxCommand);
6028 pbyte = (uint8_t *)pmbox;
6029 for (i = 0; i < *mbx_word_cnt; i++) {
6030 if (!(i % 8)) {
6031 if (i != 0)
6032 pr_err("%s\n", line_buf);
6033 len = 0;
6034 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
6035 len += scnprintf(line_buf+len,
6036 LPFC_MBX_ACC_LBUF_SZ-len,
6037 "%03d: ", i);
6038 }
6039 for (j = 0; j < 4; j++) {
6040 len += scnprintf(line_buf+len,
6041 LPFC_MBX_ACC_LBUF_SZ-len,
6042 "%02x",
6043 ((uint8_t)*pbyte) & 0xff);
6044 pbyte++;
6045 }
6046 len += scnprintf(line_buf+len,
6047 LPFC_MBX_ACC_LBUF_SZ-len, " ");
6048 }
6049 if ((i - 1) % 8)
6050 pr_err("%s\n", line_buf);
6051 pr_err("\n");
6052 }
6053 (*mbx_dump_cnt)--;
6054
6055
6056 if (*mbx_dump_cnt == 0)
6057 memset(&idiag, 0, sizeof(idiag));
6058 return;
6059 #endif
6060 }
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072 inline void
6073 lpfc_debugfs_initialize(struct lpfc_vport *vport)
6074 {
6075 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
6076 struct lpfc_hba *phba = vport->phba;
6077 char name[64];
6078 uint32_t num, i;
6079 bool pport_setup = false;
6080
6081 if (!lpfc_debugfs_enable)
6082 return;
6083
6084
6085 if (!lpfc_debugfs_root) {
6086 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
6087 atomic_set(&lpfc_debugfs_hba_count, 0);
6088 }
6089 if (!lpfc_debugfs_start_time)
6090 lpfc_debugfs_start_time = jiffies;
6091
6092
6093 snprintf(name, sizeof(name), "fn%d", phba->brd_no);
6094 if (!phba->hba_debugfs_root) {
6095 pport_setup = true;
6096 phba->hba_debugfs_root =
6097 debugfs_create_dir(name, lpfc_debugfs_root);
6098 atomic_inc(&lpfc_debugfs_hba_count);
6099 atomic_set(&phba->debugfs_vport_count, 0);
6100
6101
6102 snprintf(name, sizeof(name), "multixripools");
6103 phba->debug_multixri_pools =
6104 debugfs_create_file(name, S_IFREG | 0644,
6105 phba->hba_debugfs_root,
6106 phba,
6107 &lpfc_debugfs_op_multixripools);
6108 if (!phba->debug_multixri_pools) {
6109 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6110 "0527 Cannot create debugfs multixripools\n");
6111 goto debug_failed;
6112 }
6113
6114
6115 scnprintf(name, sizeof(name), "cgn_buffer");
6116 phba->debug_cgn_buffer =
6117 debugfs_create_file(name, S_IFREG | 0644,
6118 phba->hba_debugfs_root,
6119 phba, &lpfc_cgn_buffer_op);
6120 if (!phba->debug_cgn_buffer) {
6121 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6122 "6527 Cannot create debugfs "
6123 "cgn_buffer\n");
6124 goto debug_failed;
6125 }
6126
6127
6128 scnprintf(name, sizeof(name), "rx_monitor");
6129 phba->debug_rx_monitor =
6130 debugfs_create_file(name, S_IFREG | 0644,
6131 phba->hba_debugfs_root,
6132 phba, &lpfc_rx_monitor_op);
6133 if (!phba->debug_rx_monitor) {
6134 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6135 "6528 Cannot create debugfs "
6136 "rx_monitor\n");
6137 goto debug_failed;
6138 }
6139
6140
6141 snprintf(name, sizeof(name), "ras_log");
6142 phba->debug_ras_log =
6143 debugfs_create_file(name, 0644,
6144 phba->hba_debugfs_root,
6145 phba, &lpfc_debugfs_ras_log);
6146 if (!phba->debug_ras_log) {
6147 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6148 "6148 Cannot create debugfs"
6149 " ras_log\n");
6150 goto debug_failed;
6151 }
6152
6153
6154 snprintf(name, sizeof(name), "hbqinfo");
6155 phba->debug_hbqinfo =
6156 debugfs_create_file(name, S_IFREG | 0644,
6157 phba->hba_debugfs_root,
6158 phba, &lpfc_debugfs_op_hbqinfo);
6159
6160 #ifdef LPFC_HDWQ_LOCK_STAT
6161
6162 snprintf(name, sizeof(name), "lockstat");
6163 phba->debug_lockstat =
6164 debugfs_create_file(name, S_IFREG | 0644,
6165 phba->hba_debugfs_root,
6166 phba, &lpfc_debugfs_op_lockstat);
6167 if (!phba->debug_lockstat) {
6168 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6169 "4610 Can't create debugfs lockstat\n");
6170 goto debug_failed;
6171 }
6172 #endif
6173
6174
6175 if (phba->sli_rev < LPFC_SLI_REV4) {
6176 snprintf(name, sizeof(name), "dumpHBASlim");
6177 phba->debug_dumpHBASlim =
6178 debugfs_create_file(name,
6179 S_IFREG|S_IRUGO|S_IWUSR,
6180 phba->hba_debugfs_root,
6181 phba, &lpfc_debugfs_op_dumpHBASlim);
6182 } else
6183 phba->debug_dumpHBASlim = NULL;
6184
6185
6186 if (phba->sli_rev < LPFC_SLI_REV4) {
6187 snprintf(name, sizeof(name), "dumpHostSlim");
6188 phba->debug_dumpHostSlim =
6189 debugfs_create_file(name,
6190 S_IFREG|S_IRUGO|S_IWUSR,
6191 phba->hba_debugfs_root,
6192 phba, &lpfc_debugfs_op_dumpHostSlim);
6193 } else
6194 phba->debug_dumpHostSlim = NULL;
6195
6196
6197 snprintf(name, sizeof(name), "InjErrLBA");
6198 phba->debug_InjErrLBA =
6199 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6200 phba->hba_debugfs_root,
6201 phba, &lpfc_debugfs_op_dif_err);
6202 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
6203
6204 snprintf(name, sizeof(name), "InjErrNPortID");
6205 phba->debug_InjErrNPortID =
6206 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6207 phba->hba_debugfs_root,
6208 phba, &lpfc_debugfs_op_dif_err);
6209
6210 snprintf(name, sizeof(name), "InjErrWWPN");
6211 phba->debug_InjErrWWPN =
6212 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6213 phba->hba_debugfs_root,
6214 phba, &lpfc_debugfs_op_dif_err);
6215
6216 snprintf(name, sizeof(name), "writeGuardInjErr");
6217 phba->debug_writeGuard =
6218 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6219 phba->hba_debugfs_root,
6220 phba, &lpfc_debugfs_op_dif_err);
6221
6222 snprintf(name, sizeof(name), "writeAppInjErr");
6223 phba->debug_writeApp =
6224 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6225 phba->hba_debugfs_root,
6226 phba, &lpfc_debugfs_op_dif_err);
6227
6228 snprintf(name, sizeof(name), "writeRefInjErr");
6229 phba->debug_writeRef =
6230 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6231 phba->hba_debugfs_root,
6232 phba, &lpfc_debugfs_op_dif_err);
6233
6234 snprintf(name, sizeof(name), "readGuardInjErr");
6235 phba->debug_readGuard =
6236 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6237 phba->hba_debugfs_root,
6238 phba, &lpfc_debugfs_op_dif_err);
6239
6240 snprintf(name, sizeof(name), "readAppInjErr");
6241 phba->debug_readApp =
6242 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6243 phba->hba_debugfs_root,
6244 phba, &lpfc_debugfs_op_dif_err);
6245
6246 snprintf(name, sizeof(name), "readRefInjErr");
6247 phba->debug_readRef =
6248 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6249 phba->hba_debugfs_root,
6250 phba, &lpfc_debugfs_op_dif_err);
6251
6252
6253 if (lpfc_debugfs_max_slow_ring_trc) {
6254 num = lpfc_debugfs_max_slow_ring_trc - 1;
6255 if (num & lpfc_debugfs_max_slow_ring_trc) {
6256
6257 num = lpfc_debugfs_max_slow_ring_trc;
6258 i = 0;
6259 while (num > 1) {
6260 num = num >> 1;
6261 i++;
6262 }
6263 lpfc_debugfs_max_slow_ring_trc = (1 << i);
6264 pr_err("lpfc_debugfs_max_disc_trc changed to "
6265 "%d\n", lpfc_debugfs_max_disc_trc);
6266 }
6267 }
6268
6269 snprintf(name, sizeof(name), "slow_ring_trace");
6270 phba->debug_slow_ring_trc =
6271 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6272 phba->hba_debugfs_root,
6273 phba, &lpfc_debugfs_op_slow_ring_trc);
6274 if (!phba->slow_ring_trc) {
6275 phba->slow_ring_trc = kcalloc(
6276 lpfc_debugfs_max_slow_ring_trc,
6277 sizeof(struct lpfc_debugfs_trc),
6278 GFP_KERNEL);
6279 if (!phba->slow_ring_trc) {
6280 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6281 "0416 Cannot create debugfs "
6282 "slow_ring buffer\n");
6283 goto debug_failed;
6284 }
6285 atomic_set(&phba->slow_ring_trc_cnt, 0);
6286 }
6287
6288 snprintf(name, sizeof(name), "nvmeio_trc");
6289 phba->debug_nvmeio_trc =
6290 debugfs_create_file(name, 0644,
6291 phba->hba_debugfs_root,
6292 phba, &lpfc_debugfs_op_nvmeio_trc);
6293
6294 atomic_set(&phba->nvmeio_trc_cnt, 0);
6295 if (lpfc_debugfs_max_nvmeio_trc) {
6296 num = lpfc_debugfs_max_nvmeio_trc - 1;
6297 if (num & lpfc_debugfs_max_disc_trc) {
6298
6299 num = lpfc_debugfs_max_nvmeio_trc;
6300 i = 0;
6301 while (num > 1) {
6302 num = num >> 1;
6303 i++;
6304 }
6305 lpfc_debugfs_max_nvmeio_trc = (1 << i);
6306 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
6307 "0575 lpfc_debugfs_max_nvmeio_trc "
6308 "changed to %d\n",
6309 lpfc_debugfs_max_nvmeio_trc);
6310 }
6311 phba->nvmeio_trc_size = lpfc_debugfs_max_nvmeio_trc;
6312
6313
6314 phba->nvmeio_trc = kzalloc(
6315 (sizeof(struct lpfc_debugfs_nvmeio_trc) *
6316 phba->nvmeio_trc_size), GFP_KERNEL);
6317
6318 if (!phba->nvmeio_trc) {
6319 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
6320 "0576 Cannot create debugfs "
6321 "nvmeio_trc buffer\n");
6322 goto nvmeio_off;
6323 }
6324 phba->nvmeio_trc_on = 1;
6325 phba->nvmeio_trc_output_idx = 0;
6326 phba->nvmeio_trc = NULL;
6327 } else {
6328 nvmeio_off:
6329 phba->nvmeio_trc_size = 0;
6330 phba->nvmeio_trc_on = 0;
6331 phba->nvmeio_trc_output_idx = 0;
6332 phba->nvmeio_trc = NULL;
6333 }
6334 }
6335
6336 snprintf(name, sizeof(name), "vport%d", vport->vpi);
6337 if (!vport->vport_debugfs_root) {
6338 vport->vport_debugfs_root =
6339 debugfs_create_dir(name, phba->hba_debugfs_root);
6340 atomic_inc(&phba->debugfs_vport_count);
6341 }
6342
6343 if (lpfc_debugfs_max_disc_trc) {
6344 num = lpfc_debugfs_max_disc_trc - 1;
6345 if (num & lpfc_debugfs_max_disc_trc) {
6346
6347 num = lpfc_debugfs_max_disc_trc;
6348 i = 0;
6349 while (num > 1) {
6350 num = num >> 1;
6351 i++;
6352 }
6353 lpfc_debugfs_max_disc_trc = (1 << i);
6354 pr_err("lpfc_debugfs_max_disc_trc changed to %d\n",
6355 lpfc_debugfs_max_disc_trc);
6356 }
6357 }
6358
6359 vport->disc_trc = kzalloc(
6360 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
6361 GFP_KERNEL);
6362
6363 if (!vport->disc_trc) {
6364 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6365 "0418 Cannot create debugfs disc trace "
6366 "buffer\n");
6367 goto debug_failed;
6368 }
6369 atomic_set(&vport->disc_trc_cnt, 0);
6370
6371 snprintf(name, sizeof(name), "discovery_trace");
6372 vport->debug_disc_trc =
6373 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6374 vport->vport_debugfs_root,
6375 vport, &lpfc_debugfs_op_disc_trc);
6376 snprintf(name, sizeof(name), "nodelist");
6377 vport->debug_nodelist =
6378 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6379 vport->vport_debugfs_root,
6380 vport, &lpfc_debugfs_op_nodelist);
6381
6382 snprintf(name, sizeof(name), "nvmestat");
6383 vport->debug_nvmestat =
6384 debugfs_create_file(name, 0644,
6385 vport->vport_debugfs_root,
6386 vport, &lpfc_debugfs_op_nvmestat);
6387
6388 snprintf(name, sizeof(name), "scsistat");
6389 vport->debug_scsistat =
6390 debugfs_create_file(name, 0644,
6391 vport->vport_debugfs_root,
6392 vport, &lpfc_debugfs_op_scsistat);
6393 if (!vport->debug_scsistat) {
6394 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6395 "4611 Cannot create debugfs scsistat\n");
6396 goto debug_failed;
6397 }
6398
6399 snprintf(name, sizeof(name), "ioktime");
6400 vport->debug_ioktime =
6401 debugfs_create_file(name, 0644,
6402 vport->vport_debugfs_root,
6403 vport, &lpfc_debugfs_op_ioktime);
6404 if (!vport->debug_ioktime) {
6405 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
6406 "0815 Cannot create debugfs ioktime\n");
6407 goto debug_failed;
6408 }
6409
6410 snprintf(name, sizeof(name), "hdwqstat");
6411 vport->debug_hdwqstat =
6412 debugfs_create_file(name, 0644,
6413 vport->vport_debugfs_root,
6414 vport, &lpfc_debugfs_op_hdwqstat);
6415
6416
6417
6418
6419
6420
6421 if (!pport_setup)
6422 goto debug_failed;
6423
6424
6425
6426
6427 if (phba->sli_rev < LPFC_SLI_REV4)
6428 goto debug_failed;
6429
6430 snprintf(name, sizeof(name), "iDiag");
6431 if (!phba->idiag_root) {
6432 phba->idiag_root =
6433 debugfs_create_dir(name, phba->hba_debugfs_root);
6434
6435 memset(&idiag, 0, sizeof(idiag));
6436 }
6437
6438
6439 snprintf(name, sizeof(name), "pciCfg");
6440 if (!phba->idiag_pci_cfg) {
6441 phba->idiag_pci_cfg =
6442 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6443 phba->idiag_root, phba, &lpfc_idiag_op_pciCfg);
6444 idiag.offset.last_rd = 0;
6445 }
6446
6447
6448 snprintf(name, sizeof(name), "barAcc");
6449 if (!phba->idiag_bar_acc) {
6450 phba->idiag_bar_acc =
6451 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6452 phba->idiag_root, phba, &lpfc_idiag_op_barAcc);
6453 idiag.offset.last_rd = 0;
6454 }
6455
6456
6457 snprintf(name, sizeof(name), "queInfo");
6458 if (!phba->idiag_que_info) {
6459 phba->idiag_que_info =
6460 debugfs_create_file(name, S_IFREG|S_IRUGO,
6461 phba->idiag_root, phba, &lpfc_idiag_op_queInfo);
6462 }
6463
6464
6465 snprintf(name, sizeof(name), "queAcc");
6466 if (!phba->idiag_que_acc) {
6467 phba->idiag_que_acc =
6468 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6469 phba->idiag_root, phba, &lpfc_idiag_op_queAcc);
6470 }
6471
6472
6473 snprintf(name, sizeof(name), "drbAcc");
6474 if (!phba->idiag_drb_acc) {
6475 phba->idiag_drb_acc =
6476 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6477 phba->idiag_root, phba, &lpfc_idiag_op_drbAcc);
6478 }
6479
6480
6481 snprintf(name, sizeof(name), "ctlAcc");
6482 if (!phba->idiag_ctl_acc) {
6483 phba->idiag_ctl_acc =
6484 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6485 phba->idiag_root, phba, &lpfc_idiag_op_ctlAcc);
6486 }
6487
6488
6489 snprintf(name, sizeof(name), "mbxAcc");
6490 if (!phba->idiag_mbx_acc) {
6491 phba->idiag_mbx_acc =
6492 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
6493 phba->idiag_root, phba, &lpfc_idiag_op_mbxAcc);
6494 }
6495
6496
6497 if (phba->sli4_hba.extents_in_use) {
6498 snprintf(name, sizeof(name), "extAcc");
6499 if (!phba->idiag_ext_acc) {
6500 phba->idiag_ext_acc =
6501 debugfs_create_file(name,
6502 S_IFREG|S_IRUGO|S_IWUSR,
6503 phba->idiag_root, phba,
6504 &lpfc_idiag_op_extAcc);
6505 }
6506 }
6507
6508 debug_failed:
6509 return;
6510 #endif
6511 }
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524 inline void
6525 lpfc_debugfs_terminate(struct lpfc_vport *vport)
6526 {
6527 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
6528 struct lpfc_hba *phba = vport->phba;
6529
6530 kfree(vport->disc_trc);
6531 vport->disc_trc = NULL;
6532
6533 debugfs_remove(vport->debug_disc_trc);
6534 vport->debug_disc_trc = NULL;
6535
6536 debugfs_remove(vport->debug_nodelist);
6537 vport->debug_nodelist = NULL;
6538
6539 debugfs_remove(vport->debug_nvmestat);
6540 vport->debug_nvmestat = NULL;
6541
6542 debugfs_remove(vport->debug_scsistat);
6543 vport->debug_scsistat = NULL;
6544
6545 debugfs_remove(vport->debug_ioktime);
6546 vport->debug_ioktime = NULL;
6547
6548 debugfs_remove(vport->debug_hdwqstat);
6549 vport->debug_hdwqstat = NULL;
6550
6551 if (vport->vport_debugfs_root) {
6552 debugfs_remove(vport->vport_debugfs_root);
6553 vport->vport_debugfs_root = NULL;
6554 atomic_dec(&phba->debugfs_vport_count);
6555 }
6556
6557 if (atomic_read(&phba->debugfs_vport_count) == 0) {
6558
6559 debugfs_remove(phba->debug_multixri_pools);
6560 phba->debug_multixri_pools = NULL;
6561
6562 debugfs_remove(phba->debug_hbqinfo);
6563 phba->debug_hbqinfo = NULL;
6564
6565 debugfs_remove(phba->debug_cgn_buffer);
6566 phba->debug_cgn_buffer = NULL;
6567
6568 debugfs_remove(phba->debug_rx_monitor);
6569 phba->debug_rx_monitor = NULL;
6570
6571 debugfs_remove(phba->debug_ras_log);
6572 phba->debug_ras_log = NULL;
6573
6574 #ifdef LPFC_HDWQ_LOCK_STAT
6575 debugfs_remove(phba->debug_lockstat);
6576 phba->debug_lockstat = NULL;
6577 #endif
6578 debugfs_remove(phba->debug_dumpHBASlim);
6579 phba->debug_dumpHBASlim = NULL;
6580
6581 debugfs_remove(phba->debug_dumpHostSlim);
6582 phba->debug_dumpHostSlim = NULL;
6583
6584 debugfs_remove(phba->debug_InjErrLBA);
6585 phba->debug_InjErrLBA = NULL;
6586
6587 debugfs_remove(phba->debug_InjErrNPortID);
6588 phba->debug_InjErrNPortID = NULL;
6589
6590 debugfs_remove(phba->debug_InjErrWWPN);
6591 phba->debug_InjErrWWPN = NULL;
6592
6593 debugfs_remove(phba->debug_writeGuard);
6594 phba->debug_writeGuard = NULL;
6595
6596 debugfs_remove(phba->debug_writeApp);
6597 phba->debug_writeApp = NULL;
6598
6599 debugfs_remove(phba->debug_writeRef);
6600 phba->debug_writeRef = NULL;
6601
6602 debugfs_remove(phba->debug_readGuard);
6603 phba->debug_readGuard = NULL;
6604
6605 debugfs_remove(phba->debug_readApp);
6606 phba->debug_readApp = NULL;
6607
6608 debugfs_remove(phba->debug_readRef);
6609 phba->debug_readRef = NULL;
6610
6611 kfree(phba->slow_ring_trc);
6612 phba->slow_ring_trc = NULL;
6613
6614
6615 debugfs_remove(phba->debug_slow_ring_trc);
6616 phba->debug_slow_ring_trc = NULL;
6617
6618 debugfs_remove(phba->debug_nvmeio_trc);
6619 phba->debug_nvmeio_trc = NULL;
6620
6621 kfree(phba->nvmeio_trc);
6622 phba->nvmeio_trc = NULL;
6623
6624
6625
6626
6627 if (phba->sli_rev == LPFC_SLI_REV4) {
6628
6629 debugfs_remove(phba->idiag_ext_acc);
6630 phba->idiag_ext_acc = NULL;
6631
6632
6633 debugfs_remove(phba->idiag_mbx_acc);
6634 phba->idiag_mbx_acc = NULL;
6635
6636
6637 debugfs_remove(phba->idiag_ctl_acc);
6638 phba->idiag_ctl_acc = NULL;
6639
6640
6641 debugfs_remove(phba->idiag_drb_acc);
6642 phba->idiag_drb_acc = NULL;
6643
6644
6645 debugfs_remove(phba->idiag_que_acc);
6646 phba->idiag_que_acc = NULL;
6647
6648
6649 debugfs_remove(phba->idiag_que_info);
6650 phba->idiag_que_info = NULL;
6651
6652
6653 debugfs_remove(phba->idiag_bar_acc);
6654 phba->idiag_bar_acc = NULL;
6655
6656
6657 debugfs_remove(phba->idiag_pci_cfg);
6658 phba->idiag_pci_cfg = NULL;
6659
6660
6661 debugfs_remove(phba->idiag_root);
6662 phba->idiag_root = NULL;
6663 }
6664
6665 if (phba->hba_debugfs_root) {
6666 debugfs_remove(phba->hba_debugfs_root);
6667 phba->hba_debugfs_root = NULL;
6668 atomic_dec(&lpfc_debugfs_hba_count);
6669 }
6670
6671 if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
6672 debugfs_remove(lpfc_debugfs_root);
6673 lpfc_debugfs_root = NULL;
6674 }
6675 }
6676 #endif
6677 return;
6678 }
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692 void
6693 lpfc_debug_dump_all_queues(struct lpfc_hba *phba)
6694 {
6695 int idx;
6696
6697
6698
6699
6700 lpfc_debug_dump_wq(phba, DUMP_MBX, 0);
6701 lpfc_debug_dump_wq(phba, DUMP_ELS, 0);
6702 lpfc_debug_dump_wq(phba, DUMP_NVMELS, 0);
6703
6704 for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6705 lpfc_debug_dump_wq(phba, DUMP_IO, idx);
6706
6707 lpfc_debug_dump_hdr_rq(phba);
6708 lpfc_debug_dump_dat_rq(phba);
6709
6710
6711
6712 lpfc_debug_dump_cq(phba, DUMP_MBX, 0);
6713 lpfc_debug_dump_cq(phba, DUMP_ELS, 0);
6714 lpfc_debug_dump_cq(phba, DUMP_NVMELS, 0);
6715
6716 for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6717 lpfc_debug_dump_cq(phba, DUMP_IO, idx);
6718
6719
6720
6721
6722 for (idx = 0; idx < phba->cfg_hdw_queue; idx++)
6723 lpfc_debug_dump_hba_eq(phba, idx);
6724 }