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