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