fnic_debugfs.c 18 KB

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