fnic_debugfs.c 20 KB

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