1 /*
2  * ng_ubt.c
3  */
4 
5 /*-
6  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
7  *
8  * Copyright (c) 2001-2009 Maksim Yevmenkin <m_evmenkin@yahoo.com>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $Id: ng_ubt.c,v 1.16 2003/10/10 19:15:06 max Exp $
33  * $FreeBSD$
34  */
35 
36 /*
37  * NOTE: ng_ubt2 driver has a split personality. On one side it is
38  * a USB device driver and on the other it is a Netgraph node. This
39  * driver will *NOT* create traditional /dev/ enties, only Netgraph
40  * node.
41  *
42  * NOTE ON LOCKS USED: ng_ubt2 drives uses 2 locks (mutexes)
43  *
44  * 1) sc_if_mtx - lock for device's interface #0 and #1. This lock is used
45  *    by USB for any USB request going over device's interface #0 and #1,
46  *    i.e. interrupt, control, bulk and isoc. transfers.
47  *
48  * 2) sc_ng_mtx - this lock is used to protect shared (between USB, Netgraph
49  *    and Taskqueue) data, such as outgoing mbuf queues, task flags and hook
50  *    pointer. This lock *SHOULD NOT* be grabbed for a long time. In fact,
51  *    think of it as a spin lock.
52  *
53  * NOTE ON LOCKING STRATEGY: ng_ubt2 driver operates in 3 different contexts.
54  *
55  * 1) USB context. This is where all the USB related stuff happens. All
56  *    callbacks run in this context. All callbacks are called (by USB) with
57  *    appropriate interface lock held. It is (generally) allowed to grab
58  *    any additional locks.
59  *
60  * 2) Netgraph context. This is where all the Netgraph related stuff happens.
61  *    Since we mark node as WRITER, the Netgraph node will be "locked" (from
62  *    Netgraph point of view). Any variable that is only modified from the
63  *    Netgraph context does not require any additional locking. It is generally
64  *    *NOT* allowed to grab *ANY* additional locks. Whatever you do, *DO NOT*
65  *    grab any lock in the Netgraph context that could cause de-scheduling of
66  *    the Netgraph thread for significant amount of time. In fact, the only
67  *    lock that is allowed in the Netgraph context is the sc_ng_mtx lock.
68  *    Also make sure that any code that is called from the Netgraph context
69  *    follows the rule above.
70  *
71  * 3) Taskqueue context. This is where ubt_task runs. Since we are generally
72  *    NOT allowed to grab any lock that could cause de-scheduling in the
73  *    Netgraph context, and, USB requires us to grab interface lock before
74  *    doing things with transfers, it is safer to transition from the Netgraph
75  *    context to the Taskqueue context before we can call into USB subsystem.
76  *
77  * So, to put everything together, the rules are as follows.
78  *	It is OK to call from the USB context or the Taskqueue context into
79  * the Netgraph context (i.e. call NG_SEND_xxx functions). In other words
80  * it is allowed to call into the Netgraph context with locks held.
81  *	Is it *NOT* OK to call from the Netgraph context into the USB context,
82  * because USB requires us to grab interface locks, and, it is safer to
83  * avoid it. So, to make things safer we set task flags to indicate which
84  * actions we want to perform and schedule ubt_task which would run in the
85  * Taskqueue context.
86  *	Is is OK to call from the Taskqueue context into the USB context,
87  * and, ubt_task does just that (i.e. grabs appropriate interface locks
88  * before calling into USB).
89  *	Access to the outgoing queues, task flags and hook pointer is
90  * controlled by the sc_ng_mtx lock. It is an unavoidable evil. Again,
91  * sc_ng_mtx should really be a spin lock (and it is very likely to an
92  * equivalent of spin lock due to adaptive nature of FreeBSD mutexes).
93  *	All USB callbacks accept softc pointer as a private data. USB ensures
94  * that this pointer is valid.
95  */
96 
97 #include <sys/stdint.h>
98 #include <sys/stddef.h>
99 #include <sys/param.h>
100 #include <sys/queue.h>
101 #include <sys/types.h>
102 #include <sys/systm.h>
103 #include <sys/kernel.h>
104 #include <sys/bus.h>
105 #include <sys/module.h>
106 #include <sys/lock.h>
107 #include <sys/mutex.h>
108 #include <sys/condvar.h>
109 #include <sys/sysctl.h>
110 #include <sys/sx.h>
111 #include <sys/unistd.h>
112 #include <sys/callout.h>
113 #include <sys/malloc.h>
114 #include <sys/priv.h>
115 
116 #include "usbdevs.h"
117 #include <dev/usb/usb.h>
118 #include <dev/usb/usbdi.h>
119 #include <dev/usb/usbdi_util.h>
120 
121 #define	USB_DEBUG_VAR usb_debug
122 #include <dev/usb/usb_debug.h>
123 #include <dev/usb/usb_busdma.h>
124 
125 #include <sys/mbuf.h>
126 #include <sys/taskqueue.h>
127 
128 #include <netgraph/ng_message.h>
129 #include <netgraph/netgraph.h>
130 #include <netgraph/ng_parse.h>
131 #include <netgraph/bluetooth/include/ng_bluetooth.h>
132 #include <netgraph/bluetooth/include/ng_hci.h>
133 #include <netgraph/bluetooth/include/ng_ubt.h>
134 #include <netgraph/bluetooth/drivers/ubt/ng_ubt_var.h>
135 
136 static int		ubt_modevent(module_t, int, void *);
137 static device_probe_t	ubt_probe;
138 static device_attach_t	ubt_attach;
139 static device_detach_t	ubt_detach;
140 
141 static void		ubt_task_schedule(ubt_softc_p, int);
142 static task_fn_t	ubt_task;
143 
144 #define	ubt_xfer_start(sc, i)	usbd_transfer_start((sc)->sc_xfer[(i)])
145 
146 /* Netgraph methods */
147 static ng_constructor_t	ng_ubt_constructor;
148 static ng_shutdown_t	ng_ubt_shutdown;
149 static ng_newhook_t	ng_ubt_newhook;
150 static ng_connect_t	ng_ubt_connect;
151 static ng_disconnect_t	ng_ubt_disconnect;
152 static ng_rcvmsg_t	ng_ubt_rcvmsg;
153 static ng_rcvdata_t	ng_ubt_rcvdata;
154 
155 /* Queue length */
156 static const struct ng_parse_struct_field	ng_ubt_node_qlen_type_fields[] =
157 {
158 	{ "queue", &ng_parse_int32_type, },
159 	{ "qlen",  &ng_parse_int32_type, },
160 	{ NULL, }
161 };
162 static const struct ng_parse_type		ng_ubt_node_qlen_type =
163 {
164 	&ng_parse_struct_type,
165 	&ng_ubt_node_qlen_type_fields
166 };
167 
168 /* Stat info */
169 static const struct ng_parse_struct_field	ng_ubt_node_stat_type_fields[] =
170 {
171 	{ "pckts_recv", &ng_parse_uint32_type, },
172 	{ "bytes_recv", &ng_parse_uint32_type, },
173 	{ "pckts_sent", &ng_parse_uint32_type, },
174 	{ "bytes_sent", &ng_parse_uint32_type, },
175 	{ "oerrors",    &ng_parse_uint32_type, },
176 	{ "ierrors",    &ng_parse_uint32_type, },
177 	{ NULL, }
178 };
179 static const struct ng_parse_type		ng_ubt_node_stat_type =
180 {
181 	&ng_parse_struct_type,
182 	&ng_ubt_node_stat_type_fields
183 };
184 
185 /* Netgraph node command list */
186 static const struct ng_cmdlist			ng_ubt_cmdlist[] =
187 {
188 	{
189 		NGM_UBT_COOKIE,
190 		NGM_UBT_NODE_SET_DEBUG,
191 		"set_debug",
192 		&ng_parse_uint16_type,
193 		NULL
194 	},
195 	{
196 		NGM_UBT_COOKIE,
197 		NGM_UBT_NODE_GET_DEBUG,
198 		"get_debug",
199 		NULL,
200 		&ng_parse_uint16_type
201 	},
202 	{
203 		NGM_UBT_COOKIE,
204 		NGM_UBT_NODE_SET_QLEN,
205 		"set_qlen",
206 		&ng_ubt_node_qlen_type,
207 		NULL
208 	},
209 	{
210 		NGM_UBT_COOKIE,
211 		NGM_UBT_NODE_GET_QLEN,
212 		"get_qlen",
213 		&ng_ubt_node_qlen_type,
214 		&ng_ubt_node_qlen_type
215 	},
216 	{
217 		NGM_UBT_COOKIE,
218 		NGM_UBT_NODE_GET_STAT,
219 		"get_stat",
220 		NULL,
221 		&ng_ubt_node_stat_type
222 	},
223 	{
224 		NGM_UBT_COOKIE,
225 		NGM_UBT_NODE_RESET_STAT,
226 		"reset_stat",
227 		NULL,
228 		NULL
229 	},
230 	{ 0, }
231 };
232 
233 /* Netgraph node type */
234 static struct ng_type	typestruct =
235 {
236 	.version = 	NG_ABI_VERSION,
237 	.name =		NG_UBT_NODE_TYPE,
238 	.constructor =	ng_ubt_constructor,
239 	.rcvmsg =	ng_ubt_rcvmsg,
240 	.shutdown =	ng_ubt_shutdown,
241 	.newhook =	ng_ubt_newhook,
242 	.connect =	ng_ubt_connect,
243 	.rcvdata =	ng_ubt_rcvdata,
244 	.disconnect =	ng_ubt_disconnect,
245 	.cmdlist =	ng_ubt_cmdlist
246 };
247 
248 /****************************************************************************
249  ****************************************************************************
250  **                              USB specific
251  ****************************************************************************
252  ****************************************************************************/
253 
254 /* USB methods */
255 static usb_callback_t	ubt_ctrl_write_callback;
256 static usb_callback_t	ubt_intr_read_callback;
257 static usb_callback_t	ubt_bulk_read_callback;
258 static usb_callback_t	ubt_bulk_write_callback;
259 static usb_callback_t	ubt_isoc_read_callback;
260 static usb_callback_t	ubt_isoc_write_callback;
261 
262 static int		ubt_fwd_mbuf_up(ubt_softc_p, struct mbuf **);
263 static int		ubt_isoc_read_one_frame(struct usb_xfer *, int);
264 
265 /*
266  * USB config
267  *
268  * The following desribes usb transfers that could be submitted on USB device.
269  *
270  * Interface 0 on the USB device must present the following endpoints
271  *	1) Interrupt endpoint to receive HCI events
272  *	2) Bulk IN endpoint to receive ACL data
273  *	3) Bulk OUT endpoint to send ACL data
274  *
275  * Interface 1 on the USB device must present the following endpoints
276  *	1) Isochronous IN endpoint to receive SCO data
277  *	2) Isochronous OUT endpoint to send SCO data
278  */
279 
280 static const struct usb_config		ubt_config[UBT_N_TRANSFER] =
281 {
282 	/*
283 	 * Interface #0
284  	 */
285 
286 	/* Outgoing bulk transfer - ACL packets */
287 	[UBT_IF_0_BULK_DT_WR] = {
288 		.type =		UE_BULK,
289 		.endpoint =	UE_ADDR_ANY,
290 		.direction =	UE_DIR_OUT,
291 		.if_index = 	0,
292 		.bufsize =	UBT_BULK_WRITE_BUFFER_SIZE,
293 		.flags =	{ .pipe_bof = 1, .force_short_xfer = 1, },
294 		.callback =	&ubt_bulk_write_callback,
295 	},
296 	/* Incoming bulk transfer - ACL packets */
297 	[UBT_IF_0_BULK_DT_RD] = {
298 		.type =		UE_BULK,
299 		.endpoint =	UE_ADDR_ANY,
300 		.direction =	UE_DIR_IN,
301 		.if_index = 	0,
302 		.bufsize =	UBT_BULK_READ_BUFFER_SIZE,
303 		.flags =	{ .pipe_bof = 1, .short_xfer_ok = 1, },
304 		.callback =	&ubt_bulk_read_callback,
305 	},
306 	/* Incoming interrupt transfer - HCI events */
307 	[UBT_IF_0_INTR_DT_RD] = {
308 		.type =		UE_INTERRUPT,
309 		.endpoint =	UE_ADDR_ANY,
310 		.direction =	UE_DIR_IN,
311 		.if_index = 	0,
312 		.flags =	{ .pipe_bof = 1, .short_xfer_ok = 1, },
313 		.bufsize =	UBT_INTR_BUFFER_SIZE,
314 		.callback =	&ubt_intr_read_callback,
315 	},
316 	/* Outgoing control transfer - HCI commands */
317 	[UBT_IF_0_CTRL_DT_WR] = {
318 		.type =		UE_CONTROL,
319 		.endpoint =	0x00,	/* control pipe */
320 		.direction =	UE_DIR_ANY,
321 		.if_index = 	0,
322 		.bufsize =	UBT_CTRL_BUFFER_SIZE,
323 		.callback =	&ubt_ctrl_write_callback,
324 		.timeout =	5000,	/* 5 seconds */
325 	},
326 
327 	/*
328 	 * Interface #1
329  	 */
330 
331 	/* Incoming isochronous transfer #1 - SCO packets */
332 	[UBT_IF_1_ISOC_DT_RD1] = {
333 		.type =		UE_ISOCHRONOUS,
334 		.endpoint =	UE_ADDR_ANY,
335 		.direction =	UE_DIR_IN,
336 		.if_index = 	1,
337 		.bufsize =	0,	/* use "wMaxPacketSize * frames" */
338 		.frames =	UBT_ISOC_NFRAMES,
339 		.flags =	{ .short_xfer_ok = 1, },
340 		.callback =	&ubt_isoc_read_callback,
341 	},
342 	/* Incoming isochronous transfer #2 - SCO packets */
343 	[UBT_IF_1_ISOC_DT_RD2] = {
344 		.type =		UE_ISOCHRONOUS,
345 		.endpoint =	UE_ADDR_ANY,
346 		.direction =	UE_DIR_IN,
347 		.if_index = 	1,
348 		.bufsize =	0,	/* use "wMaxPacketSize * frames" */
349 		.frames =	UBT_ISOC_NFRAMES,
350 		.flags =	{ .short_xfer_ok = 1, },
351 		.callback =	&ubt_isoc_read_callback,
352 	},
353 	/* Outgoing isochronous transfer #1 - SCO packets */
354 	[UBT_IF_1_ISOC_DT_WR1] = {
355 		.type =		UE_ISOCHRONOUS,
356 		.endpoint =	UE_ADDR_ANY,
357 		.direction =	UE_DIR_OUT,
358 		.if_index = 	1,
359 		.bufsize =	0,	/* use "wMaxPacketSize * frames" */
360 		.frames =	UBT_ISOC_NFRAMES,
361 		.flags =	{ .short_xfer_ok = 1, },
362 		.callback =	&ubt_isoc_write_callback,
363 	},
364 	/* Outgoing isochronous transfer #2 - SCO packets */
365 	[UBT_IF_1_ISOC_DT_WR2] = {
366 		.type =		UE_ISOCHRONOUS,
367 		.endpoint =	UE_ADDR_ANY,
368 		.direction =	UE_DIR_OUT,
369 		.if_index = 	1,
370 		.bufsize =	0,	/* use "wMaxPacketSize * frames" */
371 		.frames =	UBT_ISOC_NFRAMES,
372 		.flags =	{ .short_xfer_ok = 1, },
373 		.callback =	&ubt_isoc_write_callback,
374 	},
375 };
376 
377 /*
378  * If for some reason device should not be attached then put
379  * VendorID/ProductID pair into the list below. The format is
380  * as follows:
381  *
382  *	{ USB_VPI(VENDOR_ID, PRODUCT_ID, 0) },
383  *
384  * where VENDOR_ID and PRODUCT_ID are hex numbers.
385  */
386 
387 static const STRUCT_USB_HOST_ID ubt_ignore_devs[] =
388 {
389 	/* AVM USB Bluetooth-Adapter BlueFritz! v1.0 */
390 	{ USB_VPI(USB_VENDOR_AVM, 0x2200, 0) },
391 
392 	/* Atheros 3011 with sflash firmware */
393 	{ USB_VPI(0x0cf3, 0x3002, 0) },
394 	{ USB_VPI(0x0cf3, 0xe019, 0) },
395 	{ USB_VPI(0x13d3, 0x3304, 0) },
396 	{ USB_VPI(0x0930, 0x0215, 0) },
397 	{ USB_VPI(0x0489, 0xe03d, 0) },
398 	{ USB_VPI(0x0489, 0xe027, 0) },
399 
400 	/* Atheros AR9285 Malbec with sflash firmware */
401 	{ USB_VPI(0x03f0, 0x311d, 0) },
402 
403 	/* Atheros 3012 with sflash firmware */
404 	{ USB_VPI(0x0cf3, 0x3004, 0), USB_DEV_BCD_LTEQ(1) },
405 	{ USB_VPI(0x0cf3, 0x311d, 0), USB_DEV_BCD_LTEQ(1) },
406 	{ USB_VPI(0x13d3, 0x3375, 0), USB_DEV_BCD_LTEQ(1) },
407 	{ USB_VPI(0x04ca, 0x3005, 0), USB_DEV_BCD_LTEQ(1) },
408 	{ USB_VPI(0x04ca, 0x3006, 0), USB_DEV_BCD_LTEQ(1) },
409 	{ USB_VPI(0x04ca, 0x3008, 0), USB_DEV_BCD_LTEQ(1) },
410 	{ USB_VPI(0x13d3, 0x3362, 0), USB_DEV_BCD_LTEQ(1) },
411 	{ USB_VPI(0x0cf3, 0xe004, 0), USB_DEV_BCD_LTEQ(1) },
412 	{ USB_VPI(0x0930, 0x0219, 0), USB_DEV_BCD_LTEQ(1) },
413 	{ USB_VPI(0x0489, 0xe057, 0), USB_DEV_BCD_LTEQ(1) },
414 	{ USB_VPI(0x13d3, 0x3393, 0), USB_DEV_BCD_LTEQ(1) },
415 	{ USB_VPI(0x0489, 0xe04e, 0), USB_DEV_BCD_LTEQ(1) },
416 	{ USB_VPI(0x0489, 0xe056, 0), USB_DEV_BCD_LTEQ(1) },
417 
418 	/* Atheros AR5BBU12 with sflash firmware */
419 	{ USB_VPI(0x0489, 0xe02c, 0), USB_DEV_BCD_LTEQ(1) },
420 
421 	/* Atheros AR5BBU12 with sflash firmware */
422 	{ USB_VPI(0x0489, 0xe03c, 0), USB_DEV_BCD_LTEQ(1) },
423 	{ USB_VPI(0x0489, 0xe036, 0), USB_DEV_BCD_LTEQ(1) },
424 };
425 
426 /* List of supported bluetooth devices */
427 static const STRUCT_USB_HOST_ID ubt_devs[] =
428 {
429 	/* Generic Bluetooth class devices */
430 	{ USB_IFACE_CLASS(UDCLASS_WIRELESS),
431 	  USB_IFACE_SUBCLASS(UDSUBCLASS_RF),
432 	  USB_IFACE_PROTOCOL(UDPROTO_BLUETOOTH) },
433 
434 	/* AVM USB Bluetooth-Adapter BlueFritz! v2.0 */
435 	{ USB_VPI(USB_VENDOR_AVM, 0x3800, 0) },
436 
437 	/* Broadcom USB dongles, mostly BCM20702 and BCM20702A0 */
438 	{ USB_VENDOR(USB_VENDOR_BROADCOM),
439 	  USB_IFACE_CLASS(UICLASS_VENDOR),
440 	  USB_IFACE_SUBCLASS(UDSUBCLASS_RF),
441 	  USB_IFACE_PROTOCOL(UDPROTO_BLUETOOTH) },
442 
443 	/* Apple-specific (Broadcom) devices */
444 	{ USB_VENDOR(USB_VENDOR_APPLE),
445 	  USB_IFACE_CLASS(UICLASS_VENDOR),
446 	  USB_IFACE_SUBCLASS(UDSUBCLASS_RF),
447 	  USB_IFACE_PROTOCOL(UDPROTO_BLUETOOTH) },
448 
449 	/* Foxconn - Hon Hai */
450 	{ USB_VENDOR(USB_VENDOR_FOXCONN),
451 	  USB_IFACE_CLASS(UICLASS_VENDOR),
452 	  USB_IFACE_SUBCLASS(UDSUBCLASS_RF),
453 	  USB_IFACE_PROTOCOL(UDPROTO_BLUETOOTH) },
454 
455 	/* MediaTek MT76x0E */
456 	{ USB_VPI(USB_VENDOR_MEDIATEK, 0x763f, 0) },
457 
458 	/* Broadcom SoftSailing reporting vendor specific */
459 	{ USB_VPI(USB_VENDOR_BROADCOM, 0x21e1, 0) },
460 
461 	/* Apple MacBookPro 7,1 */
462 	{ USB_VPI(USB_VENDOR_APPLE, 0x8213, 0) },
463 
464 	/* Apple iMac11,1 */
465 	{ USB_VPI(USB_VENDOR_APPLE, 0x8215, 0) },
466 
467 	/* Apple MacBookPro6,2 */
468 	{ USB_VPI(USB_VENDOR_APPLE, 0x8218, 0) },
469 
470 	/* Apple MacBookAir3,1, MacBookAir3,2 */
471 	{ USB_VPI(USB_VENDOR_APPLE, 0x821b, 0) },
472 
473 	/* Apple MacBookAir4,1 */
474 	{ USB_VPI(USB_VENDOR_APPLE, 0x821f, 0) },
475 
476 	/* MacBookAir6,1 */
477 	{ USB_VPI(USB_VENDOR_APPLE, 0x828f, 0) },
478 
479 	/* Apple MacBookPro8,2 */
480 	{ USB_VPI(USB_VENDOR_APPLE, 0x821a, 0) },
481 
482 	/* Apple MacMini5,1 */
483 	{ USB_VPI(USB_VENDOR_APPLE, 0x8281, 0) },
484 
485 	/* Bluetooth Ultraport Module from IBM */
486 	{ USB_VPI(USB_VENDOR_TDK, 0x030a, 0) },
487 
488 	/* ALPS Modules with non-standard ID */
489 	{ USB_VPI(USB_VENDOR_ALPS, 0x3001, 0) },
490 	{ USB_VPI(USB_VENDOR_ALPS, 0x3002, 0) },
491 
492 	{ USB_VPI(USB_VENDOR_ERICSSON2, 0x1002, 0) },
493 
494 	/* Canyon CN-BTU1 with HID interfaces */
495 	{ USB_VPI(USB_VENDOR_CANYON, 0x0000, 0) },
496 
497 	/* Broadcom BCM20702A0 */
498 	{ USB_VPI(USB_VENDOR_ASUS, 0x17b5, 0) },
499 	{ USB_VPI(USB_VENDOR_ASUS, 0x17cb, 0) },
500 	{ USB_VPI(USB_VENDOR_LITEON, 0x2003, 0) },
501 	{ USB_VPI(USB_VENDOR_FOXCONN, 0xe042, 0) },
502 	{ USB_VPI(USB_VENDOR_DELL, 0x8197, 0) },
503 };
504 
505 /*
506  * Probe for a USB Bluetooth device.
507  * USB context.
508  */
509 
510 static int
511 ubt_probe(device_t dev)
512 {
513 	struct usb_attach_arg	*uaa = device_get_ivars(dev);
514 	int error;
515 
516 	if (uaa->usb_mode != USB_MODE_HOST)
517 		return (ENXIO);
518 
519 	if (uaa->info.bIfaceIndex != 0)
520 		return (ENXIO);
521 
522 	if (usbd_lookup_id_by_uaa(ubt_ignore_devs,
523 			sizeof(ubt_ignore_devs), uaa) == 0)
524 		return (ENXIO);
525 
526 	error = usbd_lookup_id_by_uaa(ubt_devs, sizeof(ubt_devs), uaa);
527 	if (error == 0)
528 		return (BUS_PROBE_GENERIC);
529 	return (error);
530 } /* ubt_probe */
531 
532 /*
533  * Attach the device.
534  * USB context.
535  */
536 
537 static int
538 ubt_attach(device_t dev)
539 {
540 	struct usb_attach_arg		*uaa = device_get_ivars(dev);
541 	struct ubt_softc		*sc = device_get_softc(dev);
542 	struct usb_endpoint_descriptor	*ed;
543 	struct usb_interface_descriptor *id;
544 	struct usb_interface		*iface;
545 	uint16_t			wMaxPacketSize;
546 	uint8_t				alt_index, i, j;
547 	uint8_t				iface_index[2] = { 0, 1 };
548 
549 	device_set_usb_desc(dev);
550 
551 	sc->sc_dev = dev;
552 	sc->sc_debug = NG_UBT_WARN_LEVEL;
553 
554 	/*
555 	 * Create Netgraph node
556 	 */
557 
558 	if (ng_make_node_common(&typestruct, &sc->sc_node) != 0) {
559 		UBT_ALERT(sc, "could not create Netgraph node\n");
560 		return (ENXIO);
561 	}
562 
563 	/* Name Netgraph node */
564 	if (ng_name_node(sc->sc_node, device_get_nameunit(dev)) != 0) {
565 		UBT_ALERT(sc, "could not name Netgraph node\n");
566 		NG_NODE_UNREF(sc->sc_node);
567 		return (ENXIO);
568 	}
569 	NG_NODE_SET_PRIVATE(sc->sc_node, sc);
570 	NG_NODE_FORCE_WRITER(sc->sc_node);
571 
572 	/*
573 	 * Initialize device softc structure
574 	 */
575 
576 	/* initialize locks */
577 	mtx_init(&sc->sc_ng_mtx, "ubt ng", NULL, MTX_DEF);
578 	mtx_init(&sc->sc_if_mtx, "ubt if", NULL, MTX_DEF | MTX_RECURSE);
579 
580 	/* initialize packet queues */
581 	NG_BT_MBUFQ_INIT(&sc->sc_cmdq, UBT_DEFAULT_QLEN);
582 	NG_BT_MBUFQ_INIT(&sc->sc_aclq, UBT_DEFAULT_QLEN);
583 	NG_BT_MBUFQ_INIT(&sc->sc_scoq, UBT_DEFAULT_QLEN);
584 
585 	/* initialize glue task */
586 	TASK_INIT(&sc->sc_task, 0, ubt_task, sc);
587 
588 	/*
589 	 * Configure Bluetooth USB device. Discover all required USB
590 	 * interfaces and endpoints.
591 	 *
592 	 * USB device must present two interfaces:
593 	 * 1) Interface 0 that has 3 endpoints
594 	 *	1) Interrupt endpoint to receive HCI events
595 	 *	2) Bulk IN endpoint to receive ACL data
596 	 *	3) Bulk OUT endpoint to send ACL data
597 	 *
598 	 * 2) Interface 1 then has 2 endpoints
599 	 *	1) Isochronous IN endpoint to receive SCO data
600  	 *	2) Isochronous OUT endpoint to send SCO data
601 	 *
602 	 * Interface 1 (with isochronous endpoints) has several alternate
603 	 * configurations with different packet size.
604 	 */
605 
606 	/*
607 	 * For interface #1 search alternate settings, and find
608 	 * the descriptor with the largest wMaxPacketSize
609 	 */
610 
611 	wMaxPacketSize = 0;
612 	alt_index = 0;
613 	i = 0;
614 	j = 0;
615 	ed = NULL;
616 
617 	/*
618 	 * Search through all the descriptors looking for the largest
619 	 * packet size:
620 	 */
621 	while ((ed = (struct usb_endpoint_descriptor *)usb_desc_foreach(
622 	    usbd_get_config_descriptor(uaa->device),
623 	    (struct usb_descriptor *)ed))) {
624 
625 		if ((ed->bDescriptorType == UDESC_INTERFACE) &&
626 		    (ed->bLength >= sizeof(*id))) {
627 			id = (struct usb_interface_descriptor *)ed;
628 			i = id->bInterfaceNumber;
629 			j = id->bAlternateSetting;
630 		}
631 
632 		if ((ed->bDescriptorType == UDESC_ENDPOINT) &&
633 		    (ed->bLength >= sizeof(*ed)) &&
634 		    (i == 1)) {
635 			uint16_t temp;
636 
637 			temp = UGETW(ed->wMaxPacketSize);
638 			if (temp > wMaxPacketSize) {
639 				wMaxPacketSize = temp;
640 				alt_index = j;
641 			}
642 		}
643 	}
644 
645 	/* Set alt configuration on interface #1 only if we found it */
646 	if (wMaxPacketSize > 0 &&
647 	    usbd_set_alt_interface_index(uaa->device, 1, alt_index)) {
648 		UBT_ALERT(sc, "could not set alternate setting %d " \
649 			"for interface 1!\n", alt_index);
650 		goto detach;
651 	}
652 
653 	/* Setup transfers for both interfaces */
654 	if (usbd_transfer_setup(uaa->device, iface_index, sc->sc_xfer,
655 			ubt_config, UBT_N_TRANSFER, sc, &sc->sc_if_mtx)) {
656 		UBT_ALERT(sc, "could not allocate transfers\n");
657 		goto detach;
658 	}
659 
660 	/* Claim all interfaces belonging to the Bluetooth part */
661 	for (i = 1;; i++) {
662 		iface = usbd_get_iface(uaa->device, i);
663 		if (iface == NULL)
664 			break;
665 		id = usbd_get_interface_descriptor(iface);
666 
667 		if ((id != NULL) &&
668 		    (id->bInterfaceClass == UICLASS_WIRELESS) &&
669 		    (id->bInterfaceSubClass == UISUBCLASS_RF) &&
670 		    (id->bInterfaceProtocol == UIPROTO_BLUETOOTH)) {
671 			usbd_set_parent_iface(uaa->device, i,
672 			    uaa->info.bIfaceIndex);
673 		}
674 	}
675 	return (0); /* success */
676 
677 detach:
678 	ubt_detach(dev);
679 
680 	return (ENXIO);
681 } /* ubt_attach */
682 
683 /*
684  * Detach the device.
685  * USB context.
686  */
687 
688 int
689 ubt_detach(device_t dev)
690 {
691 	struct ubt_softc	*sc = device_get_softc(dev);
692 	node_p			node = sc->sc_node;
693 
694 	/* Destroy Netgraph node */
695 	if (node != NULL) {
696 		sc->sc_node = NULL;
697 		NG_NODE_REALLY_DIE(node);
698 		ng_rmnode_self(node);
699 	}
700 
701 	/* Make sure ubt_task in gone */
702 	taskqueue_drain(taskqueue_swi, &sc->sc_task);
703 
704 	/* Free USB transfers, if any */
705 	usbd_transfer_unsetup(sc->sc_xfer, UBT_N_TRANSFER);
706 
707 	/* Destroy queues */
708 	UBT_NG_LOCK(sc);
709 	NG_BT_MBUFQ_DESTROY(&sc->sc_cmdq);
710 	NG_BT_MBUFQ_DESTROY(&sc->sc_aclq);
711 	NG_BT_MBUFQ_DESTROY(&sc->sc_scoq);
712 	UBT_NG_UNLOCK(sc);
713 
714 	mtx_destroy(&sc->sc_if_mtx);
715 	mtx_destroy(&sc->sc_ng_mtx);
716 
717 	return (0);
718 } /* ubt_detach */
719 
720 /*
721  * Called when outgoing control request (HCI command) has completed, i.e.
722  * HCI command was sent to the device.
723  * USB context.
724  */
725 
726 static void
727 ubt_ctrl_write_callback(struct usb_xfer *xfer, usb_error_t error)
728 {
729 	struct ubt_softc		*sc = usbd_xfer_softc(xfer);
730 	struct usb_device_request	req;
731 	struct mbuf			*m;
732 	struct usb_page_cache		*pc;
733 	int				actlen;
734 
735 	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
736 
737 	switch (USB_GET_STATE(xfer)) {
738 	case USB_ST_TRANSFERRED:
739 		UBT_INFO(sc, "sent %d bytes to control pipe\n", actlen);
740 		UBT_STAT_BYTES_SENT(sc, actlen);
741 		UBT_STAT_PCKTS_SENT(sc);
742 		/* FALLTHROUGH */
743 
744 	case USB_ST_SETUP:
745 send_next:
746 		/* Get next command mbuf, if any */
747 		UBT_NG_LOCK(sc);
748 		NG_BT_MBUFQ_DEQUEUE(&sc->sc_cmdq, m);
749 		UBT_NG_UNLOCK(sc);
750 
751 		if (m == NULL) {
752 			UBT_INFO(sc, "HCI command queue is empty\n");
753 			break;	/* transfer complete */
754 		}
755 
756 		/* Initialize a USB control request and then schedule it */
757 		bzero(&req, sizeof(req));
758 		req.bmRequestType = UBT_HCI_REQUEST;
759 		USETW(req.wLength, m->m_pkthdr.len);
760 
761 		UBT_INFO(sc, "Sending control request, " \
762 			"bmRequestType=0x%02x, wLength=%d\n",
763 			req.bmRequestType, UGETW(req.wLength));
764 
765 		pc = usbd_xfer_get_frame(xfer, 0);
766 		usbd_copy_in(pc, 0, &req, sizeof(req));
767 		pc = usbd_xfer_get_frame(xfer, 1);
768 		usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len);
769 
770 		usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
771 		usbd_xfer_set_frame_len(xfer, 1, m->m_pkthdr.len);
772 		usbd_xfer_set_frames(xfer, 2);
773 
774 		NG_FREE_M(m);
775 
776 		usbd_transfer_submit(xfer);
777 		break;
778 
779 	default: /* Error */
780 		if (error != USB_ERR_CANCELLED) {
781 			UBT_WARN(sc, "control transfer failed: %s\n",
782 				usbd_errstr(error));
783 
784 			UBT_STAT_OERROR(sc);
785 			goto send_next;
786 		}
787 
788 		/* transfer cancelled */
789 		break;
790 	}
791 } /* ubt_ctrl_write_callback */
792 
793 /*
794  * Called when incoming interrupt transfer (HCI event) has completed, i.e.
795  * HCI event was received from the device.
796  * USB context.
797  */
798 
799 static void
800 ubt_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
801 {
802 	struct ubt_softc	*sc = usbd_xfer_softc(xfer);
803 	struct mbuf		*m;
804 	ng_hci_event_pkt_t	*hdr;
805 	struct usb_page_cache	*pc;
806 	int			actlen;
807 
808 	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
809 
810 	m = NULL;
811 
812 	switch (USB_GET_STATE(xfer)) {
813 	case USB_ST_TRANSFERRED:
814 		/* Allocate a new mbuf */
815 		MGETHDR(m, M_NOWAIT, MT_DATA);
816 		if (m == NULL) {
817 			UBT_STAT_IERROR(sc);
818 			goto submit_next;
819 		}
820 
821 		if (!(MCLGET(m, M_NOWAIT))) {
822 			UBT_STAT_IERROR(sc);
823 			goto submit_next;
824 		}
825 
826 		/* Add HCI packet type */
827 		*mtod(m, uint8_t *)= NG_HCI_EVENT_PKT;
828 		m->m_pkthdr.len = m->m_len = 1;
829 
830 		if (actlen > MCLBYTES - 1)
831 			actlen = MCLBYTES - 1;
832 
833 		pc = usbd_xfer_get_frame(xfer, 0);
834 		usbd_copy_out(pc, 0, mtod(m, uint8_t *) + 1, actlen);
835 		m->m_pkthdr.len += actlen;
836 		m->m_len += actlen;
837 
838 		UBT_INFO(sc, "got %d bytes from interrupt pipe\n",
839 			actlen);
840 
841 		/* Validate packet and send it up the stack */
842 		if (m->m_pkthdr.len < (int)sizeof(*hdr)) {
843 			UBT_INFO(sc, "HCI event packet is too short\n");
844 
845 			UBT_STAT_IERROR(sc);
846 			goto submit_next;
847 		}
848 
849 		hdr = mtod(m, ng_hci_event_pkt_t *);
850 		if (hdr->length != (m->m_pkthdr.len - sizeof(*hdr))) {
851 			UBT_ERR(sc, "Invalid HCI event packet size, " \
852 				"length=%d, pktlen=%d\n",
853 				hdr->length, m->m_pkthdr.len);
854 
855 			UBT_STAT_IERROR(sc);
856 			goto submit_next;
857 		}
858 
859 		UBT_INFO(sc, "got complete HCI event frame, pktlen=%d, " \
860 			"length=%d\n", m->m_pkthdr.len, hdr->length);
861 
862 		UBT_STAT_PCKTS_RECV(sc);
863 		UBT_STAT_BYTES_RECV(sc, m->m_pkthdr.len);
864 
865 		ubt_fwd_mbuf_up(sc, &m);
866 		/* m == NULL at this point */
867 		/* FALLTHROUGH */
868 
869 	case USB_ST_SETUP:
870 submit_next:
871 		NG_FREE_M(m); /* checks for m != NULL */
872 
873 		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
874 		usbd_transfer_submit(xfer);
875 		break;
876 
877 	default: /* Error */
878 		if (error != USB_ERR_CANCELLED) {
879 			UBT_WARN(sc, "interrupt transfer failed: %s\n",
880 				usbd_errstr(error));
881 
882 			/* Try to clear stall first */
883 			usbd_xfer_set_stall(xfer);
884 			goto submit_next;
885 		}
886 			/* transfer cancelled */
887 		break;
888 	}
889 } /* ubt_intr_read_callback */
890 
891 /*
892  * Called when incoming bulk transfer (ACL packet) has completed, i.e.
893  * ACL packet was received from the device.
894  * USB context.
895  */
896 
897 static void
898 ubt_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
899 {
900 	struct ubt_softc	*sc = usbd_xfer_softc(xfer);
901 	struct mbuf		*m;
902 	ng_hci_acldata_pkt_t	*hdr;
903 	struct usb_page_cache	*pc;
904 	int len;
905 	int actlen;
906 
907 	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
908 
909 	m = NULL;
910 
911 	switch (USB_GET_STATE(xfer)) {
912 	case USB_ST_TRANSFERRED:
913 		/* Allocate new mbuf */
914 		MGETHDR(m, M_NOWAIT, MT_DATA);
915 		if (m == NULL) {
916 			UBT_STAT_IERROR(sc);
917 			goto submit_next;
918 		}
919 
920 		if (!(MCLGET(m, M_NOWAIT))) {
921 			UBT_STAT_IERROR(sc);
922 			goto submit_next;
923 		}
924 
925 		/* Add HCI packet type */
926 		*mtod(m, uint8_t *)= NG_HCI_ACL_DATA_PKT;
927 		m->m_pkthdr.len = m->m_len = 1;
928 
929 		if (actlen > MCLBYTES - 1)
930 			actlen = MCLBYTES - 1;
931 
932 		pc = usbd_xfer_get_frame(xfer, 0);
933 		usbd_copy_out(pc, 0, mtod(m, uint8_t *) + 1, actlen);
934 		m->m_pkthdr.len += actlen;
935 		m->m_len += actlen;
936 
937 		UBT_INFO(sc, "got %d bytes from bulk-in pipe\n",
938 			actlen);
939 
940 		/* Validate packet and send it up the stack */
941 		if (m->m_pkthdr.len < (int)sizeof(*hdr)) {
942 			UBT_INFO(sc, "HCI ACL packet is too short\n");
943 
944 			UBT_STAT_IERROR(sc);
945 			goto submit_next;
946 		}
947 
948 		hdr = mtod(m, ng_hci_acldata_pkt_t *);
949 		len = le16toh(hdr->length);
950 		if (len != (int)(m->m_pkthdr.len - sizeof(*hdr))) {
951 			UBT_ERR(sc, "Invalid ACL packet size, length=%d, " \
952 				"pktlen=%d\n", len, m->m_pkthdr.len);
953 
954 			UBT_STAT_IERROR(sc);
955 			goto submit_next;
956 		}
957 
958 		UBT_INFO(sc, "got complete ACL data packet, pktlen=%d, " \
959 			"length=%d\n", m->m_pkthdr.len, len);
960 
961 		UBT_STAT_PCKTS_RECV(sc);
962 		UBT_STAT_BYTES_RECV(sc, m->m_pkthdr.len);
963 
964 		ubt_fwd_mbuf_up(sc, &m);
965 		/* m == NULL at this point */
966 		/* FALLTHOUGH */
967 
968 	case USB_ST_SETUP:
969 submit_next:
970 		NG_FREE_M(m); /* checks for m != NULL */
971 
972 		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
973 		usbd_transfer_submit(xfer);
974 		break;
975 
976 	default: /* Error */
977 		if (error != USB_ERR_CANCELLED) {
978 			UBT_WARN(sc, "bulk-in transfer failed: %s\n",
979 				usbd_errstr(error));
980 
981 			/* Try to clear stall first */
982 			usbd_xfer_set_stall(xfer);
983 			goto submit_next;
984 		}
985 			/* transfer cancelled */
986 		break;
987 	}
988 } /* ubt_bulk_read_callback */
989 
990 /*
991  * Called when outgoing bulk transfer (ACL packet) has completed, i.e.
992  * ACL packet was sent to the device.
993  * USB context.
994  */
995 
996 static void
997 ubt_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
998 {
999 	struct ubt_softc	*sc = usbd_xfer_softc(xfer);
1000 	struct mbuf		*m;
1001 	struct usb_page_cache	*pc;
1002 	int			actlen;
1003 
1004 	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
1005 
1006 	switch (USB_GET_STATE(xfer)) {
1007 	case USB_ST_TRANSFERRED:
1008 		UBT_INFO(sc, "sent %d bytes to bulk-out pipe\n", actlen);
1009 		UBT_STAT_BYTES_SENT(sc, actlen);
1010 		UBT_STAT_PCKTS_SENT(sc);
1011 		/* FALLTHROUGH */
1012 
1013 	case USB_ST_SETUP:
1014 send_next:
1015 		/* Get next mbuf, if any */
1016 		UBT_NG_LOCK(sc);
1017 		NG_BT_MBUFQ_DEQUEUE(&sc->sc_aclq, m);
1018 		UBT_NG_UNLOCK(sc);
1019 
1020 		if (m == NULL) {
1021 			UBT_INFO(sc, "ACL data queue is empty\n");
1022 			break; /* transfer completed */
1023 		}
1024 
1025 		/*
1026 		 * Copy ACL data frame back to a linear USB transfer buffer
1027 		 * and schedule transfer
1028 		 */
1029 
1030 		pc = usbd_xfer_get_frame(xfer, 0);
1031 		usbd_m_copy_in(pc, 0, m, 0, m->m_pkthdr.len);
1032 		usbd_xfer_set_frame_len(xfer, 0, m->m_pkthdr.len);
1033 
1034 		UBT_INFO(sc, "bulk-out transfer has been started, len=%d\n",
1035 			m->m_pkthdr.len);
1036 
1037 		NG_FREE_M(m);
1038 
1039 		usbd_transfer_submit(xfer);
1040 		break;
1041 
1042 	default: /* Error */
1043 		if (error != USB_ERR_CANCELLED) {
1044 			UBT_WARN(sc, "bulk-out transfer failed: %s\n",
1045 				usbd_errstr(error));
1046 
1047 			UBT_STAT_OERROR(sc);
1048 
1049 			/* try to clear stall first */
1050 			usbd_xfer_set_stall(xfer);
1051 			goto send_next;
1052 		}
1053 			/* transfer cancelled */
1054 		break;
1055 	}
1056 } /* ubt_bulk_write_callback */
1057 
1058 /*
1059  * Called when incoming isoc transfer (SCO packet) has completed, i.e.
1060  * SCO packet was received from the device.
1061  * USB context.
1062  */
1063 
1064 static void
1065 ubt_isoc_read_callback(struct usb_xfer *xfer, usb_error_t error)
1066 {
1067 	struct ubt_softc	*sc = usbd_xfer_softc(xfer);
1068 	int			n;
1069 	int actlen, nframes;
1070 
1071 	usbd_xfer_status(xfer, &actlen, NULL, NULL, &nframes);
1072 
1073 	switch (USB_GET_STATE(xfer)) {
1074 	case USB_ST_TRANSFERRED:
1075 		for (n = 0; n < nframes; n ++)
1076 			if (ubt_isoc_read_one_frame(xfer, n) < 0)
1077 				break;
1078 		/* FALLTHROUGH */
1079 
1080 	case USB_ST_SETUP:
1081 read_next:
1082 		for (n = 0; n < nframes; n ++)
1083 			usbd_xfer_set_frame_len(xfer, n,
1084 			    usbd_xfer_max_framelen(xfer));
1085 
1086 		usbd_transfer_submit(xfer);
1087 		break;
1088 
1089 	default: /* Error */
1090                 if (error != USB_ERR_CANCELLED) {
1091                         UBT_STAT_IERROR(sc);
1092                         goto read_next;
1093                 }
1094 
1095 		/* transfer cancelled */
1096 		break;
1097 	}
1098 } /* ubt_isoc_read_callback */
1099 
1100 /*
1101  * Helper function. Called from ubt_isoc_read_callback() to read
1102  * SCO data from one frame.
1103  * USB context.
1104  */
1105 
1106 static int
1107 ubt_isoc_read_one_frame(struct usb_xfer *xfer, int frame_no)
1108 {
1109 	struct ubt_softc	*sc = usbd_xfer_softc(xfer);
1110 	struct usb_page_cache	*pc;
1111 	struct mbuf		*m;
1112 	int			len, want, got, total;
1113 
1114 	/* Get existing SCO reassembly buffer */
1115 	pc = usbd_xfer_get_frame(xfer, 0);
1116 	m = sc->sc_isoc_in_buffer;
1117 	total = usbd_xfer_frame_len(xfer, frame_no);
1118 
1119 	/* While we have data in the frame */
1120 	while (total > 0) {
1121 		if (m == NULL) {
1122 			/* Start new reassembly buffer */
1123 			MGETHDR(m, M_NOWAIT, MT_DATA);
1124 			if (m == NULL) {
1125 				UBT_STAT_IERROR(sc);
1126 				return (-1);	/* XXX out of sync! */
1127 			}
1128 
1129 			if (!(MCLGET(m, M_NOWAIT))) {
1130 				UBT_STAT_IERROR(sc);
1131 				NG_FREE_M(m);
1132 				return (-1);	/* XXX out of sync! */
1133 			}
1134 
1135 			/* Expect SCO header */
1136 			*mtod(m, uint8_t *) = NG_HCI_SCO_DATA_PKT;
1137 			m->m_pkthdr.len = m->m_len = got = 1;
1138 			want = sizeof(ng_hci_scodata_pkt_t);
1139 		} else {
1140 			/*
1141 			 * Check if we have SCO header and if so
1142 			 * adjust amount of data we want
1143 			 */
1144 			got = m->m_pkthdr.len;
1145 			want = sizeof(ng_hci_scodata_pkt_t);
1146 
1147 			if (got >= want)
1148 				want += mtod(m, ng_hci_scodata_pkt_t *)->length;
1149 		}
1150 
1151 		/* Append frame data to the SCO reassembly buffer */
1152 		len = total;
1153 		if (got + len > want)
1154 			len = want - got;
1155 
1156 		usbd_copy_out(pc, frame_no * usbd_xfer_max_framelen(xfer),
1157 			mtod(m, uint8_t *) + m->m_pkthdr.len, len);
1158 
1159 		m->m_pkthdr.len += len;
1160 		m->m_len += len;
1161 		total -= len;
1162 
1163 		/* Check if we got everything we wanted, if not - continue */
1164 		if (got != want)
1165 			continue;
1166 
1167 		/* If we got here then we got complete SCO frame */
1168 		UBT_INFO(sc, "got complete SCO data frame, pktlen=%d, " \
1169 			"length=%d\n", m->m_pkthdr.len,
1170 			mtod(m, ng_hci_scodata_pkt_t *)->length);
1171 
1172 		UBT_STAT_PCKTS_RECV(sc);
1173 		UBT_STAT_BYTES_RECV(sc, m->m_pkthdr.len);
1174 
1175 		ubt_fwd_mbuf_up(sc, &m);
1176 		/* m == NULL at this point */
1177 	}
1178 
1179 	/* Put SCO reassembly buffer back */
1180 	sc->sc_isoc_in_buffer = m;
1181 
1182 	return (0);
1183 } /* ubt_isoc_read_one_frame */
1184 
1185 /*
1186  * Called when outgoing isoc transfer (SCO packet) has completed, i.e.
1187  * SCO packet was sent to the device.
1188  * USB context.
1189  */
1190 
1191 static void
1192 ubt_isoc_write_callback(struct usb_xfer *xfer, usb_error_t error)
1193 {
1194 	struct ubt_softc	*sc = usbd_xfer_softc(xfer);
1195 	struct usb_page_cache	*pc;
1196 	struct mbuf		*m;
1197 	int			n, space, offset;
1198 	int			actlen, nframes;
1199 
1200 	usbd_xfer_status(xfer, &actlen, NULL, NULL, &nframes);
1201 	pc = usbd_xfer_get_frame(xfer, 0);
1202 
1203 	switch (USB_GET_STATE(xfer)) {
1204 	case USB_ST_TRANSFERRED:
1205 		UBT_INFO(sc, "sent %d bytes to isoc-out pipe\n", actlen);
1206 		UBT_STAT_BYTES_SENT(sc, actlen);
1207 		UBT_STAT_PCKTS_SENT(sc);
1208 		/* FALLTHROUGH */
1209 
1210 	case USB_ST_SETUP:
1211 send_next:
1212 		offset = 0;
1213 		space = usbd_xfer_max_framelen(xfer) * nframes;
1214 		m = NULL;
1215 
1216 		while (space > 0) {
1217 			if (m == NULL) {
1218 				UBT_NG_LOCK(sc);
1219 				NG_BT_MBUFQ_DEQUEUE(&sc->sc_scoq, m);
1220 				UBT_NG_UNLOCK(sc);
1221 
1222 				if (m == NULL)
1223 					break;
1224 			}
1225 
1226 			n = min(space, m->m_pkthdr.len);
1227 			if (n > 0) {
1228 				usbd_m_copy_in(pc, offset, m,0, n);
1229 				m_adj(m, n);
1230 
1231 				offset += n;
1232 				space -= n;
1233 			}
1234 
1235 			if (m->m_pkthdr.len == 0)
1236 				NG_FREE_M(m); /* sets m = NULL */
1237 		}
1238 
1239 		/* Put whatever is left from mbuf back on queue */
1240 		if (m != NULL) {
1241 			UBT_NG_LOCK(sc);
1242 			NG_BT_MBUFQ_PREPEND(&sc->sc_scoq, m);
1243 			UBT_NG_UNLOCK(sc);
1244 		}
1245 
1246 		/*
1247 		 * Calculate sizes for isoc frames.
1248 		 * Note that offset could be 0 at this point (i.e. we have
1249 		 * nothing to send). That is fine, as we have isoc. transfers
1250 		 * going in both directions all the time. In this case it
1251 		 * would be just empty isoc. transfer.
1252 		 */
1253 
1254 		for (n = 0; n < nframes; n ++) {
1255 			usbd_xfer_set_frame_len(xfer, n,
1256 			    min(offset, usbd_xfer_max_framelen(xfer)));
1257 			offset -= usbd_xfer_frame_len(xfer, n);
1258 		}
1259 
1260 		usbd_transfer_submit(xfer);
1261 		break;
1262 
1263 	default: /* Error */
1264 		if (error != USB_ERR_CANCELLED) {
1265 			UBT_STAT_OERROR(sc);
1266 			goto send_next;
1267 		}
1268 
1269 		/* transfer cancelled */
1270 		break;
1271 	}
1272 }
1273 
1274 /*
1275  * Utility function to forward provided mbuf upstream (i.e. up the stack).
1276  * Modifies value of the mbuf pointer (sets it to NULL).
1277  * Save to call from any context.
1278  */
1279 
1280 static int
1281 ubt_fwd_mbuf_up(ubt_softc_p sc, struct mbuf **m)
1282 {
1283 	hook_p	hook;
1284 	int	error;
1285 
1286 	/*
1287 	 * Close the race with Netgraph hook newhook/disconnect methods.
1288 	 * Save the hook pointer atomically. Two cases are possible:
1289 	 *
1290 	 * 1) The hook pointer is NULL. It means disconnect method got
1291 	 *    there first. In this case we are done.
1292 	 *
1293 	 * 2) The hook pointer is not NULL. It means that hook pointer
1294 	 *    could be either in valid or invalid (i.e. in the process
1295 	 *    of disconnect) state. In any case grab an extra reference
1296 	 *    to protect the hook pointer.
1297 	 *
1298 	 * It is ok to pass hook in invalid state to NG_SEND_DATA_ONLY() as
1299 	 * it checks for it. Drop extra reference after NG_SEND_DATA_ONLY().
1300 	 */
1301 
1302 	UBT_NG_LOCK(sc);
1303 	if ((hook = sc->sc_hook) != NULL)
1304 		NG_HOOK_REF(hook);
1305 	UBT_NG_UNLOCK(sc);
1306 
1307 	if (hook == NULL) {
1308 		NG_FREE_M(*m);
1309 		return (ENETDOWN);
1310 	}
1311 
1312 	NG_SEND_DATA_ONLY(error, hook, *m);
1313 	NG_HOOK_UNREF(hook);
1314 
1315 	if (error != 0)
1316 		UBT_STAT_IERROR(sc);
1317 
1318 	return (error);
1319 } /* ubt_fwd_mbuf_up */
1320 
1321 /****************************************************************************
1322  ****************************************************************************
1323  **                                 Glue
1324  ****************************************************************************
1325  ****************************************************************************/
1326 
1327 /*
1328  * Schedule glue task. Should be called with sc_ng_mtx held.
1329  * Netgraph context.
1330  */
1331 
1332 static void
1333 ubt_task_schedule(ubt_softc_p sc, int action)
1334 {
1335 	mtx_assert(&sc->sc_ng_mtx, MA_OWNED);
1336 
1337 	/*
1338 	 * Try to handle corner case when "start all" and "stop all"
1339 	 * actions can both be set before task is executed.
1340 	 *
1341 	 * The rules are
1342 	 *
1343 	 * sc_task_flags	action		new sc_task_flags
1344 	 * ------------------------------------------------------
1345 	 * 0			start		start
1346 	 * 0			stop		stop
1347 	 * start		start		start
1348 	 * start		stop		stop
1349 	 * stop			start		stop|start
1350 	 * stop			stop		stop
1351 	 * stop|start		start		stop|start
1352 	 * stop|start		stop		stop
1353 	 */
1354 
1355 	if (action != 0) {
1356 		if ((action & UBT_FLAG_T_STOP_ALL) != 0)
1357 			sc->sc_task_flags &= ~UBT_FLAG_T_START_ALL;
1358 
1359 		sc->sc_task_flags |= action;
1360 	}
1361 
1362 	if (sc->sc_task_flags & UBT_FLAG_T_PENDING)
1363 		return;
1364 
1365 	if (taskqueue_enqueue(taskqueue_swi, &sc->sc_task) == 0) {
1366 		sc->sc_task_flags |= UBT_FLAG_T_PENDING;
1367 		return;
1368 	}
1369 
1370 	/* XXX: i think this should never happen */
1371 } /* ubt_task_schedule */
1372 
1373 /*
1374  * Glue task. Examines sc_task_flags and does things depending on it.
1375  * Taskqueue context.
1376  */
1377 
1378 static void
1379 ubt_task(void *context, int pending)
1380 {
1381 	ubt_softc_p	sc = context;
1382 	int		task_flags, i;
1383 
1384 	UBT_NG_LOCK(sc);
1385 	task_flags = sc->sc_task_flags;
1386 	sc->sc_task_flags = 0;
1387 	UBT_NG_UNLOCK(sc);
1388 
1389 	/*
1390 	 * Stop all USB transfers synchronously.
1391 	 * Stop interface #0 and #1 transfers at the same time and in the
1392 	 * same loop. usbd_transfer_drain() will do appropriate locking.
1393 	 */
1394 
1395 	if (task_flags & UBT_FLAG_T_STOP_ALL)
1396 		for (i = 0; i < UBT_N_TRANSFER; i ++)
1397 			usbd_transfer_drain(sc->sc_xfer[i]);
1398 
1399 	/* Start incoming interrupt and bulk, and all isoc. USB transfers */
1400 	if (task_flags & UBT_FLAG_T_START_ALL) {
1401 		/*
1402 		 * Interface #0
1403 		 */
1404 
1405 		mtx_lock(&sc->sc_if_mtx);
1406 
1407 		ubt_xfer_start(sc, UBT_IF_0_INTR_DT_RD);
1408 		ubt_xfer_start(sc, UBT_IF_0_BULK_DT_RD);
1409 
1410 		/*
1411 		 * Interface #1
1412 		 * Start both read and write isoc. transfers by default.
1413 		 * Get them going all the time even if we have nothing
1414 		 * to send to avoid any delays.
1415 		 */
1416 
1417 		ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_RD1);
1418 		ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_RD2);
1419 		ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_WR1);
1420 		ubt_xfer_start(sc, UBT_IF_1_ISOC_DT_WR2);
1421 
1422 		mtx_unlock(&sc->sc_if_mtx);
1423 	}
1424 
1425  	/* Start outgoing control transfer */
1426 	if (task_flags & UBT_FLAG_T_START_CTRL) {
1427 		mtx_lock(&sc->sc_if_mtx);
1428 		ubt_xfer_start(sc, UBT_IF_0_CTRL_DT_WR);
1429 		mtx_unlock(&sc->sc_if_mtx);
1430 	}
1431 
1432 	/* Start outgoing bulk transfer */
1433 	if (task_flags & UBT_FLAG_T_START_BULK) {
1434 		mtx_lock(&sc->sc_if_mtx);
1435 		ubt_xfer_start(sc, UBT_IF_0_BULK_DT_WR);
1436 		mtx_unlock(&sc->sc_if_mtx);
1437 	}
1438 } /* ubt_task */
1439 
1440 /****************************************************************************
1441  ****************************************************************************
1442  **                        Netgraph specific
1443  ****************************************************************************
1444  ****************************************************************************/
1445 
1446 /*
1447  * Netgraph node constructor. Do not allow to create node of this type.
1448  * Netgraph context.
1449  */
1450 
1451 static int
1452 ng_ubt_constructor(node_p node)
1453 {
1454 	return (EINVAL);
1455 } /* ng_ubt_constructor */
1456 
1457 /*
1458  * Netgraph node destructor. Destroy node only when device has been detached.
1459  * Netgraph context.
1460  */
1461 
1462 static int
1463 ng_ubt_shutdown(node_p node)
1464 {
1465 	if (node->nd_flags & NGF_REALLY_DIE) {
1466 		/*
1467                  * We came here because the USB device is being
1468 		 * detached, so stop being persistent.
1469                  */
1470 		NG_NODE_SET_PRIVATE(node, NULL);
1471 		NG_NODE_UNREF(node);
1472 	} else
1473 		NG_NODE_REVIVE(node); /* tell ng_rmnode we are persisant */
1474 
1475 	return (0);
1476 } /* ng_ubt_shutdown */
1477 
1478 /*
1479  * Create new hook. There can only be one.
1480  * Netgraph context.
1481  */
1482 
1483 static int
1484 ng_ubt_newhook(node_p node, hook_p hook, char const *name)
1485 {
1486 	struct ubt_softc	*sc = NG_NODE_PRIVATE(node);
1487 
1488 	if (strcmp(name, NG_UBT_HOOK) != 0)
1489 		return (EINVAL);
1490 
1491 	UBT_NG_LOCK(sc);
1492 	if (sc->sc_hook != NULL) {
1493 		UBT_NG_UNLOCK(sc);
1494 
1495 		return (EISCONN);
1496 	}
1497 
1498 	sc->sc_hook = hook;
1499 	UBT_NG_UNLOCK(sc);
1500 
1501 	return (0);
1502 } /* ng_ubt_newhook */
1503 
1504 /*
1505  * Connect hook. Start incoming USB transfers.
1506  * Netgraph context.
1507  */
1508 
1509 static int
1510 ng_ubt_connect(hook_p hook)
1511 {
1512 	struct ubt_softc	*sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
1513 
1514 	NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
1515 
1516 	UBT_NG_LOCK(sc);
1517 	ubt_task_schedule(sc, UBT_FLAG_T_START_ALL);
1518 	UBT_NG_UNLOCK(sc);
1519 
1520 	return (0);
1521 } /* ng_ubt_connect */
1522 
1523 /*
1524  * Disconnect hook.
1525  * Netgraph context.
1526  */
1527 
1528 static int
1529 ng_ubt_disconnect(hook_p hook)
1530 {
1531 	struct ubt_softc	*sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
1532 
1533 	UBT_NG_LOCK(sc);
1534 
1535 	if (hook != sc->sc_hook) {
1536 		UBT_NG_UNLOCK(sc);
1537 
1538 		return (EINVAL);
1539 	}
1540 
1541 	sc->sc_hook = NULL;
1542 
1543 	/* Kick off task to stop all USB xfers */
1544 	ubt_task_schedule(sc, UBT_FLAG_T_STOP_ALL);
1545 
1546 	/* Drain queues */
1547 	NG_BT_MBUFQ_DRAIN(&sc->sc_cmdq);
1548 	NG_BT_MBUFQ_DRAIN(&sc->sc_aclq);
1549 	NG_BT_MBUFQ_DRAIN(&sc->sc_scoq);
1550 
1551 	UBT_NG_UNLOCK(sc);
1552 
1553 	return (0);
1554 } /* ng_ubt_disconnect */
1555 
1556 /*
1557  * Process control message.
1558  * Netgraph context.
1559  */
1560 
1561 static int
1562 ng_ubt_rcvmsg(node_p node, item_p item, hook_p lasthook)
1563 {
1564 	struct ubt_softc	*sc = NG_NODE_PRIVATE(node);
1565 	struct ng_mesg		*msg, *rsp = NULL;
1566 	struct ng_bt_mbufq	*q;
1567 	int			error = 0, queue, qlen;
1568 
1569 	NGI_GET_MSG(item, msg);
1570 
1571 	switch (msg->header.typecookie) {
1572 	case NGM_GENERIC_COOKIE:
1573 		switch (msg->header.cmd) {
1574 		case NGM_TEXT_STATUS:
1575 			NG_MKRESPONSE(rsp, msg, NG_TEXTRESPONSE, M_NOWAIT);
1576 			if (rsp == NULL) {
1577 				error = ENOMEM;
1578 				break;
1579 			}
1580 
1581 			snprintf(rsp->data, NG_TEXTRESPONSE,
1582 				"Hook: %s\n" \
1583 				"Task flags: %#x\n" \
1584 				"Debug: %d\n" \
1585 				"CMD queue: [have:%d,max:%d]\n" \
1586 				"ACL queue: [have:%d,max:%d]\n" \
1587 				"SCO queue: [have:%d,max:%d]",
1588 				(sc->sc_hook != NULL) ? NG_UBT_HOOK : "",
1589 				sc->sc_task_flags,
1590 				sc->sc_debug,
1591 				sc->sc_cmdq.len,
1592 				sc->sc_cmdq.maxlen,
1593 				sc->sc_aclq.len,
1594 				sc->sc_aclq.maxlen,
1595 				sc->sc_scoq.len,
1596 				sc->sc_scoq.maxlen);
1597 			break;
1598 
1599 		default:
1600 			error = EINVAL;
1601 			break;
1602 		}
1603 		break;
1604 
1605 	case NGM_UBT_COOKIE:
1606 		switch (msg->header.cmd) {
1607 		case NGM_UBT_NODE_SET_DEBUG:
1608 			if (msg->header.arglen != sizeof(ng_ubt_node_debug_ep)){
1609 				error = EMSGSIZE;
1610 				break;
1611 			}
1612 
1613 			sc->sc_debug = *((ng_ubt_node_debug_ep *) (msg->data));
1614 			break;
1615 
1616 		case NGM_UBT_NODE_GET_DEBUG:
1617 			NG_MKRESPONSE(rsp, msg, sizeof(ng_ubt_node_debug_ep),
1618 			    M_NOWAIT);
1619 			if (rsp == NULL) {
1620 				error = ENOMEM;
1621 				break;
1622 			}
1623 
1624 			*((ng_ubt_node_debug_ep *) (rsp->data)) = sc->sc_debug;
1625 			break;
1626 
1627 		case NGM_UBT_NODE_SET_QLEN:
1628 			if (msg->header.arglen != sizeof(ng_ubt_node_qlen_ep)) {
1629 				error = EMSGSIZE;
1630 				break;
1631 			}
1632 
1633 			queue = ((ng_ubt_node_qlen_ep *) (msg->data))->queue;
1634 			qlen = ((ng_ubt_node_qlen_ep *) (msg->data))->qlen;
1635 
1636 			switch (queue) {
1637 			case NGM_UBT_NODE_QUEUE_CMD:
1638 				q = &sc->sc_cmdq;
1639 				break;
1640 
1641 			case NGM_UBT_NODE_QUEUE_ACL:
1642 				q = &sc->sc_aclq;
1643 				break;
1644 
1645 			case NGM_UBT_NODE_QUEUE_SCO:
1646 				q = &sc->sc_scoq;
1647 				break;
1648 
1649 			default:
1650 				error = EINVAL;
1651 				goto done;
1652 				/* NOT REACHED */
1653 			}
1654 
1655 			q->maxlen = qlen;
1656 			break;
1657 
1658 		case NGM_UBT_NODE_GET_QLEN:
1659 			if (msg->header.arglen != sizeof(ng_ubt_node_qlen_ep)) {
1660 				error = EMSGSIZE;
1661 				break;
1662 			}
1663 
1664 			queue = ((ng_ubt_node_qlen_ep *) (msg->data))->queue;
1665 
1666 			switch (queue) {
1667 			case NGM_UBT_NODE_QUEUE_CMD:
1668 				q = &sc->sc_cmdq;
1669 				break;
1670 
1671 			case NGM_UBT_NODE_QUEUE_ACL:
1672 				q = &sc->sc_aclq;
1673 				break;
1674 
1675 			case NGM_UBT_NODE_QUEUE_SCO:
1676 				q = &sc->sc_scoq;
1677 				break;
1678 
1679 			default:
1680 				error = EINVAL;
1681 				goto done;
1682 				/* NOT REACHED */
1683 			}
1684 
1685 			NG_MKRESPONSE(rsp, msg, sizeof(ng_ubt_node_qlen_ep),
1686 				M_NOWAIT);
1687 			if (rsp == NULL) {
1688 				error = ENOMEM;
1689 				break;
1690 			}
1691 
1692 			((ng_ubt_node_qlen_ep *) (rsp->data))->queue = queue;
1693 			((ng_ubt_node_qlen_ep *) (rsp->data))->qlen = q->maxlen;
1694 			break;
1695 
1696 		case NGM_UBT_NODE_GET_STAT:
1697 			NG_MKRESPONSE(rsp, msg, sizeof(ng_ubt_node_stat_ep),
1698 			    M_NOWAIT);
1699 			if (rsp == NULL) {
1700 				error = ENOMEM;
1701 				break;
1702 			}
1703 
1704 			bcopy(&sc->sc_stat, rsp->data,
1705 				sizeof(ng_ubt_node_stat_ep));
1706 			break;
1707 
1708 		case NGM_UBT_NODE_RESET_STAT:
1709 			UBT_STAT_RESET(sc);
1710 			break;
1711 
1712 		default:
1713 			error = EINVAL;
1714 			break;
1715 		}
1716 		break;
1717 
1718 	default:
1719 		error = EINVAL;
1720 		break;
1721 	}
1722 done:
1723 	NG_RESPOND_MSG(error, node, item, rsp);
1724 	NG_FREE_MSG(msg);
1725 
1726 	return (error);
1727 } /* ng_ubt_rcvmsg */
1728 
1729 /*
1730  * Process data.
1731  * Netgraph context.
1732  */
1733 
1734 static int
1735 ng_ubt_rcvdata(hook_p hook, item_p item)
1736 {
1737 	struct ubt_softc	*sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
1738 	struct mbuf		*m;
1739 	struct ng_bt_mbufq	*q;
1740 	int			action, error = 0;
1741 
1742 	if (hook != sc->sc_hook) {
1743 		error = EINVAL;
1744 		goto done;
1745 	}
1746 
1747 	/* Deatch mbuf and get HCI frame type */
1748 	NGI_GET_M(item, m);
1749 
1750 	/*
1751 	 * Minimal size of the HCI frame is 4 bytes: 1 byte frame type,
1752 	 * 2 bytes connection handle and at least 1 byte of length.
1753 	 * Panic on data frame that has size smaller than 4 bytes (it
1754 	 * should not happen)
1755 	 */
1756 
1757 	if (m->m_pkthdr.len < 4)
1758 		panic("HCI frame size is too small! pktlen=%d\n",
1759 			m->m_pkthdr.len);
1760 
1761 	/* Process HCI frame */
1762 	switch (*mtod(m, uint8_t *)) {	/* XXX call m_pullup ? */
1763 	case NG_HCI_CMD_PKT:
1764 		if (m->m_pkthdr.len - 1 > (int)UBT_CTRL_BUFFER_SIZE)
1765 			panic("HCI command frame size is too big! " \
1766 				"buffer size=%zd, packet len=%d\n",
1767 				UBT_CTRL_BUFFER_SIZE, m->m_pkthdr.len);
1768 
1769 		q = &sc->sc_cmdq;
1770 		action = UBT_FLAG_T_START_CTRL;
1771 		break;
1772 
1773 	case NG_HCI_ACL_DATA_PKT:
1774 		if (m->m_pkthdr.len - 1 > UBT_BULK_WRITE_BUFFER_SIZE)
1775 			panic("ACL data frame size is too big! " \
1776 				"buffer size=%d, packet len=%d\n",
1777 				UBT_BULK_WRITE_BUFFER_SIZE, m->m_pkthdr.len);
1778 
1779 		q = &sc->sc_aclq;
1780 		action = UBT_FLAG_T_START_BULK;
1781 		break;
1782 
1783 	case NG_HCI_SCO_DATA_PKT:
1784 		q = &sc->sc_scoq;
1785 		action = 0;
1786 		break;
1787 
1788 	default:
1789 		UBT_ERR(sc, "Dropping unsupported HCI frame, type=0x%02x, " \
1790 			"pktlen=%d\n", *mtod(m, uint8_t *), m->m_pkthdr.len);
1791 
1792 		NG_FREE_M(m);
1793 		error = EINVAL;
1794 		goto done;
1795 		/* NOT REACHED */
1796 	}
1797 
1798 	UBT_NG_LOCK(sc);
1799 	if (NG_BT_MBUFQ_FULL(q)) {
1800 		NG_BT_MBUFQ_DROP(q);
1801 		UBT_NG_UNLOCK(sc);
1802 
1803 		UBT_ERR(sc, "Dropping HCI frame 0x%02x, len=%d. Queue full\n",
1804 			*mtod(m, uint8_t *), m->m_pkthdr.len);
1805 
1806 		NG_FREE_M(m);
1807 	} else {
1808 		/* Loose HCI packet type, enqueue mbuf and kick off task */
1809 		m_adj(m, sizeof(uint8_t));
1810 		NG_BT_MBUFQ_ENQUEUE(q, m);
1811 		ubt_task_schedule(sc, action);
1812 		UBT_NG_UNLOCK(sc);
1813 	}
1814 done:
1815 	NG_FREE_ITEM(item);
1816 
1817 	return (error);
1818 } /* ng_ubt_rcvdata */
1819 
1820 /****************************************************************************
1821  ****************************************************************************
1822  **                              Module
1823  ****************************************************************************
1824  ****************************************************************************/
1825 
1826 /*
1827  * Load/Unload the driver module
1828  */
1829 
1830 static int
1831 ubt_modevent(module_t mod, int event, void *data)
1832 {
1833 	int	error;
1834 
1835 	switch (event) {
1836 	case MOD_LOAD:
1837 		error = ng_newtype(&typestruct);
1838 		if (error != 0)
1839 			printf("%s: Could not register Netgraph node type, " \
1840 				"error=%d\n", NG_UBT_NODE_TYPE, error);
1841 		break;
1842 
1843 	case MOD_UNLOAD:
1844 		error = ng_rmtype(&typestruct);
1845 		break;
1846 
1847 	default:
1848 		error = EOPNOTSUPP;
1849 		break;
1850 	}
1851 
1852 	return (error);
1853 } /* ubt_modevent */
1854 
1855 static devclass_t	ubt_devclass;
1856 
1857 static device_method_t	ubt_methods[] =
1858 {
1859 	DEVMETHOD(device_probe,	ubt_probe),
1860 	DEVMETHOD(device_attach, ubt_attach),
1861 	DEVMETHOD(device_detach, ubt_detach),
1862 	DEVMETHOD_END
1863 };
1864 
1865 static driver_t		ubt_driver =
1866 {
1867 	.name =	   "ubt",
1868 	.methods = ubt_methods,
1869 	.size =	   sizeof(struct ubt_softc),
1870 };
1871 
1872 DRIVER_MODULE(ng_ubt, uhub, ubt_driver, ubt_devclass, ubt_modevent, 0);
1873 MODULE_VERSION(ng_ubt, NG_BLUETOOTH_VERSION);
1874 MODULE_DEPEND(ng_ubt, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
1875 MODULE_DEPEND(ng_ubt, ng_hci, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
1876 MODULE_DEPEND(ng_ubt, usb, 1, 1, 1);
1877 USB_PNP_HOST_INFO(ubt_devs);
1878