0001
0002
0003
0004 #include <linux/module.h>
0005 #include <linux/errno.h>
0006 #include <linux/debugfs.h>
0007 #include <linux/vmalloc.h>
0008 #include "fnic.h"
0009
0010 static struct dentry *fnic_trace_debugfs_root;
0011 static struct dentry *fnic_trace_debugfs_file;
0012 static struct dentry *fnic_trace_enable;
0013 static struct dentry *fnic_stats_debugfs_root;
0014
0015 static struct dentry *fnic_fc_trace_debugfs_file;
0016 static struct dentry *fnic_fc_rdata_trace_debugfs_file;
0017 static struct dentry *fnic_fc_trace_enable;
0018 static struct dentry *fnic_fc_trace_clear;
0019
0020 struct fc_trace_flag_type {
0021 u8 fc_row_file;
0022 u8 fc_normal_file;
0023 u8 fnic_trace;
0024 u8 fc_trace;
0025 u8 fc_clear;
0026 };
0027
0028 static struct fc_trace_flag_type *fc_trc_flag;
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 int fnic_debugfs_init(void)
0040 {
0041 fnic_trace_debugfs_root = debugfs_create_dir("fnic", NULL);
0042
0043 fnic_stats_debugfs_root = debugfs_create_dir("statistics",
0044 fnic_trace_debugfs_root);
0045
0046
0047 fc_trc_flag = vmalloc(sizeof(struct fc_trace_flag_type));
0048
0049 if (fc_trc_flag) {
0050 fc_trc_flag->fc_row_file = 0;
0051 fc_trc_flag->fc_normal_file = 1;
0052 fc_trc_flag->fnic_trace = 2;
0053 fc_trc_flag->fc_trace = 3;
0054 fc_trc_flag->fc_clear = 4;
0055 }
0056
0057 return 0;
0058 }
0059
0060
0061
0062
0063
0064
0065
0066
0067 void fnic_debugfs_terminate(void)
0068 {
0069 debugfs_remove(fnic_stats_debugfs_root);
0070 fnic_stats_debugfs_root = NULL;
0071
0072 debugfs_remove(fnic_trace_debugfs_root);
0073 fnic_trace_debugfs_root = NULL;
0074
0075 vfree(fc_trc_flag);
0076 }
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 static ssize_t fnic_trace_ctrl_read(struct file *filp,
0098 char __user *ubuf,
0099 size_t cnt, loff_t *ppos)
0100 {
0101 char buf[64];
0102 int len;
0103 u8 *trace_type;
0104 len = 0;
0105 trace_type = (u8 *)filp->private_data;
0106 if (*trace_type == fc_trc_flag->fnic_trace)
0107 len = sprintf(buf, "%d\n", fnic_tracing_enabled);
0108 else if (*trace_type == fc_trc_flag->fc_trace)
0109 len = sprintf(buf, "%d\n", fnic_fc_tracing_enabled);
0110 else if (*trace_type == fc_trc_flag->fc_clear)
0111 len = sprintf(buf, "%d\n", fnic_fc_trace_cleared);
0112 else
0113 pr_err("fnic: Cannot read to any debugfs file\n");
0114
0115 return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
0116 }
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 static ssize_t fnic_trace_ctrl_write(struct file *filp,
0136 const char __user *ubuf,
0137 size_t cnt, loff_t *ppos)
0138 {
0139 char buf[64];
0140 unsigned long val;
0141 int ret;
0142 u8 *trace_type;
0143 trace_type = (u8 *)filp->private_data;
0144
0145 if (cnt >= sizeof(buf))
0146 return -EINVAL;
0147
0148 if (copy_from_user(&buf, ubuf, cnt))
0149 return -EFAULT;
0150
0151 buf[cnt] = 0;
0152
0153 ret = kstrtoul(buf, 10, &val);
0154 if (ret < 0)
0155 return ret;
0156
0157 if (*trace_type == fc_trc_flag->fnic_trace)
0158 fnic_tracing_enabled = val;
0159 else if (*trace_type == fc_trc_flag->fc_trace)
0160 fnic_fc_tracing_enabled = val;
0161 else if (*trace_type == fc_trc_flag->fc_clear)
0162 fnic_fc_trace_cleared = val;
0163 else
0164 pr_err("fnic: cannot write to any debugfs file\n");
0165
0166 (*ppos)++;
0167
0168 return cnt;
0169 }
0170
0171 static const struct file_operations fnic_trace_ctrl_fops = {
0172 .owner = THIS_MODULE,
0173 .open = simple_open,
0174 .read = fnic_trace_ctrl_read,
0175 .write = fnic_trace_ctrl_write,
0176 };
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193 static int fnic_trace_debugfs_open(struct inode *inode,
0194 struct file *file)
0195 {
0196 fnic_dbgfs_t *fnic_dbg_prt;
0197 u8 *rdata_ptr;
0198 rdata_ptr = (u8 *)inode->i_private;
0199 fnic_dbg_prt = kzalloc(sizeof(fnic_dbgfs_t), GFP_KERNEL);
0200 if (!fnic_dbg_prt)
0201 return -ENOMEM;
0202
0203 if (*rdata_ptr == fc_trc_flag->fnic_trace) {
0204 fnic_dbg_prt->buffer = vmalloc(array3_size(3, trace_max_pages,
0205 PAGE_SIZE));
0206 if (!fnic_dbg_prt->buffer) {
0207 kfree(fnic_dbg_prt);
0208 return -ENOMEM;
0209 }
0210 memset((void *)fnic_dbg_prt->buffer, 0,
0211 3 * (trace_max_pages * PAGE_SIZE));
0212 fnic_dbg_prt->buffer_len = fnic_get_trace_data(fnic_dbg_prt);
0213 } else {
0214 fnic_dbg_prt->buffer =
0215 vmalloc(array3_size(3, fnic_fc_trace_max_pages,
0216 PAGE_SIZE));
0217 if (!fnic_dbg_prt->buffer) {
0218 kfree(fnic_dbg_prt);
0219 return -ENOMEM;
0220 }
0221 memset((void *)fnic_dbg_prt->buffer, 0,
0222 3 * (fnic_fc_trace_max_pages * PAGE_SIZE));
0223 fnic_dbg_prt->buffer_len =
0224 fnic_fc_trace_get_data(fnic_dbg_prt, *rdata_ptr);
0225 }
0226 file->private_data = fnic_dbg_prt;
0227
0228 return 0;
0229 }
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248 static loff_t fnic_trace_debugfs_lseek(struct file *file,
0249 loff_t offset,
0250 int howto)
0251 {
0252 fnic_dbgfs_t *fnic_dbg_prt = file->private_data;
0253 return fixed_size_llseek(file, offset, howto,
0254 fnic_dbg_prt->buffer_len);
0255 }
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273 static ssize_t fnic_trace_debugfs_read(struct file *file,
0274 char __user *ubuf,
0275 size_t nbytes,
0276 loff_t *pos)
0277 {
0278 fnic_dbgfs_t *fnic_dbg_prt = file->private_data;
0279 int rc = 0;
0280 rc = simple_read_from_buffer(ubuf, nbytes, pos,
0281 fnic_dbg_prt->buffer,
0282 fnic_dbg_prt->buffer_len);
0283 return rc;
0284 }
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 static int fnic_trace_debugfs_release(struct inode *inode,
0300 struct file *file)
0301 {
0302 fnic_dbgfs_t *fnic_dbg_prt = file->private_data;
0303
0304 vfree(fnic_dbg_prt->buffer);
0305 kfree(fnic_dbg_prt);
0306 return 0;
0307 }
0308
0309 static const struct file_operations fnic_trace_debugfs_fops = {
0310 .owner = THIS_MODULE,
0311 .open = fnic_trace_debugfs_open,
0312 .llseek = fnic_trace_debugfs_lseek,
0313 .read = fnic_trace_debugfs_read,
0314 .release = fnic_trace_debugfs_release,
0315 };
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 void fnic_trace_debugfs_init(void)
0328 {
0329 fnic_trace_enable = debugfs_create_file("tracing_enable",
0330 S_IFREG|S_IRUGO|S_IWUSR,
0331 fnic_trace_debugfs_root,
0332 &(fc_trc_flag->fnic_trace),
0333 &fnic_trace_ctrl_fops);
0334
0335 fnic_trace_debugfs_file = debugfs_create_file("trace",
0336 S_IFREG|S_IRUGO|S_IWUSR,
0337 fnic_trace_debugfs_root,
0338 &(fc_trc_flag->fnic_trace),
0339 &fnic_trace_debugfs_fops);
0340 }
0341
0342
0343
0344
0345
0346
0347
0348
0349 void fnic_trace_debugfs_terminate(void)
0350 {
0351 debugfs_remove(fnic_trace_debugfs_file);
0352 fnic_trace_debugfs_file = NULL;
0353
0354 debugfs_remove(fnic_trace_enable);
0355 fnic_trace_enable = NULL;
0356 }
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370 void fnic_fc_trace_debugfs_init(void)
0371 {
0372 fnic_fc_trace_enable = debugfs_create_file("fc_trace_enable",
0373 S_IFREG|S_IRUGO|S_IWUSR,
0374 fnic_trace_debugfs_root,
0375 &(fc_trc_flag->fc_trace),
0376 &fnic_trace_ctrl_fops);
0377
0378 fnic_fc_trace_clear = debugfs_create_file("fc_trace_clear",
0379 S_IFREG|S_IRUGO|S_IWUSR,
0380 fnic_trace_debugfs_root,
0381 &(fc_trc_flag->fc_clear),
0382 &fnic_trace_ctrl_fops);
0383
0384 fnic_fc_rdata_trace_debugfs_file =
0385 debugfs_create_file("fc_trace_rdata",
0386 S_IFREG|S_IRUGO|S_IWUSR,
0387 fnic_trace_debugfs_root,
0388 &(fc_trc_flag->fc_normal_file),
0389 &fnic_trace_debugfs_fops);
0390
0391 fnic_fc_trace_debugfs_file =
0392 debugfs_create_file("fc_trace",
0393 S_IFREG|S_IRUGO|S_IWUSR,
0394 fnic_trace_debugfs_root,
0395 &(fc_trc_flag->fc_row_file),
0396 &fnic_trace_debugfs_fops);
0397 }
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407 void fnic_fc_trace_debugfs_terminate(void)
0408 {
0409 debugfs_remove(fnic_fc_trace_debugfs_file);
0410 fnic_fc_trace_debugfs_file = NULL;
0411
0412 debugfs_remove(fnic_fc_rdata_trace_debugfs_file);
0413 fnic_fc_rdata_trace_debugfs_file = NULL;
0414
0415 debugfs_remove(fnic_fc_trace_enable);
0416 fnic_fc_trace_enable = NULL;
0417
0418 debugfs_remove(fnic_fc_trace_clear);
0419 fnic_fc_trace_clear = NULL;
0420 }
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435 static int fnic_reset_stats_open(struct inode *inode, struct file *file)
0436 {
0437 struct stats_debug_info *debug;
0438
0439 debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL);
0440 if (!debug)
0441 return -ENOMEM;
0442
0443 debug->i_private = inode->i_private;
0444
0445 file->private_data = debug;
0446
0447 return 0;
0448 }
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465 static ssize_t fnic_reset_stats_read(struct file *file,
0466 char __user *ubuf,
0467 size_t cnt, loff_t *ppos)
0468 {
0469 struct stats_debug_info *debug = file->private_data;
0470 struct fnic *fnic = (struct fnic *)debug->i_private;
0471 char buf[64];
0472 int len;
0473
0474 len = sprintf(buf, "%u\n", fnic->reset_stats);
0475
0476 return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
0477 }
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 static ssize_t fnic_reset_stats_write(struct file *file,
0494 const char __user *ubuf,
0495 size_t cnt, loff_t *ppos)
0496 {
0497 struct stats_debug_info *debug = file->private_data;
0498 struct fnic *fnic = (struct fnic *)debug->i_private;
0499 struct fnic_stats *stats = &fnic->fnic_stats;
0500 u64 *io_stats_p = (u64 *)&stats->io_stats;
0501 u64 *fw_stats_p = (u64 *)&stats->fw_stats;
0502 char buf[64];
0503 unsigned long val;
0504 int ret;
0505
0506 if (cnt >= sizeof(buf))
0507 return -EINVAL;
0508
0509 if (copy_from_user(&buf, ubuf, cnt))
0510 return -EFAULT;
0511
0512 buf[cnt] = 0;
0513
0514 ret = kstrtoul(buf, 10, &val);
0515 if (ret < 0)
0516 return ret;
0517
0518 fnic->reset_stats = val;
0519
0520 if (fnic->reset_stats) {
0521
0522
0523
0524
0525 atomic64_set(&fnic->io_cmpl_skip,
0526 atomic64_read(&stats->io_stats.active_ios));
0527 memset(&stats->abts_stats, 0, sizeof(struct abort_stats));
0528 memset(&stats->term_stats, 0,
0529 sizeof(struct terminate_stats));
0530 memset(&stats->reset_stats, 0, sizeof(struct reset_stats));
0531 memset(&stats->misc_stats, 0, sizeof(struct misc_stats));
0532 memset(&stats->vlan_stats, 0, sizeof(struct vlan_stats));
0533 memset(io_stats_p+1, 0,
0534 sizeof(struct io_path_stats) - sizeof(u64));
0535 memset(fw_stats_p+1, 0,
0536 sizeof(struct fw_stats) - sizeof(u64));
0537 ktime_get_real_ts64(&stats->stats_timestamps.last_reset_time);
0538 }
0539
0540 (*ppos)++;
0541 return cnt;
0542 }
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557 static int fnic_reset_stats_release(struct inode *inode,
0558 struct file *file)
0559 {
0560 struct stats_debug_info *debug = file->private_data;
0561 kfree(debug);
0562 return 0;
0563 }
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578 static int fnic_stats_debugfs_open(struct inode *inode,
0579 struct file *file)
0580 {
0581 struct fnic *fnic = inode->i_private;
0582 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
0583 struct stats_debug_info *debug;
0584 int buf_size = 2 * PAGE_SIZE;
0585
0586 debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL);
0587 if (!debug)
0588 return -ENOMEM;
0589
0590 debug->debug_buffer = vmalloc(buf_size);
0591 if (!debug->debug_buffer) {
0592 kfree(debug);
0593 return -ENOMEM;
0594 }
0595
0596 debug->buf_size = buf_size;
0597 memset((void *)debug->debug_buffer, 0, buf_size);
0598 debug->buffer_len = fnic_get_stats_data(debug, fnic_stats);
0599
0600 file->private_data = debug;
0601
0602 return 0;
0603 }
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621 static ssize_t fnic_stats_debugfs_read(struct file *file,
0622 char __user *ubuf,
0623 size_t nbytes,
0624 loff_t *pos)
0625 {
0626 struct stats_debug_info *debug = file->private_data;
0627 int rc = 0;
0628 rc = simple_read_from_buffer(ubuf, nbytes, pos,
0629 debug->debug_buffer,
0630 debug->buffer_len);
0631 return rc;
0632 }
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647 static int fnic_stats_debugfs_release(struct inode *inode,
0648 struct file *file)
0649 {
0650 struct stats_debug_info *debug = file->private_data;
0651 vfree(debug->debug_buffer);
0652 kfree(debug);
0653 return 0;
0654 }
0655
0656 static const struct file_operations fnic_stats_debugfs_fops = {
0657 .owner = THIS_MODULE,
0658 .open = fnic_stats_debugfs_open,
0659 .read = fnic_stats_debugfs_read,
0660 .release = fnic_stats_debugfs_release,
0661 };
0662
0663 static const struct file_operations fnic_reset_debugfs_fops = {
0664 .owner = THIS_MODULE,
0665 .open = fnic_reset_stats_open,
0666 .read = fnic_reset_stats_read,
0667 .write = fnic_reset_stats_write,
0668 .release = fnic_reset_stats_release,
0669 };
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679 void fnic_stats_debugfs_init(struct fnic *fnic)
0680 {
0681 char name[16];
0682
0683 snprintf(name, sizeof(name), "host%d", fnic->lport->host->host_no);
0684
0685 fnic->fnic_stats_debugfs_host = debugfs_create_dir(name,
0686 fnic_stats_debugfs_root);
0687
0688 fnic->fnic_stats_debugfs_file = debugfs_create_file("stats",
0689 S_IFREG|S_IRUGO|S_IWUSR,
0690 fnic->fnic_stats_debugfs_host,
0691 fnic,
0692 &fnic_stats_debugfs_fops);
0693
0694 fnic->fnic_reset_debugfs_file = debugfs_create_file("reset_stats",
0695 S_IFREG|S_IRUGO|S_IWUSR,
0696 fnic->fnic_stats_debugfs_host,
0697 fnic,
0698 &fnic_reset_debugfs_fops);
0699 }
0700
0701
0702
0703
0704
0705
0706
0707
0708 void fnic_stats_debugfs_remove(struct fnic *fnic)
0709 {
0710 if (!fnic)
0711 return;
0712
0713 debugfs_remove(fnic->fnic_stats_debugfs_file);
0714 fnic->fnic_stats_debugfs_file = NULL;
0715
0716 debugfs_remove(fnic->fnic_reset_debugfs_file);
0717 fnic->fnic_reset_debugfs_file = NULL;
0718
0719 debugfs_remove(fnic->fnic_stats_debugfs_host);
0720 fnic->fnic_stats_debugfs_host = NULL;
0721 }