smux_debug.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /* drivers/tty/smux_debug.c
  2. *
  3. * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include <linux/debugfs.h>
  16. #include <linux/list.h>
  17. #include <linux/ctype.h>
  18. #include <linux/jiffies.h>
  19. #include <linux/slab.h>
  20. #include <linux/delay.h>
  21. #include <linux/completion.h>
  22. #include <linux/termios.h>
  23. #include <linux/smux.h>
  24. #include "smux_private.h"
  25. #define DEBUG_BUFMAX 4096
  26. /**
  27. * smux_dump_ch() - Dumps the information of a channel to the screen.
  28. * @buf: Buffer for status message.
  29. * @max: Size of status queue.
  30. * @lch_number: Number of the logical channel.
  31. * @lch: Pointer to the lch_number'th instance of struct smux_lch_t.
  32. *
  33. */
  34. static int smux_dump_ch(char *buf, int max, struct smux_lch_t *lch)
  35. {
  36. int bytes_written;
  37. long tiocm_bits;
  38. unsigned long flags;
  39. spin_lock_irqsave(&lch->state_lock_lhb1, flags);
  40. spin_lock(&lch->tx_lock_lhb2);
  41. tiocm_bits = msm_smux_tiocm_get_atomic(lch);
  42. bytes_written = scnprintf(
  43. buf, max,
  44. "ch%02d: "
  45. "%s(%s) "
  46. "%c%c%c%c%c "
  47. "%d "
  48. "%s(%s) "
  49. "%c%c\n",
  50. lch->lcid,
  51. local_lch_state(lch->local_state), lch_mode(lch->local_mode),
  52. (tiocm_bits & TIOCM_DSR) ? 'D' : 'd',
  53. (tiocm_bits & TIOCM_CTS) ? 'T' : 't',
  54. (tiocm_bits & TIOCM_RI) ? 'I' : 'i',
  55. (tiocm_bits & TIOCM_CD) ? 'C' : 'c',
  56. lch->tx_flow_control ? 'F' : 'f',
  57. lch->tx_pending_data_cnt,
  58. remote_lch_state(lch->remote_state), lch_mode(lch->remote_mode),
  59. (tiocm_bits & TIOCM_DTR) ? 'R' : 'r',
  60. (tiocm_bits & TIOCM_RTS) ? 'S' : 's'
  61. );
  62. spin_unlock(&lch->tx_lock_lhb2);
  63. spin_unlock_irqrestore(&lch->state_lock_lhb1, flags);
  64. return bytes_written;
  65. }
  66. /**
  67. * smux_dump_format_ch() - Informs user of format for channel dump
  68. * @buf: Buffer for status message.
  69. * @max: Size of status queue.
  70. *
  71. */
  72. static int smux_dump_format_ch(char *buf, int max)
  73. {
  74. return scnprintf(
  75. buf, max,
  76. "ch_id "
  77. "local state(mode) tiocm "
  78. "tx_queue "
  79. "remote state(mode) tiocm\n"
  80. "local tiocm: DSR(D) CTS(T) RI(I) DCD(C) FLOW_CONTROL(F)\n"
  81. "remote tiocm: DTR(R) RTS(S)\n"
  82. "A capital letter indicates set, otherwise, it is not set.\n\n"
  83. );
  84. }
  85. /**
  86. * smux_debug_ch() - Log following information about each channel
  87. * local open, local mode, remote open, remote mode,
  88. * tiocm bits, flow control state and transmit queue size.
  89. * Returns the number of bytes written to buf.
  90. * @buf Buffer for status message
  91. * @max Size of status queue
  92. *
  93. */
  94. static int smux_debug_ch(char *buf, int max)
  95. {
  96. int ch_id;
  97. int bytes_written = smux_dump_format_ch(buf, max);
  98. for (ch_id = 0; ch_id < SMUX_NUM_LOGICAL_CHANNELS; ch_id++) {
  99. bytes_written += smux_dump_ch(buf + bytes_written,
  100. max - bytes_written,
  101. &smux_lch[ch_id]);
  102. }
  103. return bytes_written;
  104. }
  105. static char debug_buffer[DEBUG_BUFMAX];
  106. static ssize_t debug_read(struct file *file, char __user *buf,
  107. size_t count, loff_t *ppos)
  108. {
  109. int (*fill)(char *buf, int max) = file->private_data;
  110. int bsize;
  111. if (*ppos != 0)
  112. return 0;
  113. bsize = fill(debug_buffer, DEBUG_BUFMAX);
  114. return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
  115. }
  116. static int debug_open(struct inode *inode, struct file *file)
  117. {
  118. file->private_data = inode->i_private;
  119. return 0;
  120. }
  121. static const struct file_operations debug_ops = {
  122. .read = debug_read,
  123. .open = debug_open,
  124. };
  125. static void debug_create(const char *name, mode_t mode,
  126. struct dentry *dent,
  127. int (*fill)(char *buf, int max))
  128. {
  129. debugfs_create_file(name, mode, dent, fill, &debug_ops);
  130. }
  131. static int __init smux_debugfs_init(void)
  132. {
  133. struct dentry *dent;
  134. dent = debugfs_create_dir("n_smux", 0);
  135. if (IS_ERR(dent))
  136. return PTR_ERR(dent);
  137. debug_create("ch", 0444, dent, smux_debug_ch);
  138. return 0;
  139. }
  140. late_initcall(smux_debugfs_init);