fnic_debugfs.c 22 KB

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