Deleted Added
full compact
ng_h4.c (171345) ng_h4.c (171818)
1/*
2 * ng_h4.c
3 */
4
5/*-
6 * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7 * All rights reserved.
8 *

--- 13 unchanged lines hidden (view full) ---

22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
1/*
2 * ng_h4.c
3 */
4
5/*-
6 * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7 * All rights reserved.
8 *

--- 13 unchanged lines hidden (view full) ---

22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $Id: ng_h4.c,v 1.7 2004/08/23 18:08:15 max Exp $
31 * $FreeBSD: head/sys/netgraph/bluetooth/drivers/h4/ng_h4.c 171345 2007-07-10 16:38:43Z emax $
30 * $Id: ng_h4.c,v 1.10 2005/10/31 17:57:43 max Exp $
31 * $FreeBSD: head/sys/netgraph/bluetooth/drivers/h4/ng_h4.c 171818 2007-08-13 17:19:28Z emax $
32 *
33 * Based on:
34 * ---------
35 *
36 * FreeBSD: src/sys/netgraph/ng_tty.c
37 * Author: Archie Cobbs <archie@freebsd.org>
38 *
39 */

--- 4 unchanged lines hidden (view full) ---

44#include <sys/conf.h>
45#include <sys/endian.h>
46#include <sys/errno.h>
47#include <sys/fcntl.h>
48#include <sys/ioccom.h>
49#include <sys/malloc.h>
50#include <sys/mbuf.h>
51#include <sys/priv.h>
32 *
33 * Based on:
34 * ---------
35 *
36 * FreeBSD: src/sys/netgraph/ng_tty.c
37 * Author: Archie Cobbs <archie@freebsd.org>
38 *
39 */

--- 4 unchanged lines hidden (view full) ---

44#include <sys/conf.h>
45#include <sys/endian.h>
46#include <sys/errno.h>
47#include <sys/fcntl.h>
48#include <sys/ioccom.h>
49#include <sys/malloc.h>
50#include <sys/mbuf.h>
51#include <sys/priv.h>
52#include <sys/socket.h>
52#include <sys/tty.h>
53#include <sys/ttycom.h>
53#include <sys/tty.h>
54#include <sys/ttycom.h>
55#include <net/if.h>
56#include <net/if_var.h>
54#include <netgraph/ng_message.h>
55#include <netgraph/netgraph.h>
56#include <netgraph/ng_parse.h>
57#include <netgraph/bluetooth/include/ng_bluetooth.h>
58#include <netgraph/bluetooth/include/ng_hci.h>
59#include <netgraph/bluetooth/include/ng_h4.h>
60#include <netgraph/bluetooth/drivers/h4/ng_h4_var.h>
61#include <netgraph/bluetooth/drivers/h4/ng_h4_prse.h>

--- 6 unchanged lines hidden (view full) ---

68 ** on a terminal device instantiates a new netgraph node of this type, which
69 ** allows access to the device via the "hook" hook of the node.
70 **
71 ** Once the line discipline is installed, you can find out the name of the
72 ** corresponding netgraph node via a NGIOCGINFO ioctl().
73 *****************************************************************************
74 *****************************************************************************/
75
57#include <netgraph/ng_message.h>
58#include <netgraph/netgraph.h>
59#include <netgraph/ng_parse.h>
60#include <netgraph/bluetooth/include/ng_bluetooth.h>
61#include <netgraph/bluetooth/include/ng_hci.h>
62#include <netgraph/bluetooth/include/ng_h4.h>
63#include <netgraph/bluetooth/drivers/h4/ng_h4_var.h>
64#include <netgraph/bluetooth/drivers/h4/ng_h4_prse.h>

--- 6 unchanged lines hidden (view full) ---

