1/* 2 * Copyright 2012 Cisco Systems, Inc. All rights reserved. 3 * 4 * This program is free software; you may redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; version 2 of the License. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 15 * SOFTWARE. 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 * fnic_debugfs_init - Initialize debugfs for fnic debug logging 46 * 47 * Description: 48 * When Debugfs is configured this routine sets up the fnic debugfs 49 * file system. If not already created, this routine will create the 50 * fnic directory and statistics directory for trace buffer and 51 * stats logging. 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 /* Allocate memory to structure */ 61 fc_trc_flag = (struct fc_trace_flag_type *) 62 vmalloc(sizeof(struct fc_trace_flag_type)); 63 64 if (fc_trc_flag) { 65 fc_trc_flag->fc_row_file = 0; 66 fc_trc_flag->fc_normal_file = 1; 67 fc_trc_flag->fnic_trace = 2; 68 fc_trc_flag->fc_trace = 3; 69 fc_trc_flag->fc_clear = 4; 70 return 0; 71 } 72 73 return -ENOMEM; 74} 75 76/* 77 * fnic_debugfs_terminate - Tear down debugfs infrastructure 78 * 79 * Description: 80 * When Debugfs is configured this routine removes debugfs file system 81 * elements that are specific to fnic. 82 */ 83void fnic_debugfs_terminate(void) 84{ 85 debugfs_remove(fnic_stats_debugfs_root); 86 fnic_stats_debugfs_root = NULL; 87 88 debugfs_remove(fnic_trace_debugfs_root); 89 fnic_trace_debugfs_root = NULL; 90 91 if (fc_trc_flag) 92 vfree(fc_trc_flag); 93} 94 95/* 96 * fnic_trace_ctrl_read - 97 * Read trace_enable ,fc_trace_enable 98 * or fc_trace_clear debugfs file 99 * @filp: The file pointer to read from. 100 * @ubuf: The buffer to copy the data to. 101 * @cnt: The number of bytes to read. 102 * @ppos: The position in the file to start reading from. 103 * 104 * Description: 105 * This routine reads value of variable fnic_tracing_enabled or 106 * fnic_fc_tracing_enabled or fnic_fc_trace_cleared 107 * and stores into local @buf. 108 * It will start reading file at @ppos and 109 * copy up to @cnt of data to @ubuf from @buf. 110 * 111 * Returns: 112 * This function returns the amount of data that was read. 113 */ 114static ssize_t fnic_trace_ctrl_read(struct file *filp, 115 char __user *ubuf, 116 size_t cnt, loff_t *ppos) 117{ 118 char buf[64]; 119 int len; 120 u8 *trace_type; 121 len = 0; 122 trace_type = (u8 *)filp->private_data; 123 if (*trace_type == fc_trc_flag->fnic_trace) 124 len = sprintf(buf, "%d\n", fnic_tracing_enabled); 125 else if (*trace_type == fc_trc_flag->fc_trace) 126 len = sprintf(buf, "%d\n", fnic_fc_tracing_enabled); 127 else if (*trace_type == fc_trc_flag->fc_clear) 128 len = sprintf(buf, "%d\n", fnic_fc_trace_cleared); 129 else 130 pr_err("fnic: Cannot read to any debugfs file\n"); 131 132 return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); 133} 134 135/* 136 * fnic_trace_ctrl_write - 137 * Write to trace_enable, fc_trace_enable or 138 * fc_trace_clear debugfs file 139 * @filp: The file pointer to write from. 140 * @ubuf: The buffer to copy the data from. 141 * @cnt: The number of bytes to write. 142 * @ppos: The position in the file to start writing to. 143 * 144 * Description: 145 * This routine writes data from user buffer @ubuf to buffer @buf and 146 * sets fc_trace_enable ,tracing_enable or fnic_fc_trace_cleared 147 * value as per user input. 148 * 149 * Returns: 150 * This function returns the amount of data that was written. 151 */ 152static ssize_t fnic_trace_ctrl_write(struct file *filp, 153 const char __user *ubuf, 154 size_t cnt, loff_t *ppos) 155{ 156 char buf[64]; 157 unsigned long val; 158 int ret; 159 u8 *trace_type; 160 trace_type = (u8 *)filp->private_data; 161 162 if (cnt >= sizeof(buf)) 163 return -EINVAL; 164 165 if (copy_from_user(&buf, ubuf, cnt)) 166 return -EFAULT; 167 168 buf[cnt] = 0; 169 170 ret = kstrtoul(buf, 10, &val); 171 if (ret < 0) 172 return ret; 173 174 if (*trace_type == fc_trc_flag->fnic_trace) 175 fnic_tracing_enabled = val; 176 else if (*trace_type == fc_trc_flag->fc_trace) 177 fnic_fc_tracing_enabled = val; 178 else if (*trace_type == fc_trc_flag->fc_clear) 179 fnic_fc_trace_cleared = val; 180 else 181 pr_err("fnic: cannot write to any debugfs file\n"); 182 183 (*ppos)++; 184 185 return cnt; 186} 187 188static const struct file_operations fnic_trace_ctrl_fops = { 189 .owner = THIS_MODULE, 190 .open = simple_open, 191 .read = fnic_trace_ctrl_read, 192 .write = fnic_trace_ctrl_write, 193}; 194 195/* 196 * fnic_trace_debugfs_open - Open the fnic trace log 197 * @inode: The inode pointer 198 * @file: The file pointer to attach the log output 199 * 200 * Description: 201 * This routine is the entry point for the debugfs open file operation. 202 * It allocates the necessary buffer for the log, fills the buffer from 203 * the in-memory log and then returns a pointer to that log in 204 * the private_data field in @file. 205 * 206 * Returns: 207 * This function returns zero if successful. On error it will return 208 * a negative error value. 209 */ 210static int fnic_trace_debugfs_open(struct inode *inode, 211 struct file *file) 212{ 213 fnic_dbgfs_t *fnic_dbg_prt; 214 u8 *rdata_ptr; 215 rdata_ptr = (u8 *)inode->i_private; 216 fnic_dbg_prt = kzalloc(sizeof(fnic_dbgfs_t), GFP_KERNEL); 217 if (!fnic_dbg_prt) 218 return -ENOMEM; 219 220 if (*rdata_ptr == fc_trc_flag->fnic_trace) { 221 fnic_dbg_prt->buffer = vmalloc(array3_size(3, trace_max_pages, 222 PAGE_SIZE)); 223 if (!fnic_dbg_prt->buffer) { 224 kfree(fnic_dbg_prt); 225 return -ENOMEM; 226 } 227 memset((void *)fnic_dbg_prt->buffer, 0, 228 3 * (trace_max_pages * PAGE_SIZE)); 229 fnic_dbg_prt->buffer_len = fnic_get_trace_data(fnic_dbg_prt); 230 } else { 231 fnic_dbg_prt->buffer = 232 vmalloc(array3_size(3, fnic_fc_trace_max_pages, 233 PAGE_SIZE)); 234 if (!fnic_dbg_prt->buffer) { 235 kfree(fnic_dbg_prt); 236 return -ENOMEM; 237 } 238 memset((void *)fnic_dbg_prt->buffer, 0, 239 3 * (fnic_fc_trace_max_pages * PAGE_SIZE)); 240 fnic_dbg_prt->buffer_len = 241 fnic_fc_trace_get_data(fnic_dbg_prt, *rdata_ptr); 242 } 243 file->private_data = fnic_dbg_prt; 244 245 return 0; 246} 247 248/* 249 * fnic_trace_debugfs_lseek - Seek through a debugfs file 250 * @file: The file pointer to seek through. 251 * @offset: The offset to seek to or the amount to seek by. 252 * @howto: Indicates how to seek. 253 * 254 * Description: 255 * This routine is the entry point for the debugfs lseek file operation. 256 * The @howto parameter indicates whether @offset is the offset to directly 257 * seek to, or if it is a value to seek forward or reverse by. This function 258 * figures out what the new offset of the debugfs file will be and assigns 259 * that value to the f_pos field of @file. 260 * 261 * Returns: 262 * This function returns the new offset if successful and returns a negative 263 * error if unable to process the seek. 264 */ 265static loff_t fnic_trace_debugfs_lseek(struct file *file, 266 loff_t offset, 267 int howto) 268{ 269 fnic_dbgfs_t *fnic_dbg_prt = file->private_data; 270 return fixed_size_llseek(file, offset, howto, 271 fnic_dbg_prt->buffer_len); 272} 273 274/* 275 * fnic_trace_debugfs_read - Read a debugfs file 276 * @file: The file pointer to read from. 277 * @ubuf: The buffer to copy the data to. 278 * @nbytes: The number of bytes to read. 279 * @pos: The position in the file to start reading from. 280 * 281 * Description: 282 * This routine reads data from the buffer indicated in the private_data 283 * field of @file. It will start reading at @pos and copy up to @nbytes of 284 * data to @ubuf. 285 * 286 * Returns: 287 * This function returns the amount of data that was read (this could be 288 * less than @nbytes if the end of the file was reached). 289 */ 290static ssize_t fnic_trace_debugfs_read(struct file *file, 291 char __user *ubuf, 292 size_t nbytes, 293 loff_t *pos) 294{ 295 fnic_dbgfs_t *fnic_dbg_prt = file->private_data; 296 int rc = 0; 297 rc = simple_read_from_buffer(ubuf, nbytes, pos, 298 fnic_dbg_prt->buffer, 299 fnic_dbg_prt->buffer_len); 300 return rc; 301} 302 303/* 304 * fnic_trace_debugfs_release - Release the buffer used to store 305 * debugfs file data 306 * @inode: The inode pointer 307 * @file: The file pointer that contains the buffer to release 308 * 309 * Description: 310 * This routine frees the buffer that was allocated when the debugfs 311 * file was opened. 312 * 313 * Returns: 314 * This function returns zero. 315 */ 316static int fnic_trace_debugfs_release(struct inode *inode, 317 struct file *file) 318{ 319 fnic_dbgfs_t *fnic_dbg_prt = file->private_data; 320 321 vfree(fnic_dbg_prt->buffer); 322 kfree(fnic_dbg_prt); 323 return 0; 324} 325 326static const struct file_operations fnic_trace_debugfs_fops = { 327 .owner = THIS_MODULE, 328 .open = fnic_trace_debugfs_open, 329 .llseek = fnic_trace_debugfs_lseek, 330 .read = fnic_trace_debugfs_read, 331 .release = fnic_trace_debugfs_release, 332}; 333 334/* 335 * fnic_trace_debugfs_init - Initialize debugfs for fnic trace logging 336 * 337 * Description: 338 * When Debugfs is configured this routine sets up the fnic debugfs 339 * file system. If not already created, this routine will create the 340 * create file trace to log fnic trace buffer output into debugfs and 341 * it will also create file trace_enable to control enable/disable of 342 * trace logging into trace buffer. 343 */ 344void fnic_trace_debugfs_init(void) 345{ 346 fnic_trace_enable = debugfs_create_file("tracing_enable", 347 S_IFREG|S_IRUGO|S_IWUSR, 348 fnic_trace_debugfs_root, 349 &(fc_trc_flag->fnic_trace), 350 &fnic_trace_ctrl_fops); 351 352 fnic_trace_debugfs_file = debugfs_create_file("trace", 353 S_IFREG|S_IRUGO|S_IWUSR, 354 fnic_trace_debugfs_root, 355 &(fc_trc_flag->fnic_trace), 356 &fnic_trace_debugfs_fops); 357} 358 359/* 360 * fnic_trace_debugfs_terminate - Tear down debugfs infrastructure 361 * 362 * Description: 363 * When Debugfs is configured this routine removes debugfs file system 364 * elements that are specific to fnic trace logging. 365 */ 366void fnic_trace_debugfs_terminate(void) 367{ 368 debugfs_remove(fnic_trace_debugfs_file); 369 fnic_trace_debugfs_file = NULL; 370 371 debugfs_remove(fnic_trace_enable); 372 fnic_trace_enable = NULL; 373} 374 375/* 376 * fnic_fc_trace_debugfs_init - 377 * Initialize debugfs for fnic control frame trace logging 378 * 379 * Description: 380 * When Debugfs is configured this routine sets up the fnic_fc debugfs 381 * file system. If not already created, this routine will create the 382 * create file trace to log fnic fc trace buffer output into debugfs and 383 * it will also create file fc_trace_enable to control enable/disable of 384 * trace logging into trace buffer. 385 */ 386 387void fnic_fc_trace_debugfs_init(void) 388{ 389 fnic_fc_trace_enable = debugfs_create_file("fc_trace_enable", 390 S_IFREG|S_IRUGO|S_IWUSR, 391 fnic_trace_debugfs_root, 392 &(fc_trc_flag->fc_trace), 393 &fnic_trace_ctrl_fops); 394 395 fnic_fc_trace_clear = debugfs_create_file("fc_trace_clear", 396 S_IFREG|S_IRUGO|S_IWUSR, 397 fnic_trace_debugfs_root, 398 &(fc_trc_flag->fc_clear), 399 &fnic_trace_ctrl_fops); 400 401 fnic_fc_rdata_trace_debugfs_file = 402 debugfs_create_file("fc_trace_rdata", 403 S_IFREG|S_IRUGO|S_IWUSR, 404 fnic_trace_debugfs_root, 405 &(fc_trc_flag->fc_normal_file), 406 &fnic_trace_debugfs_fops); 407 408 fnic_fc_trace_debugfs_file = 409 debugfs_create_file("fc_trace", 410 S_IFREG|S_IRUGO|S_IWUSR, 411 fnic_trace_debugfs_root, 412 &(fc_trc_flag->fc_row_file), 413 &fnic_trace_debugfs_fops); 414} 415 416/* 417 * fnic_fc_trace_debugfs_terminate - Tear down debugfs infrastructure 418 * 419 * Description: 420 * When Debugfs is configured this routine removes debugfs file system 421 * elements that are specific to fnic_fc trace logging. 422 */ 423 424void fnic_fc_trace_debugfs_terminate(void) 425{ 426 debugfs_remove(fnic_fc_trace_debugfs_file); 427 fnic_fc_trace_debugfs_file = NULL; 428 429 debugfs_remove(fnic_fc_rdata_trace_debugfs_file); 430 fnic_fc_rdata_trace_debugfs_file = NULL; 431 432 debugfs_remove(fnic_fc_trace_enable); 433 fnic_fc_trace_enable = NULL; 434 435 debugfs_remove(fnic_fc_trace_clear); 436 fnic_fc_trace_clear = NULL; 437} 438 439/* 440 * fnic_reset_stats_open - Open the reset_stats file 441 * @inode: The inode pointer. 442 * @file: The file pointer to attach the stats reset flag. 443 * 444 * Description: 445 * This routine opens a debugsfs file reset_stats and stores i_private data 446 * to debug structure to retrieve later for while performing other 447 * file oprations. 448 * 449 * Returns: 450 * This function returns zero if successful. 451 */ 452static int fnic_reset_stats_open(struct inode *inode, struct file *file) 453{ 454 struct stats_debug_info *debug; 455 456 debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL); 457 if (!debug) 458 return -ENOMEM; 459 460 debug->i_private = inode->i_private; 461 462 file->private_data = debug; 463 464 return 0; 465} 466 467/* 468 * fnic_reset_stats_read - Read a reset_stats debugfs file 469 * @filp: The file pointer to read from. 470 * @ubuf: The buffer to copy the data to. 471 * @cnt: The number of bytes to read. 472 * @ppos: The position in the file to start reading from. 473 * 474 * Description: 475 * This routine reads value of variable reset_stats 476 * and stores into local @buf. It will start reading file at @ppos and 477 * copy up to @cnt of data to @ubuf from @buf. 478 * 479 * Returns: 480 * This function returns the amount of data that was read. 481 */ 482static ssize_t fnic_reset_stats_read(struct file *file, 483 char __user *ubuf, 484 size_t cnt, loff_t *ppos) 485{ 486 struct stats_debug_info *debug = file->private_data; 487 struct fnic *fnic = (struct fnic *)debug->i_private; 488 char buf[64]; 489 int len; 490 491 len = sprintf(buf, "%u\n", fnic->reset_stats); 492 493 return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); 494} 495 496/* 497 * fnic_reset_stats_write - Write to reset_stats debugfs file 498 * @filp: The file pointer to write from. 499 * @ubuf: The buffer to copy the data from. 500 * @cnt: The number of bytes to write. 501 * @ppos: The position in the file to start writing to. 502 * 503 * Description: 504 * This routine writes data from user buffer @ubuf to buffer @buf and 505 * resets cumulative stats of fnic. 506 * 507 * Returns: 508 * This function returns the amount of data that was written. 509 */ 510static ssize_t fnic_reset_stats_write(struct file *file, 511 const char __user *ubuf, 512 size_t cnt, loff_t *ppos) 513{ 514 struct stats_debug_info *debug = file->private_data; 515 struct fnic *fnic = (struct fnic *)debug->i_private; 516 struct fnic_stats *stats = &fnic->fnic_stats; 517 u64 *io_stats_p = (u64 *)&stats->io_stats; 518 u64 *fw_stats_p = (u64 *)&stats->fw_stats; 519 char buf[64]; 520 unsigned long val; 521 int ret; 522 523 if (cnt >= sizeof(buf)) 524 return -EINVAL; 525 526 if (copy_from_user(&buf, ubuf, cnt)) 527 return -EFAULT; 528 529 buf[cnt] = 0; 530 531 ret = kstrtoul(buf, 10, &val); 532 if (ret < 0) 533 return ret; 534 535 fnic->reset_stats = val; 536 537 if (fnic->reset_stats) { 538 /* Skip variable is used to avoid descrepancies to Num IOs 539 * and IO Completions stats. Skip incrementing No IO Compls 540 * for pending active IOs after reset stats 541 */ 542 atomic64_set(&fnic->io_cmpl_skip, 543 atomic64_read(&stats->io_stats.active_ios)); 544 memset(&stats->abts_stats, 0, sizeof(struct abort_stats)); 545 memset(&stats->term_stats, 0, 546 sizeof(struct terminate_stats)); 547 memset(&stats->reset_stats, 0, sizeof(struct reset_stats)); 548 memset(&stats->misc_stats, 0, sizeof(struct misc_stats)); 549 memset(&stats->vlan_stats, 0, sizeof(struct vlan_stats)); 550 memset(io_stats_p+1, 0, 551 sizeof(struct io_path_stats) - sizeof(u64)); 552 memset(fw_stats_p+1, 0, 553 sizeof(struct fw_stats) - sizeof(u64)); 554 ktime_get_real_ts64(&stats->stats_timestamps.last_reset_time); 555 } 556 557 (*ppos)++; 558 return cnt; 559} 560 561/* 562 * fnic_reset_stats_release - Release the buffer used to store 563 * debugfs file data 564 * @inode: The inode pointer 565 * @file: The file pointer that contains the buffer to release 566 * 567 * Description: 568 * This routine frees the buffer that was allocated when the debugfs 569 * file was opened. 570 * 571 * Returns: 572 * This function returns zero. 573 */ 574static int fnic_reset_stats_release(struct inode *inode, 575 struct file *file) 576{ 577 struct stats_debug_info *debug = file->private_data; 578 kfree(debug); 579 return 0; 580} 581 582/* 583 * fnic_stats_debugfs_open - Open the stats file for specific host 584 * and get fnic stats. 585 * @inode: The inode pointer. 586 * @file: The file pointer to attach the specific host statistics. 587 * 588 * Description: 589 * This routine opens a debugsfs file stats of specific host and print 590 * fnic stats. 591 * 592 * Returns: 593 * This function returns zero if successful. 594 */ 595static int fnic_stats_debugfs_open(struct inode *inode, 596 struct file *file) 597{ 598 struct fnic *fnic = inode->i_private; 599 struct fnic_stats *fnic_stats = &fnic->fnic_stats; 600 struct stats_debug_info *debug; 601 int buf_size = 2 * PAGE_SIZE; 602 603 debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL); 604 if (!debug) 605 return -ENOMEM; 606 607 debug->debug_buffer = vmalloc(buf_size); 608 if (!debug->debug_buffer) { 609 kfree(debug); 610 return -ENOMEM; 611 } 612 613 debug->buf_size = buf_size; 614 memset((void *)debug->debug_buffer, 0, buf_size); 615 debug->buffer_len = fnic_get_stats_data(debug, fnic_stats); 616 617 file->private_data = debug; 618 619 return 0; 620} 621 622/* 623 * fnic_stats_debugfs_read - Read a debugfs file 624 * @file: The file pointer to read from. 625 * @ubuf: The buffer to copy the data to. 626 * @nbytes: The number of bytes to read. 627 * @pos: The position in the file to start reading from. 628 * 629 * Description: 630 * This routine reads data from the buffer indicated in the private_data 631 * field of @file. It will start reading at @pos and copy up to @nbytes of 632 * data to @ubuf. 633 * 634 * Returns: 635 * This function returns the amount of data that was read (this could be 636 * less than @nbytes if the end of the file was reached). 637 */ 638static ssize_t fnic_stats_debugfs_read(struct file *file, 639 char __user *ubuf, 640 size_t nbytes, 641 loff_t *pos) 642{ 643 struct stats_debug_info *debug = file->private_data; 644 int rc = 0; 645 rc = simple_read_from_buffer(ubuf, nbytes, pos, 646 debug->debug_buffer, 647 debug->buffer_len); 648 return rc; 649} 650 651/* 652 * fnic_stats_stats_release - Release the buffer used to store 653 * debugfs file data 654 * @inode: The inode pointer 655 * @file: The file pointer that contains the buffer to release 656 * 657 * Description: 658 * This routine frees the buffer that was allocated when the debugfs 659 * file was opened. 660 * 661 * Returns: 662 * This function returns zero. 663 */ 664static int fnic_stats_debugfs_release(struct inode *inode, 665 struct file *file) 666{ 667 struct stats_debug_info *debug = file->private_data; 668 vfree(debug->debug_buffer); 669 kfree(debug); 670 return 0; 671} 672 673static const struct file_operations fnic_stats_debugfs_fops = { 674 .owner = THIS_MODULE, 675 .open = fnic_stats_debugfs_open, 676 .read = fnic_stats_debugfs_read, 677 .release = fnic_stats_debugfs_release, 678}; 679 680static const struct file_operations fnic_reset_debugfs_fops = { 681 .owner = THIS_MODULE, 682 .open = fnic_reset_stats_open, 683 .read = fnic_reset_stats_read, 684 .write = fnic_reset_stats_write, 685 .release = fnic_reset_stats_release, 686}; 687 688/* 689 * fnic_stats_init - Initialize stats struct and create stats file per fnic 690 * 691 * Description: 692 * When Debugfs is configured this routine sets up the stats file per fnic 693 * It will create file stats and reset_stats under statistics/host# directory 694 * to log per fnic stats. 695 */ 696void fnic_stats_debugfs_init(struct fnic *fnic) 697{ 698 char name[16]; 699 700 snprintf(name, sizeof(name), "host%d", fnic->lport->host->host_no); 701 702 fnic->fnic_stats_debugfs_host = debugfs_create_dir(name, 703 fnic_stats_debugfs_root); 704 705 fnic->fnic_stats_debugfs_file = debugfs_create_file("stats", 706 S_IFREG|S_IRUGO|S_IWUSR, 707 fnic->fnic_stats_debugfs_host, 708 fnic, 709 &fnic_stats_debugfs_fops); 710 711 fnic->fnic_reset_debugfs_file = debugfs_create_file("reset_stats", 712 S_IFREG|S_IRUGO|S_IWUSR, 713 fnic->fnic_stats_debugfs_host, 714 fnic, 715 &fnic_reset_debugfs_fops); 716} 717 718/* 719 * fnic_stats_debugfs_remove - Tear down debugfs infrastructure of stats 720 * 721 * Description: 722 * When Debugfs is configured this routine removes debugfs file system 723 * elements that are specific to fnic stats. 724 */ 725void fnic_stats_debugfs_remove(struct fnic *fnic) 726{ 727 if (!fnic) 728 return; 729 730 debugfs_remove(fnic->fnic_stats_debugfs_file); 731 fnic->fnic_stats_debugfs_file = NULL; 732 733 debugfs_remove(fnic->fnic_reset_debugfs_file); 734 fnic->fnic_reset_debugfs_file = NULL; 735 736 debugfs_remove(fnic->fnic_stats_debugfs_host); 737 fnic->fnic_stats_debugfs_host = NULL; 738} 739