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