162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci// Copyright 2014 Cisco Systems, Inc. All rights reserved. 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/module.h> 562306a36Sopenharmony_ci#include <linux/errno.h> 662306a36Sopenharmony_ci#include <linux/debugfs.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include "snic.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci/* 1162306a36Sopenharmony_ci * snic_debugfs_init - Initialize debugfs for snic debug logging 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * Description: 1462306a36Sopenharmony_ci * When Debugfs is configured this routine sets up fnic debugfs 1562306a36Sopenharmony_ci * filesystem. If not already created. this routine will crate the 1662306a36Sopenharmony_ci * fnic directory and statistics directory for trace buffer and 1762306a36Sopenharmony_ci * stats logging 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_civoid snic_debugfs_init(void) 2062306a36Sopenharmony_ci{ 2162306a36Sopenharmony_ci snic_glob->trc_root = debugfs_create_dir("snic", NULL); 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci snic_glob->stats_root = debugfs_create_dir("statistics", 2462306a36Sopenharmony_ci snic_glob->trc_root); 2562306a36Sopenharmony_ci} 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* 2862306a36Sopenharmony_ci * snic_debugfs_term - Tear down debugfs intrastructure 2962306a36Sopenharmony_ci * 3062306a36Sopenharmony_ci * Description: 3162306a36Sopenharmony_ci * When Debufs is configured this routine removes debugfs file system 3262306a36Sopenharmony_ci * elements that are specific to snic 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_civoid 3562306a36Sopenharmony_cisnic_debugfs_term(void) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci debugfs_remove(snic_glob->stats_root); 3862306a36Sopenharmony_ci snic_glob->stats_root = NULL; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci debugfs_remove(snic_glob->trc_root); 4162306a36Sopenharmony_ci snic_glob->trc_root = NULL; 4262306a36Sopenharmony_ci} 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* 4562306a36Sopenharmony_ci * snic_reset_stats_open - Open the reset_stats file 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_cistatic int 4862306a36Sopenharmony_cisnic_reset_stats_open(struct inode *inode, struct file *filp) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci SNIC_BUG_ON(!inode->i_private); 5162306a36Sopenharmony_ci filp->private_data = inode->i_private; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci return 0; 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/* 5762306a36Sopenharmony_ci * snic_reset_stats_read - Read a reset_stats debugfs file 5862306a36Sopenharmony_ci * @filp: The file pointer to read from. 5962306a36Sopenharmony_ci * @ubuf: The buffer tocopy the data to. 6062306a36Sopenharmony_ci * @cnt: The number of bytes to read. 6162306a36Sopenharmony_ci * @ppos: The position in the file to start reading frm. 6262306a36Sopenharmony_ci * 6362306a36Sopenharmony_ci * Description: 6462306a36Sopenharmony_ci * This routine reads value of variable reset_stats 6562306a36Sopenharmony_ci * and stores into local @buf. It will start reading file @ppos and 6662306a36Sopenharmony_ci * copy up to @cnt of data to @ubuf from @buf. 6762306a36Sopenharmony_ci * 6862306a36Sopenharmony_ci * Returns: 6962306a36Sopenharmony_ci * This function returns the amount of data that was read. 7062306a36Sopenharmony_ci */ 7162306a36Sopenharmony_cistatic ssize_t 7262306a36Sopenharmony_cisnic_reset_stats_read(struct file *filp, 7362306a36Sopenharmony_ci char __user *ubuf, 7462306a36Sopenharmony_ci size_t cnt, 7562306a36Sopenharmony_ci loff_t *ppos) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci struct snic *snic = (struct snic *) filp->private_data; 7862306a36Sopenharmony_ci char buf[64]; 7962306a36Sopenharmony_ci int len; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci len = sprintf(buf, "%u\n", snic->reset_stats); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/* 8762306a36Sopenharmony_ci * snic_reset_stats_write - Write to reset_stats debugfs file 8862306a36Sopenharmony_ci * @filp: The file pointer to write from 8962306a36Sopenharmony_ci * @ubuf: The buffer to copy the data from. 9062306a36Sopenharmony_ci * @cnt: The number of bytes to write. 9162306a36Sopenharmony_ci * @ppos: The position in the file to start writing to. 9262306a36Sopenharmony_ci * 9362306a36Sopenharmony_ci * Description: 9462306a36Sopenharmony_ci * This routine writes data from user buffer @ubuf to buffer @buf and 9562306a36Sopenharmony_ci * resets cumulative stats of snic. 9662306a36Sopenharmony_ci * 9762306a36Sopenharmony_ci * Returns: 9862306a36Sopenharmony_ci * This function returns the amount of data that was written. 9962306a36Sopenharmony_ci */ 10062306a36Sopenharmony_cistatic ssize_t 10162306a36Sopenharmony_cisnic_reset_stats_write(struct file *filp, 10262306a36Sopenharmony_ci const char __user *ubuf, 10362306a36Sopenharmony_ci size_t cnt, 10462306a36Sopenharmony_ci loff_t *ppos) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci struct snic *snic = (struct snic *) filp->private_data; 10762306a36Sopenharmony_ci struct snic_stats *stats = &snic->s_stats; 10862306a36Sopenharmony_ci u64 *io_stats_p = (u64 *) &stats->io; 10962306a36Sopenharmony_ci u64 *fw_stats_p = (u64 *) &stats->fw; 11062306a36Sopenharmony_ci char buf[64]; 11162306a36Sopenharmony_ci unsigned long val; 11262306a36Sopenharmony_ci int ret; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci if (cnt >= sizeof(buf)) 11562306a36Sopenharmony_ci return -EINVAL; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci if (copy_from_user(&buf, ubuf, cnt)) 11862306a36Sopenharmony_ci return -EFAULT; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci buf[cnt] = '\0'; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci ret = kstrtoul(buf, 10, &val); 12362306a36Sopenharmony_ci if (ret < 0) 12462306a36Sopenharmony_ci return ret; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci snic->reset_stats = val; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci if (snic->reset_stats) { 12962306a36Sopenharmony_ci /* Skip variable is used to avoid descrepancies to Num IOs 13062306a36Sopenharmony_ci * and IO Completions stats. Skip incrementing No IO Compls 13162306a36Sopenharmony_ci * for pending active IOs after reset_stats 13262306a36Sopenharmony_ci */ 13362306a36Sopenharmony_ci atomic64_set(&snic->io_cmpl_skip, 13462306a36Sopenharmony_ci atomic64_read(&stats->io.active)); 13562306a36Sopenharmony_ci memset(&stats->abts, 0, sizeof(struct snic_abort_stats)); 13662306a36Sopenharmony_ci memset(&stats->reset, 0, sizeof(struct snic_reset_stats)); 13762306a36Sopenharmony_ci memset(&stats->misc, 0, sizeof(struct snic_misc_stats)); 13862306a36Sopenharmony_ci memset(io_stats_p+1, 13962306a36Sopenharmony_ci 0, 14062306a36Sopenharmony_ci sizeof(struct snic_io_stats) - sizeof(u64)); 14162306a36Sopenharmony_ci memset(fw_stats_p+1, 14262306a36Sopenharmony_ci 0, 14362306a36Sopenharmony_ci sizeof(struct snic_fw_stats) - sizeof(u64)); 14462306a36Sopenharmony_ci } 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci (*ppos)++; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci SNIC_HOST_INFO(snic->shost, "Reset Op: Driver statistics.\n"); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci return cnt; 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistatic int 15462306a36Sopenharmony_cisnic_reset_stats_release(struct inode *inode, struct file *filp) 15562306a36Sopenharmony_ci{ 15662306a36Sopenharmony_ci filp->private_data = NULL; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci return 0; 15962306a36Sopenharmony_ci} 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* 16262306a36Sopenharmony_ci * snic_stats_show - Formats and prints per host specific driver stats. 16362306a36Sopenharmony_ci */ 16462306a36Sopenharmony_cistatic int 16562306a36Sopenharmony_cisnic_stats_show(struct seq_file *sfp, void *data) 16662306a36Sopenharmony_ci{ 16762306a36Sopenharmony_ci struct snic *snic = (struct snic *) sfp->private; 16862306a36Sopenharmony_ci struct snic_stats *stats = &snic->s_stats; 16962306a36Sopenharmony_ci struct timespec64 last_isr_tms, last_ack_tms; 17062306a36Sopenharmony_ci u64 maxio_tm; 17162306a36Sopenharmony_ci int i; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci /* Dump IO Stats */ 17462306a36Sopenharmony_ci seq_printf(sfp, 17562306a36Sopenharmony_ci "------------------------------------------\n" 17662306a36Sopenharmony_ci "\t\t IO Statistics\n" 17762306a36Sopenharmony_ci "------------------------------------------\n"); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci maxio_tm = (u64) atomic64_read(&stats->io.max_time); 18062306a36Sopenharmony_ci seq_printf(sfp, 18162306a36Sopenharmony_ci "Active IOs : %lld\n" 18262306a36Sopenharmony_ci "Max Active IOs : %lld\n" 18362306a36Sopenharmony_ci "Total IOs : %lld\n" 18462306a36Sopenharmony_ci "IOs Completed : %lld\n" 18562306a36Sopenharmony_ci "IOs Failed : %lld\n" 18662306a36Sopenharmony_ci "IOs Not Found : %lld\n" 18762306a36Sopenharmony_ci "Memory Alloc Failures : %lld\n" 18862306a36Sopenharmony_ci "REQs Null : %lld\n" 18962306a36Sopenharmony_ci "SCSI Cmd Pointers Null : %lld\n" 19062306a36Sopenharmony_ci "Max SGL for any IO : %lld\n" 19162306a36Sopenharmony_ci "Max IO Size : %lld Sectors\n" 19262306a36Sopenharmony_ci "Max Queuing Time : %lld\n" 19362306a36Sopenharmony_ci "Max Completion Time : %lld\n" 19462306a36Sopenharmony_ci "Max IO Process Time(FW) : %lld (%u msec)\n", 19562306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.active), 19662306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.max_active), 19762306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.num_ios), 19862306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.compl), 19962306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.fail), 20062306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.io_not_found), 20162306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.alloc_fail), 20262306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.req_null), 20362306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.sc_null), 20462306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.max_sgl), 20562306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.max_io_sz), 20662306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.max_qtime), 20762306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.max_cmpl_time), 20862306a36Sopenharmony_ci maxio_tm, 20962306a36Sopenharmony_ci jiffies_to_msecs(maxio_tm)); 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci seq_puts(sfp, "\nSGL Counters\n"); 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci for (i = 0; i < SNIC_MAX_SG_DESC_CNT; i++) { 21462306a36Sopenharmony_ci seq_printf(sfp, 21562306a36Sopenharmony_ci "%10lld ", 21662306a36Sopenharmony_ci (u64) atomic64_read(&stats->io.sgl_cnt[i])); 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci if ((i + 1) % 8 == 0) 21962306a36Sopenharmony_ci seq_puts(sfp, "\n"); 22062306a36Sopenharmony_ci } 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci /* Dump Abort Stats */ 22362306a36Sopenharmony_ci seq_printf(sfp, 22462306a36Sopenharmony_ci "\n-------------------------------------------\n" 22562306a36Sopenharmony_ci "\t\t Abort Statistics\n" 22662306a36Sopenharmony_ci "---------------------------------------------\n"); 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci seq_printf(sfp, 22962306a36Sopenharmony_ci "Aborts : %lld\n" 23062306a36Sopenharmony_ci "Aborts Fail : %lld\n" 23162306a36Sopenharmony_ci "Aborts Driver Timeout : %lld\n" 23262306a36Sopenharmony_ci "Abort FW Timeout : %lld\n" 23362306a36Sopenharmony_ci "Abort IO NOT Found : %lld\n" 23462306a36Sopenharmony_ci "Abort Queuing Failed : %lld\n", 23562306a36Sopenharmony_ci (u64) atomic64_read(&stats->abts.num), 23662306a36Sopenharmony_ci (u64) atomic64_read(&stats->abts.fail), 23762306a36Sopenharmony_ci (u64) atomic64_read(&stats->abts.drv_tmo), 23862306a36Sopenharmony_ci (u64) atomic64_read(&stats->abts.fw_tmo), 23962306a36Sopenharmony_ci (u64) atomic64_read(&stats->abts.io_not_found), 24062306a36Sopenharmony_ci (u64) atomic64_read(&stats->abts.q_fail)); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci /* Dump Reset Stats */ 24362306a36Sopenharmony_ci seq_printf(sfp, 24462306a36Sopenharmony_ci "\n-------------------------------------------\n" 24562306a36Sopenharmony_ci "\t\t Reset Statistics\n" 24662306a36Sopenharmony_ci "---------------------------------------------\n"); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci seq_printf(sfp, 24962306a36Sopenharmony_ci "HBA Resets : %lld\n" 25062306a36Sopenharmony_ci "HBA Reset Cmpls : %lld\n" 25162306a36Sopenharmony_ci "HBA Reset Fail : %lld\n", 25262306a36Sopenharmony_ci (u64) atomic64_read(&stats->reset.hba_resets), 25362306a36Sopenharmony_ci (u64) atomic64_read(&stats->reset.hba_reset_cmpl), 25462306a36Sopenharmony_ci (u64) atomic64_read(&stats->reset.hba_reset_fail)); 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci /* Dump Firmware Stats */ 25762306a36Sopenharmony_ci seq_printf(sfp, 25862306a36Sopenharmony_ci "\n-------------------------------------------\n" 25962306a36Sopenharmony_ci "\t\t Firmware Statistics\n" 26062306a36Sopenharmony_ci "---------------------------------------------\n"); 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci seq_printf(sfp, 26362306a36Sopenharmony_ci "Active FW Requests : %lld\n" 26462306a36Sopenharmony_ci "Max FW Requests : %lld\n" 26562306a36Sopenharmony_ci "FW Out Of Resource Errs : %lld\n" 26662306a36Sopenharmony_ci "FW IO Errors : %lld\n" 26762306a36Sopenharmony_ci "FW SCSI Errors : %lld\n", 26862306a36Sopenharmony_ci (u64) atomic64_read(&stats->fw.actv_reqs), 26962306a36Sopenharmony_ci (u64) atomic64_read(&stats->fw.max_actv_reqs), 27062306a36Sopenharmony_ci (u64) atomic64_read(&stats->fw.out_of_res), 27162306a36Sopenharmony_ci (u64) atomic64_read(&stats->fw.io_errs), 27262306a36Sopenharmony_ci (u64) atomic64_read(&stats->fw.scsi_errs)); 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci /* Dump Miscellenous Stats */ 27662306a36Sopenharmony_ci seq_printf(sfp, 27762306a36Sopenharmony_ci "\n---------------------------------------------\n" 27862306a36Sopenharmony_ci "\t\t Other Statistics\n" 27962306a36Sopenharmony_ci "\n---------------------------------------------\n"); 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci jiffies_to_timespec64(stats->misc.last_isr_time, &last_isr_tms); 28262306a36Sopenharmony_ci jiffies_to_timespec64(stats->misc.last_ack_time, &last_ack_tms); 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci seq_printf(sfp, 28562306a36Sopenharmony_ci "Last ISR Time : %llu (%8llu.%09lu)\n" 28662306a36Sopenharmony_ci "Last Ack Time : %llu (%8llu.%09lu)\n" 28762306a36Sopenharmony_ci "Ack ISRs : %llu\n" 28862306a36Sopenharmony_ci "IO Cmpl ISRs : %llu\n" 28962306a36Sopenharmony_ci "Err Notify ISRs : %llu\n" 29062306a36Sopenharmony_ci "Max CQ Entries : %lld\n" 29162306a36Sopenharmony_ci "Data Count Mismatch : %lld\n" 29262306a36Sopenharmony_ci "IOs w/ Timeout Status : %lld\n" 29362306a36Sopenharmony_ci "IOs w/ Aborted Status : %lld\n" 29462306a36Sopenharmony_ci "IOs w/ SGL Invalid Stat : %lld\n" 29562306a36Sopenharmony_ci "WQ Desc Alloc Fail : %lld\n" 29662306a36Sopenharmony_ci "Queue Full : %lld\n" 29762306a36Sopenharmony_ci "Queue Ramp Up : %lld\n" 29862306a36Sopenharmony_ci "Queue Ramp Down : %lld\n" 29962306a36Sopenharmony_ci "Queue Last Queue Depth : %lld\n" 30062306a36Sopenharmony_ci "Target Not Ready : %lld\n", 30162306a36Sopenharmony_ci (u64) stats->misc.last_isr_time, 30262306a36Sopenharmony_ci last_isr_tms.tv_sec, last_isr_tms.tv_nsec, 30362306a36Sopenharmony_ci (u64)stats->misc.last_ack_time, 30462306a36Sopenharmony_ci last_ack_tms.tv_sec, last_ack_tms.tv_nsec, 30562306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.ack_isr_cnt), 30662306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.cmpl_isr_cnt), 30762306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.errnotify_isr_cnt), 30862306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.max_cq_ents), 30962306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.data_cnt_mismat), 31062306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.io_tmo), 31162306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.io_aborted), 31262306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.sgl_inval), 31362306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.wq_alloc_fail), 31462306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.qfull), 31562306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.qsz_rampup), 31662306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.qsz_rampdown), 31762306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.last_qsz), 31862306a36Sopenharmony_ci (u64) atomic64_read(&stats->misc.tgt_not_rdy)); 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci return 0; 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(snic_stats); 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_cistatic const struct file_operations snic_reset_stats_fops = { 32662306a36Sopenharmony_ci .owner = THIS_MODULE, 32762306a36Sopenharmony_ci .open = snic_reset_stats_open, 32862306a36Sopenharmony_ci .read = snic_reset_stats_read, 32962306a36Sopenharmony_ci .write = snic_reset_stats_write, 33062306a36Sopenharmony_ci .release = snic_reset_stats_release, 33162306a36Sopenharmony_ci}; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci/* 33462306a36Sopenharmony_ci * snic_stats_init - Initialize stats struct and create stats file 33562306a36Sopenharmony_ci * per snic 33662306a36Sopenharmony_ci * 33762306a36Sopenharmony_ci * Description: 33862306a36Sopenharmony_ci * When debugfs is cofigured this routine sets up the stats file per snic 33962306a36Sopenharmony_ci * It will create file stats and reset_stats under statistics/host# directory 34062306a36Sopenharmony_ci * to log per snic stats 34162306a36Sopenharmony_ci */ 34262306a36Sopenharmony_civoid snic_stats_debugfs_init(struct snic *snic) 34362306a36Sopenharmony_ci{ 34462306a36Sopenharmony_ci char name[16]; 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci snprintf(name, sizeof(name), "host%d", snic->shost->host_no); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci snic->stats_host = debugfs_create_dir(name, snic_glob->stats_root); 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci snic->stats_file = debugfs_create_file("stats", S_IFREG|S_IRUGO, 35162306a36Sopenharmony_ci snic->stats_host, snic, 35262306a36Sopenharmony_ci &snic_stats_fops); 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci snic->reset_stats_file = debugfs_create_file("reset_stats", 35562306a36Sopenharmony_ci S_IFREG|S_IRUGO|S_IWUSR, 35662306a36Sopenharmony_ci snic->stats_host, snic, 35762306a36Sopenharmony_ci &snic_reset_stats_fops); 35862306a36Sopenharmony_ci} 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci/* 36162306a36Sopenharmony_ci * snic_stats_debugfs_remove - Tear down debugfs infrastructure of stats 36262306a36Sopenharmony_ci * 36362306a36Sopenharmony_ci * Description: 36462306a36Sopenharmony_ci * When Debufs is configured this routine removes debugfs file system 36562306a36Sopenharmony_ci * elements that are specific to to snic stats 36662306a36Sopenharmony_ci */ 36762306a36Sopenharmony_civoid 36862306a36Sopenharmony_cisnic_stats_debugfs_remove(struct snic *snic) 36962306a36Sopenharmony_ci{ 37062306a36Sopenharmony_ci debugfs_remove(snic->stats_file); 37162306a36Sopenharmony_ci snic->stats_file = NULL; 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci debugfs_remove(snic->reset_stats_file); 37462306a36Sopenharmony_ci snic->reset_stats_file = NULL; 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci debugfs_remove(snic->stats_host); 37762306a36Sopenharmony_ci snic->stats_host = NULL; 37862306a36Sopenharmony_ci} 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci/* Trace Facility related API */ 38162306a36Sopenharmony_cistatic void * 38262306a36Sopenharmony_cisnic_trc_seq_start(struct seq_file *sfp, loff_t *pos) 38362306a36Sopenharmony_ci{ 38462306a36Sopenharmony_ci return &snic_glob->trc; 38562306a36Sopenharmony_ci} 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_cistatic void * 38862306a36Sopenharmony_cisnic_trc_seq_next(struct seq_file *sfp, void *data, loff_t *pos) 38962306a36Sopenharmony_ci{ 39062306a36Sopenharmony_ci return NULL; 39162306a36Sopenharmony_ci} 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_cistatic void 39462306a36Sopenharmony_cisnic_trc_seq_stop(struct seq_file *sfp, void *data) 39562306a36Sopenharmony_ci{ 39662306a36Sopenharmony_ci} 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci#define SNIC_TRC_PBLEN 256 39962306a36Sopenharmony_cistatic int 40062306a36Sopenharmony_cisnic_trc_seq_show(struct seq_file *sfp, void *data) 40162306a36Sopenharmony_ci{ 40262306a36Sopenharmony_ci char buf[SNIC_TRC_PBLEN]; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci if (snic_get_trc_data(buf, SNIC_TRC_PBLEN) > 0) 40562306a36Sopenharmony_ci seq_printf(sfp, "%s\n", buf); 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci return 0; 40862306a36Sopenharmony_ci} 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_cistatic const struct seq_operations snic_trc_sops = { 41162306a36Sopenharmony_ci .start = snic_trc_seq_start, 41262306a36Sopenharmony_ci .next = snic_trc_seq_next, 41362306a36Sopenharmony_ci .stop = snic_trc_seq_stop, 41462306a36Sopenharmony_ci .show = snic_trc_seq_show, 41562306a36Sopenharmony_ci}; 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ciDEFINE_SEQ_ATTRIBUTE(snic_trc); 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci#define TRC_ENABLE_FILE "tracing_enable" 42062306a36Sopenharmony_ci#define TRC_FILE "trace" 42162306a36Sopenharmony_ci/* 42262306a36Sopenharmony_ci * snic_trc_debugfs_init : creates trace/tracing_enable files for trace 42362306a36Sopenharmony_ci * under debugfs 42462306a36Sopenharmony_ci */ 42562306a36Sopenharmony_civoid snic_trc_debugfs_init(void) 42662306a36Sopenharmony_ci{ 42762306a36Sopenharmony_ci debugfs_create_bool(TRC_ENABLE_FILE, S_IFREG | S_IRUGO | S_IWUSR, 42862306a36Sopenharmony_ci snic_glob->trc_root, &snic_glob->trc.enable); 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci debugfs_create_file(TRC_FILE, S_IFREG | S_IRUGO | S_IWUSR, 43162306a36Sopenharmony_ci snic_glob->trc_root, NULL, &snic_trc_fops); 43262306a36Sopenharmony_ci} 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci/* 43562306a36Sopenharmony_ci * snic_trc_debugfs_term : cleans up the files created for trace under debugfs 43662306a36Sopenharmony_ci */ 43762306a36Sopenharmony_civoid 43862306a36Sopenharmony_cisnic_trc_debugfs_term(void) 43962306a36Sopenharmony_ci{ 44062306a36Sopenharmony_ci debugfs_lookup_and_remove(TRC_FILE, snic_glob->trc_root); 44162306a36Sopenharmony_ci debugfs_lookup_and_remove(TRC_ENABLE_FILE, snic_glob->trc_root); 44262306a36Sopenharmony_ci} 443