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 |