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