71 ** on a terminal device instantiates a new netgraph node of this type, which
72 ** allows access to the device via the "hook" hook of the node.
73 **
74 ** Once the line discipline is installed, you can find out the name of the
75 ** corresponding netgraph node via a NGIOCGINFO ioctl().
76 *****************************************************************************
77 *****************************************************************************/
78
76#error "NET_NEEDS_GIANT"
77
78/* MALLOC define */
79#ifndef NG_SEPARATE_MALLOC
80MALLOC_DEFINE(M_NETGRAPH_H4, "netgraph_h4", "Netgraph Bluetooth H4 node");
81#else
82#define M_NETGRAPH_H4 M_NETGRAPH
83#endif /* NG_SEPARATE_MALLOC */
84
85/* Line discipline methods */
86static int ng_h4_open (struct cdev *, struct tty *);
87static int ng_h4_close (struct tty *, int);
88static int ng_h4_read (struct tty *, struct uio *, int);
89static int ng_h4_write (struct tty *, struct uio *, int);
90static int ng_h4_input (int, struct tty *);
91static int ng_h4_start (struct tty *);
79/* MALLOC define */
80#ifndef NG_SEPARATE_MALLOC
81MALLOC_DEFINE(M_NETGRAPH_H4, "netgraph_h4", "Netgraph Bluetooth H4 node");
82#else
83#define M_NETGRAPH_H4 M_NETGRAPH
84#endif /* NG_SEPARATE_MALLOC */
85
86/* Line discipline methods */
87static int ng_h4_open (struct cdev *, struct tty *);
88static int ng_h4_close (struct tty *, int);
89static int ng_h4_read (struct tty *, struct uio *, int);
90static int ng_h4_write (struct tty *, struct uio *, int);
91static int ng_h4_input (int, struct tty *);
92static int ng_h4_start (struct tty *);
92static void ng_h4_start2 (node_p, hook_p, void *, int);
93static int ng_h4_ioctl (struct tty *, u_long, caddr_t,
94 int, struct thread *);
95
96/* Line discipline descriptor */
97static struct linesw ng_h4_disc = {
98 ng_h4_open, /* open */
99 ng_h4_close, /* close */
100 ng_h4_read, /* read */

--- 9 unchanged lines hidden (view full) ---

110static ng_rcvmsg_t ng_h4_rcvmsg;
111static ng_shutdown_t ng_h4_shutdown;
112static ng_newhook_t ng_h4_newhook;
113static ng_connect_t ng_h4_connect;
114static ng_rcvdata_t ng_h4_rcvdata;
115static ng_disconnect_t ng_h4_disconnect;
116
117/* Other stuff */
93static int ng_h4_ioctl (struct tty *, u_long, caddr_t,
94 int, struct thread *);
95
96/* Line discipline descriptor */
97static struct linesw ng_h4_disc = {
98 ng_h4_open, /* open */
99 ng_h4_close, /* close */
100 ng_h4_read, /* read */

--- 9 unchanged lines hidden (view full) ---

110static ng_rcvmsg_t ng_h4_rcvmsg;
111static ng_shutdown_t ng_h4_shutdown;
112static ng_newhook_t ng_h4_newhook;
113static ng_connect_t ng_h4_connect;
114static ng_rcvdata_t ng_h4_rcvdata;
115static ng_disconnect_t ng_h4_disconnect;
116
117/* Other stuff */
118static void ng_h4_timeout (node_p);
119static void ng_h4_untimeout (node_p);
120static void ng_h4_process_timeout (node_p, hook_p, void *, int);
121static int ng_h4_mod_event (module_t, int, void *);
122
123/* Netgraph node type descriptor */
124static struct ng_type typestruct = {
125 .version = NG_ABI_VERSION,
126 .name = NG_H4_NODE_TYPE,
127 .mod_event = ng_h4_mod_event,

--- 19 unchanged lines hidden (view full) ---

147
148/*
149 * Set our line discipline on the tty.
150 */
151
152static int
153ng_h4_open(struct cdev *dev, struct tty *tp)
154{
118static void ng_h4_process_timeout (node_p, hook_p, void *, int);
119static int ng_h4_mod_event (module_t, int, void *);
120
121/* Netgraph node type descriptor */
122static struct ng_type typestruct = {
123 .version = NG_ABI_VERSION,
124 .name = NG_H4_NODE_TYPE,
125 .mod_event = ng_h4_mod_event,

--- 19 unchanged lines hidden (view full) ---

145
146/*
147 * Set our line discipline on the tty.
148 */
149
150static int
151ng_h4_open(struct cdev *dev, struct tty *tp)
152{
153 struct thread *td = curthread;
155 char name[NG_NODESIZ];
156 ng_h4_info_p sc = NULL;
154 char name[NG_NODESIZ];
155 ng_h4_info_p sc = NULL;
157 int s, error;
156 int error;
158
159 /* Super-user only */
157
158 /* Super-user only */
160 error = priv_check(curthread, PRIV_NETGRAPH_TTY); /* XXX */
159 error = priv_check(td, PRIV_NETGRAPH_TTY); /* XXX */
161 if (error != 0)
162 return (error);
163
160 if (error != 0)
161 return (error);
162
164 s = splnet(); /* XXX */
165 spltty(); /* XXX */
166
167 /* Initialize private struct */
168 MALLOC(sc, ng_h4_info_p, sizeof(*sc), M_NETGRAPH_H4, M_NOWAIT|M_ZERO);
163 /* Initialize private struct */
164 MALLOC(sc, ng_h4_info_p, sizeof(*sc), M_NETGRAPH_H4, M_NOWAIT|M_ZERO);
169 if (sc == NULL) {
170 error = ENOMEM;
171 goto out;
172 }
165 if (sc == NULL)
166 return (ENOMEM);
173
174 sc->tp = tp;
175 sc->debug = NG_H4_WARN_LEVEL;
176
177 sc->state = NG_H4_W4_PKT_IND;
178 sc->want = 1;
179 sc->got = 0;
180
167
168 sc->tp = tp;
169 sc->debug = NG_H4_WARN_LEVEL;
170
171 sc->state = NG_H4_W4_PKT_IND;
172 sc->want = 1;
173 sc->got = 0;
174
181 NG_BT_MBUFQ_INIT(&sc->outq, NG_H4_DEFAULTQLEN);
175 mtx_init(&sc->outq.ifq_mtx, "ng_h4 node+queue", NULL, MTX_DEF);
176 IFQ_SET_MAXLEN(&sc->outq, NG_H4_DEFAULTQLEN);
182 ng_callout_init(&sc->timo);
183
177 ng_callout_init(&sc->timo);
178
179 NG_H4_LOCK(sc);
180
184 /* Setup netgraph node */
185 error = ng_make_node_common(&typestruct, &sc->node);
186 if (error != 0) {
181 /* Setup netgraph node */
182 error = ng_make_node_common(&typestruct, &sc->node);
183 if (error != 0) {
184 NG_H4_UNLOCK(sc);
185
186 printf("%s: Unable to create new node!\n", __func__);
187
188 mtx_destroy(&sc->outq.ifq_mtx);
187 bzero(sc, sizeof(*sc));
188 FREE(sc, M_NETGRAPH_H4);
189 bzero(sc, sizeof(*sc));
190 FREE(sc, M_NETGRAPH_H4);
189 goto out;
191
192 return (error);
190 }
191
192 /* Assign node its name */
193 snprintf(name, sizeof(name), "%s%d", typestruct.name, ng_h4_node ++);
194
195 error = ng_name_node(sc->node, name);
196 if (error != 0) {
193 }
194
195 /* Assign node its name */
196 snprintf(name, sizeof(name), "%s%d", typestruct.name, ng_h4_node ++);
197
198 error = ng_name_node(sc->node, name);
199 if (error != 0) {
197 NG_H4_ALERT("%s: %s - node name exists?\n", __func__, name);
200 NG_H4_UNLOCK(sc);
201
202 printf("%s: %s - node name exists?\n", __func__, name);
203
198 NG_NODE_UNREF(sc->node);
204 NG_NODE_UNREF(sc->node);
205 mtx_destroy(&sc->outq.ifq_mtx);
199 bzero(sc, sizeof(*sc));
200 FREE(sc, M_NETGRAPH_H4);
206 bzero(sc, sizeof(*sc));
207 FREE(sc, M_NETGRAPH_H4);
201 goto out;
208
209 return (error);
202 }
203
204 /* Set back pointers */
205 NG_NODE_SET_PRIVATE(sc->node, sc);
206 tp->t_lsc = (caddr_t) sc;
207
208 /* The node has to be a WRITER because data can change node status */
209 NG_NODE_FORCE_WRITER(sc->node);
210
211 /*
212 * Pre-allocate cblocks to the an appropriate amount.
213 * I'm not sure what is appropriate.
214 */
215
216 ttyflush(tp, FREAD | FWRITE);
217 clist_alloc_cblocks(&tp->t_canq, 0, 0);
218 clist_alloc_cblocks(&tp->t_rawq, 0, 0);
219 clist_alloc_cblocks(&tp->t_outq,
220 MLEN + NG_H4_HIWATER, MLEN + NG_H4_HIWATER);
210 }
211
212 /* Set back pointers */
213 NG_NODE_SET_PRIVATE(sc->node, sc);
214 tp->t_lsc = (caddr_t) sc;
215
216 /* The node has to be a WRITER because data can change node status */
217 NG_NODE_FORCE_WRITER(sc->node);
218
219 /*
220 * Pre-allocate cblocks to the an appropriate amount.
221 * I'm not sure what is appropriate.
222 */
223
224 ttyflush(tp, FREAD | FWRITE);
225 clist_alloc_cblocks(&tp->t_canq, 0, 0);
226 clist_alloc_cblocks(&tp->t_rawq, 0, 0);
227 clist_alloc_cblocks(&tp->t_outq,
228 MLEN + NG_H4_HIWATER, MLEN + NG_H4_HIWATER);
221out:
222 splx(s); /* XXX */
223
229
230 NG_H4_UNLOCK(sc);
231
224 return (error);
225} /* ng_h4_open */
226
227/*
228 * Line specific close routine, called from device close routine
229 * and from ttioctl. This causes the node to be destroyed as well.
230 */
231
232static int
233ng_h4_close(struct tty *tp, int flag)
234{
235 ng_h4_info_p sc = (ng_h4_info_p) tp->t_lsc;
232 return (error);
233} /* ng_h4_open */
234
235/*
236 * Line specific close routine, called from device close routine
237 * and from ttioctl. This causes the node to be destroyed as well.
238 */
239
240static int
241ng_h4_close(struct tty *tp, int flag)
242{
243 ng_h4_info_p sc = (ng_h4_info_p) tp->t_lsc;
236 int s;
237
244
238 s = spltty(); /* XXX */
239
240 ttyflush(tp, FREAD | FWRITE);
241 clist_free_cblocks(&tp->t_outq);
245 ttyflush(tp, FREAD | FWRITE);
246 clist_free_cblocks(&tp->t_outq);
247
242 if (sc != NULL) {
248 if (sc != NULL) {
243 tp->t_lsc = NULL;
249 NG_H4_LOCK(sc);
244
250
245 if (sc->node != NULL) {
246 if (sc->flags & NG_H4_TIMEOUT)
247 ng_h4_untimeout(sc->node);
251 if (callout_pending(&sc->timo))
252 ng_uncallout(&sc->timo, sc->node);
248
253
249 NG_NODE_SET_PRIVATE(sc->node, NULL);
250 ng_rmnode_self(sc->node);
251 sc->node = NULL;
252 }
254 tp->t_lsc = NULL;
255 sc->dying = 1;
253
256
254 NG_BT_MBUFQ_DESTROY(&sc->outq);
255 bzero(sc, sizeof(*sc));
256 FREE(sc, M_NETGRAPH_H4);
257 NG_H4_UNLOCK(sc);
258
259 ng_rmnode_self(sc->node);
257 }
258
260 }
261
259 splx(s); /* XXX */
260
261 return (0);
262} /* ng_h4_close */
263
264/*
265 * Once the device has been turned into a node, we don't allow reading.
266 */
267
268static int

--- 16 unchanged lines hidden (view full) ---

285 * We implement the NGIOCGINFO ioctl() defined in ng_message.h.
286 */
287
288static int
289ng_h4_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
290 struct thread *td)
291{
292 ng_h4_info_p sc = (ng_h4_info_p) tp->t_lsc;
262 return (0);
263} /* ng_h4_close */
264
265/*
266 * Once the device has been turned into a node, we don't allow reading.
267 */
268
269static int

--- 16 unchanged lines hidden (view full) ---

286 * We implement the NGIOCGINFO ioctl() defined in ng_message.h.
287 */
288
289static int
290ng_h4_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
291 struct thread *td)
292{
293 ng_h4_info_p sc = (ng_h4_info_p) tp->t_lsc;
293 int s, error = 0;
294 int error = 0;
294
295
295 s = spltty(); /* XXX */
296 if (sc == NULL)
297 return (ENXIO);
296
298
299 NG_H4_LOCK(sc);
300
297 switch (cmd) {
298 case NGIOCGINFO:
299#undef NI
300#define NI(x) ((struct nodeinfo *)(x))
301
302 bzero(data, sizeof(*NI(data)));
303
304 if (NG_NODE_HAS_NAME(sc->node))

--- 7 unchanged lines hidden (view full) ---

312 NI(data)->hooks = NG_NODE_NUMHOOKS(sc->node);
313 break;
314
315 default:
316 error = ENOIOCTL;
317 break;
318 }
319
301 switch (cmd) {
302 case NGIOCGINFO:
303#undef NI
304#define NI(x) ((struct nodeinfo *)(x))
305
306 bzero(data, sizeof(*NI(data)));
307
308 if (NG_NODE_HAS_NAME(sc->node))

--- 7 unchanged lines hidden (view full) ---

316 NI(data)->hooks = NG_NODE_NUMHOOKS(sc->node);
317 break;
318
319 default:
320 error = ENOIOCTL;
321 break;
322 }
323
320 splx(s); /* XXX */
324 NG_H4_UNLOCK(sc);
321
322 return (error);
323} /* ng_h4_ioctl */
324
325/*
326 * Receive data coming from the device. We get one character at a time, which
327 * is kindof silly.
328 */
329
330static int
331ng_h4_input(int c, struct tty *tp)
332{
333 ng_h4_info_p sc = (ng_h4_info_p) tp->t_lsc;
334
335 if (sc == NULL || tp != sc->tp ||
336 sc->node == NULL || NG_NODE_NOT_VALID(sc->node))
337 return (0);
338
325
326 return (error);
327} /* ng_h4_ioctl */
328
329/*
330 * Receive data coming from the device. We get one character at a time, which
331 * is kindof silly.
332 */
333
334static int
335ng_h4_input(int c, struct tty *tp)
336{
337 ng_h4_info_p sc = (ng_h4_info_p) tp->t_lsc;
338
339 if (sc == NULL || tp != sc->tp ||
340 sc->node == NULL || NG_NODE_NOT_VALID(sc->node))
341 return (0);
342
343 NG_H4_LOCK(sc);
344
339 /* Check for error conditions */
345 /* Check for error conditions */
340 if ((sc->tp->t_state & TS_CONNECTED) == 0) {
346 if ((tp->t_state & TS_CONNECTED) == 0) {
341 NG_H4_INFO("%s: %s - no carrier\n", __func__,
342 NG_NODE_NAME(sc->node));
343
344 sc->state = NG_H4_W4_PKT_IND;
345 sc->want = 1;
346 sc->got = 0;
347
347 NG_H4_INFO("%s: %s - no carrier\n", __func__,
348 NG_NODE_NAME(sc->node));
349
350 sc->state = NG_H4_W4_PKT_IND;
351 sc->want = 1;
352 sc->got = 0;
353
354 NG_H4_UNLOCK(sc);
355
348 return (0); /* XXX Loss of synchronization here! */
349 }
350
351 /* Check for framing error or overrun on this char */
352 if (c & TTY_ERRORMASK) {
353 NG_H4_ERR("%s: %s - line error %#x, c=%#x\n", __func__,
354 NG_NODE_NAME(sc->node), c & TTY_ERRORMASK,
355 c & TTY_CHARMASK);
356
357 NG_H4_STAT_IERROR(sc->stat);
358
359 sc->state = NG_H4_W4_PKT_IND;
360 sc->want = 1;
361 sc->got = 0;
362
356 return (0); /* XXX Loss of synchronization here! */
357 }
358
359 /* Check for framing error or overrun on this char */
360 if (c & TTY_ERRORMASK) {
361 NG_H4_ERR("%s: %s - line error %#x, c=%#x\n", __func__,
362 NG_NODE_NAME(sc->node), c & TTY_ERRORMASK,
363 c & TTY_CHARMASK);
364
365 NG_H4_STAT_IERROR(sc->stat);
366
367 sc->state = NG_H4_W4_PKT_IND;
368 sc->want = 1;
369 sc->got = 0;
370
371 NG_H4_UNLOCK(sc);
372
363 return (0); /* XXX Loss of synchronization here! */
364 }
365
366 NG_H4_STAT_BYTES_RECV(sc->stat, 1);
367
368 /* Append char to mbuf */
369 if (sc->got >= sizeof(sc->ibuf)) {
370 NG_H4_ALERT("%s: %s - input buffer overflow, c=%#x, got=%d\n",
371 __func__, NG_NODE_NAME(sc->node), c & TTY_CHARMASK,
372 sc->got);
373
374 NG_H4_STAT_IERROR(sc->stat);
375
376 sc->state = NG_H4_W4_PKT_IND;
377 sc->want = 1;
378 sc->got = 0;
379
373 return (0); /* XXX Loss of synchronization here! */
374 }
375
376 NG_H4_STAT_BYTES_RECV(sc->stat, 1);
377
378 /* Append char to mbuf */
379 if (sc->got >= sizeof(sc->ibuf)) {
380 NG_H4_ALERT("%s: %s - input buffer overflow, c=%#x, got=%d\n",
381 __func__, NG_NODE_NAME(sc->node), c & TTY_CHARMASK,
382 sc->got);
383
384 NG_H4_STAT_IERROR(sc->stat);
385
386 sc->state = NG_H4_W4_PKT_IND;
387 sc->want = 1;
388 sc->got = 0;
389
390 NG_H4_UNLOCK(sc);
391
380 return (0); /* XXX Loss of synchronization here! */
381 }
382
383 sc->ibuf[sc->got ++] = (c & TTY_CHARMASK);
384
385 NG_H4_INFO("%s: %s - got char %#x, want=%d, got=%d\n", __func__,
386 NG_NODE_NAME(sc->node), c, sc->want, sc->got);
387
392 return (0); /* XXX Loss of synchronization here! */
393 }
394
395 sc->ibuf[sc->got ++] = (c & TTY_CHARMASK);
396
397 NG_H4_INFO("%s: %s - got char %#x, want=%d, got=%d\n", __func__,
398 NG_NODE_NAME(sc->node), c, sc->want, sc->got);
399
388 if (sc->got < sc->want)
400 if (sc->got < sc->want) {
401 NG_H4_UNLOCK(sc);
402
389 return (0); /* Wait for more */
403 return (0); /* Wait for more */
404 }
390
391 switch (sc->state) {
392 /* Got packet indicator */
393 case NG_H4_W4_PKT_IND:
394 NG_H4_INFO("%s: %s - got packet indicator %#x\n", __func__,
395 NG_NODE_NAME(sc->node), sc->ibuf[0]);
396
397 sc->state = NG_H4_W4_PKT_HDR;

--- 136 unchanged lines hidden (view full) ---

534 NG_H4_STAT_PCKTS_RECV(sc->stat);
535 break;
536
537 default:
538 KASSERT((0), ("Invalid H4 node state=%d", sc->state));
539 break;
540 }
541
405
406 switch (sc->state) {
407 /* Got packet indicator */
408 case NG_H4_W4_PKT_IND:
409 NG_H4_INFO("%s: %s - got packet indicator %#x\n", __func__,
410 NG_NODE_NAME(sc->node), sc->ibuf[0]);
411
412 sc->state = NG_H4_W4_PKT_HDR;

--- 136 unchanged lines hidden (view full) ---

549 NG_H4_STAT_PCKTS_RECV(sc->stat);
550 break;
551
552 default:
553 KASSERT((0), ("Invalid H4 node state=%d", sc->state));
554 break;
555 }
556
557 NG_H4_UNLOCK(sc);
558
542 return (0);
543} /* ng_h4_input */
544
545/*
546 * This is called when the device driver is ready for more output. Called from
547 * tty system.
548 */
549
550static int
551ng_h4_start(struct tty *tp)
552{
559 return (0);
560} /* ng_h4_input */
561
562/*
563 * This is called when the device driver is ready for more output. Called from
564 * tty system.
565 */
566
567static int
568ng_h4_start(struct tty *tp)
569{
553 ng_h4_info_p sc = (ng_h4_info_p) tp->t_lsc;
570 ng_h4_info_p sc = (ng_h4_info_p) tp->t_lsc;
571 struct mbuf *m = NULL;
572 int size;
554
555 if (sc == NULL || tp != sc->tp ||
556 sc->node == NULL || NG_NODE_NOT_VALID(sc->node))
557 return (0);
558
573
574 if (sc == NULL || tp != sc->tp ||
575 sc->node == NULL || NG_NODE_NOT_VALID(sc->node))
576 return (0);
577
559 return (ng_send_fn(sc->node, NULL, ng_h4_start2, NULL, 0));
560} /* ng_h4_start */
561
562/*
563 * Device driver is ready for more output. Part 2. Called (via ng_send_fn)
564 * ng_h4_start() and from ng_h4_rcvdata() when a new mbuf is available for
565 * output.
566 */
567
568static void
569ng_h4_start2(node_p node, hook_p hook, void *arg1, int arg2)
570{
571 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(node);
572 struct mbuf *m = NULL;
573 int s, size;
574
575 s = spltty(); /* XXX */
576
577#if 0
578#if 0
578 while (sc->tp->t_outq.c_cc < NG_H4_HIWATER) { /* XXX 2.2 specific ? */
579 while (tp->t_outq.c_cc < NG_H4_HIWATER) { /* XXX 2.2 specific ? */
579#else
580 while (1) {
581#endif
582 /* Remove first mbuf from queue */
580#else
581 while (1) {
582#endif
583 /* Remove first mbuf from queue */
583 NG_BT_MBUFQ_DEQUEUE(&sc->outq, m);
584 IF_DEQUEUE(&sc->outq, m);
584 if (m == NULL)
585 break;
586
587 /* Send as much of it as possible */
588 while (m != NULL) {
589 size = m->m_len - b_to_q(mtod(m, u_char *),
585 if (m == NULL)
586 break;
587
588 /* Send as much of it as possible */
589 while (m != NULL) {
590 size = m->m_len - b_to_q(mtod(m, u_char *),
590 m->m_len, &sc->tp->t_outq);
591 m->m_len, &tp->t_outq);
591
592
593 NG_H4_LOCK(sc);
592 NG_H4_STAT_BYTES_SENT(sc->stat, size);
594 NG_H4_STAT_BYTES_SENT(sc->stat, size);
595 NG_H4_UNLOCK(sc);
593
594 m->m_data += size;
595 m->m_len -= size;
596 if (m->m_len > 0)
597 break; /* device can't take no more */
598
599 m = m_free(m);
600 }
601
602 /* Put remainder of mbuf chain (if any) back on queue */
603 if (m != NULL) {
596
597 m->m_data += size;
598 m->m_len -= size;
599 if (m->m_len > 0)
600 break; /* device can't take no more */
601
602 m = m_free(m);
603 }
604
605 /* Put remainder of mbuf chain (if any) back on queue */
606 if (m != NULL) {
604 NG_BT_MBUFQ_PREPEND(&sc->outq, m);
607 IF_PREPEND(&sc->outq, m);
605 break;
606 }
607
608 /* Full packet has been sent */
608 break;
609 }
610
611 /* Full packet has been sent */
612 NG_H4_LOCK(sc);
609 NG_H4_STAT_PCKTS_SENT(sc->stat);
613 NG_H4_STAT_PCKTS_SENT(sc->stat);
614 NG_H4_UNLOCK(sc);
610 }
611
612 /*
613 * Call output process whether or not there is any output. We are
614 * being called in lieu of ttstart and must do what it would.
615 */
616
617 tt_oproc(sc->tp);
618
619 /*
620 * This timeout is needed for operation on a pseudo-tty, because the
621 * pty code doesn't call pppstart after it has drained the t_outq.
622 */
623
615 }
616
617 /*
618 * Call output process whether or not there is any output. We are
619 * being called in lieu of ttstart and must do what it would.
620 */
621
622 tt_oproc(sc->tp);
623
624 /*
625 * This timeout is needed for operation on a pseudo-tty, because the
626 * pty code doesn't call pppstart after it has drained the t_outq.
627 */
628
624 if (NG_BT_MBUFQ_LEN(&sc->outq) > 0 && (sc->flags & NG_H4_TIMEOUT) == 0)
625 ng_h4_timeout(node);
629 NG_H4_LOCK(sc);
626
630
627 splx(s); /* XXX */
628} /* ng_h4_start2 */
631 if (!IFQ_IS_EMPTY(&sc->outq) && !callout_pending(&sc->timo))
632 ng_callout(&sc->timo, sc->node, NULL, 1,
633 ng_h4_process_timeout, NULL, 0);
629
634
635 NG_H4_UNLOCK(sc);
636
637 return (0);
638} /* ng_h4_start */
639
630/*****************************************************************************
631 *****************************************************************************
632 ** Netgraph node methods
633 *****************************************************************************
634 *****************************************************************************/
635
636/*
637 * Initialize a new node of this type. We only allow nodes to be created as

--- 14 unchanged lines hidden (view full) ---

652static int
653ng_h4_newhook(node_p node, hook_p hook, const char *name)
654{
655 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(node);
656
657 if (strcmp(name, NG_H4_HOOK) != 0)
658 return (EINVAL);
659
640/*****************************************************************************
641 *****************************************************************************
642 ** Netgraph node methods
643 *****************************************************************************
644 *****************************************************************************/
645
646/*
647 * Initialize a new node of this type. We only allow nodes to be created as

--- 14 unchanged lines hidden (view full) ---

662static int
663ng_h4_newhook(node_p node, hook_p hook, const char *name)
664{
665 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(node);
666
667 if (strcmp(name, NG_H4_HOOK) != 0)
668 return (EINVAL);
669
660 if (sc->hook != NULL)
661 return (EISCONN);
670 NG_H4_LOCK(sc);
662
671
672 if (sc->hook != NULL) {
673 NG_H4_UNLOCK(sc);
674 return (EISCONN);
675 }
663 sc->hook = hook;
664
676 sc->hook = hook;
677
678 NG_H4_UNLOCK(sc);
679
665 return (0);
666} /* ng_h4_newhook */
667
668/*
669 * Connect hook. Just say yes.
670 */
671
672static int
673ng_h4_connect(hook_p hook)
674{
675 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
676
680 return (0);
681} /* ng_h4_newhook */
682
683/*
684 * Connect hook. Just say yes.
685 */
686
687static int
688ng_h4_connect(hook_p hook)
689{
690 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
691
677 if (hook != sc->hook) {
678 sc->hook = NULL;
679 return (EINVAL);
680 }
692 if (hook != sc->hook)
693 panic("%s: hook != sc->hook\n", __func__);
681
682 NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
694
695 NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
696 NG_HOOK_FORCE_QUEUE(hook);
683
684 return (0);
685} /* ng_h4_connect */
686
687/*
688 * Disconnect the hook
689 */
690
691static int
692ng_h4_disconnect(hook_p hook)
693{
694 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
695
696 /*
697 * We need to check for sc != NULL because we can be called from
697
698 return (0);
699} /* ng_h4_connect */
700
701/*
702 * Disconnect the hook
703 */
704
705static int
706ng_h4_disconnect(hook_p hook)
707{
708 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
709
710 /*
711 * We need to check for sc != NULL because we can be called from
698 * ng_h4_clsoe() via ng_rmnode_self()
712 * ng_h4_close() via ng_rmnode_self()
699 */
700
701 if (sc != NULL) {
702 if (hook != sc->hook)
713 */
714
715 if (sc != NULL) {
716 if (hook != sc->hook)
703 return (EINVAL);
717 panic("%s: hook != sc->hook\n", __func__);
704
718
719 NG_H4_LOCK(sc);
720
705 /* XXX do we have to untimeout and drain out queue? */
721 /* XXX do we have to untimeout and drain out queue? */
706 if (sc->flags & NG_H4_TIMEOUT)
707 ng_h4_untimeout(NG_HOOK_NODE(hook));
722 if (callout_pending(&sc->timo))
723 ng_uncallout(&sc->timo, sc->node);
708
724
709 NG_BT_MBUFQ_DRAIN(&sc->outq);
725 _IF_DRAIN(&sc->outq);
726
710 sc->state = NG_H4_W4_PKT_IND;
711 sc->want = 1;
712 sc->got = 0;
713
714 sc->hook = NULL;
727 sc->state = NG_H4_W4_PKT_IND;
728 sc->want = 1;
729 sc->got = 0;
730
731 sc->hook = NULL;
732
733 NG_H4_UNLOCK(sc);
715 }
716
717 return (0);
718} /* ng_h4_disconnect */
719
720/*
721 * Remove this node. The does the netgraph portion of the shutdown.
722 * This should only be called indirectly from ng_h4_close().
723 */
724
725static int
726ng_h4_shutdown(node_p node)
727{
728 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(node);
734 }
735
736 return (0);
737} /* ng_h4_disconnect */
738
739/*
740 * Remove this node. The does the netgraph portion of the shutdown.
741 * This should only be called indirectly from ng_h4_close().
742 */
743
744static int
745ng_h4_shutdown(node_p node)
746{
747 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(node);
729 char name[NG_NODESIZ];
730
748
731 /* Let old node go */
732 NG_NODE_SET_PRIVATE(node, NULL);
733 NG_NODE_UNREF(node);
749 NG_H4_LOCK(sc);
734
750
735 /* Check if device was closed */
736 if (sc == NULL)
737 goto out;
751 if (!sc->dying) {
752 NG_H4_UNLOCK(sc);
738
753
739 /* Setup new netgraph node */
740 if (ng_make_node_common(&typestruct, &sc->node) != 0) {
741 printf("%s: Unable to create new node!\n", __func__);
742 sc->node = NULL;
743 goto out;
754 NG_NODE_REVIVE(node); /* we will persist */
755
756 return (EOPNOTSUPP);
744 }
745
757 }
758
746 /* Assign node its name */
747 snprintf(name, sizeof(name), "%s%d", typestruct.name, ng_h4_node ++);
759 NG_H4_UNLOCK(sc);
748
760
749 if (ng_name_node(sc->node, name) != 0) {
750 printf("%s: %s - node name exists?\n", __func__, name);
751 NG_NODE_UNREF(sc->node);
752 sc->node = NULL;
753 goto out;
754 }
761 NG_NODE_SET_PRIVATE(node, NULL);
755
762
756 /* The node has to be a WRITER because data can change node status */
757 NG_NODE_FORCE_WRITER(sc->node);
758 NG_NODE_SET_PRIVATE(sc->node, sc);
759out:
763 _IF_DRAIN(&sc->outq);
764
765 NG_NODE_UNREF(node);
766 mtx_destroy(&sc->outq.ifq_mtx);
767 bzero(sc, sizeof(*sc));
768 FREE(sc, M_NETGRAPH_H4);
769
760 return (0);
761} /* ng_h4_shutdown */
762
763/*
764 * Receive incoming data from Netgraph system. Put it on our
765 * output queue and start output if necessary.
766 */
767
768static int
769ng_h4_rcvdata(hook_p hook, item_p item)
770{
771 ng_h4_info_p sc = (ng_h4_info_p)NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
770 return (0);
771} /* ng_h4_shutdown */
772
773/*
774 * Receive incoming data from Netgraph system. Put it on our
775 * output queue and start output if necessary.
776 */
777
778static int
779ng_h4_rcvdata(hook_p hook, item_p item)
780{
781 ng_h4_info_p sc = (ng_h4_info_p)NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
772 int error = 0;
773 struct mbuf *m = NULL;
782 struct mbuf *m = NULL;
783 int qlen;
774
784
775 if (sc == NULL) {
776 error = EHOSTDOWN;
777 goto out;
778 }
785 if (sc == NULL)
786 return (EHOSTDOWN);
779
787
780 if (hook != sc->hook) {
781 error = EINVAL;
782 goto out;
783 }
788 if (hook != sc->hook)
789 panic("%s: hook != sc->hook\n", __func__);
784
785 NGI_GET_M(item, m);
790
791 NGI_GET_M(item, m);
792 NG_FREE_ITEM(item);
786
793
787 if (NG_BT_MBUFQ_FULL(&sc->outq)) {
794 NG_H4_LOCK(sc);
795
796 if (_IF_QFULL(&sc->outq)) {
788 NG_H4_ERR("%s: %s - dropping mbuf, len=%d\n", __func__,
789 NG_NODE_NAME(sc->node), m->m_pkthdr.len);
790
797 NG_H4_ERR("%s: %s - dropping mbuf, len=%d\n", __func__,
798 NG_NODE_NAME(sc->node), m->m_pkthdr.len);
799
791 NG_BT_MBUFQ_DROP(&sc->outq);
792 NG_H4_STAT_OERROR(sc->stat);
800 NG_H4_STAT_OERROR(sc->stat);
801 _IF_DROP(&sc->outq);
793
802
803 NG_H4_UNLOCK(sc);
804
794 NG_FREE_M(m);
805 NG_FREE_M(m);
795 error = ENOBUFS;
796 } else {
797 NG_H4_INFO("%s: %s - queue mbuf, len=%d\n", __func__,
798 NG_NODE_NAME(sc->node), m->m_pkthdr.len);
799
806
800 NG_BT_MBUFQ_ENQUEUE(&sc->outq, m);
807 return (ENOBUFS);
808 }
801
809
802 /*
803 * We have lock on the node, so we can call ng_h4_start2()
804 * directly
805 */
810 NG_H4_INFO("%s: %s - queue mbuf, len=%d\n", __func__,
811 NG_NODE_NAME(sc->node), m->m_pkthdr.len);
806
812
807 ng_h4_start2(sc->node, NULL, NULL, 0);
813 _IF_ENQUEUE(&sc->outq, m);
814 qlen = _IF_QLEN(&sc->outq);
815
816 NG_H4_UNLOCK(sc);
817
818 /*
819 * If qlen > 1, then we should already have a scheduled callout
820 */
821
822 if (qlen == 1) {
823 mtx_lock(&Giant);
824 ng_h4_start(sc->tp);
825 mtx_unlock(&Giant);
808 }
826 }
809out:
810 NG_FREE_ITEM(item);
811
827
812 return (error);
828 return (0);
813} /* ng_h4_rcvdata */
814
815/*
816 * Receive control message
817 */
818
819static int
820ng_h4_rcvmsg(node_p node, item_p item, hook_p lasthook)
821{
822 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(node);
823 struct ng_mesg *msg = NULL, *resp = NULL;
824 int error = 0;
825
829} /* ng_h4_rcvdata */
830
831/*
832 * Receive control message
833 */
834
835static int
836ng_h4_rcvmsg(node_p node, item_p item, hook_p lasthook)
837{
838 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(node);
839 struct ng_mesg *msg = NULL, *resp = NULL;
840 int error = 0;
841
826 if (sc == NULL) {
827 error = EHOSTDOWN;
828 goto out;
829 }
842 if (sc == NULL)
843 return (EHOSTDOWN);
830
831 NGI_GET_MSG(item, msg);
844
845 NGI_GET_MSG(item, msg);
846 NG_H4_LOCK(sc);
832
833 switch (msg->header.typecookie) {
834 case NGM_GENERIC_COOKIE:
835 switch (msg->header.cmd) {
836 case NGM_TEXT_STATUS:
837 NG_MKRESPONSE(resp, msg, NG_TEXTRESPONSE, M_NOWAIT);
838 if (resp == NULL)
839 error = ENOMEM;
840 else
841 snprintf(resp->data, NG_TEXTRESPONSE,
842 "Hook: %s\n" \
847
848 switch (msg->header.typecookie) {
849 case NGM_GENERIC_COOKIE:
850 switch (msg->header.cmd) {
851 case NGM_TEXT_STATUS:
852 NG_MKRESPONSE(resp, msg, NG_TEXTRESPONSE, M_NOWAIT);
853 if (resp == NULL)
854 error = ENOMEM;
855 else
856 snprintf(resp->data, NG_TEXTRESPONSE,
857 "Hook: %s\n" \
843 "Flags: %#x\n" \
844 "Debug: %d\n" \
845 "State: %d\n" \
846 "Queue: [have:%d,max:%d]\n" \
847 "Input: [got:%d,want:%d]",
848 (sc->hook != NULL)? NG_H4_HOOK : "",
858 "Debug: %d\n" \
859 "State: %d\n" \
860 "Queue: [have:%d,max:%d]\n" \
861 "Input: [got:%d,want:%d]",
862 (sc->hook != NULL)? NG_H4_HOOK : "",
849 sc->flags,
850 sc->debug,
851 sc->state,
863 sc->debug,
864 sc->state,
852 NG_BT_MBUFQ_LEN(&sc->outq),
853 sc->outq.maxlen,
865 _IF_QLEN(&sc->outq),
866 sc->outq.ifq_maxlen,
854 sc->got,
855 sc->want);
856 break;
857
858 default:
859 error = EINVAL;
860 break;
861 }
862 break;
863
864 case NGM_H4_COOKIE:
865 switch (msg->header.cmd) {
866 case NGM_H4_NODE_RESET:
867 sc->got,
868 sc->want);
869 break;
870
871 default:
872 error = EINVAL;
873 break;
874 }
875 break;
876
877 case NGM_H4_COOKIE:
878 switch (msg->header.cmd) {
879 case NGM_H4_NODE_RESET:
867 NG_BT_MBUFQ_DRAIN(&sc->outq);
880 _IF_DRAIN(&sc->outq);
868 sc->state = NG_H4_W4_PKT_IND;
869 sc->want = 1;
870 sc->got = 0;
871 break;
872
873 case NGM_H4_NODE_GET_STATE:
874 NG_MKRESPONSE(resp, msg, sizeof(ng_h4_node_state_ep),
875 M_NOWAIT);

--- 24 unchanged lines hidden (view full) ---

900
901 case NGM_H4_NODE_GET_QLEN:
902 NG_MKRESPONSE(resp, msg, sizeof(ng_h4_node_qlen_ep),
903 M_NOWAIT);
904 if (resp == NULL)
905 error = ENOMEM;
906 else
907 *((ng_h4_node_qlen_ep *)(resp->data)) =
881 sc->state = NG_H4_W4_PKT_IND;
882 sc->want = 1;
883 sc->got = 0;
884 break;
885
886 case NGM_H4_NODE_GET_STATE:
887 NG_MKRESPONSE(resp, msg, sizeof(ng_h4_node_state_ep),
888 M_NOWAIT);

--- 24 unchanged lines hidden (view full) ---

913
914 case NGM_H4_NODE_GET_QLEN:
915 NG_MKRESPONSE(resp, msg, sizeof(ng_h4_node_qlen_ep),
916 M_NOWAIT);
917 if (resp == NULL)
918 error = ENOMEM;
919 else
920 *((ng_h4_node_qlen_ep *)(resp->data)) =
908 sc->outq.maxlen;
921 sc->outq.ifq_maxlen;
909 break;
910
911 case NGM_H4_NODE_SET_QLEN:
912 if (msg->header.arglen != sizeof(ng_h4_node_qlen_ep))
913 error = EMSGSIZE;
914 else if (*((ng_h4_node_qlen_ep *)(msg->data)) <= 0)
915 error = EINVAL;
916 else
922 break;
923
924 case NGM_H4_NODE_SET_QLEN:
925 if (msg->header.arglen != sizeof(ng_h4_node_qlen_ep))
926 error = EMSGSIZE;
927 else if (*((ng_h4_node_qlen_ep *)(msg->data)) <= 0)
928 error = EINVAL;
929 else
917 sc->outq.maxlen =
918 *((ng_h4_node_qlen_ep *)(msg->data));
930 IFQ_SET_MAXLEN(&sc->outq,
931 *((ng_h4_node_qlen_ep *)(msg->data)));
919 break;
920
921 case NGM_H4_NODE_GET_STAT:
922 NG_MKRESPONSE(resp, msg, sizeof(ng_h4_node_stat_ep),
923 M_NOWAIT);
924 if (resp == NULL)
925 error = ENOMEM;
926 else

--- 10 unchanged lines hidden (view full) ---

937 break;
938 }
939 break;
940
941 default:
942 error = EINVAL;
943 break;
944 }
932 break;
933
934 case NGM_H4_NODE_GET_STAT:
935 NG_MKRESPONSE(resp, msg, sizeof(ng_h4_node_stat_ep),
936 M_NOWAIT);
937 if (resp == NULL)
938 error = ENOMEM;
939 else

--- 10 unchanged lines hidden (view full) ---

950 break;
951 }
952 break;
953
954 default:
955 error = EINVAL;
956 break;
957 }
945out:
958
959 NG_H4_UNLOCK(sc);
960
946 NG_RESPOND_MSG(error, node, item, resp);
947 NG_FREE_MSG(msg);
948
949 return (error);
950} /* ng_h4_rcvmsg */
951
952/*
961 NG_RESPOND_MSG(error, node, item, resp);
962 NG_FREE_MSG(msg);
963
964 return (error);
965} /* ng_h4_rcvmsg */
966
967/*
953 * Set timeout
954 */
955
956static void
957ng_h4_timeout(node_p node)
958{
959 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(node);
960
961 ng_callout(&sc->timo, node, NULL, 1, ng_h4_process_timeout, NULL, 0);
962 sc->flags |= NG_H4_TIMEOUT;
963} /* ng_h4_timeout */
964
965/*
966 * Unset timeout
967 */
968
969static void
970ng_h4_untimeout(node_p node)
971{
972 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(node);
973
974 sc->flags &= ~NG_H4_TIMEOUT;
975 ng_uncallout(&sc->timo, node);
976} /* ng_h4_untimeout */
977
978/*
979 * Timeout processing function.
980 * We still have data to output to the device, so try sending more.
981 */
982
983static void
984ng_h4_process_timeout(node_p node, hook_p hook, void *arg1, int arg2)
985{
986 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(node);
987
968 * Timeout processing function.
969 * We still have data to output to the device, so try sending more.
970 */
971
972static void
973ng_h4_process_timeout(node_p node, hook_p hook, void *arg1, int arg2)
974{
975 ng_h4_info_p sc = (ng_h4_info_p) NG_NODE_PRIVATE(node);
976
988 sc->flags &= ~NG_H4_TIMEOUT;
989
990 /*
991 * We can call ng_h4_start2() directly here because we have lock
992 * on the node.
993 */
994
995 ng_h4_start2(node, NULL, NULL, 0);
977 mtx_lock(&Giant);
978 ng_h4_start(sc->tp);
979 mtx_unlock(&Giant);
996} /* ng_h4_process_timeout */
997
998/*
999 * Handle loading and unloading for this node type
1000 */
1001
1002static int
1003ng_h4_mod_event(module_t mod, int event, void *data)
1004{
1005 static int ng_h4_ldisc;
980} /* ng_h4_process_timeout */
981
982/*
983 * Handle loading and unloading for this node type
984 */
985
986static int
987ng_h4_mod_event(module_t mod, int event, void *data)
988{
989 static int ng_h4_ldisc;
1006 int s, error = 0;
990 int error = 0;
1007
991
1008 s = spltty(); /* XXX */
1009
1010 switch (event) {
1011 case MOD_LOAD:
1012 /* Register line discipline */
992 switch (event) {
993 case MOD_LOAD:
994 /* Register line discipline */
995 mtx_lock(&Giant);
1013 ng_h4_ldisc = ldisc_register(H4DISC, &ng_h4_disc);
996 ng_h4_ldisc = ldisc_register(H4DISC, &ng_h4_disc);
997 mtx_unlock(&Giant);
998
1014 if (ng_h4_ldisc < 0) {
1015 printf("%s: can't register H4 line discipline\n",
1016 __func__);
1017 error = EIO;
1018 }
1019 break;
1020
1021 case MOD_UNLOAD:
1022 /* Unregister line discipline */
999 if (ng_h4_ldisc < 0) {
1000 printf("%s: can't register H4 line discipline\n",
1001 __func__);
1002 error = EIO;
1003 }
1004 break;
1005
1006 case MOD_UNLOAD:
1007 /* Unregister line discipline */
1008 mtx_lock(&Giant);
1023 ldisc_deregister(ng_h4_ldisc);
1009 ldisc_deregister(ng_h4_ldisc);
1010 mtx_unlock(&Giant);
1024 break;
1025
1026 default:
1027 error = EOPNOTSUPP;
1028 break;
1029 }
1030
1011 break;
1012
1013 default:
1014 error = EOPNOTSUPP;
1015 break;
1016 }
1017
1031 splx(s); /* XXX */
1032
1033 return (error);
1034} /* ng_h4_mod_event */
1035
1018 return (error);
1019} /* ng_h4_mod_event */
1020