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 = vzalloc(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 fnic_dbg_prt->buffer_len = fnic_get_trace_data(fnic_dbg_prt); 211 } else { 212 fnic_dbg_prt->buffer = 213 vzalloc(array3_size(3, fnic_fc_trace_max_pages, 214 PAGE_SIZE)); 215 if (!fnic_dbg_prt->buffer) { 216 kfree(fnic_dbg_prt); 217 return -ENOMEM; 218 } 219 fnic_dbg_prt->buffer_len = 220 fnic_fc_trace_get_data(fnic_dbg_prt, *rdata_ptr); 221 } 222 file->private_data = fnic_dbg_prt; 223 224 return 0; 225 } 226 227 /* 228 * fnic_trace_debugfs_lseek - Seek through a debugfs file 229 * @file: The file pointer to seek through. 230 * @offset: The offset to seek to or the amount to seek by. 231 * @howto: Indicates how to seek. 232 * 233 * Description: 234 * This routine is the entry point for the debugfs lseek file operation. 235 * The @howto parameter indicates whether @offset is the offset to directly 236 * seek to, or if it is a value to seek forward or reverse by. This function 237 * figures out what the new offset of the debugfs file will be and assigns 238 * that value to the f_pos field of @file. 239 * 240 * Returns: 241 * This function returns the new offset if successful and returns a negative 242 * error if unable to process the seek. 243 */ 244 static loff_t fnic_trace_debugfs_lseek(struct file *file, 245 loff_t offset, 246 int howto) 247 { 248 fnic_dbgfs_t *fnic_dbg_prt = file->private_data; 249 return fixed_size_llseek(file, offset, howto, 250 fnic_dbg_prt->buffer_len); 251 } 252 253 /* 254 * fnic_trace_debugfs_read - Read a debugfs file 255 * @file: The file pointer to read from. 256 * @ubuf: The buffer to copy the data to. 257 * @nbytes: The number of bytes to read. 258 * @pos: The position in the file to start reading from. 259 * 260 * Description: 261 * This routine reads data from the buffer indicated in the private_data 262 * field of @file. It will start reading at @pos and copy up to @nbytes of 263 * data to @ubuf. 264 * 265 * Returns: 266 * This function returns the amount of data that was read (this could be 267 * less than @nbytes if the end of the file was reached). 268 */ 269 static ssize_t fnic_trace_debugfs_read(struct file *file, 270 char __user *ubuf, 271 size_t nbytes, 272 loff_t *pos) 273 { 274 fnic_dbgfs_t *fnic_dbg_prt = file->private_data; 275 int rc = 0; 276 rc = simple_read_from_buffer(ubuf, nbytes, pos, 277 fnic_dbg_prt->buffer, 278 fnic_dbg_prt->buffer_len); 279 return rc; 280 } 281 282 /* 283 * fnic_trace_debugfs_release - Release the buffer used to store 284 * debugfs file data 285 * @inode: The inode pointer 286 * @file: The file pointer that contains the buffer to release 287 * 288 * Description: 289 * This routine frees the buffer that was allocated when the debugfs 290 * file was opened. 291 * 292 * Returns: 293 * This function returns zero. 294 */ 295 static int fnic_trace_debugfs_release(struct inode *inode, 296 struct file *file) 297 { 298 fnic_dbgfs_t *fnic_dbg_prt = file->private_data; 299 300 vfree(fnic_dbg_prt->buffer); 301 kfree(fnic_dbg_prt); 302 return 0; 303 } 304 305 static const struct file_operations fnic_trace_debugfs_fops = { 306 .owner = THIS_MODULE, 307 .open = fnic_trace_debugfs_open, 308 .llseek = fnic_trace_debugfs_lseek, 309 .read = fnic_trace_debugfs_read, 310 .release = fnic_trace_debugfs_release, 311 }; 312 313 /* 314 * fnic_trace_debugfs_init - Initialize debugfs for fnic trace logging 315 * 316 * Description: 317 * When Debugfs is configured this routine sets up the fnic debugfs 318 * file system. If not already created, this routine will create the 319 * create file trace to log fnic trace buffer output into debugfs and 320 * it will also create file trace_enable to control enable/disable of 321 * trace logging into trace buffer. 322 */ 323 void fnic_trace_debugfs_init(void) 324 { 325 fnic_trace_enable = debugfs_create_file("tracing_enable", 326 S_IFREG|S_IRUGO|S_IWUSR, 327 fnic_trace_debugfs_root, 328 &(fc_trc_flag->fnic_trace), 329 &fnic_trace_ctrl_fops); 330 331 fnic_trace_debugfs_file = debugfs_create_file("trace", 332 S_IFREG|S_IRUGO|S_IWUSR, 333 fnic_trace_debugfs_root, 334 &(fc_trc_flag->fnic_trace), 335 &fnic_trace_debugfs_fops); 336 } 337 338 /* 339 * fnic_trace_debugfs_terminate - Tear down debugfs infrastructure 340 * 341 * Description: 342 * When Debugfs is configured this routine removes debugfs file system 343 * elements that are specific to fnic trace logging. 344 */ 345 void fnic_trace_debugfs_terminate(void) 346 { 347 debugfs_remove(fnic_trace_debugfs_file); 348 fnic_trace_debugfs_file = NULL; 349 350 debugfs_remove(fnic_trace_enable); 351 fnic_trace_enable = NULL; 352 } 353 354 /* 355 * fnic_fc_trace_debugfs_init - 356 * Initialize debugfs for fnic control frame trace logging 357 * 358 * Description: 359 * When Debugfs is configured this routine sets up the fnic_fc debugfs 360 * file system. If not already created, this routine will create the 361 * create file trace to log fnic fc trace buffer output into debugfs and 362 * it will also create file fc_trace_enable to control enable/disable of 363 * trace logging into trace buffer. 364 */ 365 366 void fnic_fc_trace_debugfs_init(void) 367 { 368 fnic_fc_trace_enable = debugfs_create_file("fc_trace_enable", 369 S_IFREG|S_IRUGO|S_IWUSR, 370 fnic_trace_debugfs_root, 371 &(fc_trc_flag->fc_trace), 372 &fnic_trace_ctrl_fops); 373 374 fnic_fc_trace_clear = debugfs_create_file("fc_trace_clear", 375 S_IFREG|S_IRUGO|S_IWUSR, 376 fnic_trace_debugfs_root, 377 &(fc_trc_flag->fc_clear), 378 &fnic_trace_ctrl_fops); 379 380 fnic_fc_rdata_trace_debugfs_file = 381 debugfs_create_file("fc_trace_rdata", 382 S_IFREG|S_IRUGO|S_IWUSR, 383 fnic_trace_debugfs_root, 384 &(fc_trc_flag->fc_normal_file), 385 &fnic_trace_debugfs_fops); 386 387 fnic_fc_trace_debugfs_file = 388 debugfs_create_file("fc_trace", 389 S_IFREG|S_IRUGO|S_IWUSR, 390 fnic_trace_debugfs_root, 391 &(fc_trc_flag->fc_row_file), 392 &fnic_trace_debugfs_fops); 393 } 394 395 /* 396 * fnic_fc_trace_debugfs_terminate - Tear down debugfs infrastructure 397 * 398 * Description: 399 * When Debugfs is configured this routine removes debugfs file system 400 * elements that are specific to fnic_fc trace logging. 401 */ 402 403 void fnic_fc_trace_debugfs_terminate(void) 404 { 405 debugfs_remove(fnic_fc_trace_debugfs_file); 406 fnic_fc_trace_debugfs_file = NULL; 407 408 debugfs_remove(fnic_fc_rdata_trace_debugfs_file); 409 fnic_fc_rdata_trace_debugfs_file = NULL; 410 411 debugfs_remove(fnic_fc_trace_enable); 412 fnic_fc_trace_enable = NULL; 413 414 debugfs_remove(fnic_fc_trace_clear); 415 fnic_fc_trace_clear = NULL; 416 } 417 418 /* 419 * fnic_reset_stats_open - Open the reset_stats file 420 * @inode: The inode pointer. 421 * @file: The file pointer to attach the stats reset flag. 422 * 423 * Description: 424 * This routine opens a debugsfs file reset_stats and stores i_private data 425 * to debug structure to retrieve later for while performing other 426 * file oprations. 427 * 428 * Returns: 429 * This function returns zero if successful. 430 */ 431 static int fnic_reset_stats_open(struct inode *inode, struct file *file) 432 { 433 struct stats_debug_info *debug; 434 435 debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL); 436 if (!debug) 437 return -ENOMEM; 438 439 debug->i_private = inode->i_private; 440 441 file->private_data = debug; 442 443 return 0; 444 } 445 446 /* 447 * fnic_reset_stats_read - Read a reset_stats debugfs file 448 * @filp: The file pointer to read from. 449 * @ubuf: The buffer to copy the data to. 450 * @cnt: The number of bytes to read. 451 * @ppos: The position in the file to start reading from. 452 * 453 * Description: 454 * This routine reads value of variable reset_stats 455 * and stores into local @buf. It will start reading file at @ppos and 456 * copy up to @cnt of data to @ubuf from @buf. 457 * 458 * Returns: 459 * This function returns the amount of data that was read. 460 */ 461 static ssize_t fnic_reset_stats_read(struct file *file, 462 char __user *ubuf, 463 size_t cnt, loff_t *ppos) 464 { 465 struct stats_debug_info *debug = file->private_data; 466 struct fnic *fnic = (struct fnic *)debug->i_private; 467 char buf[64]; 468 int len; 469 470 len = sprintf(buf, "%u\n", fnic->reset_stats); 471 472 return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); 473 } 474 475 /* 476 * fnic_reset_stats_write - Write to reset_stats debugfs file 477 * @filp: The file pointer to write from. 478 * @ubuf: The buffer to copy the data from. 479 * @cnt: The number of bytes to write. 480 * @ppos: The position in the file to start writing to. 481 * 482 * Description: 483 * This routine writes data from user buffer @ubuf to buffer @buf and 484 * resets cumulative stats of fnic. 485 * 486 * Returns: 487 * This function returns the amount of data that was written. 488 */ 489 static ssize_t fnic_reset_stats_write(struct file *file, 490 const char __user *ubuf, 491 size_t cnt, loff_t *ppos) 492 { 493 struct stats_debug_info *debug = file->private_data; 494 struct fnic *fnic = (struct fnic *)debug->i_private; 495 struct fnic_stats *stats = &fnic->fnic_stats; 496 u64 *io_stats_p = (u64 *)&stats->io_stats; 497 u64 *fw_stats_p = (u64 *)&stats->fw_stats; 498 char buf[64]; 499 unsigned long val; 500 int ret; 501 502 if (cnt >= sizeof(buf)) 503 return -EINVAL; 504 505 if (copy_from_user(&buf, ubuf, cnt)) 506 return -EFAULT; 507 508 buf[cnt] = 0; 509 510 ret = kstrtoul(buf, 10, &val); 511 if (ret < 0) 512 return ret; 513 514 fnic->reset_stats = val; 515 516 if (fnic->reset_stats) { 517 /* Skip variable is used to avoid descrepancies to Num IOs 518 * and IO Completions stats. Skip incrementing No IO Compls 519 * for pending active IOs after reset stats 520 */ 521 atomic64_set(&fnic->io_cmpl_skip, 522 atomic64_read(&stats->io_stats.active_ios)); 523 memset(&stats->abts_stats, 0, sizeof(struct abort_stats)); 524 memset(&stats->term_stats, 0, 525 sizeof(struct terminate_stats)); 526 memset(&stats->reset_stats, 0, sizeof(struct reset_stats)); 527 memset(&stats->misc_stats, 0, sizeof(struct misc_stats)); 528 memset(&stats->vlan_stats, 0, sizeof(struct vlan_stats)); 529 memset(io_stats_p+1, 0, 530 sizeof(struct io_path_stats) - sizeof(u64)); 531 memset(fw_stats_p+1, 0, 532 sizeof(struct fw_stats) - sizeof(u64)); 533 ktime_get_real_ts64(&stats->stats_timestamps.last_reset_time); 534 } 535 536 (*ppos)++; 537 return cnt; 538 } 539 540 /* 541 * fnic_reset_stats_release - Release the buffer used to store 542 * debugfs file data 543 * @inode: The inode pointer 544 * @file: The file pointer that contains the buffer to release 545 * 546 * Description: 547 * This routine frees the buffer that was allocated when the debugfs 548 * file was opened. 549 * 550 * Returns: 551 * This function returns zero. 552 */ 553 static int fnic_reset_stats_release(struct inode *inode, 554 struct file *file) 555 { 556 struct stats_debug_info *debug = file->private_data; 557 kfree(debug); 558 return 0; 559 } 560 561 /* 562 * fnic_stats_debugfs_open - Open the stats file for specific host 563 * and get fnic stats. 564 * @inode: The inode pointer. 565 * @file: The file pointer to attach the specific host statistics. 566 * 567 * Description: 568 * This routine opens a debugsfs file stats of specific host and print 569 * fnic stats. 570 * 571 * Returns: 572 * This function returns zero if successful. 573 */ 574 static int fnic_stats_debugfs_open(struct inode *inode, 575 struct file *file) 576 { 577 struct fnic *fnic = inode->i_private; 578 struct fnic_stats *fnic_stats = &fnic->fnic_stats; 579 struct stats_debug_info *debug; 580 int buf_size = 2 * PAGE_SIZE; 581 582 debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL); 583 if (!debug) 584 return -ENOMEM; 585 586 debug->debug_buffer = vmalloc(buf_size); 587 if (!debug->debug_buffer) { 588 kfree(debug); 589 return -ENOMEM; 590 } 591 592 debug->buf_size = buf_size; 593 memset((void *)debug->debug_buffer, 0, buf_size); 594 debug->buffer_len = fnic_get_stats_data(debug, fnic_stats); 595 596 file->private_data = debug; 597 598 return 0; 599 } 600 601 /* 602 * fnic_stats_debugfs_read - Read a debugfs file 603 * @file: The file pointer to read from. 604 * @ubuf: The buffer to copy the data to. 605 * @nbytes: The number of bytes to read. 606 * @pos: The position in the file to start reading from. 607 * 608 * Description: 609 * This routine reads data from the buffer indicated in the private_data 610 * field of @file. It will start reading at @pos and copy up to @nbytes of 611 * data to @ubuf. 612 * 613 * Returns: 614 * This function returns the amount of data that was read (this could be 615 * less than @nbytes if the end of the file was reached). 616 */ 617 static ssize_t fnic_stats_debugfs_read(struct file *file, 618 char __user *ubuf, 619 size_t nbytes, 620 loff_t *pos) 621 { 622 struct stats_debug_info *debug = file->private_data; 623 int rc = 0; 624 rc = simple_read_from_buffer(ubuf, nbytes, pos, 625 debug->debug_buffer, 626 debug->buffer_len); 627 return rc; 628 } 629 630 /* 631 * fnic_stats_stats_release - Release the buffer used to store 632 * debugfs file data 633 * @inode: The inode pointer 634 * @file: The file pointer that contains the buffer to release 635 * 636 * Description: 637 * This routine frees the buffer that was allocated when the debugfs 638 * file was opened. 639 * 640 * Returns: 641 * This function returns zero. 642 */ 643 static int fnic_stats_debugfs_release(struct inode *inode, 644 struct file *file) 645 { 646 struct stats_debug_info *debug = file->private_data; 647 vfree(debug->debug_buffer); 648 kfree(debug); 649 return 0; 650 } 651 652 static const struct file_operations fnic_stats_debugfs_fops = { 653 .owner = THIS_MODULE, 654 .open = fnic_stats_debugfs_open, 655 .read = fnic_stats_debugfs_read, 656 .release = fnic_stats_debugfs_release, 657 }; 658 659 static const struct file_operations fnic_reset_debugfs_fops = { 660 .owner = THIS_MODULE, 661 .open = fnic_reset_stats_open, 662 .read = fnic_reset_stats_read, 663 .write = fnic_reset_stats_write, 664 .release = fnic_reset_stats_release, 665 }; 666 667 /* 668 * fnic_stats_init - Initialize stats struct and create stats file per fnic 669 * 670 * Description: 671 * When Debugfs is configured this routine sets up the stats file per fnic 672 * It will create file stats and reset_stats under statistics/host# directory 673 * to log per fnic stats. 674 */ 675 void fnic_stats_debugfs_init(struct fnic *fnic) 676 { 677 char name[16]; 678 679 snprintf(name, sizeof(name), "host%d", fnic->lport->host->host_no); 680 681 fnic->fnic_stats_debugfs_host = debugfs_create_dir(name, 682 fnic_stats_debugfs_root); 683 684 fnic->fnic_stats_debugfs_file = debugfs_create_file("stats", 685 S_IFREG|S_IRUGO|S_IWUSR, 686 fnic->fnic_stats_debugfs_host, 687 fnic, 688 &fnic_stats_debugfs_fops); 689 690 fnic->fnic_reset_debugfs_file = debugfs_create_file("reset_stats", 691 S_IFREG|S_IRUGO|S_IWUSR, 692 fnic->fnic_stats_debugfs_host, 693 fnic, 694 &fnic_reset_debugfs_fops); 695 } 696 697 /* 698 * fnic_stats_debugfs_remove - Tear down debugfs infrastructure of stats 699 * 700 * Description: 701 * When Debugfs is configured this routine removes debugfs file system 702 * elements that are specific to fnic stats. 703 */ 704 void fnic_stats_debugfs_remove(struct fnic *fnic) 705 { 706 if (!fnic) 707 return; 708 709 debugfs_remove(fnic->fnic_stats_debugfs_file); 710 fnic->fnic_stats_debugfs_file = NULL; 711 712 debugfs_remove(fnic->fnic_reset_debugfs_file); 713 fnic->fnic_reset_debugfs_file = NULL; 714 715 debugfs_remove(fnic->fnic_stats_debugfs_host); 716 fnic->fnic_stats_debugfs_host = NULL; 717 } 718