xref: /freebsd/sys/dev/usb/misc/udbp.c (revision c0020399a650364d0134f79f3fa319f84064372d)
1 /*-
2  * Copyright (c) 1996-2000 Whistle Communications, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of author nor the names of its
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY NICK HIBMA AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 /* Driver for arbitrary double bulk pipe devices.
35  * The driver assumes that there will be the same driver on the other side.
36  *
37  * XXX Some more information on what the framing of the IP packets looks like.
38  *
39  * To take full advantage of bulk transmission, packets should be chosen
40  * between 1k and 5k in size (1k to make sure the sending side starts
41  * streaming, and <5k to avoid overflowing the system with small TDs).
42  */
43 
44 
45 /* probe/attach/detach:
46  *  Connect the driver to the hardware and netgraph
47  *
48  *  The reason we submit a bulk in transfer is that USB does not know about
49  *  interrupts. The bulk transfer continuously polls the device for data.
50  *  While the device has no data available, the device NAKs the TDs. As soon
51  *  as there is data, the transfer happens and the data comes flowing in.
52  *
53  *  In case you were wondering, interrupt transfers happen exactly that way.
54  *  It therefore doesn't make sense to use the interrupt pipe to signal
55  *  'data ready' and then schedule a bulk transfer to fetch it. That would
56  *  incur a 2ms delay at least, without reducing bandwidth requirements.
57  *
58  */
59 
60 #include "usbdevs.h"
61 #include <dev/usb/usb.h>
62 #include <dev/usb/usb_mfunc.h>
63 #include <dev/usb/usb_error.h>
64 
65 #define	USB_DEBUG_VAR udbp_debug
66 
67 #include <dev/usb/usb_core.h>
68 #include <dev/usb/usb_debug.h>
69 #include <dev/usb/usb_parse.h>
70 #include <dev/usb/usb_lookup.h>
71 #include <dev/usb/usb_util.h>
72 #include <dev/usb/usb_busdma.h>
73 
74 #include <sys/mbuf.h>
75 
76 #include <netgraph/ng_message.h>
77 #include <netgraph/netgraph.h>
78 #include <netgraph/ng_parse.h>
79 #include <netgraph/bluetooth/include/ng_bluetooth.h>
80 
81 #include <dev/usb/misc/udbp.h>
82 
83 #if USB_DEBUG
84 static int udbp_debug = 0;
85 
86 SYSCTL_NODE(_hw_usb2, OID_AUTO, udbp, CTLFLAG_RW, 0, "USB udbp");
87 SYSCTL_INT(_hw_usb2_udbp, OID_AUTO, debug, CTLFLAG_RW,
88     &udbp_debug, 0, "udbp debug level");
89 #endif
90 
91 #define	UDBP_TIMEOUT	2000		/* timeout on outbound transfers, in
92 					 * msecs */
93 #define	UDBP_BUFFERSIZE	MCLBYTES	/* maximum number of bytes in one
94 					 * transfer */
95 #define	UDBP_T_WR       0
96 #define	UDBP_T_RD       1
97 #define	UDBP_T_WR_CS    2
98 #define	UDBP_T_RD_CS    3
99 #define	UDBP_T_MAX      4
100 #define	UDBP_Q_MAXLEN   50
101 
102 struct udbp_softc {
103 
104 	struct mtx sc_mtx;
105 	struct ng_bt_mbufq sc_xmitq_hipri;	/* hi-priority transmit queue */
106 	struct ng_bt_mbufq sc_xmitq;	/* low-priority transmit queue */
107 
108 	struct usb2_xfer *sc_xfer[UDBP_T_MAX];
109 	node_p	sc_node;		/* back pointer to node */
110 	hook_p	sc_hook;		/* pointer to the hook */
111 	struct mbuf *sc_bulk_in_buffer;
112 
113 	uint32_t sc_packets_in;		/* packets in from downstream */
114 	uint32_t sc_packets_out;	/* packets out towards downstream */
115 
116 	uint8_t	sc_flags;
117 #define	UDBP_FLAG_READ_STALL    0x01	/* read transfer stalled */
118 #define	UDBP_FLAG_WRITE_STALL   0x02	/* write transfer stalled */
119 
120 	uint8_t	sc_name[16];
121 };
122 
123 /* prototypes */
124 
125 static int udbp_modload(module_t mod, int event, void *data);
126 
127 static device_probe_t udbp_probe;
128 static device_attach_t udbp_attach;
129 static device_detach_t udbp_detach;
130 
131 static usb2_callback_t udbp_bulk_read_callback;
132 static usb2_callback_t udbp_bulk_read_clear_stall_callback;
133 static usb2_callback_t udbp_bulk_write_callback;
134 static usb2_callback_t udbp_bulk_write_clear_stall_callback;
135 
136 static void	udbp_bulk_read_complete(node_p, hook_p, void *, int);
137 
138 static ng_constructor_t	ng_udbp_constructor;
139 static ng_rcvmsg_t	ng_udbp_rcvmsg;
140 static ng_shutdown_t	ng_udbp_rmnode;
141 static ng_newhook_t	ng_udbp_newhook;
142 static ng_connect_t	ng_udbp_connect;
143 static ng_rcvdata_t	ng_udbp_rcvdata;
144 static ng_disconnect_t	ng_udbp_disconnect;
145 
146 /* Parse type for struct ngudbpstat */
147 static const struct ng_parse_struct_field
148 	ng_udbp_stat_type_fields[] = NG_UDBP_STATS_TYPE_INFO;
149 
150 static const struct ng_parse_type ng_udbp_stat_type = {
151 	&ng_parse_struct_type,
152 	&ng_udbp_stat_type_fields
153 };
154 
155 /* List of commands and how to convert arguments to/from ASCII */
156 static const struct ng_cmdlist ng_udbp_cmdlist[] = {
157 	{
158 		NGM_UDBP_COOKIE,
159 		NGM_UDBP_GET_STATUS,
160 		"getstatus",
161 		NULL,
162 		&ng_udbp_stat_type,
163 	},
164 	{
165 		NGM_UDBP_COOKIE,
166 		NGM_UDBP_SET_FLAG,
167 		"setflag",
168 		&ng_parse_int32_type,
169 		NULL
170 	},
171 	{0}
172 };
173 
174 /* Netgraph node type descriptor */
175 static struct ng_type ng_udbp_typestruct = {
176 	.version = NG_ABI_VERSION,
177 	.name = NG_UDBP_NODE_TYPE,
178 	.constructor = ng_udbp_constructor,
179 	.rcvmsg = ng_udbp_rcvmsg,
180 	.shutdown = ng_udbp_rmnode,
181 	.newhook = ng_udbp_newhook,
182 	.connect = ng_udbp_connect,
183 	.rcvdata = ng_udbp_rcvdata,
184 	.disconnect = ng_udbp_disconnect,
185 	.cmdlist = ng_udbp_cmdlist,
186 };
187 
188 /* USB config */
189 static const struct usb2_config udbp_config[UDBP_T_MAX] = {
190 
191 	[UDBP_T_WR] = {
192 		.type = UE_BULK,
193 		.endpoint = UE_ADDR_ANY,
194 		.direction = UE_DIR_OUT,
195 		.bufsize = UDBP_BUFFERSIZE,
196 		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
197 		.callback = &udbp_bulk_write_callback,
198 		.timeout = UDBP_TIMEOUT,
199 	},
200 
201 	[UDBP_T_RD] = {
202 		.type = UE_BULK,
203 		.endpoint = UE_ADDR_ANY,
204 		.direction = UE_DIR_IN,
205 		.bufsize = UDBP_BUFFERSIZE,
206 		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
207 		.callback = &udbp_bulk_read_callback,
208 	},
209 
210 	[UDBP_T_WR_CS] = {
211 		.type = UE_CONTROL,
212 		.endpoint = 0x00,	/* Control pipe */
213 		.direction = UE_DIR_ANY,
214 		.bufsize = sizeof(struct usb2_device_request),
215 		.callback = &udbp_bulk_write_clear_stall_callback,
216 		.timeout = 1000,	/* 1 second */
217 		.interval = 50,	/* 50ms */
218 	},
219 
220 	[UDBP_T_RD_CS] = {
221 		.type = UE_CONTROL,
222 		.endpoint = 0x00,	/* Control pipe */
223 		.direction = UE_DIR_ANY,
224 		.bufsize = sizeof(struct usb2_device_request),
225 		.callback = &udbp_bulk_read_clear_stall_callback,
226 		.timeout = 1000,	/* 1 second */
227 		.interval = 50,	/* 50ms */
228 	},
229 };
230 
231 static devclass_t udbp_devclass;
232 
233 static device_method_t udbp_methods[] = {
234 	/* Device interface */
235 	DEVMETHOD(device_probe, udbp_probe),
236 	DEVMETHOD(device_attach, udbp_attach),
237 	DEVMETHOD(device_detach, udbp_detach),
238 	{0, 0}
239 };
240 
241 static driver_t udbp_driver = {
242 	.name = "udbp",
243 	.methods = udbp_methods,
244 	.size = sizeof(struct udbp_softc),
245 };
246 
247 DRIVER_MODULE(udbp, uhub, udbp_driver, udbp_devclass, udbp_modload, 0);
248 MODULE_DEPEND(udbp, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
249 MODULE_DEPEND(udbp, usb, 1, 1, 1);
250 
251 static int
252 udbp_modload(module_t mod, int event, void *data)
253 {
254 	int error;
255 
256 	switch (event) {
257 	case MOD_LOAD:
258 		error = ng_newtype(&ng_udbp_typestruct);
259 		if (error != 0) {
260 			printf("%s: Could not register "
261 			    "Netgraph node type, error=%d\n",
262 			    NG_UDBP_NODE_TYPE, error);
263 		}
264 		break;
265 
266 	case MOD_UNLOAD:
267 		error = ng_rmtype(&ng_udbp_typestruct);
268 		break;
269 
270 	default:
271 		error = EOPNOTSUPP;
272 		break;
273 	}
274 	return (error);
275 }
276 
277 static int
278 udbp_probe(device_t dev)
279 {
280 	struct usb2_attach_arg *uaa = device_get_ivars(dev);
281 
282 	if (uaa->usb2_mode != USB_MODE_HOST) {
283 		return (ENXIO);
284 	}
285 	/*
286 	 * XXX Julian, add the id of the device if you have one to test
287 	 * things with. run 'usbdevs -v' and note the 3 ID's that appear.
288 	 * The Vendor Id and Product Id are in hex and the Revision Id is in
289 	 * bcd. But as usual if the revision is 0x101 then you should
290 	 * compare the revision id in the device descriptor with 0x101 Or go
291 	 * search the file usbdevs.h. Maybe the device is already in there.
292 	 */
293 	if (((uaa->info.idVendor == USB_VENDOR_NETCHIP) &&
294 	    (uaa->info.idProduct == USB_PRODUCT_NETCHIP_TURBOCONNECT)))
295 		return (0);
296 
297 	if (((uaa->info.idVendor == USB_VENDOR_PROLIFIC) &&
298 	    ((uaa->info.idProduct == USB_PRODUCT_PROLIFIC_PL2301) ||
299 	    (uaa->info.idProduct == USB_PRODUCT_PROLIFIC_PL2302))))
300 		return (0);
301 
302 	if ((uaa->info.idVendor == USB_VENDOR_ANCHOR) &&
303 	    (uaa->info.idProduct == USB_PRODUCT_ANCHOR_EZLINK))
304 		return (0);
305 
306 	if ((uaa->info.idVendor == USB_VENDOR_GENESYS) &&
307 	    (uaa->info.idProduct == USB_PRODUCT_GENESYS_GL620USB))
308 		return (0);
309 
310 	return (ENXIO);
311 }
312 
313 static int
314 udbp_attach(device_t dev)
315 {
316 	struct usb2_attach_arg *uaa = device_get_ivars(dev);
317 	struct udbp_softc *sc = device_get_softc(dev);
318 	int error;
319 
320 	device_set_usb2_desc(dev);
321 
322 	snprintf(sc->sc_name, sizeof(sc->sc_name),
323 	    "%s", device_get_nameunit(dev));
324 
325 	mtx_init(&sc->sc_mtx, "udbp lock", NULL, MTX_DEF | MTX_RECURSE);
326 
327 	error = usb2_transfer_setup(uaa->device, &uaa->info.bIfaceIndex,
328 	    sc->sc_xfer, udbp_config, UDBP_T_MAX, sc, &sc->sc_mtx);
329 	if (error) {
330 		DPRINTF("error=%s\n", usb2_errstr(error));
331 		goto detach;
332 	}
333 	NG_BT_MBUFQ_INIT(&sc->sc_xmitq, UDBP_Q_MAXLEN);
334 
335 	NG_BT_MBUFQ_INIT(&sc->sc_xmitq_hipri, UDBP_Q_MAXLEN);
336 
337 	/* create Netgraph node */
338 
339 	if (ng_make_node_common(&ng_udbp_typestruct, &sc->sc_node) != 0) {
340 		printf("%s: Could not create Netgraph node\n",
341 		    sc->sc_name);
342 		sc->sc_node = NULL;
343 		goto detach;
344 	}
345 	/* name node */
346 
347 	if (ng_name_node(sc->sc_node, sc->sc_name) != 0) {
348 		printf("%s: Could not name node\n",
349 		    sc->sc_name);
350 		NG_NODE_UNREF(sc->sc_node);
351 		sc->sc_node = NULL;
352 		goto detach;
353 	}
354 	NG_NODE_SET_PRIVATE(sc->sc_node, sc);
355 
356 	/* the device is now operational */
357 
358 	return (0);			/* success */
359 
360 detach:
361 	udbp_detach(dev);
362 	return (ENOMEM);		/* failure */
363 }
364 
365 static int
366 udbp_detach(device_t dev)
367 {
368 	struct udbp_softc *sc = device_get_softc(dev);
369 
370 	/* destroy Netgraph node */
371 
372 	if (sc->sc_node != NULL) {
373 		NG_NODE_SET_PRIVATE(sc->sc_node, NULL);
374 		ng_rmnode_self(sc->sc_node);
375 		sc->sc_node = NULL;
376 	}
377 	/* free USB transfers, if any */
378 
379 	usb2_transfer_unsetup(sc->sc_xfer, UDBP_T_MAX);
380 
381 	mtx_destroy(&sc->sc_mtx);
382 
383 	/* destroy queues */
384 
385 	NG_BT_MBUFQ_DESTROY(&sc->sc_xmitq);
386 	NG_BT_MBUFQ_DESTROY(&sc->sc_xmitq_hipri);
387 
388 	/* extra check */
389 
390 	if (sc->sc_bulk_in_buffer) {
391 		m_freem(sc->sc_bulk_in_buffer);
392 		sc->sc_bulk_in_buffer = NULL;
393 	}
394 	return (0);			/* success */
395 }
396 
397 static void
398 udbp_bulk_read_callback(struct usb2_xfer *xfer)
399 {
400 	struct udbp_softc *sc = xfer->priv_sc;
401 	struct mbuf *m;
402 
403 	switch (USB_GET_STATE(xfer)) {
404 	case USB_ST_TRANSFERRED:
405 
406 		/* allocate new mbuf */
407 
408 		MGETHDR(m, M_DONTWAIT, MT_DATA);
409 
410 		if (m == NULL) {
411 			goto tr_setup;
412 		}
413 		MCLGET(m, M_DONTWAIT);
414 
415 		if (!(m->m_flags & M_EXT)) {
416 			m_freem(m);
417 			goto tr_setup;
418 		}
419 		m->m_pkthdr.len = m->m_len = xfer->actlen;
420 
421 		usb2_copy_out(xfer->frbuffers, 0, m->m_data, xfer->actlen);
422 
423 		sc->sc_bulk_in_buffer = m;
424 
425 		DPRINTF("received package %d "
426 		    "bytes\n", xfer->actlen);
427 
428 	case USB_ST_SETUP:
429 tr_setup:
430 		if (sc->sc_bulk_in_buffer) {
431 			ng_send_fn(sc->sc_node, NULL, &udbp_bulk_read_complete, NULL, 0);
432 			return;
433 		}
434 		if (sc->sc_flags & UDBP_FLAG_READ_STALL) {
435 			usb2_transfer_start(sc->sc_xfer[UDBP_T_RD_CS]);
436 			return;
437 		}
438 		xfer->frlengths[0] = xfer->max_data_length;
439 		usb2_start_hardware(xfer);
440 		return;
441 
442 	default:			/* Error */
443 		if (xfer->error != USB_ERR_CANCELLED) {
444 			/* try to clear stall first */
445 			sc->sc_flags |= UDBP_FLAG_READ_STALL;
446 			usb2_transfer_start(sc->sc_xfer[UDBP_T_RD_CS]);
447 		}
448 		return;
449 
450 	}
451 }
452 
453 static void
454 udbp_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
455 {
456 	struct udbp_softc *sc = xfer->priv_sc;
457 	struct usb2_xfer *xfer_other = sc->sc_xfer[UDBP_T_RD];
458 
459 	if (usb2_clear_stall_callback(xfer, xfer_other)) {
460 		DPRINTF("stall cleared\n");
461 		sc->sc_flags &= ~UDBP_FLAG_READ_STALL;
462 		usb2_transfer_start(xfer_other);
463 	}
464 }
465 
466 static void
467 udbp_bulk_read_complete(node_p node, hook_p hook, void *arg1, int arg2)
468 {
469 	struct udbp_softc *sc = NG_NODE_PRIVATE(node);
470 	struct mbuf *m;
471 	int error;
472 
473 	if (sc == NULL) {
474 		return;
475 	}
476 	mtx_lock(&sc->sc_mtx);
477 
478 	m = sc->sc_bulk_in_buffer;
479 
480 	if (m) {
481 
482 		sc->sc_bulk_in_buffer = NULL;
483 
484 		if ((sc->sc_hook == NULL) ||
485 		    NG_HOOK_NOT_VALID(sc->sc_hook)) {
486 			DPRINTF("No upstream hook\n");
487 			goto done;
488 		}
489 		sc->sc_packets_in++;
490 
491 		NG_SEND_DATA_ONLY(error, sc->sc_hook, m);
492 
493 		m = NULL;
494 	}
495 done:
496 	if (m) {
497 		m_freem(m);
498 	}
499 	/* start USB bulk-in transfer, if not already started */
500 
501 	usb2_transfer_start(sc->sc_xfer[UDBP_T_RD]);
502 
503 	mtx_unlock(&sc->sc_mtx);
504 }
505 
506 static void
507 udbp_bulk_write_callback(struct usb2_xfer *xfer)
508 {
509 	struct udbp_softc *sc = xfer->priv_sc;
510 	struct mbuf *m;
511 
512 	switch (USB_GET_STATE(xfer)) {
513 	case USB_ST_TRANSFERRED:
514 
515 		sc->sc_packets_out++;
516 
517 	case USB_ST_SETUP:
518 		if (sc->sc_flags & UDBP_FLAG_WRITE_STALL) {
519 			usb2_transfer_start(sc->sc_xfer[UDBP_T_WR_CS]);
520 			return;
521 		}
522 		/* get next mbuf, if any */
523 
524 		NG_BT_MBUFQ_DEQUEUE(&sc->sc_xmitq_hipri, m);
525 		if (m == NULL) {
526 			NG_BT_MBUFQ_DEQUEUE(&sc->sc_xmitq, m);
527 			if (m == NULL) {
528 				DPRINTF("Data queue is empty\n");
529 				return;
530 			}
531 		}
532 		if (m->m_pkthdr.len > MCLBYTES) {
533 			DPRINTF("truncating large packet "
534 			    "from %d to %d bytes\n", m->m_pkthdr.len,
535 			    MCLBYTES);
536 			m->m_pkthdr.len = MCLBYTES;
537 		}
538 		usb2_m_copy_in(xfer->frbuffers, 0, m, 0, m->m_pkthdr.len);
539 
540 		xfer->frlengths[0] = m->m_pkthdr.len;
541 
542 		m_freem(m);
543 
544 		DPRINTF("packet out: %d bytes\n",
545 		    xfer->frlengths[0]);
546 
547 		usb2_start_hardware(xfer);
548 		return;
549 
550 	default:			/* Error */
551 		if (xfer->error != USB_ERR_CANCELLED) {
552 			/* try to clear stall first */
553 			sc->sc_flags |= UDBP_FLAG_WRITE_STALL;
554 			usb2_transfer_start(sc->sc_xfer[UDBP_T_WR_CS]);
555 		}
556 		return;
557 
558 	}
559 }
560 
561 static void
562 udbp_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
563 {
564 	struct udbp_softc *sc = xfer->priv_sc;
565 	struct usb2_xfer *xfer_other = sc->sc_xfer[UDBP_T_WR];
566 
567 	if (usb2_clear_stall_callback(xfer, xfer_other)) {
568 		DPRINTF("stall cleared\n");
569 		sc->sc_flags &= ~UDBP_FLAG_WRITE_STALL;
570 		usb2_transfer_start(xfer_other);
571 	}
572 }
573 
574 /***********************************************************************
575  * Start of Netgraph methods
576  **********************************************************************/
577 
578 /*
579  * If this is a device node so this work is done in the attach()
580  * routine and the constructor will return EINVAL as you should not be able
581  * to create nodes that depend on hardware (unless you can add the hardware :)
582  */
583 static int
584 ng_udbp_constructor(node_p node)
585 {
586 	return (EINVAL);
587 }
588 
589 /*
590  * Give our ok for a hook to be added...
591  * If we are not running this might kick a device into life.
592  * Possibly decode information out of the hook name.
593  * Add the hook's private info to the hook structure.
594  * (if we had some). In this example, we assume that there is a
595  * an array of structs, called 'channel' in the private info,
596  * one for each active channel. The private
597  * pointer of each hook points to the appropriate UDBP_hookinfo struct
598  * so that the source of an input packet is easily identified.
599  */
600 static int
601 ng_udbp_newhook(node_p node, hook_p hook, const char *name)
602 {
603 	struct udbp_softc *sc = NG_NODE_PRIVATE(node);
604 	int32_t error = 0;
605 
606 	if (strcmp(name, NG_UDBP_HOOK_NAME)) {
607 		return (EINVAL);
608 	}
609 	mtx_lock(&sc->sc_mtx);
610 
611 	if (sc->sc_hook != NULL) {
612 		error = EISCONN;
613 	} else {
614 		sc->sc_hook = hook;
615 		NG_HOOK_SET_PRIVATE(hook, NULL);
616 	}
617 
618 	mtx_unlock(&sc->sc_mtx);
619 
620 	return (error);
621 }
622 
623 /*
624  * Get a netgraph control message.
625  * Check it is one we understand. If needed, send a response.
626  * We could save the address for an async action later, but don't here.
627  * Always free the message.
628  * The response should be in a malloc'd region that the caller can 'free'.
629  * A response is not required.
630  * Theoretically you could respond defferently to old message types if
631  * the cookie in the header didn't match what we consider to be current
632  * (so that old userland programs could continue to work).
633  */
634 static int
635 ng_udbp_rcvmsg(node_p node, item_p item, hook_p lasthook)
636 {
637 	struct udbp_softc *sc = NG_NODE_PRIVATE(node);
638 	struct ng_mesg *resp = NULL;
639 	int error = 0;
640 	struct ng_mesg *msg;
641 
642 	NGI_GET_MSG(item, msg);
643 	/* Deal with message according to cookie and command */
644 	switch (msg->header.typecookie) {
645 	case NGM_UDBP_COOKIE:
646 		switch (msg->header.cmd) {
647 		case NGM_UDBP_GET_STATUS:
648 			{
649 				struct ngudbpstat *stats;
650 
651 				NG_MKRESPONSE(resp, msg, sizeof(*stats), M_NOWAIT);
652 				if (!resp) {
653 					error = ENOMEM;
654 					break;
655 				}
656 				stats = (struct ngudbpstat *)resp->data;
657 				mtx_lock(&sc->sc_mtx);
658 				stats->packets_in = sc->sc_packets_in;
659 				stats->packets_out = sc->sc_packets_out;
660 				mtx_unlock(&sc->sc_mtx);
661 				break;
662 			}
663 		case NGM_UDBP_SET_FLAG:
664 			if (msg->header.arglen != sizeof(uint32_t)) {
665 				error = EINVAL;
666 				break;
667 			}
668 			DPRINTF("flags = 0x%08x\n",
669 			    *((uint32_t *)msg->data));
670 			break;
671 		default:
672 			error = EINVAL;	/* unknown command */
673 			break;
674 		}
675 		break;
676 	default:
677 		error = EINVAL;		/* unknown cookie type */
678 		break;
679 	}
680 
681 	/* Take care of synchronous response, if any */
682 	NG_RESPOND_MSG(error, node, item, resp);
683 	NG_FREE_MSG(msg);
684 	return (error);
685 }
686 
687 /*
688  * Accept data from the hook and queue it for output.
689  */
690 static int
691 ng_udbp_rcvdata(hook_p hook, item_p item)
692 {
693 	struct udbp_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
694 	struct ng_bt_mbufq *queue_ptr;
695 	struct mbuf *m;
696 	struct ng_tag_prio *ptag;
697 	int error;
698 
699 	if (sc == NULL) {
700 		NG_FREE_ITEM(item);
701 		return (EHOSTDOWN);
702 	}
703 	NGI_GET_M(item, m);
704 	NG_FREE_ITEM(item);
705 
706 	/*
707 	 * Now queue the data for when it can be sent
708 	 */
709 	ptag = (void *)m_tag_locate(m, NGM_GENERIC_COOKIE,
710 	    NG_TAG_PRIO, NULL);
711 
712 	if (ptag && (ptag->priority > NG_PRIO_CUTOFF))
713 		queue_ptr = &sc->sc_xmitq_hipri;
714 	else
715 		queue_ptr = &sc->sc_xmitq;
716 
717 	mtx_lock(&sc->sc_mtx);
718 
719 	if (NG_BT_MBUFQ_FULL(queue_ptr)) {
720 		NG_BT_MBUFQ_DROP(queue_ptr);
721 		NG_FREE_M(m);
722 		error = ENOBUFS;
723 	} else {
724 		NG_BT_MBUFQ_ENQUEUE(queue_ptr, m);
725 		/*
726 		 * start bulk-out transfer, if not already started:
727 		 */
728 		usb2_transfer_start(sc->sc_xfer[UDBP_T_WR]);
729 		error = 0;
730 	}
731 
732 	mtx_unlock(&sc->sc_mtx);
733 
734 	return (error);
735 }
736 
737 /*
738  * Do local shutdown processing..
739  * We are a persistant device, we refuse to go away, and
740  * only remove our links and reset ourself.
741  */
742 static int
743 ng_udbp_rmnode(node_p node)
744 {
745 	struct udbp_softc *sc = NG_NODE_PRIVATE(node);
746 
747 	/* Let old node go */
748 	NG_NODE_SET_PRIVATE(node, NULL);
749 	NG_NODE_UNREF(node);		/* forget it ever existed */
750 
751 	if (sc == NULL) {
752 		goto done;
753 	}
754 	/* Create Netgraph node */
755 	if (ng_make_node_common(&ng_udbp_typestruct, &sc->sc_node) != 0) {
756 		printf("%s: Could not create Netgraph node\n",
757 		    sc->sc_name);
758 		sc->sc_node = NULL;
759 		goto done;
760 	}
761 	/* Name node */
762 	if (ng_name_node(sc->sc_node, sc->sc_name) != 0) {
763 		printf("%s: Could not name Netgraph node\n",
764 		    sc->sc_name);
765 		NG_NODE_UNREF(sc->sc_node);
766 		sc->sc_node = NULL;
767 		goto done;
768 	}
769 	NG_NODE_SET_PRIVATE(sc->sc_node, sc);
770 
771 done:
772 	if (sc) {
773 		mtx_unlock(&sc->sc_mtx);
774 	}
775 	return (0);
776 }
777 
778 /*
779  * This is called once we've already connected a new hook to the other node.
780  * It gives us a chance to balk at the last minute.
781  */
782 static int
783 ng_udbp_connect(hook_p hook)
784 {
785 	struct udbp_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
786 
787 	/* probably not at splnet, force outward queueing */
788 	NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
789 
790 	mtx_lock(&sc->sc_mtx);
791 
792 	sc->sc_flags |= (UDBP_FLAG_READ_STALL |
793 	    UDBP_FLAG_WRITE_STALL);
794 
795 	/* start bulk-in transfer */
796 	usb2_transfer_start(sc->sc_xfer[UDBP_T_RD]);
797 
798 	/* start bulk-out transfer */
799 	usb2_transfer_start(sc->sc_xfer[UDBP_T_WR]);
800 
801 	mtx_unlock(&sc->sc_mtx);
802 
803 	return (0);
804 }
805 
806 /*
807  * Dook disconnection
808  *
809  * For this type, removal of the last link destroys the node
810  */
811 static int
812 ng_udbp_disconnect(hook_p hook)
813 {
814 	struct udbp_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
815 	int error = 0;
816 
817 	if (sc != NULL) {
818 
819 		mtx_lock(&sc->sc_mtx);
820 
821 		if (hook != sc->sc_hook) {
822 			error = EINVAL;
823 		} else {
824 
825 			/* stop bulk-in transfer */
826 			usb2_transfer_stop(sc->sc_xfer[UDBP_T_RD_CS]);
827 			usb2_transfer_stop(sc->sc_xfer[UDBP_T_RD]);
828 
829 			/* stop bulk-out transfer */
830 			usb2_transfer_stop(sc->sc_xfer[UDBP_T_WR_CS]);
831 			usb2_transfer_stop(sc->sc_xfer[UDBP_T_WR]);
832 
833 			/* cleanup queues */
834 			NG_BT_MBUFQ_DRAIN(&sc->sc_xmitq);
835 			NG_BT_MBUFQ_DRAIN(&sc->sc_xmitq_hipri);
836 
837 			if (sc->sc_bulk_in_buffer) {
838 				m_freem(sc->sc_bulk_in_buffer);
839 				sc->sc_bulk_in_buffer = NULL;
840 			}
841 			sc->sc_hook = NULL;
842 		}
843 
844 		mtx_unlock(&sc->sc_mtx);
845 	}
846 	if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
847 	    && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))))
848 		ng_rmnode_self(NG_HOOK_NODE(hook));
849 
850 	return (error);
851 }
852