1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/module.h>
19#include <linux/errno.h>
20#include <linux/debugfs.h>
21#include <linux/vmalloc.h>
22#include "fnic.h"
23
24static struct dentry *fnic_trace_debugfs_root;
25static struct dentry *fnic_trace_debugfs_file;
26static struct dentry *fnic_trace_enable;
27static struct dentry *fnic_stats_debugfs_root;
28
29static struct dentry *fnic_fc_trace_debugfs_file;
30static struct dentry *fnic_fc_rdata_trace_debugfs_file;
31static struct dentry *fnic_fc_trace_enable;
32static struct dentry *fnic_fc_trace_clear;
33
34struct fc_trace_flag_type {
35 u8 fc_row_file;
36 u8 fc_normal_file;
37 u8 fnic_trace;
38 u8 fc_trace;
39 u8 fc_clear;
40};
41
42static struct fc_trace_flag_type *fc_trc_flag;
43
44
45
46
47
48
49
50
51
52
53int fnic_debugfs_init(void)
54{
55 fnic_trace_debugfs_root = debugfs_create_dir("fnic", NULL);
56
57 fnic_stats_debugfs_root = debugfs_create_dir("statistics",
58 fnic_trace_debugfs_root);
59
60
61 fc_trc_flag = vmalloc(sizeof(struct fc_trace_flag_type));
62
63 if (fc_trc_flag) {
64 fc_trc_flag->fc_row_file = 0;
65 fc_trc_flag->fc_normal_file = 1;
66 fc_trc_flag->fnic_trace = 2;
67 fc_trc_flag->fc_trace = 3;
68 fc_trc_flag->fc_clear = 4;
69 }
70
71 return 0;
72}
73
74
75
76
77
78
79
80
81void fnic_debugfs_terminate(void)
82{
83 debugfs_remove(fnic_stats_debugfs_root);
84 fnic_stats_debugfs_root = NULL;
85
86 debugfs_remove(fnic_trace_debugfs_root);
87 fnic_trace_debugfs_root = NULL;
88
89 vfree(fc_trc_flag);
90}
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111static ssize_t fnic_trace_ctrl_read(struct file *filp,
112 char __user *ubuf,
113 size_t cnt, loff_t *ppos)
114{
115 char buf[64];
116 int len;
117 u8 *trace_type;
118 len = 0;
119 trace_type = (u8 *)filp->private_data;
120 if (*trace_type == fc_trc_flag->fnic_trace)
121 len = sprintf(buf, "%d\n", fnic_tracing_enabled);
122 else if (*trace_type == fc_trc_flag->fc_trace)
123 len = sprintf(buf, "%d\n", fnic_fc_tracing_enabled);
124 else if (*trace_type == fc_trc_flag->fc_clear)
125 len = sprintf(buf, "%d\n", fnic_fc_trace_cleared);
126 else
127 pr_err("fnic: Cannot read to any debugfs file\n");
128
129 return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
130}
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149static ssize_t fnic_trace_ctrl_write(struct file *filp,
150 const char __user *ubuf,
151 size_t cnt, loff_t *ppos)
152{
153 char buf[64];
154 unsigned long val;
155 int ret;
156 u8 *trace_type;
157 trace_type = (u8 *)filp->private_data;
158
159 if (cnt >= sizeof(buf))
160 return -EINVAL;
161
162 if (copy_from_user(&buf, ubuf, cnt))
163 return -EFAULT;
164
165 buf[cnt] = 0;
166
167 ret = kstrtoul(buf, 10, &val);
168 if (ret < 0)
169 return ret;
170
171 if (*trace_type == fc_trc_flag->fnic_trace)
172 fnic_tracing_enabled = val;
173 else if (*trace_type == fc_trc_flag->fc_trace)
174 fnic_fc_tracing_enabled = val;
175 else if (*trace_type == fc_trc_flag->fc_clear)
176 fnic_fc_trace_cleared = val;
177 else
178 pr_err("fnic: cannot write to any debugfs file\n");
179
180 (*ppos)++;
181
182 return cnt;
183}
184
185static const struct file_operations fnic_trace_ctrl_fops = {
186 .owner = THIS_MODULE,
187 .open = simple_open,
188 .read = fnic_trace_ctrl_read,
189 .write = fnic_trace_ctrl_write,
190};
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207static int fnic_trace_debugfs_open(struct inode *inode,
208 struct file *file)
209{
210 fnic_dbgfs_t *fnic_dbg_prt;
211 u8 *rdata_ptr;
212 rdata_ptr = (u8 *)inode->i_private;
213 fnic_dbg_prt = kzalloc(sizeof(fnic_dbgfs_t), GFP_KERNEL);
214 if (!fnic_dbg_prt)
215 return -ENOMEM;
216
217 if (*rdata_ptr == fc_trc_flag->fnic_trace) {
218 fnic_dbg_prt->buffer = vmalloc(array3_size(3, trace_max_pages,
219 PAGE_SIZE));
220 if (!fnic_dbg_prt->buffer) {
221 kfree(fnic_dbg_prt);
222 return -ENOMEM;
223 }
224 memset((void *)fnic_dbg_prt->buffer, 0,
225 3 * (trace_max_pages * PAGE_SIZE));
226 fnic_dbg_prt->buffer_len = fnic_get_trace_data(fnic_dbg_prt);
227 } else {
228 fnic_dbg_prt->buffer =
229 vmalloc(array3_size(3, fnic_fc_trace_max_pages,
230 PAGE_SIZE));
231 if (!fnic_dbg_prt->buffer) {
232 kfree(fnic_dbg_prt);
233 return -ENOMEM;
234 }
235 memset((void *)fnic_dbg_prt->buffer, 0,
236 3 * (fnic_fc_trace_max_pages * PAGE_SIZE));
237 fnic_dbg_prt->buffer_len =
238 fnic_fc_trace_get_data(fnic_dbg_prt, *rdata_ptr);
239 }
240 file->private_data = fnic_dbg_prt;
241
242 return 0;
243}
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262static loff_t fnic_trace_debugfs_lseek(struct file *file,
263 loff_t offset,
264 int howto)
265{
266 fnic_dbgfs_t *fnic_dbg_prt = file->private_data;
267 return fixed_size_llseek(file, offset, howto,
268 fnic_dbg_prt->buffer_len);
269}
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287static ssize_t fnic_trace_debugfs_read(struct file *file,
288 char __user *ubuf,
289 size_t nbytes,
290 loff_t *pos)
291{
292 fnic_dbgfs_t *fnic_dbg_prt = file->private_data;
293 int rc = 0;
294 rc = simple_read_from_buffer(ubuf, nbytes, pos,
295 fnic_dbg_prt->buffer,
296 fnic_dbg_prt->buffer_len);
297 return rc;
298}
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313static int fnic_trace_debugfs_release(struct inode *inode,
314 struct file *file)
315{
316 fnic_dbgfs_t *fnic_dbg_prt = file->private_data;
317
318 vfree(fnic_dbg_prt->buffer);
319 kfree(fnic_dbg_prt);
320 return 0;
321}
322
323static const struct file_operations fnic_trace_debugfs_fops = {
324 .owner = THIS_MODULE,
325 .open = fnic_trace_debugfs_open,
326 .llseek = fnic_trace_debugfs_lseek,
327 .read = fnic_trace_debugfs_read,
328 .release = fnic_trace_debugfs_release,
329};
330
331
332
333
334
335
336
337
338
339
340
341void fnic_trace_debugfs_init(void)
342{
343 fnic_trace_enable = debugfs_create_file("tracing_enable",
344 S_IFREG|S_IRUGO|S_IWUSR,
345 fnic_trace_debugfs_root,
346 &(fc_trc_flag->fnic_trace),
347 &fnic_trace_ctrl_fops);
348
349 fnic_trace_debugfs_file = debugfs_create_file("trace",
350 S_IFREG|S_IRUGO|S_IWUSR,
351 fnic_trace_debugfs_root,
352 &(fc_trc_flag->fnic_trace),
353 &fnic_trace_debugfs_fops);
354}
355
356
357
358
359
360
361
362
363void fnic_trace_debugfs_terminate(void)
364{
365 debugfs_remove(fnic_trace_debugfs_file);
366 fnic_trace_debugfs_file = NULL;
367
368 debugfs_remove(fnic_trace_enable);
369 fnic_trace_enable = NULL;
370}
371
372
373
374
375
376
377
378
379
380
381
382
383
384void fnic_fc_trace_debugfs_init(void)
385{
386 fnic_fc_trace_enable = debugfs_create_file("fc_trace_enable",
387 S_IFREG|S_IRUGO|S_IWUSR,
388 fnic_trace_debugfs_root,
389 &(fc_trc_flag->fc_trace),
390 &fnic_trace_ctrl_fops);
391
392 fnic_fc_trace_clear = debugfs_create_file("fc_trace_clear",
393 S_IFREG|S_IRUGO|S_IWUSR,
394 fnic_trace_debugfs_root,
395 &(fc_trc_flag->fc_clear),
396 &fnic_trace_ctrl_fops);
397
398 fnic_fc_rdata_trace_debugfs_file =
399 debugfs_create_file("fc_trace_rdata",
400 S_IFREG|S_IRUGO|S_IWUSR,
401 fnic_trace_debugfs_root,
402 &(fc_trc_flag->fc_normal_file),
403 &fnic_trace_debugfs_fops);
404
405 fnic_fc_trace_debugfs_file =
406 debugfs_create_file("fc_trace",
407 S_IFREG|S_IRUGO|S_IWUSR,
408 fnic_trace_debugfs_root,
409 &(fc_trc_flag->fc_row_file),
410 &fnic_trace_debugfs_fops);
411}
412
413
414
415
416
417
418
419
420
421void fnic_fc_trace_debugfs_terminate(void)
422{
423 debugfs_remove(fnic_fc_trace_debugfs_file);
424 fnic_fc_trace_debugfs_file = NULL;
425
426 debugfs_remove(fnic_fc_rdata_trace_debugfs_file);
427 fnic_fc_rdata_trace_debugfs_file = NULL;
428
429 debugfs_remove(fnic_fc_trace_enable);
430 fnic_fc_trace_enable = NULL;
431
432 debugfs_remove(fnic_fc_trace_clear);
433 fnic_fc_trace_clear = NULL;
434}
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449static int fnic_reset_stats_open(struct inode *inode, struct file *file)
450{
451 struct stats_debug_info *debug;
452
453 debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL);
454 if (!debug)
455 return -ENOMEM;
456
457 debug->i_private = inode->i_private;
458
459 file->private_data = debug;
460
461 return 0;
462}
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479static ssize_t fnic_reset_stats_read(struct file *file,
480 char __user *ubuf,
481 size_t cnt, loff_t *ppos)
482{
483 struct stats_debug_info *debug = file->private_data;
484 struct fnic *fnic = (struct fnic *)debug->i_private;
485 char buf[64];
486 int len;
487
488 len = sprintf(buf, "%u\n", fnic->reset_stats);
489
490 return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
491}
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507static ssize_t fnic_reset_stats_write(struct file *file,
508 const char __user *ubuf,
509 size_t cnt, loff_t *ppos)
510{
511 struct stats_debug_info *debug = file->private_data;
512 struct fnic *fnic = (struct fnic *)debug->i_private;
513 struct fnic_stats *stats = &fnic->fnic_stats;
514 u64 *io_stats_p = (u64 *)&stats->io_stats;
515 u64 *fw_stats_p = (u64 *)&stats->fw_stats;
516 char buf[64];
517 unsigned long val;
518 int ret;
519
520 if (cnt >= sizeof(buf))
521 return -EINVAL;
522
523 if (copy_from_user(&buf, ubuf, cnt))
524 return -EFAULT;
525
526 buf[cnt] = 0;
527
528 ret = kstrtoul(buf, 10, &val);
529 if (ret < 0)
530 return ret;
531
532 fnic->reset_stats = val;
533
534 if (fnic->reset_stats) {
535
536
537
538
539 atomic64_set(&fnic->io_cmpl_skip,
540 atomic64_read(&stats->io_stats.active_ios));
541 memset(&stats->abts_stats, 0, sizeof(struct abort_stats));
542 memset(&stats->term_stats, 0,
543 sizeof(struct terminate_stats));
544 memset(&stats->reset_stats, 0, sizeof(struct reset_stats));
545 memset(&stats->misc_stats, 0, sizeof(struct misc_stats));
546 memset(&stats->vlan_stats, 0, sizeof(struct vlan_stats));
547 memset(io_stats_p+1, 0,
548 sizeof(struct io_path_stats) - sizeof(u64));
549 memset(fw_stats_p+1, 0,
550 sizeof(struct fw_stats) - sizeof(u64));
551 ktime_get_real_ts64(&stats->stats_timestamps.last_reset_time);
552 }
553
554 (*ppos)++;
555 return cnt;
556}
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571static int fnic_reset_stats_release(struct inode *inode,
572 struct file *file)
573{
574 struct stats_debug_info *debug = file->private_data;
575 kfree(debug);
576 return 0;
577}
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592static int fnic_stats_debugfs_open(struct inode *inode,
593 struct file *file)
594{
595 struct fnic *fnic = inode->i_private;
596 struct fnic_stats *fnic_stats = &fnic->fnic_stats;
597 struct stats_debug_info *debug;
598 int buf_size = 2 * PAGE_SIZE;
599
600 debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL);
601 if (!debug)
602 return -ENOMEM;
603
604 debug->debug_buffer = vmalloc(buf_size);
605 if (!debug->debug_buffer) {
606 kfree(debug);
607 return -ENOMEM;
608 }
609
610 debug->buf_size = buf_size;
611 memset((void *)debug->debug_buffer, 0, buf_size);
612 debug->buffer_len = fnic_get_stats_data(debug, fnic_stats);
613
614 file->private_data = debug;
615
616 return 0;
617}
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635static ssize_t fnic_stats_debugfs_read(struct file *file,
636 char __user *ubuf,
637 size_t nbytes,
638 loff_t *pos)
639{
640 struct stats_debug_info *debug = file->private_data;
641 int rc = 0;
642 rc = simple_read_from_buffer(ubuf, nbytes, pos,
643 debug->debug_buffer,
644 debug->buffer_len);
645 return rc;
646}
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661static int fnic_stats_debugfs_release(struct inode *inode,
662 struct file *file)
663{
664 struct stats_debug_info *debug = file->private_data;
665 vfree(debug->debug_buffer);
666 kfree(debug);
667 return 0;
668}
669
670static const struct file_operations fnic_stats_debugfs_fops = {
671 .owner = THIS_MODULE,
672 .open = fnic_stats_debugfs_open,
673 .read = fnic_stats_debugfs_read,
674 .release = fnic_stats_debugfs_release,
675};
676
677static const struct file_operations fnic_reset_debugfs_fops = {
678 .owner = THIS_MODULE,
679 .open = fnic_reset_stats_open,
680 .read = fnic_reset_stats_read,
681 .write = fnic_reset_stats_write,
682 .release = fnic_reset_stats_release,
683};
684
685
686
687
688
689
690
691
692
693void fnic_stats_debugfs_init(struct fnic *fnic)
694{
695 char name[16];
696
697 snprintf(name, sizeof(name), "host%d", fnic->lport->host->host_no);
698
699 fnic->fnic_stats_debugfs_host = debugfs_create_dir(name,
700 fnic_stats_debugfs_root);
701
702 fnic->fnic_stats_debugfs_file = debugfs_create_file("stats",
703 S_IFREG|S_IRUGO|S_IWUSR,
704 fnic->fnic_stats_debugfs_host,
705 fnic,
706 &fnic_stats_debugfs_fops);
707
708 fnic->fnic_reset_debugfs_file = debugfs_create_file("reset_stats",
709 S_IFREG|S_IRUGO|S_IWUSR,
710 fnic->fnic_stats_debugfs_host,
711 fnic,
712 &fnic_reset_debugfs_fops);
713}
714
715
716
717
718
719
720
721
722void fnic_stats_debugfs_remove(struct fnic *fnic)
723{
724 if (!fnic)
725 return;
726
727 debugfs_remove(fnic->fnic_stats_debugfs_file);
728 fnic->fnic_stats_debugfs_file = NULL;
729
730 debugfs_remove(fnic->fnic_reset_debugfs_file);
731 fnic->fnic_reset_debugfs_file = NULL;
732
733 debugfs_remove(fnic->fnic_stats_debugfs_host);
734 fnic->fnic_stats_debugfs_host = NULL;
735}
736