Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 // Copyright 2012 Cisco Systems, Inc.  All rights reserved.
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  * fnic_debugfs_init - Initialize debugfs for fnic debug logging
0032  *
0033  * Description:
0034  * When Debugfs is configured this routine sets up the fnic debugfs
0035  * file system. If not already created, this routine will create the
0036  * fnic directory and statistics directory for trace buffer and
0037  * stats logging.
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     /* Allocate memory to structure */
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  * fnic_debugfs_terminate - Tear down debugfs infrastructure
0062  *
0063  * Description:
0064  * When Debugfs is configured this routine removes debugfs file system
0065  * elements that are specific to fnic.
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  * fnic_trace_ctrl_read -
0080  *          Read  trace_enable ,fc_trace_enable
0081  *              or fc_trace_clear debugfs file
0082  * @filp: The file pointer to read from.
0083  * @ubuf: The buffer to copy the data to.
0084  * @cnt: The number of bytes to read.
0085  * @ppos: The position in the file to start reading from.
0086  *
0087  * Description:
0088  * This routine reads value of variable fnic_tracing_enabled or
0089  * fnic_fc_tracing_enabled or fnic_fc_trace_cleared
0090  * and stores into local @buf.
0091  * It will start reading file at @ppos and
0092  * copy up to @cnt of data to @ubuf from @buf.
0093  *
0094  * Returns:
0095  * This function returns the amount of data that was read.
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  * fnic_trace_ctrl_write -
0120  * Write to trace_enable, fc_trace_enable or
0121  *         fc_trace_clear debugfs file
0122  * @filp: The file pointer to write from.
0123  * @ubuf: The buffer to copy the data from.
0124  * @cnt: The number of bytes to write.
0125  * @ppos: The position in the file to start writing to.
0126  *
0127  * Description:
0128  * This routine writes data from user buffer @ubuf to buffer @buf and
0129  * sets fc_trace_enable ,tracing_enable or fnic_fc_trace_cleared
0130  * value as per user input.
0131  *
0132  * Returns:
0133  * This function returns the amount of data that was written.
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  * fnic_trace_debugfs_open - Open the fnic trace log
0180  * @inode: The inode pointer
0181  * @file: The file pointer to attach the log output
0182  *
0183  * Description:
0184  * This routine is the entry point for the debugfs open file operation.
0185  * It allocates the necessary buffer for the log, fills the buffer from
0186  * the in-memory log and then returns a pointer to that log in
0187  * the private_data field in @file.
0188  *
0189  * Returns:
0190  * This function returns zero if successful. On error it will return
0191  * a negative error value.
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  * fnic_trace_debugfs_lseek - Seek through a debugfs file
0233  * @file: The file pointer to seek through.
0234  * @offset: The offset to seek to or the amount to seek by.
0235  * @howto: Indicates how to seek.
0236  *
0237  * Description:
0238  * This routine is the entry point for the debugfs lseek file operation.
0239  * The @howto parameter indicates whether @offset is the offset to directly
0240  * seek to, or if it is a value to seek forward or reverse by. This function
0241  * figures out what the new offset of the debugfs file will be and assigns
0242  * that value to the f_pos field of @file.
0243  *
0244  * Returns:
0245  * This function returns the new offset if successful and returns a negative
0246  * error if unable to process the seek.
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  * fnic_trace_debugfs_read - Read a debugfs file
0259  * @file: The file pointer to read from.
0260  * @ubuf: The buffer to copy the data to.
0261  * @nbytes: The number of bytes to read.
0262  * @pos: The position in the file to start reading from.
0263  *
0264  * Description:
0265  * This routine reads data from the buffer indicated in the private_data
0266  * field of @file. It will start reading at @pos and copy up to @nbytes of
0267  * data to @ubuf.
0268  *
0269  * Returns:
0270  * This function returns the amount of data that was read (this could be
0271  * less than @nbytes if the end of the file was reached).
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  * fnic_trace_debugfs_release - Release the buffer used to store
0288  * debugfs file data
0289  * @inode: The inode pointer
0290  * @file: The file pointer that contains the buffer to release
0291  *
0292  * Description:
0293  * This routine frees the buffer that was allocated when the debugfs
0294  * file was opened.
0295  *
0296  * Returns:
0297  * This function returns zero.
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  * fnic_trace_debugfs_init - Initialize debugfs for fnic trace logging
0319  *
0320  * Description:
0321  * When Debugfs is configured this routine sets up the fnic debugfs
0322  * file system. If not already created, this routine will create the
0323  * create file trace to log fnic trace buffer output into debugfs and
0324  * it will also create file trace_enable to control enable/disable of
0325  * trace logging into trace buffer.
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  * fnic_trace_debugfs_terminate - Tear down debugfs infrastructure
0344  *
0345  * Description:
0346  * When Debugfs is configured this routine removes debugfs file system
0347  * elements that are specific to fnic trace logging.
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  * fnic_fc_trace_debugfs_init -
0360  * Initialize debugfs for fnic control frame trace logging
0361  *
0362  * Description:
0363  * When Debugfs is configured this routine sets up the fnic_fc debugfs
0364  * file system. If not already created, this routine will create the
0365  * create file trace to log fnic fc trace buffer output into debugfs and
0366  * it will also create file fc_trace_enable to control enable/disable of
0367  * trace logging into trace buffer.
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  * fnic_fc_trace_debugfs_terminate - Tear down debugfs infrastructure
0401  *
0402  * Description:
0403  * When Debugfs is configured this routine removes debugfs file system
0404  * elements that are specific to fnic_fc trace logging.
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  * fnic_reset_stats_open - Open the reset_stats file
0424  * @inode: The inode pointer.
0425  * @file: The file pointer to attach the stats reset flag.
0426  *
0427  * Description:
0428  * This routine opens a debugsfs file reset_stats and stores i_private data
0429  * to debug structure to retrieve later for while performing other
0430  * file oprations.
0431  *
0432  * Returns:
0433  * This function returns zero if successful.
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  * fnic_reset_stats_read - Read a reset_stats debugfs file
0452  * @filp: The file pointer to read from.
0453  * @ubuf: The buffer to copy the data to.
0454  * @cnt: The number of bytes to read.
0455  * @ppos: The position in the file to start reading from.
0456  *
0457  * Description:
0458  * This routine reads value of variable reset_stats
0459  * and stores into local @buf. It will start reading file at @ppos and
0460  * copy up to @cnt of data to @ubuf from @buf.
0461  *
0462  * Returns:
0463  * This function returns the amount of data that was read.
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  * fnic_reset_stats_write - Write to reset_stats debugfs file
0481  * @filp: The file pointer to write from.
0482  * @ubuf: The buffer to copy the data from.
0483  * @cnt: The number of bytes to write.
0484  * @ppos: The position in the file to start writing to.
0485  *
0486  * Description:
0487  * This routine writes data from user buffer @ubuf to buffer @buf and
0488  * resets cumulative stats of fnic.
0489  *
0490  * Returns:
0491  * This function returns the amount of data that was written.
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         /* Skip variable is used to avoid descrepancies to Num IOs
0522          * and IO Completions stats. Skip incrementing No IO Compls
0523          * for pending active IOs after reset stats
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  * fnic_reset_stats_release - Release the buffer used to store
0546  * debugfs file data
0547  * @inode: The inode pointer
0548  * @file: The file pointer that contains the buffer to release
0549  *
0550  * Description:
0551  * This routine frees the buffer that was allocated when the debugfs
0552  * file was opened.
0553  *
0554  * Returns:
0555  * This function returns zero.
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  * fnic_stats_debugfs_open - Open the stats file for specific host
0567  * and get fnic stats.
0568  * @inode: The inode pointer.
0569  * @file: The file pointer to attach the specific host statistics.
0570  *
0571  * Description:
0572  * This routine opens a debugsfs file stats of specific host and print
0573  * fnic stats.
0574  *
0575  * Returns:
0576  * This function returns zero if successful.
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  * fnic_stats_debugfs_read - Read a debugfs file
0607  * @file: The file pointer to read from.
0608  * @ubuf: The buffer to copy the data to.
0609  * @nbytes: The number of bytes to read.
0610  * @pos: The position in the file to start reading from.
0611  *
0612  * Description:
0613  * This routine reads data from the buffer indicated in the private_data
0614  * field of @file. It will start reading at @pos and copy up to @nbytes of
0615  * data to @ubuf.
0616  *
0617  * Returns:
0618  * This function returns the amount of data that was read (this could be
0619  * less than @nbytes if the end of the file was reached).
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  * fnic_stats_stats_release - Release the buffer used to store
0636  * debugfs file data
0637  * @inode: The inode pointer
0638  * @file: The file pointer that contains the buffer to release
0639  *
0640  * Description:
0641  * This routine frees the buffer that was allocated when the debugfs
0642  * file was opened.
0643  *
0644  * Returns:
0645  * This function returns zero.
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  * fnic_stats_init - Initialize stats struct and create stats file per fnic
0673  *
0674  * Description:
0675  * When Debugfs is configured this routine sets up the stats file per fnic
0676  * It will create file stats and reset_stats under statistics/host# directory
0677  * to log per fnic stats.
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  * fnic_stats_debugfs_remove - Tear down debugfs infrastructure of stats
0703  *
0704  * Description:
0705  * When Debugfs is configured this routine removes debugfs file system
0706  * elements that are specific to fnic stats.
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 }