xref: /freebsd/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c (revision 7660b554bc59a07be0431c17e0e33815818baa69)
1 /*
2  * ng_ubt.c
3  *
4  * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $Id: ng_ubt.c,v 1.14 2003/04/14 23:00:50 max Exp $
29  * $FreeBSD$
30  */
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/conf.h>
36 #include <sys/endian.h>
37 #include <sys/filio.h>
38 #include <sys/fcntl.h>
39 #include <sys/mbuf.h>
40 #include <sys/malloc.h>
41 #include <sys/kernel.h>
42 #include <sys/poll.h>
43 #include <sys/vnode.h>
44 #include <machine/bus.h>
45 
46 #include <dev/usb/usb.h>
47 #include <dev/usb/usbdi.h>
48 #include <dev/usb/usbdi_util.h>
49 #include <dev/usb/usbdivar.h>
50 #include <dev/usb/usbdevs.h>
51 
52 #include <netgraph/ng_message.h>
53 #include <netgraph/netgraph.h>
54 #include <netgraph/ng_parse.h>
55 #include <ng_bluetooth.h>
56 #include <ng_hci.h>
57 #include "ng_ubt.h"
58 #include "ng_ubt_var.h"
59 
60 /*
61  * USB methods
62  */
63 
64 USB_DECLARE_DRIVER(ubt);
65 
66 Static int         ubt_modevent		  (module_t, int, void *);
67 
68 Static usbd_status ubt_request_start      (ubt_softc_p);
69 Static void        ubt_request_complete   (usbd_xfer_handle,
70 					   usbd_private_handle, usbd_status);
71 Static void        ubt_request_complete2  (node_p, hook_p, void *, int);
72 
73 Static usbd_status ubt_intr_start	  (ubt_softc_p);
74 Static void        ubt_intr_complete      (usbd_xfer_handle,
75 					   usbd_private_handle, usbd_status);
76 Static void        ubt_intr_complete2     (node_p, hook_p, void *, int);
77 
78 Static usbd_status ubt_bulk_in_start	  (ubt_softc_p);
79 Static void        ubt_bulk_in_complete   (usbd_xfer_handle,
80 					   usbd_private_handle, usbd_status);
81 Static void        ubt_bulk_in_complete2  (node_p, hook_p, void *, int);
82 
83 Static usbd_status ubt_bulk_out_start     (ubt_softc_p);
84 Static void        ubt_bulk_out_complete  (usbd_xfer_handle,
85 					   usbd_private_handle, usbd_status);
86 Static void        ubt_bulk_out_complete2 (node_p, hook_p, void *, int);
87 
88 Static usbd_status ubt_isoc_in_start      (ubt_softc_p);
89 Static void        ubt_isoc_in_complete   (usbd_xfer_handle,
90 					   usbd_private_handle, usbd_status);
91 Static void        ubt_isoc_in_complete2  (node_p, hook_p, void *, int);
92 
93 Static usbd_status ubt_isoc_out_start     (ubt_softc_p);
94 Static void        ubt_isoc_out_complete  (usbd_xfer_handle,
95 					   usbd_private_handle, usbd_status);
96 Static void        ubt_isoc_out_complete2 (node_p, hook_p, void *, int);
97 
98 Static void        ubt_reset              (ubt_softc_p);
99 
100 /*
101  * Netgraph methods
102  */
103 
104 Static ng_constructor_t	ng_ubt_constructor;
105 Static ng_shutdown_t	ng_ubt_shutdown;
106 Static ng_newhook_t	ng_ubt_newhook;
107 Static ng_connect_t	ng_ubt_connect;
108 Static ng_disconnect_t	ng_ubt_disconnect;
109 Static ng_rcvmsg_t	ng_ubt_rcvmsg;
110 Static ng_rcvdata_t	ng_ubt_rcvdata;
111 
112 /* Queue length */
113 Static const struct ng_parse_struct_field	ng_ubt_node_qlen_type_fields[] =
114 {
115 	{ "queue", &ng_parse_int32_type, },
116 	{ "qlen",  &ng_parse_int32_type, },
117 	{ NULL, }
118 };
119 Static const struct ng_parse_type		ng_ubt_node_qlen_type = {
120 	&ng_parse_struct_type,
121 	&ng_ubt_node_qlen_type_fields
122 };
123 
124 /* Stat info */
125 Static const struct ng_parse_struct_field	ng_ubt_node_stat_type_fields[] =
126 {
127 	{ "pckts_recv", &ng_parse_uint32_type, },
128 	{ "bytes_recv", &ng_parse_uint32_type, },
129 	{ "pckts_sent", &ng_parse_uint32_type, },
130 	{ "bytes_sent", &ng_parse_uint32_type, },
131 	{ "oerrors",    &ng_parse_uint32_type, },
132 	{ "ierrors",    &ng_parse_uint32_type, },
133 	{ NULL, }
134 };
135 Static const struct ng_parse_type	ng_ubt_node_stat_type = {
136 	&ng_parse_struct_type,
137 	&ng_ubt_node_stat_type_fields
138 };
139 
140 /* Netgraph node command list */
141 Static const struct ng_cmdlist	ng_ubt_cmdlist[] = {
142 {
143 	NGM_UBT_COOKIE,
144 	NGM_UBT_NODE_SET_DEBUG,
145 	"set_debug",
146 	&ng_parse_uint16_type,
147 	NULL
148 },
149 {
150 	NGM_UBT_COOKIE,
151 	NGM_UBT_NODE_GET_DEBUG,
152 	"get_debug",
153 	NULL,
154 	&ng_parse_uint16_type
155 },
156 {
157 	NGM_UBT_COOKIE,
158 	NGM_UBT_NODE_SET_QLEN,
159 	"set_qlen",
160 	&ng_ubt_node_qlen_type,
161 	NULL
162 },
163 {
164 	NGM_UBT_COOKIE,
165 	NGM_UBT_NODE_GET_QLEN,
166 	"get_qlen",
167 	&ng_ubt_node_qlen_type,
168 	&ng_ubt_node_qlen_type
169 },
170 {
171 	NGM_UBT_COOKIE,
172 	NGM_UBT_NODE_GET_STAT,
173 	"get_stat",
174 	NULL,
175 	&ng_ubt_node_stat_type
176 },
177 {
178 	NGM_UBT_COOKIE,
179 	NGM_UBT_NODE_RESET_STAT,
180 	"reset_stat",
181         NULL,
182 	NULL
183 },
184 {
185 	NGM_UBT_COOKIE,
186 	NGM_UBT_NODE_DEV_NODES,
187 	"dev_nodes",
188         &ng_parse_uint16_type,
189 	NULL
190 },
191 { 0, }
192 };
193 
194 /* Netgraph node type */
195 Static struct ng_type	typestruct = {
196 	NG_ABI_VERSION,
197 	NG_UBT_NODE_TYPE,	/* typename */
198 	NULL,			/* modevent */
199 	ng_ubt_constructor,	/* constructor */
200 	ng_ubt_rcvmsg,		/* control message */
201 	ng_ubt_shutdown,	/* destructor */
202 	ng_ubt_newhook,		/* new hook */
203 	NULL,			/* find hook */
204 	ng_ubt_connect,		/* connect hook */
205 	ng_ubt_rcvdata,		/* data */
206 	ng_ubt_disconnect,	/* disconnect hook */
207 	ng_ubt_cmdlist,		/* node command list */
208 };
209 
210 /*
211  * Device methods
212  */
213 
214 #define UBT_UNIT(n)	((minor(n) >> 4) & 0xf)
215 #define UBT_ENDPOINT(n)	(minor(n) & 0xf)
216 #define UBT_MINOR(u, e)	(((u) << 4) | (e))
217 #define UBT_BSIZE	1024
218 
219 Static d_open_t		ubt_open;
220 Static d_close_t	ubt_close;
221 Static d_read_t		ubt_read;
222 Static d_write_t	ubt_write;
223 Static d_ioctl_t	ubt_ioctl;
224 Static d_poll_t		ubt_poll;
225 Static void		ubt_create_device_nodes  (ubt_softc_p);
226 Static void		ubt_destroy_device_nodes (ubt_softc_p);
227 
228 #if __FreeBSD_version < 500104
229 #define CDEV_MAJOR	222
230 #else
231 #define CDEV_MAJOR	MAJOR_AUTO
232 #endif
233 
234 Static struct cdevsw	ubt_cdevsw = {
235 	.d_open =	ubt_open,
236 	.d_close =	ubt_close,
237 	.d_read =	ubt_read,
238 	.d_write =	ubt_write,
239 	.d_ioctl =	ubt_ioctl,
240 	.d_poll =	ubt_poll,
241 	.d_name =	"ubt",
242 	.d_maj =	CDEV_MAJOR,
243 };
244 
245 /*
246  * Module
247  */
248 
249 DRIVER_MODULE(ubt, uhub, ubt_driver, ubt_devclass, ubt_modevent, 0);
250 MODULE_VERSION(ng_ubt, NG_BLUETOOTH_VERSION);
251 MODULE_DEPEND(ng_ubt, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
252 
253 /****************************************************************************
254  ****************************************************************************
255  **                              USB specific
256  ****************************************************************************
257  ****************************************************************************/
258 
259 /*
260  * Load/Unload the driver module
261  */
262 
263 Static int
264 ubt_modevent(module_t mod, int event, void *data)
265 {
266 	int	error;
267 
268 	switch (event) {
269 	case MOD_LOAD:
270 		error = ng_newtype(&typestruct);
271 		if (error != 0)
272 			printf(
273 "%s: Could not register Netgraph node type, error=%d\n",
274 				NG_UBT_NODE_TYPE, error);
275 		else
276 			error = usbd_driver_load(mod, event, data);
277 		break;
278 
279 	case MOD_UNLOAD:
280 		error = ng_rmtype(&typestruct);
281 		if (error == 0)
282 			error = usbd_driver_load(mod, event, data);
283 		break;
284 
285 	default:
286 		error = EOPNOTSUPP;
287 		break;
288 	}
289 
290 	return (error);
291 } /* ubt_modevent */
292 
293 /*
294  * Probe for a USB Bluetooth device
295  */
296 
297 USB_MATCH(ubt)
298 {
299 	/*
300 	 * If for some reason device should not be attached then put
301 	 * VendorID/ProductID pair into the list below. Currently I
302 	 * do not know of any such devices. The format is as follows:
303 	 *
304 	 *	{ VENDOR_ID, PRODUCT_ID },
305 	 *
306 	 * where VENDOR_ID and PRODUCT_ID are hex numbers.
307 	 */
308 
309 	Static struct usb_devno const	ubt_ignored_devices[] = {
310 		{ 0, 0 } /* This should be the last item in the list */
311 	};
312 
313 	/*
314 	 * If device violates Bluetooth specification and has bDeviceClass,
315 	 * bDeviceSubClass and bDeviceProtocol set to wrong values then you
316 	 * could try to put VendorID/ProductID pair into the list below.
317 	 * Currently I do not know of any such devices.
318 	 */
319 
320 	Static struct usb_devno const	ubt_broken_devices[] = {
321 		{ 0, 0 } /* This should be the last item in the list */
322 	};
323 
324 	USB_MATCH_START(ubt, uaa);
325 
326 	usb_device_descriptor_t	*dd = usbd_get_device_descriptor(uaa->device);
327 
328 	if (uaa->iface == NULL ||
329 	    usb_lookup(ubt_ignored_devices, uaa->vendor, uaa->product))
330 		return (UMATCH_NONE);
331 
332 	if (dd->bDeviceClass == UDCLASS_WIRELESS &&
333 	    dd->bDeviceSubClass == UDSUBCLASS_RF &&
334 	    dd->bDeviceProtocol == UDPROTO_BLUETOOTH)
335 		return (UMATCH_DEVCLASS_DEVSUBCLASS);
336 
337 	if (usb_lookup(ubt_broken_devices, uaa->vendor, uaa->product))
338 		return (UMATCH_VENDOR_PRODUCT);
339 
340 	return (UMATCH_NONE);
341 } /* USB_MATCH(ubt) */
342 
343 /*
344  * Attach the device
345  */
346 
347 USB_ATTACH(ubt)
348 {
349 	USB_ATTACH_START(ubt, sc, uaa);
350 	usb_config_descriptor_t		*cd = NULL;
351 	usb_interface_descriptor_t	*id = NULL;
352 	usb_endpoint_descriptor_t	*ed = NULL;
353 	char				 devinfo[UBT_BSIZE];
354 	usbd_status			 error;
355 	int				 i, ai, alt_no, isoc_in, isoc_out,
356 					 isoc_isize, isoc_osize;
357 
358 	/* Get USB device info */
359 	sc->sc_udev = uaa->device;
360 	usbd_devinfo(sc->sc_udev, 0, devinfo);
361 	USB_ATTACH_SETUP;
362 	printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
363 
364 	/*
365 	 * Initialize device softc structure
366 	 */
367 
368 	/* State */
369 	sc->sc_debug = NG_UBT_WARN_LEVEL;
370 	sc->sc_flags = 0;
371 	NG_UBT_STAT_RESET(sc->sc_stat);
372 
373 	/* Interfaces */
374 	sc->sc_iface0 = sc->sc_iface1 = NULL;
375 
376 	/* Interrupt pipe */
377 	sc->sc_intr_ep = -1;
378 	sc->sc_intr_pipe = NULL;
379 	sc->sc_intr_xfer = NULL;
380 	sc->sc_intr_buffer = NULL;
381 
382 	/* Control pipe */
383 	sc->sc_ctrl_xfer = NULL;
384 	sc->sc_ctrl_buffer = NULL;
385 	NG_BT_MBUFQ_INIT(&sc->sc_cmdq, UBT_DEFAULT_QLEN);
386 
387 	/* Bulk-in pipe */
388 	sc->sc_bulk_in_ep = -1;
389 	sc->sc_bulk_in_pipe = NULL;
390 	sc->sc_bulk_in_xfer = NULL;
391 	sc->sc_bulk_in_buffer = NULL;
392 
393 	/* Bulk-out pipe */
394 	sc->sc_bulk_out_ep = -1;
395 	sc->sc_bulk_out_pipe = NULL;
396 	sc->sc_bulk_out_xfer = NULL;
397 	sc->sc_bulk_out_buffer = NULL;
398 	NG_BT_MBUFQ_INIT(&sc->sc_aclq, UBT_DEFAULT_QLEN);
399 
400 	/* Isoc-in pipe */
401 	sc->sc_isoc_in_ep = -1;
402 	sc->sc_isoc_in_pipe = NULL;
403 	sc->sc_isoc_in_xfer = NULL;
404 
405 	/* Isoc-out pipe */
406 	sc->sc_isoc_out_ep = -1;
407 	sc->sc_isoc_out_pipe = NULL;
408 	sc->sc_isoc_out_xfer = NULL;
409 	sc->sc_isoc_size = -1;
410 	NG_BT_MBUFQ_INIT(&sc->sc_scoq, UBT_DEFAULT_QLEN);
411 
412 	/* Netgraph part */
413 	sc->sc_node = NULL;
414 	sc->sc_hook = NULL;
415 
416 	/* Device part */
417 	sc->sc_ctrl_dev = sc->sc_intr_dev = sc->sc_bulk_dev = NODEV;
418 	sc->sc_refcnt = sc->sc_dying = 0;
419 
420 	/*
421 	 * XXX set configuration?
422 	 *
423 	 * Configure Bluetooth USB device. Discover all required USB interfaces
424 	 * and endpoints.
425 	 *
426 	 * USB device must present two interfaces:
427 	 * 1) Interface 0 that has 3 endpoints
428 	 *	1) Interrupt endpoint to receive HCI events
429 	 *	2) Bulk IN endpoint to receive ACL data
430 	 *	3) Bulk OUT endpoint to send ACL data
431 	 *
432 	 * 2) Interface 1 then has 2 endpoints
433 	 *	1) Isochronous IN endpoint to receive SCO data
434  	 *	2) Isochronous OUT endpoint to send SCO data
435 	 *
436 	 * Interface 1 (with isochronous endpoints) has several alternate
437 	 * configurations with different packet size.
438 	 */
439 
440 	/*
441 	 * Interface 0
442 	 */
443 
444 	error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface0);
445 	if (error || sc->sc_iface0 == NULL) {
446 		printf("%s: Could not get interface 0 handle. %s (%d), " \
447 			"handle=%p\n", USBDEVNAME(sc->sc_dev),
448 			usbd_errstr(error), error, sc->sc_iface0);
449 		goto bad;
450 	}
451 
452 	id = usbd_get_interface_descriptor(sc->sc_iface0);
453 	if (id == NULL) {
454 		printf("%s: Could not get interface 0 descriptor\n",
455 			USBDEVNAME(sc->sc_dev));
456 		goto bad;
457 	}
458 
459 	for (i = 0; i < id->bNumEndpoints; i ++) {
460 		ed = usbd_interface2endpoint_descriptor(sc->sc_iface0, i);
461 		if (ed == NULL) {
462 			printf("%s: Could not read endpoint descriptor for " \
463 				"interface 0, i=%d\n", USBDEVNAME(sc->sc_dev),
464 				i);
465 			goto bad;
466 		}
467 
468 		switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
469 		case UE_BULK:
470 			if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
471 				sc->sc_bulk_in_ep = ed->bEndpointAddress;
472 			else
473 				sc->sc_bulk_out_ep = ed->bEndpointAddress;
474 			break;
475 
476 		case UE_INTERRUPT:
477 			sc->sc_intr_ep = ed->bEndpointAddress;
478 			break;
479 		}
480 	}
481 
482 	/* Check if we got everything we wanted on Interface 0 */
483 	if (sc->sc_intr_ep == -1) {
484 		printf("%s: Could not detect interrupt endpoint\n",
485 			USBDEVNAME(sc->sc_dev));
486 		goto bad;
487 	}
488 	if (sc->sc_bulk_in_ep == -1) {
489 		printf("%s: Could not detect bulk-in endpoint\n",
490 			USBDEVNAME(sc->sc_dev));
491 		goto bad;
492 	}
493 	if (sc->sc_bulk_out_ep == -1) {
494 		printf("%s: Could not detect bulk-out endpoint\n",
495 			USBDEVNAME(sc->sc_dev));
496 		goto bad;
497 	}
498 
499 	printf("%s: Interface 0 endpoints: interrupt=%#x, bulk-in=%#x, " \
500 		"bulk-out=%#x\n", USBDEVNAME(sc->sc_dev),
501 		sc->sc_intr_ep, sc->sc_bulk_in_ep, sc->sc_bulk_out_ep);
502 
503 	/*
504 	 * Interface 1
505 	 */
506 
507 	cd = usbd_get_config_descriptor(sc->sc_udev);
508 	if (cd == NULL) {
509 		printf("%s: Could not get device configuration descriptor\n",
510 			USBDEVNAME(sc->sc_dev));
511 		goto bad;
512 	}
513 
514 	error = usbd_device2interface_handle(sc->sc_udev, 1, &sc->sc_iface1);
515 	if (error || sc->sc_iface1 == NULL) {
516 		printf("%s: Could not get interface 1 handle. %s (%d), " \
517 			"handle=%p\n", USBDEVNAME(sc->sc_dev),
518 			usbd_errstr(error), error, sc->sc_iface1);
519 		goto bad;
520 	}
521 
522 	id = usbd_get_interface_descriptor(sc->sc_iface1);
523 	if (id == NULL) {
524 		printf("%s: Could not get interface 1 descriptor\n",
525 			USBDEVNAME(sc->sc_dev));
526 		goto bad;
527 	}
528 
529 	/*
530 	 * Scan all alternate configurations for interface 1
531 	 */
532 
533 	alt_no = -1;
534 
535 	for (ai = 0; ai < usbd_get_no_alts(cd, 1); ai++)  {
536 		error = usbd_set_interface(sc->sc_iface1, ai);
537 		if (error) {
538 			printf("%s: [SCAN] Could not set alternate " \
539 				"configuration %d for interface 1. %s (%d)\n",
540 				USBDEVNAME(sc->sc_dev),  ai, usbd_errstr(error),
541 				error);
542 			goto bad;
543 		}
544 		id = usbd_get_interface_descriptor(sc->sc_iface1);
545 		if (id == NULL) {
546 			printf("%s: Could not get interface 1 descriptor for " \
547 				"alternate configuration %d\n",
548 				USBDEVNAME(sc->sc_dev), ai);
549 			goto bad;
550 		}
551 
552 		isoc_in = isoc_out = -1;
553 		isoc_isize = isoc_osize = 0;
554 
555 		for (i = 0; i < id->bNumEndpoints; i ++) {
556 			ed = usbd_interface2endpoint_descriptor(sc->sc_iface1, i);
557 			if (ed == NULL) {
558 				printf("%s: Could not read endpoint " \
559 					"descriptor for interface 1, " \
560 					"alternate configuration %d, i=%d\n",
561 					USBDEVNAME(sc->sc_dev), ai, i);
562 				goto bad;
563 			}
564 
565 			if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
566 				continue;
567 
568 			if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) {
569 				isoc_in = ed->bEndpointAddress;
570 				isoc_isize = UGETW(ed->wMaxPacketSize);
571 			} else {
572 				isoc_out = ed->bEndpointAddress;
573 				isoc_osize = UGETW(ed->wMaxPacketSize);
574 			}
575 		}
576 
577 		/*
578 		 * Make sure that configuration looks sane and if so
579 		 * update current settings
580 		 */
581 
582 		if (isoc_in != -1 && isoc_out != -1 &&
583 		    isoc_isize > 0  && isoc_osize > 0 &&
584 		    isoc_isize == isoc_osize && isoc_isize > sc->sc_isoc_size) {
585 			sc->sc_isoc_in_ep = isoc_in;
586 			sc->sc_isoc_out_ep = isoc_out;
587 			sc->sc_isoc_size = isoc_isize;
588 			alt_no = ai;
589 		}
590 	}
591 
592 	/* Check if we got everything we wanted on Interface 0 */
593 	if (sc->sc_isoc_in_ep == -1) {
594 		printf("%s: Could not detect isoc-in endpoint\n",
595 			USBDEVNAME(sc->sc_dev));
596 		goto bad;
597 	}
598 	if (sc->sc_isoc_out_ep == -1) {
599 		printf("%s: Could not detect isoc-out endpoint\n",
600 			USBDEVNAME(sc->sc_dev));
601 		goto bad;
602 	}
603 	if (sc->sc_isoc_size <= 0) {
604 		printf("%s: Invalid isoc. packet size=%d\n",
605 			USBDEVNAME(sc->sc_dev), sc->sc_isoc_size);
606 		goto bad;
607 	}
608 
609 	error = usbd_set_interface(sc->sc_iface1, alt_no);
610 	if (error) {
611 		printf("%s: Could not set alternate configuration " \
612 			"%d for interface 1. %s (%d)\n", USBDEVNAME(sc->sc_dev),
613 			alt_no, usbd_errstr(error), error);
614 		goto bad;
615 	}
616 
617 	/* Allocate USB transfer handles and buffers */
618 	sc->sc_ctrl_xfer = usbd_alloc_xfer(sc->sc_udev);
619 	if (sc->sc_ctrl_xfer == NULL) {
620 		printf("%s: Could not allocate control xfer handle\n",
621 			USBDEVNAME(sc->sc_dev));
622 		goto bad;
623 	}
624 	sc->sc_ctrl_buffer = usbd_alloc_buffer(sc->sc_ctrl_xfer,
625 						UBT_CTRL_BUFFER_SIZE);
626 	if (sc->sc_ctrl_buffer == NULL) {
627 		printf("%s: Could not allocate control buffer\n",
628 			USBDEVNAME(sc->sc_dev));
629 		goto bad;
630 	}
631 
632 	sc->sc_intr_xfer = usbd_alloc_xfer(sc->sc_udev);
633 	if (sc->sc_intr_xfer == NULL) {
634 		printf("%s: Could not allocate interrupt xfer handle\n",
635 			USBDEVNAME(sc->sc_dev));
636 		goto bad;
637 	}
638 
639 	sc->sc_bulk_in_xfer = usbd_alloc_xfer(sc->sc_udev);
640 	if (sc->sc_bulk_in_xfer == NULL) {
641 		printf("%s: Could not allocate bulk-in xfer handle\n",
642 			USBDEVNAME(sc->sc_dev));
643 		goto bad;
644 	}
645 
646 	sc->sc_bulk_out_xfer = usbd_alloc_xfer(sc->sc_udev);
647 	if (sc->sc_bulk_out_xfer == NULL) {
648 		printf("%s: Could not allocate bulk-out xfer handle\n",
649 			USBDEVNAME(sc->sc_dev));
650 		goto bad;
651 	}
652 	sc->sc_bulk_out_buffer = usbd_alloc_buffer(sc->sc_bulk_out_xfer,
653 						UBT_BULK_BUFFER_SIZE);
654 	if (sc->sc_bulk_out_buffer == NULL) {
655 		printf("%s: Could not allocate bulk-out buffer\n",
656 			USBDEVNAME(sc->sc_dev));
657 		goto bad;
658 	}
659 
660 	/*
661 	 * Allocate buffers for isoc. transfers
662 	 */
663 
664 	sc->sc_isoc_nframes = (UBT_ISOC_BUFFER_SIZE / sc->sc_isoc_size) + 1;
665 
666 	sc->sc_isoc_in_xfer = usbd_alloc_xfer(sc->sc_udev);
667 	if (sc->sc_isoc_in_xfer == NULL) {
668 		printf("%s: Could not allocate isoc-in xfer handle\n",
669 			USBDEVNAME(sc->sc_dev));
670 		goto bad;
671 	}
672 	sc->sc_isoc_in_buffer = usbd_alloc_buffer(sc->sc_isoc_in_xfer,
673 					sc->sc_isoc_nframes * sc->sc_isoc_size);
674 	if (sc->sc_isoc_in_buffer == NULL) {
675 		printf("%s: Could not allocate isoc-in buffer\n",
676 			USBDEVNAME(sc->sc_dev));
677 		goto bad;
678 	}
679 	sc->sc_isoc_in_frlen = malloc(sizeof(u_int16_t) * sc->sc_isoc_nframes,
680 						M_USBDEV, M_NOWAIT);
681 	if (sc->sc_isoc_in_frlen == NULL) {
682 		printf("%s: Could not allocate isoc-in frame sizes buffer\n",
683 			USBDEVNAME(sc->sc_dev));
684 		goto bad;
685 	}
686 
687 	sc->sc_isoc_out_xfer = usbd_alloc_xfer(sc->sc_udev);
688 	if (sc->sc_isoc_out_xfer == NULL) {
689 		printf("%s: Could not allocate isoc-out xfer handle\n",
690 			USBDEVNAME(sc->sc_dev));
691 		goto bad;
692 	}
693 	sc->sc_isoc_out_buffer = usbd_alloc_buffer(sc->sc_isoc_out_xfer,
694 					sc->sc_isoc_nframes * sc->sc_isoc_size);
695 	if (sc->sc_isoc_out_buffer == NULL) {
696 		printf("%s: Could not allocate isoc-out buffer\n",
697 			USBDEVNAME(sc->sc_dev));
698 		goto bad;
699 	}
700 	sc->sc_isoc_out_frlen = malloc(sizeof(u_int16_t) * sc->sc_isoc_nframes,
701 						M_USBDEV, M_NOWAIT);
702 	if (sc->sc_isoc_out_frlen == NULL) {
703 		printf("%s: Could not allocate isoc-out frame sizes buffer\n",
704 			USBDEVNAME(sc->sc_dev));
705 		goto bad;
706 	}
707 
708 	printf("%s: Interface 1 (alt.config %d) endpoints: isoc-in=%#x, " \
709 		"isoc-out=%#x; wMaxPacketSize=%d; nframes=%d, buffer size=%d\n",
710 		USBDEVNAME(sc->sc_dev), alt_no, sc->sc_isoc_in_ep,
711 		sc->sc_isoc_out_ep, sc->sc_isoc_size, sc->sc_isoc_nframes,
712 		(sc->sc_isoc_nframes * sc->sc_isoc_size));
713 
714 	/*
715 	 * Open pipes
716 	 */
717 
718 	/* Interrupt */
719 	error = usbd_open_pipe(sc->sc_iface0, sc->sc_intr_ep,
720 			USBD_EXCLUSIVE_USE, &sc->sc_intr_pipe);
721 	if (error != USBD_NORMAL_COMPLETION) {
722 		printf("%s: %s - Could not open interrupt pipe. %s (%d)\n",
723 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(error),
724 			error);
725 		goto bad;
726 	}
727 
728 	/* Bulk-in */
729 	error = usbd_open_pipe(sc->sc_iface0, sc->sc_bulk_in_ep,
730 			USBD_EXCLUSIVE_USE, &sc->sc_bulk_in_pipe);
731 	if (error != USBD_NORMAL_COMPLETION) {
732 		printf("%s: %s - Could not open bulk-in pipe. %s (%d)\n",
733 			__func__,  USBDEVNAME(sc->sc_dev), usbd_errstr(error),
734 			error);
735 		goto bad;
736 	}
737 
738 	/* Bulk-out */
739 	error = usbd_open_pipe(sc->sc_iface0, sc->sc_bulk_out_ep,
740 			USBD_EXCLUSIVE_USE, &sc->sc_bulk_out_pipe);
741 	if (error != USBD_NORMAL_COMPLETION) {
742 		printf("%s: %s - Could not open bulk-out pipe. %s (%d)\n",
743 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(error),
744 			error);
745 		goto bad;
746 	}
747 
748 #if __broken__ /* XXX FIXME */
749 	/* Isoc-in */
750 	error = usbd_open_pipe(sc->sc_iface1, sc->sc_isoc_in_ep,
751 			USBD_EXCLUSIVE_USE, &sc->sc_isoc_in_pipe);
752 	if (error != USBD_NORMAL_COMPLETION) {
753 		printf("%s: %s - Could not open isoc-in pipe. %s (%d)\n",
754 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(error),
755 			error);
756 		goto bad;
757 	}
758 
759 	/* Isoc-out */
760 	error = usbd_open_pipe(sc->sc_iface1, sc->sc_isoc_out_ep,
761 			USBD_EXCLUSIVE_USE, &sc->sc_isoc_out_pipe);
762 	if (error != USBD_NORMAL_COMPLETION) {
763 		printf("%s: %s - Could not open isoc-out pipe. %s (%d)\n",
764 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(error),
765 			error);
766 		goto bad;
767 	}
768 #endif /* __broken__ */
769 
770 	/* Create Netgraph node */
771 	if (ng_make_node_common(&typestruct, &sc->sc_node) != 0) {
772 		printf("%s: Could not create Netgraph node\n",
773 			USBDEVNAME(sc->sc_dev));
774 		sc->sc_node = NULL;
775 		goto bad;
776 	}
777 
778 	/* Name node */
779 	if (ng_name_node(sc->sc_node, USBDEVNAME(sc->sc_dev)) != 0) {
780 		printf("%s: Could not name Netgraph node\n",
781 			USBDEVNAME(sc->sc_dev));
782 		NG_NODE_UNREF(sc->sc_node);
783 		sc->sc_node = NULL;
784 		goto bad;
785 	}
786 
787 	NG_NODE_SET_PRIVATE(sc->sc_node, sc);
788 	NG_NODE_FORCE_WRITER(sc->sc_node);
789 
790 	/* Claim all interfaces on the device */
791 	for (i = 0; i < uaa->nifaces; i++)
792 		uaa->ifaces[i] = NULL;
793 
794 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
795 		USBDEV(sc->sc_dev));
796 
797 	USB_ATTACH_SUCCESS_RETURN;
798 bad:
799 	ubt_detach(self);
800 
801 	USB_ATTACH_ERROR_RETURN;
802 } /* USB_ATTACH(ubt) */
803 
804 /*
805  * Detach the device
806  */
807 
808 USB_DETACH(ubt)
809 {
810 	USB_DETACH_START(ubt, sc);
811 
812 	sc->sc_dying = 1;
813 
814 	ubt_destroy_device_nodes(sc); /* XXX FIXME locking? */
815 
816 	/* Destroy Netgraph node */
817 	if (sc->sc_node != NULL) {
818 		NG_NODE_SET_PRIVATE(sc->sc_node, NULL);
819 		ng_rmnode_self(sc->sc_node);
820 		sc->sc_node = NULL;
821 	}
822 
823 	/* Close pipes */
824 	if (sc->sc_intr_pipe != NULL) {
825 		usbd_close_pipe(sc->sc_intr_pipe);
826 		sc->sc_intr_pipe = NULL;
827 	}
828 
829 	if (sc->sc_bulk_in_pipe != NULL) {
830 		usbd_close_pipe(sc->sc_bulk_in_pipe);
831 		sc->sc_bulk_in_pipe = NULL;
832 	}
833 	if (sc->sc_bulk_out_pipe != NULL) {
834 		usbd_close_pipe(sc->sc_bulk_out_pipe);
835 		sc->sc_bulk_out_pipe = NULL;
836 	}
837 
838 	if (sc->sc_isoc_in_pipe != NULL) {
839 		usbd_close_pipe(sc->sc_isoc_in_pipe);
840 		sc->sc_isoc_in_pipe = NULL;
841 	}
842 	if (sc->sc_isoc_out_pipe != NULL) {
843 		usbd_close_pipe(sc->sc_isoc_out_pipe);
844 		sc->sc_isoc_out_pipe = NULL;
845 	}
846 
847 	/* Destroy USB transfer handles */
848 	if (sc->sc_ctrl_xfer != NULL) {
849 		usbd_free_xfer(sc->sc_ctrl_xfer);
850 		sc->sc_ctrl_xfer = NULL;
851 	}
852 
853 	if (sc->sc_intr_xfer != NULL) {
854 		usbd_free_xfer(sc->sc_intr_xfer);
855 		sc->sc_intr_xfer = NULL;
856 	}
857 
858 	if (sc->sc_bulk_in_xfer != NULL) {
859 		usbd_free_xfer(sc->sc_bulk_in_xfer);
860 		sc->sc_bulk_in_xfer = NULL;
861 	}
862 	if (sc->sc_bulk_out_xfer != NULL) {
863 		usbd_free_xfer(sc->sc_bulk_out_xfer);
864 		sc->sc_bulk_out_xfer = NULL;
865 	}
866 
867 	if (sc->sc_isoc_in_xfer != NULL) {
868 		usbd_free_xfer(sc->sc_isoc_in_xfer);
869 		sc->sc_isoc_in_xfer = NULL;
870 	}
871 	if (sc->sc_isoc_out_xfer != NULL) {
872 		usbd_free_xfer(sc->sc_isoc_out_xfer);
873 		sc->sc_isoc_out_xfer = NULL;
874 	}
875 
876 	/* Destroy isoc. frame size buffers */
877 	if (sc->sc_isoc_in_frlen != NULL) {
878 		free(sc->sc_isoc_in_frlen, M_USBDEV);
879 		sc->sc_isoc_in_frlen = NULL;
880 	}
881 	if (sc->sc_isoc_out_frlen != NULL) {
882 		free(sc->sc_isoc_out_frlen, M_USBDEV);
883 		sc->sc_isoc_out_frlen = NULL;
884 	}
885 
886 	/* Destroy queues */
887 	NG_BT_MBUFQ_DRAIN(&sc->sc_cmdq);
888 	NG_BT_MBUFQ_DRAIN(&sc->sc_aclq);
889 	NG_BT_MBUFQ_DRAIN(&sc->sc_scoq);
890 
891 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
892 			USBDEV(sc->sc_dev));
893 
894 	return (0);
895 } /* USB_DETACH(ubt) */
896 
897 /*
898  * Start USB control request (HCI command). Must be called with node locked
899  */
900 
901 Static usbd_status
902 ubt_request_start(ubt_softc_p sc)
903 {
904 	usb_device_request_t	 req;
905 	struct mbuf		*m = NULL;
906 	usbd_status		 status;
907 
908 	KASSERT(!(sc->sc_flags & UBT_CMD_XMIT), (
909 "%s: %s - Another control request is pending\n",
910 		__func__, USBDEVNAME(sc->sc_dev)));
911 
912 	NG_BT_MBUFQ_DEQUEUE(&sc->sc_cmdq, m);
913 	if (m == NULL) {
914 		NG_UBT_INFO(
915 "%s: %s - HCI command queue is empty\n", __func__, USBDEVNAME(sc->sc_dev));
916 
917 		return (USBD_NORMAL_COMPLETION);
918 	}
919 
920 	/*
921 	 * Check HCI command frame size and copy it back to
922 	 * linear USB transfer buffer.
923 	 */
924 
925 	if (m->m_pkthdr.len > UBT_CTRL_BUFFER_SIZE)
926 		panic(
927 "%s: %s - HCI command frame too big, size=%d, len=%d\n",
928 			__func__, USBDEVNAME(sc->sc_dev), UBT_CTRL_BUFFER_SIZE,
929 			m->m_pkthdr.len);
930 
931 	m_copydata(m, 0, m->m_pkthdr.len, sc->sc_ctrl_buffer);
932 
933 	/* Initialize a USB control request and then schedule it */
934 	bzero(&req, sizeof(req));
935 	req.bmRequestType = UBT_HCI_REQUEST;
936 	USETW(req.wLength, m->m_pkthdr.len);
937 
938 	NG_UBT_INFO(
939 "%s: %s - Sending control request, bmRequestType=%#x, wLength=%d\n",
940 		__func__, USBDEVNAME(sc->sc_dev), req.bmRequestType,
941 		UGETW(req.wLength));
942 
943 	usbd_setup_default_xfer(
944 		sc->sc_ctrl_xfer,
945 		sc->sc_udev,
946 		(usbd_private_handle) sc->sc_node,
947 		USBD_DEFAULT_TIMEOUT, /* XXX */
948 		&req,
949 		sc->sc_ctrl_buffer,
950 		m->m_pkthdr.len,
951 		USBD_NO_COPY,
952 		ubt_request_complete);
953 
954 	NG_NODE_REF(sc->sc_node);
955 
956 	status = usbd_transfer(sc->sc_ctrl_xfer);
957 	if (status != USBD_NORMAL_COMPLETION && status != USBD_IN_PROGRESS) {
958 		NG_UBT_ERR(
959 "%s: %s - Could not start control request. %s (%d)\n",
960 			__func__, USBDEVNAME(sc->sc_dev),
961 			usbd_errstr(status), status);
962 
963 		NG_NODE_UNREF(sc->sc_node);
964 
965 		NG_BT_MBUFQ_DROP(&sc->sc_cmdq);
966 		NG_UBT_STAT_OERROR(sc->sc_stat);
967 
968 		/* XXX FIXME should we try to resubmit another request? */
969 	} else {
970 		NG_UBT_INFO(
971 "%s: %s - Control request has been started\n",
972 			__func__, USBDEVNAME(sc->sc_dev));
973 
974 		sc->sc_flags |= UBT_CMD_XMIT;
975 		status = USBD_NORMAL_COMPLETION;
976 	}
977 
978 	NG_FREE_M(m);
979 
980 	return (status);
981 } /* ubt_request_start */
982 
983 /*
984  * USB control request callback
985  */
986 
987 Static void
988 ubt_request_complete(usbd_xfer_handle h, usbd_private_handle p, usbd_status s)
989 {
990 	ng_send_fn((node_p) p, NULL, ubt_request_complete2, (void *) h, s);
991 	NG_NODE_UNREF((node_p) p);
992 } /* ubt_request_complete */
993 
994 Static void
995 ubt_request_complete2(node_p node, hook_p hook, void *arg1, int arg2)
996 {
997 	ubt_softc_p		sc = (ubt_softc_p) NG_NODE_PRIVATE(node);
998 	usbd_xfer_handle	h = (usbd_xfer_handle) arg1;
999 	usbd_status		s = (usbd_status) arg2;
1000 
1001 	if (sc == NULL)
1002 		return;
1003 
1004 	KASSERT((sc->sc_flags & UBT_CMD_XMIT), (
1005 "%s: %s - No control request is pending\n", __func__, USBDEVNAME(sc->sc_dev)));
1006 
1007 	sc->sc_flags &= ~UBT_CMD_XMIT;
1008 
1009 	if (s == USBD_CANCELLED) {
1010 		NG_UBT_INFO(
1011 "%s: %s - Control request cancelled\n", __func__, USBDEVNAME(sc->sc_dev));
1012 
1013 		return;
1014 	}
1015 
1016 	if (s != USBD_NORMAL_COMPLETION) {
1017 		NG_UBT_ERR(
1018 "%s: %s - Control request failed. %s (%d)\n",
1019 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(s), s);
1020 
1021 		if (s == USBD_STALLED)
1022 			usbd_clear_endpoint_stall_async(h->pipe);
1023 
1024 		NG_UBT_STAT_OERROR(sc->sc_stat);
1025 	} else {
1026 		NG_UBT_INFO(
1027 "%s: %s - Sent %d bytes to control pipe\n",
1028 			__func__, USBDEVNAME(sc->sc_dev), h->actlen);
1029 
1030 		NG_UBT_STAT_BYTES_SENT(sc->sc_stat, h->actlen);
1031 		NG_UBT_STAT_PCKTS_SENT(sc->sc_stat);
1032 	}
1033 
1034 	if (NG_BT_MBUFQ_LEN(&sc->sc_cmdq) > 0)
1035 		ubt_request_start(sc);
1036 } /* ubt_request_complete2 */
1037 
1038 /*
1039  * Start interrupt transfer. Must be called when node is locked
1040  */
1041 
1042 Static usbd_status
1043 ubt_intr_start(ubt_softc_p sc)
1044 {
1045 	struct mbuf	*m = NULL;
1046 	usbd_status	 status;
1047 
1048 	KASSERT(!(sc->sc_flags & UBT_EVT_RECV), (
1049 "%s: %s - Another interrupt request is pending\n",
1050 		__func__, USBDEVNAME(sc->sc_dev)));
1051 
1052 	/* Allocate new mbuf cluster */
1053 	MGETHDR(m, M_DONTWAIT, MT_DATA);
1054 	if (m == NULL)
1055 		return (USBD_NOMEM);
1056 
1057 	MCLGET(m, M_DONTWAIT);
1058 	if (!(m->m_flags & M_EXT)) {
1059 		NG_FREE_M(m);
1060 		return (USBD_NOMEM);
1061 	}
1062 
1063 	if (!(sc->sc_flags & UBT_HAVE_FRAME_TYPE)) {
1064 		*mtod(m, u_int8_t *) = NG_HCI_EVENT_PKT;
1065 		m->m_pkthdr.len = m->m_len = 1;
1066 	} else
1067 		m->m_pkthdr.len = m->m_len = 0;
1068 
1069 	/* Initialize a USB transfer and then schedule it */
1070 	usbd_setup_xfer(
1071 			sc->sc_intr_xfer,
1072 			sc->sc_intr_pipe,
1073 			(usbd_private_handle) sc->sc_node,
1074 			(void *)(mtod(m, u_int8_t *) + m->m_len),
1075 			MCLBYTES - m->m_len,
1076 			USBD_SHORT_XFER_OK,
1077 			USBD_NO_TIMEOUT,
1078 			ubt_intr_complete);
1079 
1080 	NG_NODE_REF(sc->sc_node);
1081 
1082 	status = usbd_transfer(sc->sc_intr_xfer);
1083 	if (status != USBD_NORMAL_COMPLETION && status != USBD_IN_PROGRESS) {
1084 		NG_UBT_ERR(
1085 "%s: %s - Failed to start intrerrupt transfer. %s (%d)\n",
1086 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(status),
1087 			status);
1088 
1089 		NG_NODE_UNREF(sc->sc_node);
1090 
1091 		NG_FREE_M(m);
1092 
1093 		return (status);
1094 	}
1095 
1096 	sc->sc_flags |= UBT_EVT_RECV;
1097 	sc->sc_intr_buffer = m;
1098 
1099 	return (USBD_NORMAL_COMPLETION);
1100 } /* ubt_intr_start */
1101 
1102 /*
1103  * Process interrupt from USB device (We got data from interrupt pipe)
1104  */
1105 
1106 Static void
1107 ubt_intr_complete(usbd_xfer_handle h, usbd_private_handle p, usbd_status s)
1108 {
1109 	ng_send_fn((node_p) p, NULL, ubt_intr_complete2, (void *) h, s);
1110 	NG_NODE_UNREF((node_p) p);
1111 } /* ubt_intr_complete */
1112 
1113 Static void
1114 ubt_intr_complete2(node_p node, hook_p hook, void *arg1, int arg2)
1115 {
1116 	ubt_softc_p		 sc = (ubt_softc_p) NG_NODE_PRIVATE(node);
1117 	usbd_xfer_handle	 h = (usbd_xfer_handle) arg1;
1118 	usbd_status		 s = (usbd_status) arg2;
1119 	struct mbuf		*m = NULL;
1120 	ng_hci_event_pkt_t	*hdr = NULL;
1121 	int			 error;
1122 
1123 	if (sc == NULL)
1124 		return;
1125 
1126 	KASSERT((sc->sc_flags & UBT_EVT_RECV), (
1127 "%s: %s - No interrupt request is pending\n",
1128 		__func__, USBDEVNAME(sc->sc_dev)));
1129 
1130 	sc->sc_flags &= ~UBT_EVT_RECV;
1131 
1132 	m = sc->sc_intr_buffer;
1133 	sc->sc_intr_buffer = NULL;
1134 
1135 	hdr = mtod(m, ng_hci_event_pkt_t *);
1136 
1137 	if (sc->sc_hook == NULL || NG_HOOK_NOT_VALID(sc->sc_hook)) {
1138 		NG_UBT_INFO(
1139 "%s: %s - No upstream hook\n", __func__, USBDEVNAME(sc->sc_dev));
1140 
1141 		NG_FREE_M(m);
1142 		return;
1143 	}
1144 
1145 	if (s == USBD_CANCELLED) {
1146 		NG_UBT_INFO(
1147 "%s: %s - Interrupt xfer cancelled\n", __func__, USBDEVNAME(sc->sc_dev));
1148 
1149 		NG_FREE_M(m);
1150 		return;
1151 	}
1152 
1153 	if (s != USBD_NORMAL_COMPLETION) {
1154 		NG_UBT_WARN(
1155 "%s: %s - Interrupt xfer failed, %s (%d). No new xfer will be submitted!\n",
1156 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(s), s);
1157 
1158 		if (s == USBD_STALLED)
1159 			usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
1160 
1161 		NG_UBT_STAT_IERROR(sc->sc_stat);
1162 		NG_FREE_M(m);
1163 
1164 		return; /* XXX FIXME we should restart after some delay */
1165 	}
1166 
1167 	NG_UBT_STAT_BYTES_RECV(sc->sc_stat, h->actlen);
1168 	m->m_pkthdr.len += h->actlen;
1169 	m->m_len += h->actlen;
1170 
1171 	NG_UBT_INFO(
1172 "%s: %s - Got %d bytes from interrupt pipe\n",
1173 		__func__, USBDEVNAME(sc->sc_dev), h->actlen);
1174 
1175 	if (m->m_pkthdr.len < sizeof(*hdr)) {
1176 		NG_FREE_M(m);
1177 		goto done;
1178 	}
1179 
1180 	if (hdr->length == m->m_pkthdr.len - sizeof(*hdr)) {
1181 		NG_UBT_INFO(
1182 "%s: %s - Got complete HCI event frame, pktlen=%d, length=%d\n",
1183 			__func__, USBDEVNAME(sc->sc_dev), m->m_pkthdr.len,
1184 			hdr->length);
1185 
1186 		NG_UBT_STAT_PCKTS_RECV(sc->sc_stat);
1187 
1188 		NG_SEND_DATA_ONLY(error, sc->sc_hook, m);
1189 		if (error != 0)
1190 			NG_UBT_STAT_IERROR(sc->sc_stat);
1191 	} else {
1192 		NG_UBT_ERR(
1193 "%s: %s - Invalid HCI event frame size, length=%d, pktlen=%d\n",
1194 			__func__, USBDEVNAME(sc->sc_dev), hdr->length,
1195 			m->m_pkthdr.len);
1196 
1197 		NG_UBT_STAT_IERROR(sc->sc_stat);
1198 		NG_FREE_M(m);
1199 	}
1200 done:
1201 	ubt_intr_start(sc);
1202 } /* ubt_intr_complete2 */
1203 
1204 /*
1205  * Start bulk-in USB transfer (ACL data). Must be called when node is locked
1206  */
1207 
1208 Static usbd_status
1209 ubt_bulk_in_start(ubt_softc_p sc)
1210 {
1211 	struct mbuf	*m = NULL;
1212 	usbd_status	 status;
1213 
1214 	KASSERT(!(sc->sc_flags & UBT_ACL_RECV), (
1215 "%s: %s - Another bulk-in request is pending\n",
1216 		__func__, USBDEVNAME(sc->sc_dev)));
1217 
1218 	/* Allocate new mbuf cluster */
1219 	MGETHDR(m, M_DONTWAIT, MT_DATA);
1220 	if (m == NULL)
1221 		return (USBD_NOMEM);
1222 
1223 	MCLGET(m, M_DONTWAIT);
1224 	if (!(m->m_flags & M_EXT)) {
1225 		NG_FREE_M(m);
1226 		return (USBD_NOMEM);
1227 	}
1228 
1229 	if (!(sc->sc_flags & UBT_HAVE_FRAME_TYPE)) {
1230 		*mtod(m, u_int8_t *) = NG_HCI_ACL_DATA_PKT;
1231 		m->m_pkthdr.len = m->m_len = 1;
1232 	} else
1233 		m->m_pkthdr.len = m->m_len = 0;
1234 
1235 	/* Initialize a bulk-in USB transfer and then schedule it */
1236 	usbd_setup_xfer(
1237 			sc->sc_bulk_in_xfer,
1238 			sc->sc_bulk_in_pipe,
1239 			(usbd_private_handle) sc->sc_node,
1240 			(void *)(mtod(m, u_int8_t *) + m->m_len),
1241 			MCLBYTES - m->m_len,
1242 			USBD_SHORT_XFER_OK,
1243 			USBD_NO_TIMEOUT,
1244 			ubt_bulk_in_complete);
1245 
1246 	NG_NODE_REF(sc->sc_node);
1247 
1248 	status = usbd_transfer(sc->sc_bulk_in_xfer);
1249 	if (status != USBD_NORMAL_COMPLETION && status != USBD_IN_PROGRESS) {
1250 		NG_UBT_ERR(
1251 "%s: %s - Failed to start bulk-in transfer. %s (%d)\n",
1252 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(status),
1253 			status);
1254 
1255 		NG_NODE_UNREF(sc->sc_node);
1256 
1257 		NG_FREE_M(m);
1258 
1259 		return (status);
1260 	}
1261 
1262 	sc->sc_flags |= UBT_ACL_RECV;
1263 	sc->sc_bulk_in_buffer = m;
1264 
1265 	return (USBD_NORMAL_COMPLETION);
1266 } /* ubt_bulk_in_start */
1267 
1268 /*
1269  * USB bulk-in transfer callback
1270  */
1271 
1272 Static void
1273 ubt_bulk_in_complete(usbd_xfer_handle h, usbd_private_handle p, usbd_status s)
1274 {
1275 	ng_send_fn((node_p) p, NULL, ubt_bulk_in_complete2, (void *) h, s);
1276 	NG_NODE_UNREF((node_p) p);
1277 } /* ubt_bulk_in_complete */
1278 
1279 Static void
1280 ubt_bulk_in_complete2(node_p node, hook_p hook, void *arg1, int arg2)
1281 {
1282 	ubt_softc_p		 sc = (ubt_softc_p) NG_NODE_PRIVATE(node);
1283 	usbd_xfer_handle	 h = (usbd_xfer_handle) arg1;
1284 	usbd_status		 s = (usbd_status) arg2;
1285 	struct mbuf		*m = NULL;
1286 	ng_hci_acldata_pkt_t	*hdr = NULL;
1287 	int			 len;
1288 
1289 	if (sc == NULL)
1290 		return;
1291 
1292 	KASSERT((sc->sc_flags & UBT_ACL_RECV), (
1293 "%s: %s - No bulk-in request is pending\n", __func__, USBDEVNAME(sc->sc_dev)));
1294 
1295 	sc->sc_flags &= ~UBT_ACL_RECV;
1296 
1297 	m = sc->sc_bulk_in_buffer;
1298 	sc->sc_bulk_in_buffer = NULL;
1299 
1300 	hdr = mtod(m, ng_hci_acldata_pkt_t *);
1301 
1302 	if (sc->sc_hook == NULL || NG_HOOK_NOT_VALID(sc->sc_hook)) {
1303 		NG_UBT_INFO(
1304 "%s: %s - No upstream hook\n", __func__, USBDEVNAME(sc->sc_dev));
1305 
1306 		NG_FREE_M(m);
1307 		return;
1308 	}
1309 
1310 	if (s == USBD_CANCELLED) {
1311 		NG_UBT_INFO(
1312 "%s: %s - Bulk-in xfer cancelled, pipe=%p\n",
1313 			__func__, USBDEVNAME(sc->sc_dev), sc->sc_bulk_in_pipe);
1314 
1315 		NG_FREE_M(m);
1316 		return;
1317 	}
1318 
1319 	if (s != USBD_NORMAL_COMPLETION) {
1320 		NG_UBT_WARN(
1321 "%s: %s - Bulk-in xfer failed, %s (%d). No new xfer will be submitted!\n",
1322 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(s), s);
1323 
1324 		if (s == USBD_STALLED)
1325 			usbd_clear_endpoint_stall_async(sc->sc_bulk_in_pipe);
1326 
1327 		NG_UBT_STAT_IERROR(sc->sc_stat);
1328 		NG_FREE_M(m);
1329 
1330 		return; /* XXX FIXME we should restart after some delay */
1331 	}
1332 
1333 	NG_UBT_STAT_BYTES_RECV(sc->sc_stat, h->actlen);
1334 	m->m_pkthdr.len += h->actlen;
1335 	m->m_len += h->actlen;
1336 
1337 	NG_UBT_INFO(
1338 "%s: %s - Got %d bytes from bulk-in pipe\n",
1339 		__func__, USBDEVNAME(sc->sc_dev), h->actlen);
1340 
1341 	if (m->m_pkthdr.len < sizeof(*hdr)) {
1342 		NG_FREE_M(m);
1343 		goto done;
1344 	}
1345 
1346 	len = le16toh(hdr->length);
1347 	if (len == m->m_pkthdr.len - sizeof(*hdr)) {
1348 		NG_UBT_INFO(
1349 "%s: %s - Got complete ACL data frame, pktlen=%d, length=%d\n",
1350 			__func__, USBDEVNAME(sc->sc_dev), m->m_pkthdr.len, len);
1351 
1352 		NG_UBT_STAT_PCKTS_RECV(sc->sc_stat);
1353 
1354 		NG_SEND_DATA_ONLY(len, sc->sc_hook, m);
1355 		if (len != 0)
1356 			NG_UBT_STAT_IERROR(sc->sc_stat);
1357 	} else {
1358 		NG_UBT_ERR(
1359 "%s: %s - Invalid ACL frame size, length=%d, pktlen=%d\n",
1360 			__func__, USBDEVNAME(sc->sc_dev), len,
1361 			m->m_pkthdr.len);
1362 
1363 		NG_UBT_STAT_IERROR(sc->sc_stat);
1364 		NG_FREE_M(m);
1365 	}
1366 done:
1367 	ubt_bulk_in_start(sc);
1368 } /* ubt_bulk_in_complete2 */
1369 
1370 /*
1371  * Start bulk-out USB transfer. Must be called with node locked
1372  */
1373 
1374 Static usbd_status
1375 ubt_bulk_out_start(ubt_softc_p sc)
1376 {
1377 	struct mbuf	*m = NULL;
1378 	usbd_status	status;
1379 
1380 	KASSERT(!(sc->sc_flags & UBT_ACL_XMIT), (
1381 "%s: %s - Another bulk-out request is pending\n",
1382 		__func__, USBDEVNAME(sc->sc_dev)));
1383 
1384 	NG_BT_MBUFQ_DEQUEUE(&sc->sc_aclq, m);
1385 	if (m == NULL) {
1386 		NG_UBT_INFO(
1387 "%s: %s - ACL data queue is empty\n", __func__, USBDEVNAME(sc->sc_dev));
1388 
1389  		return (USBD_NORMAL_COMPLETION);
1390 	}
1391 
1392 	/*
1393 	 * Check ACL data frame size and copy it back to linear USB
1394 	 * transfer buffer.
1395 	 */
1396 
1397 	if (m->m_pkthdr.len > UBT_BULK_BUFFER_SIZE)
1398 		panic(
1399 "%s: %s - ACL data frame too big, size=%d, len=%d\n",
1400 			__func__, USBDEVNAME(sc->sc_dev), UBT_BULK_BUFFER_SIZE,
1401 			m->m_pkthdr.len);
1402 
1403 	m_copydata(m, 0, m->m_pkthdr.len, sc->sc_bulk_out_buffer);
1404 
1405 	/* Initialize a bulk-out USB transfer and then schedule it */
1406 	usbd_setup_xfer(
1407 			sc->sc_bulk_out_xfer,
1408 			sc->sc_bulk_out_pipe,
1409 			(usbd_private_handle) sc->sc_node,
1410 			sc->sc_bulk_out_buffer,
1411 			m->m_pkthdr.len,
1412 			USBD_NO_COPY,
1413 			USBD_DEFAULT_TIMEOUT, /* XXX */
1414 			ubt_bulk_out_complete);
1415 
1416 	NG_NODE_REF(sc->sc_node);
1417 
1418 	status = usbd_transfer(sc->sc_bulk_out_xfer);
1419 	if (status != USBD_NORMAL_COMPLETION && status != USBD_IN_PROGRESS) {
1420 		NG_UBT_ERR(
1421 "%s: %s - Could not start bulk-out transfer. %s (%d)\n",
1422 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(status),
1423 			status);
1424 
1425 		NG_NODE_UNREF(sc->sc_node);
1426 
1427 		NG_BT_MBUFQ_DROP(&sc->sc_aclq);
1428 		NG_UBT_STAT_OERROR(sc->sc_stat);
1429 
1430 		/* XXX FIXME should we try to start another transfer? */
1431 	} else {
1432 		NG_UBT_INFO(
1433 "%s: %s - Bulk-out transfer has been started, len=%d\n",
1434 			__func__, USBDEVNAME(sc->sc_dev), m->m_pkthdr.len);
1435 
1436 		sc->sc_flags |= UBT_ACL_XMIT;
1437 		status = USBD_NORMAL_COMPLETION;
1438 	}
1439 
1440 	NG_FREE_M(m);
1441 
1442 	return (status);
1443 } /* ubt_bulk_out_start */
1444 
1445 /*
1446  * USB bulk-out transfer callback
1447  */
1448 
1449 Static void
1450 ubt_bulk_out_complete(usbd_xfer_handle h, usbd_private_handle p, usbd_status s)
1451 {
1452 	ng_send_fn((node_p) p,  NULL, ubt_bulk_out_complete2, (void *) h, s);
1453 	NG_NODE_UNREF((node_p) p);
1454 } /* ubt_bulk_out_complete */
1455 
1456 Static void
1457 ubt_bulk_out_complete2(node_p node, hook_p hook, void *arg1, int arg2)
1458 {
1459 	ubt_softc_p		sc = (ubt_softc_p) NG_NODE_PRIVATE(node);
1460 	usbd_xfer_handle	h = (usbd_xfer_handle) arg1;
1461 	usbd_status		s = (usbd_status) arg2;
1462 
1463 	if (sc == NULL)
1464 		return;
1465 
1466 	KASSERT((sc->sc_flags & UBT_ACL_XMIT), (
1467 "%s: %s - No bulk-out request is pending\n", __func__, USBDEVNAME(sc->sc_dev)));
1468 
1469 	sc->sc_flags &= ~UBT_ACL_XMIT;
1470 
1471 	if (s == USBD_CANCELLED) {
1472 		NG_UBT_INFO(
1473 "%s: %s - Bulk-out xfer cancelled, pipe=%p\n",
1474 			__func__, USBDEVNAME(sc->sc_dev), sc->sc_bulk_out_pipe);
1475 
1476 		return;
1477 	}
1478 
1479 	if (s != USBD_NORMAL_COMPLETION) {
1480 		NG_UBT_WARN(
1481 "%s: %s - Bulk-out xfer failed. %s (%d)\n",
1482 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(s), s);
1483 
1484 		if (s == USBD_STALLED)
1485 			usbd_clear_endpoint_stall_async(sc->sc_bulk_out_pipe);
1486 
1487 		NG_UBT_STAT_OERROR(sc->sc_stat);
1488 	} else {
1489 		NG_UBT_INFO(
1490 "%s: %s - Sent %d bytes to bulk-out pipe\n",
1491 			__func__, USBDEVNAME(sc->sc_dev), h->actlen);
1492 
1493 		NG_UBT_STAT_BYTES_SENT(sc->sc_stat, h->actlen);
1494 		NG_UBT_STAT_PCKTS_SENT(sc->sc_stat);
1495 	}
1496 
1497 	if (NG_BT_MBUFQ_LEN(&sc->sc_aclq) > 0)
1498 		ubt_bulk_out_start(sc);
1499 } /* ubt_bulk_out_complete2 */
1500 
1501 /*
1502  * Start Isochronous-in USB transfer. Must be called with node locked
1503  */
1504 
1505 Static usbd_status
1506 ubt_isoc_in_start(ubt_softc_p sc)
1507 {
1508 	usbd_status	status;
1509 	int		i;
1510 
1511 	KASSERT(!(sc->sc_flags & UBT_SCO_RECV), (
1512 "%s: %s - Another isoc-in request is pending\n",
1513                 __func__, USBDEVNAME(sc->sc_dev)));
1514 
1515 	/* Initialize a isoc-in USB transfer and then schedule it */
1516 	for (i = 0; i < sc->sc_isoc_nframes; i++)
1517 		sc->sc_isoc_in_frlen[i] = sc->sc_isoc_size;
1518 
1519 	usbd_setup_isoc_xfer(
1520 			sc->sc_isoc_in_xfer,
1521 			sc->sc_isoc_in_pipe,
1522 			(usbd_private_handle) sc->sc_node,
1523 			sc->sc_isoc_in_frlen,
1524 			sc->sc_isoc_nframes,
1525 			USBD_NO_COPY, /* XXX flags */
1526 			ubt_isoc_in_complete);
1527 
1528 	NG_NODE_REF(sc->sc_node);
1529 
1530 	status = usbd_transfer(sc->sc_isoc_in_xfer);
1531 	if (status != USBD_NORMAL_COMPLETION && status != USBD_IN_PROGRESS) {
1532 		NG_UBT_ERR(
1533 "%s: %s - Failed to start isoc-in transfer. %s (%d)\n",
1534 			__func__, USBDEVNAME(sc->sc_dev),
1535 			usbd_errstr(status), status);
1536 
1537 		NG_NODE_UNREF(sc->sc_node);
1538 
1539 		return (status);
1540 	}
1541 
1542 	sc->sc_flags |= UBT_SCO_RECV;
1543 
1544 	return (USBD_NORMAL_COMPLETION);
1545 } /* ubt_isoc_in_start */
1546 
1547 /*
1548  * USB isochronous transfer callback
1549  */
1550 
1551 Static void
1552 ubt_isoc_in_complete(usbd_xfer_handle h, usbd_private_handle p, usbd_status s)
1553 {
1554 	ng_send_fn((node_p) p, NULL, ubt_isoc_in_complete2, (void *) h, s);
1555 	NG_NODE_UNREF((node_p) p);
1556 } /* ubt_isoc_in_complete */
1557 
1558 Static void
1559 ubt_isoc_in_complete2(node_p node, hook_p hook, void *arg1, int arg2)
1560 {
1561 	ubt_softc_p		 sc = (ubt_softc_p) NG_NODE_PRIVATE(node);
1562 	usbd_xfer_handle	 h = (usbd_xfer_handle) arg1;
1563 	usbd_status		 s = (usbd_status) arg2;
1564 	struct mbuf		*m = NULL;
1565 	ng_hci_scodata_pkt_t	*hdr = NULL;
1566 	u_int8_t		*b = NULL;
1567 	int			 i;
1568 
1569 	if (sc == NULL)
1570 		return;
1571 
1572 	KASSERT((sc->sc_flags & UBT_SCO_RECV), (
1573 "%s: %s - No isoc-in request is pending\n", __func__, USBDEVNAME(sc->sc_dev)));
1574 
1575 	sc->sc_flags &= ~UBT_SCO_RECV;
1576 
1577 	if (sc->sc_hook == NULL || NG_HOOK_NOT_VALID(sc->sc_hook)) {
1578 		NG_UBT_INFO(
1579 "%s: %s - No upstream hook\n", __func__, USBDEVNAME(sc->sc_dev));
1580 
1581 		return;
1582 	}
1583 
1584 	if (s == USBD_CANCELLED) {
1585 		NG_UBT_INFO(
1586 "%s: %s - Isoc-in xfer cancelled, pipe=%p\n",
1587 			__func__, USBDEVNAME(sc->sc_dev), sc->sc_isoc_in_pipe);
1588 
1589 		return;
1590 	}
1591 
1592 	if (s != USBD_NORMAL_COMPLETION) {
1593 		NG_UBT_WARN(
1594 "%s: %s - Isoc-in xfer failed, %s (%d). No new xfer will be submitted!\n",
1595 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(s), s);
1596 
1597 		if (s == USBD_STALLED)
1598 			usbd_clear_endpoint_stall_async(sc->sc_isoc_in_pipe);
1599 
1600 		NG_UBT_STAT_IERROR(sc->sc_stat);
1601 
1602 		return; /* XXX FIXME we should restart after some delay */
1603 	}
1604 
1605 	NG_UBT_STAT_BYTES_RECV(sc->sc_stat, h->actlen);
1606 
1607 	NG_UBT_INFO(
1608 "%s: %s - Got %d bytes from isoc-in pipe\n",
1609 		__func__, USBDEVNAME(sc->sc_dev), h->actlen);
1610 
1611 	/* Copy SCO data frame to mbuf */
1612 	MGETHDR(m, M_DONTWAIT, MT_DATA);
1613 	if (m == NULL) {
1614 		NG_UBT_ALERT(
1615 "%s: %s - Could not allocate mbuf\n",
1616 			__func__, USBDEVNAME(sc->sc_dev));
1617 
1618 		NG_UBT_STAT_IERROR(sc->sc_stat);
1619 		goto done;
1620 	}
1621 
1622 	/* Fix SCO data frame header if required */
1623 	if (!(sc->sc_flags & UBT_HAVE_FRAME_TYPE)) {
1624 		*mtod(m, u_int8_t *) = NG_HCI_SCO_DATA_PKT;
1625 		m->m_pkthdr.len = 1;
1626 		m->m_len = min(MHLEN, h->actlen + 1); /* XXX m_copyback */
1627 	} else {
1628 		m->m_pkthdr.len = 0;
1629 		m->m_len = min(MHLEN, h->actlen); /* XXX m_copyback */
1630 	}
1631 
1632 	/*
1633 	 * XXX FIXME how do we know how many frames we have received?
1634 	 * XXX use frlen for now. is that correct?
1635 	 */
1636 
1637 	b = (u_int8_t *) sc->sc_isoc_in_buffer;
1638 
1639 	for (i = 0; i < sc->sc_isoc_nframes; i++) {
1640 		b += (i * sc->sc_isoc_size);
1641 
1642 		if (sc->sc_isoc_in_frlen[i] > 0)
1643 			m_copyback(m, m->m_pkthdr.len,
1644 				sc->sc_isoc_in_frlen[i], b);
1645 	}
1646 
1647 	if (m->m_pkthdr.len < sizeof(*hdr))
1648 		goto done;
1649 
1650 	hdr = mtod(m, ng_hci_scodata_pkt_t *);
1651 
1652 	if (hdr->length == m->m_pkthdr.len - sizeof(*hdr)) {
1653 		NG_UBT_INFO(
1654 "%s: %s - Got complete SCO data frame, pktlen=%d, length=%d\n",
1655 			__func__, USBDEVNAME(sc->sc_dev), m->m_pkthdr.len,
1656 			hdr->length);
1657 
1658 		NG_UBT_STAT_PCKTS_RECV(sc->sc_stat);
1659 
1660 		NG_SEND_DATA_ONLY(i, sc->sc_hook, m);
1661 		if (i != 0)
1662 			NG_UBT_STAT_IERROR(sc->sc_stat);
1663 	} else {
1664 		NG_UBT_ERR(
1665 "%s: %s - Invalid SCO frame size, length=%d, pktlen=%d\n",
1666 			__func__, USBDEVNAME(sc->sc_dev), hdr->length,
1667 			m->m_pkthdr.len);
1668 
1669 		NG_UBT_STAT_IERROR(sc->sc_stat);
1670 		NG_FREE_M(m);
1671 	}
1672 done:
1673 	ubt_isoc_in_start(sc);
1674 } /* ubt_isoc_in_complete2 */
1675 
1676 /*
1677  * Start isochronous-out USB transfer. Must be called with node locked
1678  */
1679 
1680 Static usbd_status
1681 ubt_isoc_out_start(ubt_softc_p sc)
1682 {
1683 	struct mbuf	*m = NULL;
1684 	u_int8_t	*b = NULL;
1685 	int		 i, len, nframes;
1686 	usbd_status	 status;
1687 
1688 	KASSERT(!(sc->sc_flags & UBT_SCO_XMIT), (
1689 "%s: %s - Another isoc-out request is pending\n",
1690 		__func__, USBDEVNAME(sc->sc_dev)));
1691 
1692 	NG_BT_MBUFQ_DEQUEUE(&sc->sc_scoq, m);
1693 	if (m == NULL) {
1694 		NG_UBT_INFO(
1695 "%s: %s - SCO data queue is empty\n", __func__, USBDEVNAME(sc->sc_dev));
1696 
1697  		return (USBD_NORMAL_COMPLETION);
1698 	}
1699 
1700 	/* Copy entire SCO frame into USB transfer buffer and start transfer */
1701 	b = (u_int8_t *) sc->sc_isoc_out_buffer;
1702 	nframes = 0;
1703 
1704 	for (i = 0; i < sc->sc_isoc_nframes; i++) {
1705 		b += (i * sc->sc_isoc_size);
1706 
1707 		len = min(m->m_pkthdr.len, sc->sc_isoc_size);
1708 		if (len > 0) {
1709 			m_copydata(m, 0, len, b);
1710 			m_adj(m, len);
1711 			nframes ++;
1712 		}
1713 
1714 		sc->sc_isoc_out_frlen[i] = len;
1715 	}
1716 
1717 	if (m->m_pkthdr.len > 0)
1718 		panic(
1719 "%s: %s - SCO data frame is too big, nframes=%d, size=%d, len=%d\n",
1720 			__func__, USBDEVNAME(sc->sc_dev), sc->sc_isoc_nframes,
1721 			sc->sc_isoc_size, m->m_pkthdr.len);
1722 
1723 	NG_FREE_M(m);
1724 
1725 	/* Initialize a isoc-out USB transfer and then schedule it */
1726 	usbd_setup_isoc_xfer(
1727 			sc->sc_isoc_out_xfer,
1728 			sc->sc_isoc_out_pipe,
1729 			(usbd_private_handle) sc->sc_node,
1730 			sc->sc_isoc_out_frlen,
1731 			nframes,
1732 			USBD_NO_COPY,
1733 			ubt_isoc_out_complete);
1734 
1735 	NG_NODE_REF(sc->sc_node);
1736 
1737 	status = usbd_transfer(sc->sc_isoc_out_xfer);
1738 	if (status != USBD_NORMAL_COMPLETION && status != USBD_IN_PROGRESS) {
1739 		NG_UBT_ERR(
1740 "%s: %s - Could not start isoc-out transfer. %s (%d)\n",
1741 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(status),
1742 			status);
1743 
1744 		NG_NODE_UNREF(sc->sc_node);
1745 
1746 		NG_BT_MBUFQ_DROP(&sc->sc_scoq);
1747 		NG_UBT_STAT_OERROR(sc->sc_stat);
1748 	} else {
1749 		NG_UBT_INFO(
1750 "%s: %s - Isoc-out transfer has been started, nframes=%d, size=%d\n",
1751 			__func__, USBDEVNAME(sc->sc_dev), nframes,
1752 			sc->sc_isoc_size);
1753 
1754 		sc->sc_flags |= UBT_SCO_XMIT;
1755 		status = USBD_NORMAL_COMPLETION;
1756 	}
1757 
1758 	return (status);
1759 } /* ubt_isoc_out_start */
1760 
1761 /*
1762  * USB isoc-out. transfer callback
1763  */
1764 
1765 Static void
1766 ubt_isoc_out_complete(usbd_xfer_handle h, usbd_private_handle p, usbd_status s)
1767 {
1768 	ng_send_fn((node_p) p, NULL, ubt_isoc_out_complete2, (void *) h, s);
1769 	NG_NODE_UNREF((node_p) p);
1770 } /* ubt_isoc_out_complete */
1771 
1772 Static void
1773 ubt_isoc_out_complete2(node_p node, hook_p hook, void *arg1, int arg2)
1774 {
1775 	ubt_softc_p		sc = (ubt_softc_p) NG_NODE_PRIVATE(node);
1776 	usbd_xfer_handle	h = (usbd_xfer_handle) arg1;
1777 	usbd_status		s = (usbd_status) arg2;
1778 
1779 	if (sc == NULL)
1780 		return;
1781 
1782 	KASSERT((sc->sc_flags & UBT_SCO_XMIT), (
1783 "%s: %s - No isoc-out request is pending\n", __func__, USBDEVNAME(sc->sc_dev)));
1784 
1785 	sc->sc_flags &= ~UBT_SCO_XMIT;
1786 
1787 	if (s == USBD_CANCELLED) {
1788 		NG_UBT_INFO(
1789 "%s: %s - Isoc-out xfer cancelled, pipe=%p\n",
1790 			__func__, USBDEVNAME(sc->sc_dev),
1791 			sc->sc_isoc_out_pipe);
1792 
1793 		return;
1794 	}
1795 
1796 	if (s != USBD_NORMAL_COMPLETION) {
1797 		NG_UBT_WARN(
1798 "%s: %s - Isoc-out xfer failed. %s (%d)\n",
1799 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(s), s);
1800 
1801 		if (s == USBD_STALLED)
1802 			usbd_clear_endpoint_stall_async(sc->sc_isoc_out_pipe);
1803 
1804 		NG_UBT_STAT_OERROR(sc->sc_stat);
1805 	} else {
1806 		NG_UBT_INFO(
1807 "%s: %s - Sent %d bytes to isoc-out pipe\n",
1808 			__func__, USBDEVNAME(sc->sc_dev), h->actlen);
1809 
1810 		NG_UBT_STAT_BYTES_SENT(sc->sc_stat, h->actlen);
1811 		NG_UBT_STAT_PCKTS_SENT(sc->sc_stat);
1812 	}
1813 
1814 	if (NG_BT_MBUFQ_LEN(&sc->sc_scoq) > 0)
1815 		ubt_isoc_out_start(sc);
1816 } /* ubt_isoc_out_complete2 */
1817 
1818 /*
1819  * Abort transfers on all USB pipes
1820  */
1821 
1822 Static void
1823 ubt_reset(ubt_softc_p sc)
1824 {
1825 	/* Interrupt */
1826 	if (sc->sc_intr_pipe != NULL)
1827 		usbd_abort_pipe(sc->sc_intr_pipe);
1828 
1829 	/* Bulk-in/out */
1830 	if (sc->sc_bulk_in_pipe != NULL)
1831 		usbd_abort_pipe(sc->sc_bulk_in_pipe);
1832 	if (sc->sc_bulk_out_pipe != NULL)
1833 		usbd_abort_pipe(sc->sc_bulk_out_pipe);
1834 
1835 	/* Isoc-in/out */
1836 	if (sc->sc_isoc_in_pipe != NULL)
1837 		usbd_abort_pipe(sc->sc_isoc_in_pipe);
1838 	if (sc->sc_isoc_out_pipe != NULL)
1839 		usbd_abort_pipe(sc->sc_isoc_out_pipe);
1840 
1841 	/* Cleanup queues */
1842 	NG_BT_MBUFQ_DRAIN(&sc->sc_cmdq);
1843 	NG_BT_MBUFQ_DRAIN(&sc->sc_aclq);
1844 	NG_BT_MBUFQ_DRAIN(&sc->sc_scoq);
1845 } /* ubt_reset */
1846 
1847 /****************************************************************************
1848  ****************************************************************************
1849  **                        Netgraph specific
1850  ****************************************************************************
1851  ****************************************************************************/
1852 
1853 /*
1854  * Netgraph node constructor. Do not allow to create node of this type.
1855  */
1856 
1857 Static int
1858 ng_ubt_constructor(node_p node)
1859 {
1860 	return (EINVAL);
1861 } /* ng_ubt_constructor */
1862 
1863 /*
1864  * Netgraph node destructor. Destroy node only when device has been detached
1865  */
1866 
1867 Static int
1868 ng_ubt_shutdown(node_p node)
1869 {
1870 	ubt_softc_p	sc = (ubt_softc_p) NG_NODE_PRIVATE(node);
1871 
1872 	/* Let old node go */
1873 	NG_NODE_SET_PRIVATE(node, NULL);
1874 	NG_NODE_UNREF(node);
1875 
1876 	if (sc == NULL)
1877 		goto done;
1878 
1879 	/* Create Netgraph node */
1880 	if (ng_make_node_common(&typestruct, &sc->sc_node) != 0) {
1881 		printf("%s: Could not create Netgraph node\n",
1882 			USBDEVNAME(sc->sc_dev));
1883 		sc->sc_node = NULL;
1884 		goto done;
1885 	}
1886 
1887 	/* Name node */
1888 	if (ng_name_node(sc->sc_node, USBDEVNAME(sc->sc_dev)) != 0) {
1889 		printf("%s: Could not name Netgraph node\n",
1890 			USBDEVNAME(sc->sc_dev));
1891 		NG_NODE_UNREF(sc->sc_node);
1892 		sc->sc_node = NULL;
1893 		goto done;
1894 	}
1895 
1896 	NG_NODE_SET_PRIVATE(sc->sc_node, sc);
1897 	NG_NODE_FORCE_WRITER(sc->sc_node);
1898 done:
1899 	return (0);
1900 } /* ng_ubt_shutdown */
1901 
1902 /*
1903  * Create new hook. There can only be one.
1904  */
1905 
1906 Static int
1907 ng_ubt_newhook(node_p node, hook_p hook, char const *name)
1908 {
1909 	ubt_softc_p	sc = (ubt_softc_p) NG_NODE_PRIVATE(node);
1910 
1911 	/* Refuse to create new hook if device interface is active */
1912 	if (sc->sc_ctrl_dev != NODEV || sc->sc_intr_dev != NODEV ||
1913 	    sc->sc_bulk_dev != NODEV)
1914 		return (EBUSY);
1915 
1916 	if (strcmp(name, NG_UBT_HOOK) != 0)
1917 		return (EINVAL);
1918 
1919 	if (sc->sc_hook != NULL)
1920 		return (EISCONN);
1921 
1922 	sc->sc_hook = hook;
1923 
1924 	return (0);
1925 } /* ng_ubt_newhook */
1926 
1927 /*
1928  * Connect hook. Start incoming USB transfers
1929  */
1930 
1931 Static int
1932 ng_ubt_connect(hook_p hook)
1933 {
1934 	ubt_softc_p	sc = (ubt_softc_p) NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
1935 	usbd_status	status;
1936 
1937 	/* Refuse to connect hook if device interface is active */
1938 	if (sc->sc_ctrl_dev != NODEV || sc->sc_intr_dev != NODEV ||
1939 	    sc->sc_bulk_dev != NODEV)
1940 		return (EBUSY);
1941 
1942 	NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
1943 
1944 	/* Start intr transfer */
1945 	status = ubt_intr_start(sc);
1946 	if (status != USBD_NORMAL_COMPLETION) {
1947 		NG_UBT_ALERT(
1948 "%s: %s - Could not start interrupt transfer. %s (%d)\n",
1949 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(status),
1950 			status);
1951 		goto fail;
1952 	}
1953 
1954 	/* Start bulk-in transfer */
1955 	status = ubt_bulk_in_start(sc);
1956 	if (status != USBD_NORMAL_COMPLETION) {
1957 		NG_UBT_ALERT(
1958 "%s: %s - Could not start bulk-in transfer. %s (%d)\n",
1959 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(status),
1960 			status);
1961 		goto fail;
1962 	}
1963 
1964 #if __broken__ /* XXX FIXME */
1965 	/* Start isoc-in transfer */
1966 	status = ubt_isoc_in_start(sc);
1967 	if (status != USBD_NORMAL_COMPLETION) {
1968 		NG_UBT_ALERT(
1969 "%s: %s - Could not start isoc-in transfer. %s (%d)\n",
1970 			__func__, USBDEVNAME(sc->sc_dev), usbd_errstr(status),
1971 			status);
1972 		goto fail;
1973 	}
1974 #endif /* __broken__ */
1975 
1976 	return (0);
1977 fail:
1978 	ubt_reset(sc);
1979 	sc->sc_hook = NULL;
1980 
1981 	return (ENXIO);
1982 } /* ng_ubt_connect */
1983 
1984 /*
1985  * Disconnect hook
1986  */
1987 
1988 Static int
1989 ng_ubt_disconnect(hook_p hook)
1990 {
1991 	ubt_softc_p	sc = (ubt_softc_p) NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
1992 
1993 	if (sc != NULL) {
1994 		if (hook != sc->sc_hook)
1995 			return (EINVAL);
1996 
1997 		ubt_reset(sc);
1998 		sc->sc_hook = NULL;
1999 	}
2000 
2001 	return (0);
2002 } /* ng_ubt_disconnect */
2003 
2004 /*
2005  * Process control message
2006  */
2007 
2008 Static int
2009 ng_ubt_rcvmsg(node_p node, item_p item, hook_p lasthook)
2010 {
2011 	ubt_softc_p		 sc = (ubt_softc_p) NG_NODE_PRIVATE(node);
2012 	struct ng_mesg		*msg = NULL, *rsp = NULL;
2013 	struct ng_bt_mbufq	*q = NULL;
2014 	int			 error = 0, queue, qlen;
2015 
2016 	if (sc == NULL) {
2017 		NG_FREE_ITEM(item);
2018 		return (EHOSTDOWN);
2019 	}
2020 
2021 	NGI_GET_MSG(item, msg);
2022 
2023 	switch (msg->header.typecookie) {
2024 	case NGM_GENERIC_COOKIE:
2025 		switch (msg->header.cmd) {
2026 		case NGM_TEXT_STATUS:
2027 			NG_MKRESPONSE(rsp, msg, NG_TEXTRESPONSE, M_NOWAIT);
2028 			if (rsp == NULL)
2029 				error = ENOMEM;
2030 			else
2031 				snprintf(rsp->data, NG_TEXTRESPONSE,
2032 					"Hook: %s\n"   \
2033 					"Flags: %#x\n" \
2034 					"Debug: %d\n"  \
2035 					"CMD queue: [have:%d,max:%d]\n" \
2036 					"ACL queue: [have:%d,max:%d]\n" \
2037 					"SCO queue: [have:%d,max:%d]",
2038 					(sc->sc_hook != NULL)? NG_UBT_HOOK : "",
2039 					sc->sc_flags,
2040 					sc->sc_debug,
2041 					NG_BT_MBUFQ_LEN(&sc->sc_cmdq),
2042 					sc->sc_cmdq.maxlen,
2043 					NG_BT_MBUFQ_LEN(&sc->sc_aclq),
2044 					sc->sc_aclq.maxlen,
2045 					NG_BT_MBUFQ_LEN(&sc->sc_scoq),
2046 					sc->sc_scoq.maxlen);
2047 			break;
2048 
2049 		default:
2050 			error = EINVAL;
2051 			break;
2052 		}
2053 		break;
2054 
2055 	case NGM_UBT_COOKIE:
2056 		switch (msg->header.cmd) {
2057 		case NGM_UBT_NODE_SET_DEBUG:
2058 			if (msg->header.arglen != sizeof(ng_ubt_node_debug_ep))
2059 				error = EMSGSIZE;
2060 			else
2061 				sc->sc_debug =
2062 					*((ng_ubt_node_debug_ep *)(msg->data));
2063 			break;
2064 
2065 		case NGM_UBT_NODE_GET_DEBUG:
2066 			NG_MKRESPONSE(rsp, msg, sizeof(ng_ubt_node_debug_ep),
2067 				M_NOWAIT);
2068 			if (rsp == NULL)
2069 				error = ENOMEM;
2070 			else
2071 				*((ng_ubt_node_debug_ep *)(rsp->data)) =
2072 					sc->sc_debug;
2073                         break;
2074 
2075 		case NGM_UBT_NODE_SET_QLEN:
2076 			if (msg->header.arglen != sizeof(ng_ubt_node_qlen_ep))
2077 				error = EMSGSIZE;
2078 			else {
2079 				queue = ((ng_ubt_node_qlen_ep *)
2080 						(msg->data))->queue;
2081 				qlen = ((ng_ubt_node_qlen_ep *)
2082 						(msg->data))->qlen;
2083 
2084 				if (qlen <= 0) {
2085 					error = EINVAL;
2086 					break;
2087 				}
2088 
2089 				switch (queue) {
2090 				case NGM_UBT_NODE_QUEUE_CMD:
2091 					q = &sc->sc_cmdq;
2092 					break;
2093 
2094 				case NGM_UBT_NODE_QUEUE_ACL:
2095 					q = &sc->sc_aclq;
2096 					break;
2097 
2098 				case NGM_UBT_NODE_QUEUE_SCO:
2099 					q = &sc->sc_scoq;
2100 					break;
2101 
2102 				default:
2103 					q = NULL;
2104 					error = EINVAL;
2105 					break;
2106 				}
2107 
2108 				if (q != NULL)
2109 					q->maxlen = qlen;
2110 			}
2111 			break;
2112 
2113 		case NGM_UBT_NODE_GET_QLEN:
2114 			if (msg->header.arglen != sizeof(ng_ubt_node_qlen_ep)) {
2115 				error = EMSGSIZE;
2116 				break;
2117 			}
2118 
2119 			queue = ((ng_ubt_node_qlen_ep *)(msg->data))->queue;
2120 			switch (queue) {
2121 			case NGM_UBT_NODE_QUEUE_CMD:
2122 				q = &sc->sc_cmdq;
2123 				break;
2124 
2125 			case NGM_UBT_NODE_QUEUE_ACL:
2126 				q = &sc->sc_aclq;
2127 				break;
2128 
2129 			case NGM_UBT_NODE_QUEUE_SCO:
2130 				q = &sc->sc_scoq;
2131 				break;
2132 
2133 			default:
2134 				q = NULL;
2135 				error = EINVAL;
2136 				break;
2137 			}
2138 
2139 			if (q != NULL) {
2140 				NG_MKRESPONSE(rsp, msg,
2141 					sizeof(ng_ubt_node_qlen_ep), M_NOWAIT);
2142 				if (rsp == NULL) {
2143 					error = ENOMEM;
2144 					break;
2145 				}
2146 
2147 				((ng_ubt_node_qlen_ep *)(rsp->data))->queue =
2148 					queue;
2149 				((ng_ubt_node_qlen_ep *)(rsp->data))->qlen =
2150 					q->maxlen;
2151 			}
2152 			break;
2153 
2154 		case NGM_UBT_NODE_GET_STAT:
2155 			NG_MKRESPONSE(rsp, msg, sizeof(ng_ubt_node_stat_ep),
2156 				M_NOWAIT);
2157 			if (rsp == NULL)
2158 				error = ENOMEM;
2159 			else
2160 				bcopy(&sc->sc_stat, rsp->data,
2161 					sizeof(ng_ubt_node_stat_ep));
2162 			break;
2163 
2164 		case NGM_UBT_NODE_RESET_STAT:
2165 			NG_UBT_STAT_RESET(sc->sc_stat);
2166 			break;
2167 
2168 		case NGM_UBT_NODE_DEV_NODES:
2169 			if (msg->header.arglen !=
2170 					sizeof(ng_ubt_node_dev_nodes_ep)) {
2171 				error = EMSGSIZE;
2172 				break;
2173 			}
2174 
2175 			if ((sc->sc_flags & UBT_ANY_DEV) ||
2176 			    sc->sc_hook != NULL) {
2177 				error = EBUSY;
2178 				break;
2179 			}
2180 
2181 			if (*((ng_ubt_node_dev_nodes_ep *)(msg->data)))
2182 				ubt_create_device_nodes(sc);
2183 			else
2184 				ubt_destroy_device_nodes(sc);
2185 			break;
2186 
2187 		default:
2188 			error = EINVAL;
2189 			break;
2190 		}
2191 		break;
2192 
2193 	default:
2194 		error = EINVAL;
2195 		break;
2196 	}
2197 
2198 	NG_RESPOND_MSG(error, node, item, rsp);
2199 	NG_FREE_MSG(msg);
2200 
2201 	return (error);
2202 } /* ng_ubt_rcvmsg */
2203 
2204 /*
2205  * Process data
2206  */
2207 
2208 Static int
2209 ng_ubt_rcvdata(hook_p hook, item_p item)
2210 {
2211 	ubt_softc_p		 sc = (ubt_softc_p) NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
2212 	struct mbuf		*m = NULL;
2213 	usbd_status		(*f)(ubt_softc_p) = NULL;
2214 	struct ng_bt_mbufq	*q = NULL;
2215 	int			 b, error = 0;
2216 
2217 	if (sc == NULL) {
2218 		error = EHOSTDOWN;
2219 		goto done;
2220 	}
2221 
2222 	if (hook != sc->sc_hook) {
2223 		error = EINVAL;
2224 		goto done;
2225 	}
2226 
2227 	/* Deatch mbuf and get HCI frame type */
2228 	NGI_GET_M(item, m);
2229 
2230 	/* Process HCI frame */
2231 	switch (*mtod(m, u_int8_t *)) { /* XXX call m_pullup ? */
2232 	case NG_HCI_CMD_PKT:
2233 		f = ubt_request_start;
2234 		q = &sc->sc_cmdq;
2235 		b = UBT_CMD_XMIT;
2236 		break;
2237 
2238 	case NG_HCI_ACL_DATA_PKT:
2239 		f = ubt_bulk_out_start;
2240 		q = &sc->sc_aclq;
2241 		b = UBT_ACL_XMIT;
2242 		break;
2243 
2244 #if __broken__ /* XXX FIXME */
2245 	case NG_HCI_SCO_DATA_PKT:
2246 		f = ubt_isoc_out_start;
2247 		q = &sc->sc_scoq;
2248 		b = UBT_SCO_XMIT;
2249 		break;
2250 #endif /* __broken__ */
2251 
2252 	default:
2253 		NG_UBT_ERR(
2254 "%s: %s - Dropping unknown/unsupported HCI frame, type=%d, pktlen=%d\n",
2255 			__func__, USBDEVNAME(sc->sc_dev), *mtod(m, u_int8_t *),
2256 			m->m_pkthdr.len);
2257 
2258 		NG_FREE_M(m);
2259 		error = EINVAL;
2260 
2261 		goto done;
2262 		/* NOT REACHED */
2263 	}
2264 
2265 	/* Loose frame type, if required */
2266 	if (!(sc->sc_flags & UBT_NEED_FRAME_TYPE))
2267 		m_adj(m, sizeof(u_int8_t));
2268 
2269 	if (NG_BT_MBUFQ_FULL(q)) {
2270 		NG_UBT_ERR(
2271 "%s: %s - Dropping HCI frame %#x, len=%d. Queue full\n",
2272 			__func__, USBDEVNAME(sc->sc_dev),
2273 			*mtod(m, u_int8_t *), m->m_pkthdr.len);
2274 
2275 		NG_FREE_M(m);
2276 	} else
2277 		NG_BT_MBUFQ_ENQUEUE(q, m);
2278 
2279 	if (!(sc->sc_flags & b))
2280 		if ((*f)(sc) != USBD_NORMAL_COMPLETION)
2281 			error = EIO;
2282 done:
2283 	NG_FREE_ITEM(item);
2284 
2285 	return (error);
2286 } /* ng_ubt_rcvdata */
2287 
2288 /****************************************************************************
2289  ****************************************************************************
2290  **                              Device specific
2291  ****************************************************************************
2292  ****************************************************************************/
2293 
2294 /*
2295  * Open endpoint device
2296  * XXX FIXME softc locking
2297  */
2298 
2299 Static int
2300 ubt_open(dev_t dev, int flag, int mode, usb_proc_ptr p)
2301 {
2302 	ubt_softc_p	sc = NULL;
2303 	int		ep = UBT_ENDPOINT(dev);
2304 
2305 	USB_GET_SC_OPEN(ubt, UBT_UNIT(dev), sc); /* check for sc != NULL */
2306 	if (sc->sc_dying)
2307 		return (ENXIO);
2308 
2309 	if (ep == USB_CONTROL_ENDPOINT) {
2310 		if (sc->sc_flags & UBT_CTRL_DEV)
2311 			return (EBUSY);
2312 
2313 		sc->sc_flags |= UBT_CTRL_DEV;
2314 	} else if (ep == UE_GET_ADDR(sc->sc_intr_ep)) {
2315 		if (sc->sc_flags & UBT_INTR_DEV)
2316 			return (EBUSY);
2317 		if (sc->sc_intr_pipe == NULL)
2318 			return (ENXIO);
2319 
2320 		sc->sc_flags |= UBT_INTR_DEV;
2321 	} else if (ep == UE_GET_ADDR(sc->sc_bulk_in_ep)) {
2322 		if (sc->sc_flags & UBT_BULK_DEV)
2323 			return (EBUSY);
2324 		if (sc->sc_bulk_in_pipe == NULL || sc->sc_bulk_out_pipe == NULL)
2325 			return (ENXIO);
2326 
2327 		sc->sc_flags |= UBT_BULK_DEV;
2328 	} else
2329 		return (EINVAL);
2330 
2331 	return (0);
2332 } /* ubt_open */
2333 
2334 /*
2335  * Close endpoint device
2336  * XXX FIXME softc locking
2337  */
2338 
2339 Static int
2340 ubt_close(dev_t dev, int flag, int mode, usb_proc_ptr p)
2341 {
2342 	ubt_softc_p	sc = NULL;
2343 	int		ep = UBT_ENDPOINT(dev);
2344 
2345 	USB_GET_SC(ubt, UBT_UNIT(dev), sc);
2346 	if (sc == NULL)
2347 		return (ENXIO);
2348 
2349 	if (ep == USB_CONTROL_ENDPOINT)
2350 		sc->sc_flags &= ~UBT_CTRL_DEV;
2351 	else if (ep == UE_GET_ADDR(sc->sc_intr_ep)) {
2352 		if (sc->sc_intr_pipe != NULL)
2353 			usbd_abort_pipe(sc->sc_intr_pipe);
2354 
2355 		sc->sc_flags &= ~UBT_INTR_DEV;
2356 	} else if (ep == UE_GET_ADDR(sc->sc_bulk_in_ep)) {
2357 		/* Close both in and out bulk pipes */
2358 		if (sc->sc_bulk_in_pipe != NULL)
2359 			usbd_abort_pipe(sc->sc_bulk_in_pipe);
2360 
2361 		if (sc->sc_bulk_out_pipe != NULL)
2362 			usbd_abort_pipe(sc->sc_bulk_out_pipe);
2363 
2364 		sc->sc_flags &= ~UBT_BULK_DEV;
2365 	} else
2366 		return (EINVAL);
2367 
2368 	return (0);
2369 } /* ubt_close */
2370 
2371 /*
2372  * Read from the endpoint device
2373  * XXX FIXME softc locking
2374  */
2375 
2376 Static int
2377 ubt_read(dev_t dev, struct uio *uio, int flag)
2378 {
2379 	ubt_softc_p		sc = NULL;
2380 	int			error = 0, n, tn, ep = UBT_ENDPOINT(dev);
2381 	usbd_status		status;
2382 	usbd_pipe_handle	pipe = NULL;
2383 	usbd_xfer_handle	xfer = NULL;
2384 	u_int8_t		buf[UBT_BSIZE];
2385 
2386 	USB_GET_SC(ubt, UBT_UNIT(dev), sc);
2387 	if (sc == NULL || sc->sc_dying)
2388 		return (ENXIO);
2389 
2390 	if (ep == USB_CONTROL_ENDPOINT)
2391 		return (EOPNOTSUPP);
2392 
2393 	if (ep == UE_GET_ADDR(sc->sc_intr_ep)) {
2394 		pipe = sc->sc_intr_pipe;
2395 		xfer = sc->sc_intr_xfer;
2396 	} else if (ep == UE_GET_ADDR(sc->sc_bulk_in_ep)) {
2397 		pipe = sc->sc_bulk_in_pipe;
2398 		xfer = sc->sc_bulk_in_xfer;
2399 	} else
2400 		return (EINVAL);
2401 
2402 	if (pipe == NULL || xfer == NULL)
2403 		return (ENXIO);
2404 
2405 	sc->sc_refcnt ++;
2406 
2407 	while ((n = min(sizeof(buf), uio->uio_resid)) != 0) {
2408 		tn = n;
2409 		status = usbd_bulk_transfer(xfer, pipe, USBD_SHORT_XFER_OK,
2410 				USBD_DEFAULT_TIMEOUT, buf, &tn, "ubtrd");
2411 		switch (status) {
2412 		case USBD_NORMAL_COMPLETION:
2413 			error = uiomove(buf, tn, uio);
2414 			break;
2415 
2416 		case USBD_INTERRUPTED:
2417 			error = EINTR;
2418 			break;
2419 
2420 		case USBD_TIMEOUT:
2421 			error = ETIMEDOUT;
2422 			break;
2423 
2424 		default:
2425 			error = EIO;
2426 			break;
2427 		}
2428 
2429 		if (error != 0 || tn < n)
2430 			break;
2431 	}
2432 
2433 	if (-- sc->sc_refcnt < 0)
2434 		usb_detach_wakeup(USBDEV(sc->sc_dev));
2435 
2436 	return (error);
2437 } /* ubt_read */
2438 
2439 /*
2440  * Write into the endpoint device
2441  * XXX FIXME softc locking
2442  */
2443 
2444 Static int
2445 ubt_write(dev_t dev, struct uio *uio, int flag)
2446 {
2447 	ubt_softc_p	sc = NULL;
2448 	int		error = 0, n, ep = UBT_ENDPOINT(dev);
2449 	usbd_status	status;
2450 	u_int8_t	buf[UBT_BSIZE];
2451 
2452 	USB_GET_SC(ubt, UBT_UNIT(dev), sc);
2453 	if (sc == NULL || sc->sc_dying)
2454 		return (ENXIO);
2455 
2456 	if (ep == USB_CONTROL_ENDPOINT || ep == UE_GET_ADDR(sc->sc_intr_ep))
2457 		return (EOPNOTSUPP);
2458 	if (ep != UE_GET_ADDR(sc->sc_bulk_in_ep))
2459 		return (EINVAL);
2460 
2461 	sc->sc_refcnt ++;
2462 
2463 	while ((n = min(sizeof(buf), uio->uio_resid)) != 0) {
2464 		error = uiomove(buf, n, uio);
2465 		if (error != 0)
2466 			break;
2467 
2468 		status = usbd_bulk_transfer(sc->sc_bulk_out_xfer,
2469 				sc->sc_bulk_out_pipe, 0, USBD_DEFAULT_TIMEOUT,
2470 				buf, &n,"ubtwr");
2471 		switch (status) {
2472 		case USBD_NORMAL_COMPLETION:
2473 			break;
2474 
2475 		case USBD_INTERRUPTED:
2476 			error = EINTR;
2477 			break;
2478 
2479 		case USBD_TIMEOUT:
2480 			error = ETIMEDOUT;
2481 			break;
2482 
2483 		default:
2484 			error = EIO;
2485 			break;
2486 		}
2487 
2488 		if (error != 0)
2489 			break;
2490 	}
2491 
2492 	if (-- sc->sc_refcnt < 0)
2493 		usb_detach_wakeup(USBDEV(sc->sc_dev));
2494 
2495 	return (error);
2496 } /* ubt_write */
2497 
2498 /*
2499  * Process ioctl on the endpoint device. Mostly stolen from ugen(4)
2500  * XXX FIXME softc locking
2501  */
2502 
2503 Static int
2504 ubt_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
2505 {
2506 	ubt_softc_p		 sc = NULL;
2507 	int			 len, error = 0, ep = UBT_ENDPOINT(dev);
2508 	usbd_status		 status;
2509 	struct usb_string_desc	*si = NULL;
2510 	struct usb_ctl_request	*ur = NULL;
2511 	void			*ptr = NULL;
2512 	struct iovec		 iov;
2513 	struct uio		 uio;
2514 
2515 	USB_GET_SC(ubt, UBT_UNIT(dev), sc);
2516 	if (sc == NULL || sc->sc_dying)
2517 		return (ENXIO);
2518 
2519 	if (ep != USB_CONTROL_ENDPOINT)
2520 		return (EOPNOTSUPP);
2521 
2522 	sc->sc_refcnt ++;
2523 
2524 	switch (cmd) {
2525 	case USB_GET_DEVICE_DESC:
2526 		*(usb_device_descriptor_t *) data =
2527 				*usbd_get_device_descriptor(sc->sc_udev);
2528 		break;
2529 
2530 	case USB_GET_STRING_DESC:
2531 		si = (struct usb_string_desc *) data;
2532 		status = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
2533 				si->usd_language_id, &si->usd_desc);
2534 		if (status != USBD_NORMAL_COMPLETION)
2535 			error = EINVAL;
2536 		break;
2537 
2538 	case USB_DO_REQUEST:
2539 		ur = (void *) data;
2540 		len = UGETW(ur->ucr_request.wLength);
2541 
2542 		if (!(flag & FWRITE)) {
2543 			error = EPERM;
2544 			break;
2545 		}
2546 
2547 		/* Avoid requests that would damage the bus integrity. */
2548 		if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
2549 		     ur->ucr_request.bRequest == UR_SET_ADDRESS) ||
2550 		    (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
2551 		     ur->ucr_request.bRequest == UR_SET_CONFIG) ||
2552 		    (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE &&
2553 		     ur->ucr_request.bRequest == UR_SET_INTERFACE) ||
2554 		    len < 0 || len > 32767) {
2555 			error = EINVAL;
2556 			break;
2557 		}
2558 
2559 		if (len != 0) {
2560 			iov.iov_base = (caddr_t) ur->ucr_data;
2561 			iov.iov_len = len;
2562 
2563 			uio.uio_iov = &iov;
2564 			uio.uio_iovcnt = 1;
2565 			uio.uio_resid = len;
2566 			uio.uio_offset = 0;
2567 			uio.uio_segflg = UIO_USERSPACE;
2568 			uio.uio_rw = ur->ucr_request.bmRequestType & UT_READ ?
2569 						UIO_READ : UIO_WRITE;
2570 			uio.uio_procp = p;
2571 
2572 			ptr = malloc(len, M_TEMP, M_WAITOK);
2573 			if (uio.uio_rw == UIO_WRITE) {
2574 				error = uiomove(ptr, len, &uio);
2575 				if (error != 0)
2576 					goto ret;
2577 			}
2578 		}
2579 
2580 		status = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request,
2581 				ptr, ur->ucr_flags, &ur->ucr_actlen,
2582 				USBD_DEFAULT_TIMEOUT);
2583 		if (status != USBD_NORMAL_COMPLETION) {
2584 			error = EIO;
2585 			goto ret;
2586 		}
2587 
2588 		if (len != 0) {
2589 			if (uio.uio_rw == UIO_READ) {
2590 				error = uiomove(ptr, len, &uio);
2591 				if (error != 0)
2592 					goto ret;
2593 			}
2594 		}
2595 ret:
2596 		if (ptr != NULL)
2597 			free(ptr, M_TEMP);
2598 		break;
2599 
2600 	case USB_GET_DEVICEINFO:
2601 		usbd_fill_deviceinfo(sc->sc_udev,
2602 			(struct usb_device_info *) data, 1);
2603 		break;
2604 
2605 	default:
2606 		error = EINVAL;
2607 		break;
2608 	}
2609 
2610 	if (-- sc->sc_refcnt < 0)
2611 		usb_detach_wakeup(USBDEV(sc->sc_dev));
2612 
2613 	return (error);
2614 } /* ubt_ioctl */
2615 
2616 /*
2617  * Poll the endpoint device
2618  * XXX FIXME softc locking
2619  */
2620 
2621 Static int
2622 ubt_poll(dev_t dev, int events, usb_proc_ptr p)
2623 {
2624 	ubt_softc_p	sc = NULL;
2625 	int		revents = 0, ep = UBT_ENDPOINT(dev);
2626 
2627 	USB_GET_SC(ubt, UBT_UNIT(dev), sc);
2628 	if (sc == NULL || sc->sc_dying)
2629 		return (ENXIO);
2630 
2631 	if (ep == USB_CONTROL_ENDPOINT)
2632 		return (EOPNOTSUPP);
2633 
2634 	if (ep == UE_GET_ADDR(sc->sc_intr_ep)) {
2635 		if (sc->sc_intr_pipe != NULL)
2636 			revents |= events & (POLLIN | POLLRDNORM);
2637 		else
2638 			revents = EIO;
2639 	} else if (ep == UE_GET_ADDR(sc->sc_bulk_in_ep)) {
2640 		if (sc->sc_bulk_in_pipe != NULL)
2641 			revents |= events & (POLLIN | POLLRDNORM);
2642 
2643 		if (sc->sc_bulk_out_pipe != NULL)
2644 			revents |= events & (POLLOUT | POLLWRNORM);
2645 
2646 		if (revents == 0)
2647 			revents = EIO; /* both pipes closed */
2648 	} else
2649 		revents = EINVAL;
2650 
2651 	return (revents);
2652 } /* ubt_poll */
2653 
2654 /*
2655  * Create device nodes for all endpoints. Must be called with node locked.
2656  */
2657 
2658 Static void
2659 ubt_create_device_nodes(ubt_softc_p sc)
2660 {
2661 	int	ep;
2662 
2663 	KASSERT((sc->sc_hook == NULL), (
2664 "%s: %s - hook != NULL!\n", __func__, USBDEVNAME(sc->sc_dev)));
2665 
2666 	/* Control device */
2667 	if (sc->sc_ctrl_dev == NODEV)
2668 		sc->sc_ctrl_dev = make_dev(&ubt_cdevsw,
2669 					UBT_MINOR(USBDEVUNIT(sc->sc_dev), 0),
2670 					UID_ROOT, GID_OPERATOR, 0644,
2671 					"%s", USBDEVNAME(sc->sc_dev));
2672 
2673 	/* Interrupt device */
2674 	if (sc->sc_intr_dev == NODEV && sc->sc_intr_ep != -1) {
2675 		ep = UE_GET_ADDR(sc->sc_intr_ep);
2676 		sc->sc_intr_dev = make_dev(&ubt_cdevsw,
2677 					UBT_MINOR(USBDEVUNIT(sc->sc_dev), ep),
2678 					UID_ROOT, GID_OPERATOR, 0644,
2679 					"%s.%d", USBDEVNAME(sc->sc_dev), ep);
2680 	}
2681 
2682 	/*
2683 	 * Bulk-in and bulk-out device
2684 	 * XXX will create one device for both in and out endpoints.
2685 	 * XXX note that address of the in and out endpoint should be the same
2686 	 */
2687 
2688 	if (sc->sc_bulk_dev == NODEV &&
2689 	    sc->sc_bulk_in_ep != -1 && sc->sc_bulk_out_ep != -1 &&
2690 	    UE_GET_ADDR(sc->sc_bulk_in_ep) == UE_GET_ADDR(sc->sc_bulk_out_ep)) {
2691 		ep = UE_GET_ADDR(sc->sc_bulk_in_ep);
2692 		sc->sc_bulk_dev = make_dev(&ubt_cdevsw,
2693 					UBT_MINOR(USBDEVUNIT(sc->sc_dev), ep),
2694 					UID_ROOT, GID_OPERATOR, 0644,
2695 					"%s.%d", USBDEVNAME(sc->sc_dev), ep);
2696 	}
2697 } /* ubt_create_device_nodes */
2698 
2699 /*
2700  * Destroy device nodes for all endpoints
2701  * XXX FIXME locking
2702  */
2703 
2704 Static void
2705 ubt_destroy_device_nodes(ubt_softc_p sc)
2706 {
2707 	struct vnode	*vp = NULL;
2708 
2709 	/*
2710 	 * Wait for processes to go away. This should be safe as we will not
2711 	 * call ubt_destroy_device_nodes() from Netgraph unless all devices
2712 	 * were closed (and thus no active processes).
2713 	 */
2714 
2715 	if (-- sc->sc_refcnt >= 0) {
2716 		ubt_reset(sc);
2717 		usb_detach_wait(USBDEV(sc->sc_dev));
2718 	}
2719 
2720 	sc->sc_refcnt = 0;
2721 
2722 	/* Destroy device nodes */
2723 	if (sc->sc_bulk_dev != NODEV) {
2724 		vp = SLIST_FIRST(&sc->sc_bulk_dev->si_hlist);
2725 		if (vp != NULL)
2726 			VOP_REVOKE(vp, REVOKEALL);
2727 
2728 		destroy_dev(sc->sc_bulk_dev);
2729 		sc->sc_bulk_dev = NODEV;
2730 	}
2731 
2732 	if (sc->sc_intr_dev != NODEV) {
2733 		vp = SLIST_FIRST(&sc->sc_intr_dev->si_hlist);
2734 		if (vp != NULL)
2735 			VOP_REVOKE(vp, REVOKEALL);
2736 
2737 		destroy_dev(sc->sc_intr_dev);
2738 		sc->sc_intr_dev = NODEV;
2739 	}
2740 
2741 	if (sc->sc_ctrl_dev != NODEV) {
2742 		vp = SLIST_FIRST(&sc->sc_ctrl_dev->si_hlist);
2743 		if (vp != NULL)
2744 			VOP_REVOKE(vp, REVOKEALL);
2745 
2746 		destroy_dev(sc->sc_ctrl_dev);
2747 		sc->sc_ctrl_dev = NODEV;
2748 	}
2749 } /* ubt_destroy_device_nodes */
2750 
2751