This source file includes following definitions.
- n_tracerouter_open
- n_tracerouter_close
- n_tracerouter_read
- n_tracerouter_write
- n_tracerouter_receivebuf
- n_tracerouter_init
- n_tracerouter_exit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/types.h>
20 #include <linux/ioctl.h>
21 #include <linux/tty.h>
22 #include <linux/tty_ldisc.h>
23 #include <linux/errno.h>
24 #include <linux/string.h>
25 #include <linux/mutex.h>
26 #include <linux/slab.h>
27 #include <linux/bug.h>
28 #include "n_tracesink.h"
29
30
31
32
33
34
35 #define RECEIVE_ROOM 65536
36 #define DRIVERNAME "n_tracerouter"
37
38
39
40
41
42
43 struct tracerouter_data {
44 u8 opencalled;
45 struct tty_struct *kref_tty;
46 };
47 static struct tracerouter_data *tr_data;
48
49
50 static DEFINE_MUTEX(routelock);
51
52
53
54
55
56
57
58
59
60
61 static int n_tracerouter_open(struct tty_struct *tty)
62 {
63 int retval = -EEXIST;
64
65 mutex_lock(&routelock);
66 if (tr_data->opencalled == 0) {
67
68 tr_data->kref_tty = tty_kref_get(tty);
69 if (tr_data->kref_tty == NULL) {
70 retval = -EFAULT;
71 } else {
72 tr_data->opencalled = 1;
73 tty->disc_data = tr_data;
74 tty->receive_room = RECEIVE_ROOM;
75 tty_driver_flush_buffer(tty);
76 retval = 0;
77 }
78 }
79 mutex_unlock(&routelock);
80 return retval;
81 }
82
83
84
85
86
87
88
89 static void n_tracerouter_close(struct tty_struct *tty)
90 {
91 struct tracerouter_data *tptr = tty->disc_data;
92
93 mutex_lock(&routelock);
94 WARN_ON(tptr->kref_tty != tr_data->kref_tty);
95 tty_driver_flush_buffer(tty);
96 tty_kref_put(tr_data->kref_tty);
97 tr_data->kref_tty = NULL;
98 tr_data->opencalled = 0;
99 tty->disc_data = NULL;
100 mutex_unlock(&routelock);
101 }
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 static ssize_t n_tracerouter_read(struct tty_struct *tty, struct file *file,
121 unsigned char __user *buf, size_t nr) {
122 return -EINVAL;
123 }
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144 static ssize_t n_tracerouter_write(struct tty_struct *tty, struct file *file,
145 const unsigned char *buf, size_t nr) {
146 return -EINVAL;
147 }
148
149
150
151
152
153
154
155
156
157
158
159
160
161 static void n_tracerouter_receivebuf(struct tty_struct *tty,
162 const unsigned char *cp,
163 char *fp, int count)
164 {
165 mutex_lock(&routelock);
166 n_tracesink_datadrain((u8 *) cp, count);
167 mutex_unlock(&routelock);
168 }
169
170
171
172
173
174
175 static struct tty_ldisc_ops tty_ptirouter_ldisc = {
176 .owner = THIS_MODULE,
177 .magic = TTY_LDISC_MAGIC,
178 .name = DRIVERNAME,
179 .open = n_tracerouter_open,
180 .close = n_tracerouter_close,
181 .read = n_tracerouter_read,
182 .write = n_tracerouter_write,
183 .receive_buf = n_tracerouter_receivebuf
184 };
185
186
187
188
189
190
191
192
193
194 static int __init n_tracerouter_init(void)
195 {
196 int retval;
197
198 tr_data = kzalloc(sizeof(struct tracerouter_data), GFP_KERNEL);
199 if (tr_data == NULL)
200 return -ENOMEM;
201
202
203
204 retval = tty_register_ldisc(N_TRACEROUTER, &tty_ptirouter_ldisc);
205 if (retval < 0) {
206 pr_err("%s: Registration failed: %d\n", __func__, retval);
207 kfree(tr_data);
208 }
209 return retval;
210 }
211
212
213
214
215
216
217 static void __exit n_tracerouter_exit(void)
218 {
219 int retval = tty_unregister_ldisc(N_TRACEROUTER);
220
221 if (retval < 0)
222 pr_err("%s: Unregistration failed: %d\n", __func__, retval);
223 else
224 kfree(tr_data);
225 }
226
227 module_init(n_tracerouter_init);
228 module_exit(n_tracerouter_exit);
229
230 MODULE_LICENSE("GPL");
231 MODULE_AUTHOR("Jay Freyensee");
232 MODULE_ALIAS_LDISC(N_TRACEROUTER);
233 MODULE_DESCRIPTION("Trace router ldisc driver");