ubt.c revision 1.28 1 /* $NetBSD: ubt.c,v 1.28 2007/11/11 12:59:06 plunky Exp $ */
2
3 /*-
4 * Copyright (c) 2006 Itronix Inc.
5 * All rights reserved.
6 *
7 * Written by Iain Hibbert for Itronix Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of Itronix Inc. may not be used to endorse
18 * or promote products derived from this software without specific
19 * prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33 /*
34 * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
35 * All rights reserved.
36 *
37 * This code is derived from software contributed to The NetBSD Foundation
38 * by Lennart Augustsson (lennart (at) augustsson.net) and
39 * David Sainty (David.Sainty (at) dtsp.co.nz).
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. All advertising materials mentioning features or use of this software
50 * must display the following acknowledgement:
51 * This product includes software developed by the NetBSD
52 * Foundation, Inc. and its contributors.
53 * 4. Neither the name of The NetBSD Foundation nor the names of its
54 * contributors may be used to endorse or promote products derived
55 * from this software without specific prior written permission.
56 *
57 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
58 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
59 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
60 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
61 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
62 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
63 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
64 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
65 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
66 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
67 * POSSIBILITY OF SUCH DAMAGE.
68 */
69 /*
70 * This driver originally written by Lennart Augustsson and David Sainty,
71 * but was mostly rewritten for the NetBSD Bluetooth protocol stack by
72 * Iain Hibbert for Itronix, Inc using the FreeBSD ng_ubt.c driver as a
73 * reference.
74 */
75
76 #include <sys/cdefs.h>
77 __KERNEL_RCSID(0, "$NetBSD: ubt.c,v 1.28 2007/11/11 12:59:06 plunky Exp $");
78
79 #include <sys/param.h>
80 #include <sys/device.h>
81 #include <sys/ioctl.h>
82 #include <sys/kernel.h>
83 #include <sys/malloc.h>
84 #include <sys/mbuf.h>
85 #include <sys/proc.h>
86 #include <sys/sysctl.h>
87 #include <sys/systm.h>
88
89 #include <dev/usb/usb.h>
90 #include <dev/usb/usbdi.h>
91 #include <dev/usb/usbdi_util.h>
92 #include <dev/usb/usbdevs.h>
93
94 #include <netbt/bluetooth.h>
95 #include <netbt/hci.h>
96
97 /*******************************************************************************
98 *
99 * debugging stuff
100 */
101 #undef DPRINTF
102 #undef DPRINTFN
103
104 #ifdef UBT_DEBUG
105 int ubt_debug = 0;
106
107 #define DPRINTF(fmt, args...) do { \
108 if (ubt_debug) \
109 printf("%s: "fmt, __func__ , ##args); \
110 } while (/* CONSTCOND */0)
111
112 #define DPRINTFN(n, fmt, args...) do { \
113 if (ubt_debug > (n)) \
114 printf("%s: "fmt, __func__ , ##args); \
115 } while (/* CONSTCOND */0)
116
117 SYSCTL_SETUP(sysctl_hw_ubt_debug_setup, "sysctl hw.ubt_debug setup")
118 {
119
120 sysctl_createv(NULL, 0, NULL, NULL,
121 CTLFLAG_PERMANENT,
122 CTLTYPE_NODE, "hw",
123 NULL,
124 NULL, 0,
125 NULL, 0,
126 CTL_HW, CTL_EOL);
127
128 sysctl_createv(NULL, 0, NULL, NULL,
129 CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
130 CTLTYPE_INT, "ubt_debug",
131 SYSCTL_DESCR("ubt debug level"),
132 NULL, 0,
133 &ubt_debug, sizeof(ubt_debug),
134 CTL_HW, CTL_CREATE, CTL_EOL);
135 }
136 #else
137 #define DPRINTF(...)
138 #define DPRINTFN(...)
139 #endif
140
141 /*******************************************************************************
142 *
143 * ubt softc structure
144 *
145 */
146
147 /* buffer sizes */
148 /*
149 * NB: although ACL packets can extend to 65535 bytes, most devices
150 * have max_acl_size at much less (largest I have seen is 384)
151 */
152 #define UBT_BUFSIZ_CMD (HCI_CMD_PKT_SIZE - 1)
153 #define UBT_BUFSIZ_ACL (2048 - 1)
154 #define UBT_BUFSIZ_EVENT (HCI_EVENT_PKT_SIZE - 1)
155
156 /* Transmit timeouts */
157 #define UBT_CMD_TIMEOUT USBD_DEFAULT_TIMEOUT
158 #define UBT_ACL_TIMEOUT USBD_DEFAULT_TIMEOUT
159
160 /*
161 * ISOC transfers
162 *
163 * xfer buffer size depends on the frame size, and the number
164 * of frames per transfer is fixed, as each frame should be
165 * 1ms worth of data. This keeps the rate that xfers complete
166 * fairly constant. We use multiple xfers to keep the hardware
167 * busy
168 */
169 #define UBT_NXFERS 3 /* max xfers to queue */
170 #define UBT_NFRAMES 10 /* frames per xfer */
171
172 struct ubt_isoc_xfer {
173 struct ubt_softc *softc;
174 usbd_xfer_handle xfer;
175 uint8_t *buf;
176 uint16_t size[UBT_NFRAMES];
177 int busy;
178 };
179
180 struct ubt_softc {
181 USBBASEDEVICE sc_dev;
182 usbd_device_handle sc_udev;
183 int sc_refcnt;
184 int sc_dying;
185
186 /* Control Interface */
187 usbd_interface_handle sc_iface0;
188
189 /* Commands (control) */
190 usbd_xfer_handle sc_cmd_xfer;
191 uint8_t *sc_cmd_buf;
192
193 /* Events (interrupt) */
194 int sc_evt_addr; /* endpoint address */
195 usbd_pipe_handle sc_evt_pipe;
196 uint8_t *sc_evt_buf;
197
198 /* ACL data (in) */
199 int sc_aclrd_addr; /* endpoint address */
200 usbd_pipe_handle sc_aclrd_pipe; /* read pipe */
201 usbd_xfer_handle sc_aclrd_xfer; /* read xfer */
202 uint8_t *sc_aclrd_buf; /* read buffer */
203 int sc_aclrd_busy; /* reading */
204
205 /* ACL data (out) */
206 int sc_aclwr_addr; /* endpoint address */
207 usbd_pipe_handle sc_aclwr_pipe; /* write pipe */
208 usbd_xfer_handle sc_aclwr_xfer; /* write xfer */
209 uint8_t *sc_aclwr_buf; /* write buffer */
210
211 /* ISOC interface */
212 usbd_interface_handle sc_iface1; /* ISOC interface */
213 struct sysctllog *sc_log; /* sysctl log */
214 int sc_config; /* current config no */
215 int sc_alt_config; /* no of alternates */
216
217 /* SCO data (in) */
218 int sc_scord_addr; /* endpoint address */
219 usbd_pipe_handle sc_scord_pipe; /* read pipe */
220 int sc_scord_size; /* frame length */
221 struct ubt_isoc_xfer sc_scord[UBT_NXFERS];
222 struct mbuf *sc_scord_mbuf; /* current packet */
223
224 /* SCO data (out) */
225 int sc_scowr_addr; /* endpoint address */
226 usbd_pipe_handle sc_scowr_pipe; /* write pipe */
227 int sc_scowr_size; /* frame length */
228 struct ubt_isoc_xfer sc_scowr[UBT_NXFERS];
229 struct mbuf *sc_scowr_mbuf; /* current packet */
230
231 /* Protocol structure */
232 struct hci_unit sc_unit;
233
234 /* Successfully attached */
235 int sc_ok;
236 };
237
238 /*******************************************************************************
239 *
240 * Bluetooth unit/USB callback routines
241 *
242 */
243 static int ubt_enable(device_ptr_t);
244 static void ubt_disable(device_ptr_t);
245
246 static void ubt_xmit_cmd_start(device_ptr_t);
247 static void ubt_xmit_cmd_complete(usbd_xfer_handle,
248 usbd_private_handle, usbd_status);
249
250 static void ubt_xmit_acl_start(device_ptr_t);
251 static void ubt_xmit_acl_complete(usbd_xfer_handle,
252 usbd_private_handle, usbd_status);
253
254 static void ubt_xmit_sco_start(device_ptr_t);
255 static void ubt_xmit_sco_start1(struct ubt_softc *, struct ubt_isoc_xfer *);
256 static void ubt_xmit_sco_complete(usbd_xfer_handle,
257 usbd_private_handle, usbd_status);
258
259 static void ubt_recv_event(usbd_xfer_handle,
260 usbd_private_handle, usbd_status);
261
262 static void ubt_recv_acl_start(struct ubt_softc *);
263 static void ubt_recv_acl_complete(usbd_xfer_handle,
264 usbd_private_handle, usbd_status);
265
266 static void ubt_recv_sco_start1(struct ubt_softc *, struct ubt_isoc_xfer *);
267 static void ubt_recv_sco_complete(usbd_xfer_handle,
268 usbd_private_handle, usbd_status);
269
270
271 /*******************************************************************************
272 *
273 * USB Autoconfig stuff
274 *
275 */
276
277 USB_DECLARE_DRIVER(ubt);
278
279 static int ubt_set_isoc_config(struct ubt_softc *);
280 static int ubt_sysctl_config(SYSCTLFN_PROTO);
281 static void ubt_abortdealloc(struct ubt_softc *);
282
283 /*
284 * Match against the whole device, since we want to take
285 * both interfaces. If a device should be ignored then add
286 *
287 * { VendorID, ProductID }
288 *
289 * to the ubt_ignore list.
290 */
291 static const struct usb_devno ubt_ignore[] = {
292 { USB_VENDOR_BROADCOM, USB_PRODUCT_BROADCOM_BCM2033NF },
293 { 0, 0 } /* end of list */
294 };
295
296 USB_MATCH(ubt)
297 {
298 USB_MATCH_START(ubt, uaa);
299
300 DPRINTFN(50, "ubt_match\n");
301
302 if (usb_lookup(ubt_ignore, uaa->vendor, uaa->product))
303 return UMATCH_NONE;
304
305 if (uaa->class == UDCLASS_WIRELESS
306 && uaa->subclass == UDSUBCLASS_RF
307 && uaa->proto == UDPROTO_BLUETOOTH)
308 return UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO;
309
310 return UMATCH_NONE;
311 }
312
313 USB_ATTACH(ubt)
314 {
315 USB_ATTACH_START(ubt, sc, uaa);
316 usb_config_descriptor_t *cd;
317 usb_endpoint_descriptor_t *ed;
318 const struct sysctlnode *node;
319 char *devinfop;
320 int err;
321 uint8_t count, i;
322
323 DPRINTFN(50, "ubt_attach: sc=%p\n", sc);
324
325 sc->sc_udev = uaa->device;
326
327 devinfop = usbd_devinfo_alloc(sc->sc_udev, 0);
328 USB_ATTACH_SETUP;
329 aprint_normal("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfop);
330 usbd_devinfo_free(devinfop);
331
332 /*
333 * Move the device into the configured state
334 */
335 err = usbd_set_config_index(sc->sc_udev, 0, 1);
336 if (err) {
337 aprint_error("%s: failed to set configuration idx 0: %s\n",
338 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
339
340 USB_ATTACH_ERROR_RETURN;
341 }
342
343 /*
344 * Interface 0 must have 3 endpoints
345 * 1) Interrupt endpoint to receive HCI events
346 * 2) Bulk IN endpoint to receive ACL data
347 * 3) Bulk OUT endpoint to send ACL data
348 */
349 err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface0);
350 if (err) {
351 aprint_error("%s: Could not get interface 0 handle %s (%d)\n",
352 USBDEVNAME(sc->sc_dev), usbd_errstr(err), err);
353
354 USB_ATTACH_ERROR_RETURN;
355 }
356
357 sc->sc_evt_addr = -1;
358 sc->sc_aclrd_addr = -1;
359 sc->sc_aclwr_addr = -1;
360
361 count = 0;
362 (void)usbd_endpoint_count(sc->sc_iface0, &count);
363
364 for (i = 0 ; i < count ; i++) {
365 int dir, type;
366
367 ed = usbd_interface2endpoint_descriptor(sc->sc_iface0, i);
368 if (ed == NULL) {
369 aprint_error("%s: could not read endpoint descriptor %d\n",
370 USBDEVNAME(sc->sc_dev), i);
371
372 USB_ATTACH_ERROR_RETURN;
373 }
374
375 dir = UE_GET_DIR(ed->bEndpointAddress);
376 type = UE_GET_XFERTYPE(ed->bmAttributes);
377
378 if (dir == UE_DIR_IN && type == UE_INTERRUPT)
379 sc->sc_evt_addr = ed->bEndpointAddress;
380 else if (dir == UE_DIR_IN && type == UE_BULK)
381 sc->sc_aclrd_addr = ed->bEndpointAddress;
382 else if (dir == UE_DIR_OUT && type == UE_BULK)
383 sc->sc_aclwr_addr = ed->bEndpointAddress;
384 }
385
386 if (sc->sc_evt_addr == -1) {
387 aprint_error("%s: missing INTERRUPT endpoint on interface 0\n",
388 USBDEVNAME(sc->sc_dev));
389
390 USB_ATTACH_ERROR_RETURN;
391 }
392 if (sc->sc_aclrd_addr == -1) {
393 aprint_error("%s: missing BULK IN endpoint on interface 0\n",
394 USBDEVNAME(sc->sc_dev));
395
396 USB_ATTACH_ERROR_RETURN;
397 }
398 if (sc->sc_aclwr_addr == -1) {
399 aprint_error("%s: missing BULK OUT endpoint on interface 0\n",
400 USBDEVNAME(sc->sc_dev));
401
402 USB_ATTACH_ERROR_RETURN;
403 }
404
405 /*
406 * Interface 1 must have 2 endpoints
407 * 1) Isochronous IN endpoint to receive SCO data
408 * 2) Isochronous OUT endpoint to send SCO data
409 *
410 * and will have several configurations, which can be selected
411 * via a sysctl variable. We select config 0 to start, which
412 * means that no SCO data will be available.
413 */
414 err = usbd_device2interface_handle(sc->sc_udev, 1, &sc->sc_iface1);
415 if (err) {
416 aprint_error("%s: Could not get interface 1 handle %s (%d)\n",
417 USBDEVNAME(sc->sc_dev), usbd_errstr(err), err);
418
419 USB_ATTACH_ERROR_RETURN;
420 }
421
422 cd = usbd_get_config_descriptor(sc->sc_udev);
423 if (cd == NULL) {
424 aprint_error("%s: could not get config descriptor\n",
425 USBDEVNAME(sc->sc_dev));
426
427 USB_ATTACH_ERROR_RETURN;
428 }
429
430 sc->sc_alt_config = usbd_get_no_alts(cd, 1);
431
432 /* set initial config */
433 err = ubt_set_isoc_config(sc);
434 if (err) {
435 aprint_error("%s: ISOC config failed\n",
436 USBDEVNAME(sc->sc_dev));
437
438 USB_ATTACH_ERROR_RETURN;
439 }
440
441 /* Attach HCI */
442 sc->sc_unit.hci_dev = USBDEV(sc->sc_dev);
443 sc->sc_unit.hci_enable = ubt_enable;
444 sc->sc_unit.hci_disable = ubt_disable;
445 sc->sc_unit.hci_start_cmd = ubt_xmit_cmd_start;
446 sc->sc_unit.hci_start_acl = ubt_xmit_acl_start;
447 sc->sc_unit.hci_start_sco = ubt_xmit_sco_start;
448 sc->sc_unit.hci_ipl = makeiplcookie(IPL_USB); /* XXX: IPL_SOFTUSB ?? */
449 hci_attach(&sc->sc_unit);
450
451 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
452 USBDEV(sc->sc_dev));
453
454 /* sysctl set-up for alternate configs */
455 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
456 CTLFLAG_PERMANENT,
457 CTLTYPE_NODE, "hw",
458 NULL,
459 NULL, 0,
460 NULL, 0,
461 CTL_HW, CTL_EOL);
462
463 sysctl_createv(&sc->sc_log, 0, NULL, &node,
464 0,
465 CTLTYPE_NODE, USBDEVNAME(sc->sc_dev),
466 SYSCTL_DESCR("ubt driver information"),
467 NULL, 0,
468 NULL, 0,
469 CTL_HW,
470 CTL_CREATE, CTL_EOL);
471
472 if (node != NULL) {
473 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
474 CTLFLAG_READWRITE,
475 CTLTYPE_INT, "config",
476 SYSCTL_DESCR("configuration number"),
477 ubt_sysctl_config, 0,
478 sc, 0,
479 CTL_HW, node->sysctl_num,
480 CTL_CREATE, CTL_EOL);
481
482 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
483 CTLFLAG_READONLY,
484 CTLTYPE_INT, "alt_config",
485 SYSCTL_DESCR("number of alternate configurations"),
486 NULL, 0,
487 &sc->sc_alt_config, sizeof(sc->sc_alt_config),
488 CTL_HW, node->sysctl_num,
489 CTL_CREATE, CTL_EOL);
490
491 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
492 CTLFLAG_READONLY,
493 CTLTYPE_INT, "sco_rxsize",
494 SYSCTL_DESCR("max SCO receive size"),
495 NULL, 0,
496 &sc->sc_scord_size, sizeof(sc->sc_scord_size),
497 CTL_HW, node->sysctl_num,
498 CTL_CREATE, CTL_EOL);
499
500 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
501 CTLFLAG_READONLY,
502 CTLTYPE_INT, "sco_txsize",
503 SYSCTL_DESCR("max SCO transmit size"),
504 NULL, 0,
505 &sc->sc_scowr_size, sizeof(sc->sc_scowr_size),
506 CTL_HW, node->sysctl_num,
507 CTL_CREATE, CTL_EOL);
508 }
509
510 sc->sc_ok = 1;
511 USB_ATTACH_SUCCESS_RETURN;
512 }
513
514 USB_DETACH(ubt)
515 {
516 USB_DETACH_START(ubt, sc);
517 int s;
518
519 DPRINTF("sc=%p flags=%d\n", sc, flags);
520
521 sc->sc_dying = 1;
522
523 if (!sc->sc_ok)
524 return 0;
525
526 /* delete sysctl nodes */
527 sysctl_teardown(&sc->sc_log);
528
529 /* Detach HCI interface */
530 hci_detach(&sc->sc_unit);
531
532 /*
533 * Abort all pipes. Causes processes waiting for transfer to wake.
534 *
535 * Actually, hci_detach() above will call ubt_disable() which may
536 * call ubt_abortdealloc(), but lets be sure since doing it twice
537 * wont cause an error.
538 */
539 ubt_abortdealloc(sc);
540
541 /* wait for all processes to finish */
542 s = splusb();
543 if (sc->sc_refcnt-- > 0)
544 usb_detach_wait(USBDEV(sc->sc_dev));
545
546 splx(s);
547
548 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
549 USBDEV(sc->sc_dev));
550
551 DPRINTFN(1, "driver detached\n");
552
553 return 0;
554 }
555
556 int
557 ubt_activate(device_ptr_t self, enum devact act)
558 {
559 struct ubt_softc *sc = USBGETSOFTC(self);
560 int error = 0;
561
562 DPRINTFN(1, "sc=%p, act=%d\n", sc, act);
563
564 switch (act) {
565 case DVACT_ACTIVATE:
566 break;
567
568 case DVACT_DEACTIVATE:
569 sc->sc_dying = 1;
570 break;
571
572 default:
573 error = EOPNOTSUPP;
574 break;
575 }
576
577 return error;
578 }
579
580 /* set ISOC configuration */
581 static int
582 ubt_set_isoc_config(struct ubt_softc *sc)
583 {
584 usb_endpoint_descriptor_t *ed;
585 int rd_addr, wr_addr, rd_size, wr_size;
586 uint8_t count, i;
587 int err;
588
589 err = usbd_set_interface(sc->sc_iface1, sc->sc_config);
590 if (err != USBD_NORMAL_COMPLETION) {
591 aprint_error(
592 "%s: Could not set config %d on ISOC interface. %s (%d)\n",
593 USBDEVNAME(sc->sc_dev), sc->sc_config, usbd_errstr(err), err);
594
595 return err == USBD_IN_USE ? EBUSY : EIO;
596 }
597
598 /*
599 * We wont get past the above if there are any pipes open, so no
600 * need to worry about buf/xfer/pipe deallocation. If we get an
601 * error after this, the frame quantities will be 0 and no SCO
602 * data will be possible.
603 */
604
605 sc->sc_scord_size = rd_size = 0;
606 sc->sc_scord_addr = rd_addr = -1;
607
608 sc->sc_scowr_size = wr_size = 0;
609 sc->sc_scowr_addr = wr_addr = -1;
610
611 count = 0;
612 (void)usbd_endpoint_count(sc->sc_iface1, &count);
613
614 for (i = 0 ; i < count ; i++) {
615 ed = usbd_interface2endpoint_descriptor(sc->sc_iface1, i);
616 if (ed == NULL) {
617 aprint_error("%s: could not read endpoint descriptor %d\n",
618 USBDEVNAME(sc->sc_dev), i);
619
620 return EIO;
621 }
622
623 DPRINTFN(5, "%s: endpoint type %02x (%02x) addr %02x (%s)\n",
624 USBDEVNAME(sc->sc_dev),
625 UE_GET_XFERTYPE(ed->bmAttributes),
626 UE_GET_ISO_TYPE(ed->bmAttributes),
627 ed->bEndpointAddress,
628 UE_GET_DIR(ed->bEndpointAddress) ? "in" : "out");
629
630 if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
631 continue;
632
633 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) {
634 rd_addr = ed->bEndpointAddress;
635 rd_size = UGETW(ed->wMaxPacketSize);
636 } else {
637 wr_addr = ed->bEndpointAddress;
638 wr_size = UGETW(ed->wMaxPacketSize);
639 }
640 }
641
642 if (rd_addr == -1) {
643 aprint_error(
644 "%s: missing ISOC IN endpoint on interface config %d\n",
645 USBDEVNAME(sc->sc_dev), sc->sc_config);
646
647 return ENOENT;
648 }
649 if (wr_addr == -1) {
650 aprint_error(
651 "%s: missing ISOC OUT endpoint on interface config %d\n",
652 USBDEVNAME(sc->sc_dev), sc->sc_config);
653
654 return ENOENT;
655 }
656
657 #ifdef DIAGNOSTIC
658 if (rd_size > MLEN) {
659 aprint_error("%s: rd_size=%d exceeds MLEN\n",
660 USBDEVNAME(sc->sc_dev), rd_size);
661
662 return EOVERFLOW;
663 }
664
665 if (wr_size > MLEN) {
666 aprint_error("%s: wr_size=%d exceeds MLEN\n",
667 USBDEVNAME(sc->sc_dev), wr_size);
668
669 return EOVERFLOW;
670 }
671 #endif
672
673 sc->sc_scord_size = rd_size;
674 sc->sc_scord_addr = rd_addr;
675
676 sc->sc_scowr_size = wr_size;
677 sc->sc_scowr_addr = wr_addr;
678
679 return 0;
680 }
681
682 /* sysctl helper to set alternate configurations */
683 static int
684 ubt_sysctl_config(SYSCTLFN_ARGS)
685 {
686 struct sysctlnode node;
687 struct ubt_softc *sc;
688 int t, error;
689
690 node = *rnode;
691 sc = node.sysctl_data;
692
693 t = sc->sc_config;
694 node.sysctl_data = &t;
695 error = sysctl_lookup(SYSCTLFN_CALL(&node));
696 if (error || newp == NULL)
697 return error;
698
699 if (t < 0 || t >= sc->sc_alt_config)
700 return EINVAL;
701
702 /* This may not change when the unit is enabled */
703 if (sc->sc_unit.hci_flags & BTF_RUNNING)
704 return EBUSY;
705
706 sc->sc_config = t;
707 return ubt_set_isoc_config(sc);
708 }
709
710 static void
711 ubt_abortdealloc(struct ubt_softc *sc)
712 {
713 int i;
714
715 DPRINTFN(1, "sc=%p\n", sc);
716
717 /* Abort all pipes */
718 if (sc->sc_evt_pipe != NULL) {
719 usbd_abort_pipe(sc->sc_evt_pipe);
720 usbd_close_pipe(sc->sc_evt_pipe);
721 sc->sc_evt_pipe = NULL;
722 }
723
724 if (sc->sc_aclrd_pipe != NULL) {
725 usbd_abort_pipe(sc->sc_aclrd_pipe);
726 usbd_close_pipe(sc->sc_aclrd_pipe);
727 sc->sc_aclrd_pipe = NULL;
728 }
729
730 if (sc->sc_aclwr_pipe != NULL) {
731 usbd_abort_pipe(sc->sc_aclwr_pipe);
732 usbd_close_pipe(sc->sc_aclwr_pipe);
733 sc->sc_aclwr_pipe = NULL;
734 }
735
736 if (sc->sc_scord_pipe != NULL) {
737 usbd_abort_pipe(sc->sc_scord_pipe);
738 usbd_close_pipe(sc->sc_scord_pipe);
739 sc->sc_scord_pipe = NULL;
740 }
741
742 if (sc->sc_scowr_pipe != NULL) {
743 usbd_abort_pipe(sc->sc_scowr_pipe);
744 usbd_close_pipe(sc->sc_scowr_pipe);
745 sc->sc_scowr_pipe = NULL;
746 }
747
748 /* Free event buffer */
749 if (sc->sc_evt_buf != NULL) {
750 free(sc->sc_evt_buf, M_USBDEV);
751 sc->sc_evt_buf = NULL;
752 }
753
754 /* Free all xfers and xfer buffers (implicit) */
755 if (sc->sc_cmd_xfer != NULL) {
756 usbd_free_xfer(sc->sc_cmd_xfer);
757 sc->sc_cmd_xfer = NULL;
758 sc->sc_cmd_buf = NULL;
759 }
760
761 if (sc->sc_aclrd_xfer != NULL) {
762 usbd_free_xfer(sc->sc_aclrd_xfer);
763 sc->sc_aclrd_xfer = NULL;
764 sc->sc_aclrd_buf = NULL;
765 }
766
767 if (sc->sc_aclwr_xfer != NULL) {
768 usbd_free_xfer(sc->sc_aclwr_xfer);
769 sc->sc_aclwr_xfer = NULL;
770 sc->sc_aclwr_buf = NULL;
771 }
772
773 for (i = 0 ; i < UBT_NXFERS ; i++) {
774 if (sc->sc_scord[i].xfer != NULL) {
775 usbd_free_xfer(sc->sc_scord[i].xfer);
776 sc->sc_scord[i].xfer = NULL;
777 sc->sc_scord[i].buf = NULL;
778 }
779
780 if (sc->sc_scowr[i].xfer != NULL) {
781 usbd_free_xfer(sc->sc_scowr[i].xfer);
782 sc->sc_scowr[i].xfer = NULL;
783 sc->sc_scowr[i].buf = NULL;
784 }
785 }
786
787 /* Free partial SCO packets */
788 if (sc->sc_scord_mbuf != NULL) {
789 m_freem(sc->sc_scord_mbuf);
790 sc->sc_scord_mbuf = NULL;
791 }
792
793 if (sc->sc_scowr_mbuf != NULL) {
794 m_freem(sc->sc_scowr_mbuf);
795 sc->sc_scowr_mbuf = NULL;
796 }
797 }
798
799 /*******************************************************************************
800 *
801 * Bluetooth Unit/USB callbacks
802 *
803 * All of this will be called at the IPL_ we specified above
804 */
805 static int
806 ubt_enable(device_ptr_t self)
807 {
808 struct ubt_softc *sc = USBGETSOFTC(self);
809 struct hci_unit *unit = &sc->sc_unit;
810 usbd_status err;
811 int i, error;
812
813 DPRINTFN(1, "sc=%p\n", sc);
814
815 if (unit->hci_flags & BTF_RUNNING)
816 return 0;
817
818 /* Events */
819 sc->sc_evt_buf = malloc(UBT_BUFSIZ_EVENT, M_USBDEV, M_NOWAIT);
820 if (sc->sc_evt_buf == NULL) {
821 error = ENOMEM;
822 goto bad;
823 }
824 err = usbd_open_pipe_intr(sc->sc_iface0,
825 sc->sc_evt_addr,
826 USBD_SHORT_XFER_OK,
827 &sc->sc_evt_pipe,
828 sc,
829 sc->sc_evt_buf,
830 UBT_BUFSIZ_EVENT,
831 ubt_recv_event,
832 USBD_DEFAULT_INTERVAL);
833 if (err != USBD_NORMAL_COMPLETION) {
834 error = EIO;
835 goto bad;
836 }
837
838 /* Commands */
839 sc->sc_cmd_xfer = usbd_alloc_xfer(sc->sc_udev);
840 if (sc->sc_cmd_xfer == NULL) {
841 error = ENOMEM;
842 goto bad;
843 }
844 sc->sc_cmd_buf = usbd_alloc_buffer(sc->sc_cmd_xfer, UBT_BUFSIZ_CMD);
845 if (sc->sc_cmd_buf == NULL) {
846 error = ENOMEM;
847 goto bad;
848 }
849
850 /* ACL read */
851 err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclrd_addr,
852 USBD_EXCLUSIVE_USE, &sc->sc_aclrd_pipe);
853 if (err != USBD_NORMAL_COMPLETION) {
854 error = EIO;
855 goto bad;
856 }
857 sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev);
858 if (sc->sc_aclrd_xfer == NULL) {
859 error = ENOMEM;
860 goto bad;
861 }
862 sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer, UBT_BUFSIZ_ACL);
863 if (sc->sc_aclrd_buf == NULL) {
864 error = ENOMEM;
865 goto bad;
866 }
867 sc->sc_aclrd_busy = 0;
868 ubt_recv_acl_start(sc);
869
870 /* ACL write */
871 err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclwr_addr,
872 USBD_EXCLUSIVE_USE, &sc->sc_aclwr_pipe);
873 if (err != USBD_NORMAL_COMPLETION) {
874 error = EIO;
875 goto bad;
876 }
877 sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev);
878 if (sc->sc_aclwr_xfer == NULL) {
879 error = ENOMEM;
880 goto bad;
881 }
882 sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer, UBT_BUFSIZ_ACL);
883 if (sc->sc_aclwr_buf == NULL) {
884 error = ENOMEM;
885 goto bad;
886 }
887
888 /* SCO read */
889 if (sc->sc_scord_size > 0) {
890 err = usbd_open_pipe(sc->sc_iface1, sc->sc_scord_addr,
891 USBD_EXCLUSIVE_USE, &sc->sc_scord_pipe);
892 if (err != USBD_NORMAL_COMPLETION) {
893 error = EIO;
894 goto bad;
895 }
896
897 for (i = 0 ; i < UBT_NXFERS ; i++) {
898 sc->sc_scord[i].xfer = usbd_alloc_xfer(sc->sc_udev);
899 if (sc->sc_scord[i].xfer == NULL) {
900 error = ENOMEM;
901 goto bad;
902 }
903 sc->sc_scord[i].buf = usbd_alloc_buffer(sc->sc_scord[i].xfer,
904 sc->sc_scord_size * UBT_NFRAMES);
905 if (sc->sc_scord[i].buf == NULL) {
906 error = ENOMEM;
907 goto bad;
908 }
909 sc->sc_scord[i].softc = sc;
910 sc->sc_scord[i].busy = 0;
911 ubt_recv_sco_start1(sc, &sc->sc_scord[i]);
912 }
913 }
914
915 /* SCO write */
916 if (sc->sc_scowr_size > 0) {
917 err = usbd_open_pipe(sc->sc_iface1, sc->sc_scowr_addr,
918 USBD_EXCLUSIVE_USE, &sc->sc_scowr_pipe);
919 if (err != USBD_NORMAL_COMPLETION) {
920 error = EIO;
921 goto bad;
922 }
923
924 for (i = 0 ; i < UBT_NXFERS ; i++) {
925 sc->sc_scowr[i].xfer = usbd_alloc_xfer(sc->sc_udev);
926 if (sc->sc_scowr[i].xfer == NULL) {
927 error = ENOMEM;
928 goto bad;
929 }
930 sc->sc_scowr[i].buf = usbd_alloc_buffer(sc->sc_scowr[i].xfer,
931 sc->sc_scowr_size * UBT_NFRAMES);
932 if (sc->sc_scowr[i].buf == NULL) {
933 error = ENOMEM;
934 goto bad;
935 }
936 sc->sc_scowr[i].softc = sc;
937 sc->sc_scowr[i].busy = 0;
938 }
939 }
940
941 unit->hci_flags &= ~BTF_XMIT;
942 unit->hci_flags |= BTF_RUNNING;
943 return 0;
944
945 bad:
946 ubt_abortdealloc(sc);
947 return error;
948 }
949
950 static void
951 ubt_disable(device_ptr_t self)
952 {
953 struct ubt_softc *sc = USBGETSOFTC(self);
954 struct hci_unit *unit = &sc->sc_unit;
955
956 DPRINTFN(1, "sc=%p\n", sc);
957
958 if ((unit->hci_flags & BTF_RUNNING) == 0)
959 return;
960
961 ubt_abortdealloc(sc);
962
963 unit->hci_flags &= ~BTF_RUNNING;
964 }
965
966 static void
967 ubt_xmit_cmd_start(device_ptr_t self)
968 {
969 struct ubt_softc *sc = USBGETSOFTC(self);
970 struct hci_unit *unit = &sc->sc_unit;
971 usb_device_request_t req;
972 usbd_status status;
973 struct mbuf *m;
974 int len;
975
976 if (sc->sc_dying)
977 return;
978
979 if (MBUFQ_FIRST(&unit->hci_cmdq) == NULL)
980 return;
981
982 MBUFQ_DEQUEUE(&unit->hci_cmdq, m);
983 KASSERT(m != NULL);
984
985 DPRINTFN(15, "%s: xmit CMD packet (%d bytes)\n",
986 USBDEVNAME(sc->sc_dev), m->m_pkthdr.len);
987
988 sc->sc_refcnt++;
989 unit->hci_flags |= BTF_XMIT_CMD;
990
991 len = m->m_pkthdr.len - 1;
992 m_copydata(m, 1, len, sc->sc_cmd_buf);
993 m_freem(m);
994
995 memset(&req, 0, sizeof(req));
996 req.bmRequestType = UT_WRITE_CLASS_DEVICE;
997 USETW(req.wLength, len);
998
999 usbd_setup_default_xfer(sc->sc_cmd_xfer,
1000 sc->sc_udev,
1001 sc,
1002 UBT_CMD_TIMEOUT,
1003 &req,
1004 sc->sc_cmd_buf,
1005 len,
1006 USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
1007 ubt_xmit_cmd_complete);
1008
1009 status = usbd_transfer(sc->sc_cmd_xfer);
1010
1011 KASSERT(status != USBD_NORMAL_COMPLETION);
1012
1013 if (status != USBD_IN_PROGRESS) {
1014 DPRINTF("usbd_transfer status=%s (%d)\n",
1015 usbd_errstr(status), status);
1016
1017 sc->sc_refcnt--;
1018 unit->hci_flags &= ~BTF_XMIT_CMD;
1019 }
1020 }
1021
1022 static void
1023 ubt_xmit_cmd_complete(usbd_xfer_handle xfer,
1024 usbd_private_handle h, usbd_status status)
1025 {
1026 struct ubt_softc *sc = h;
1027 struct hci_unit *unit = &sc->sc_unit;
1028 uint32_t count;
1029
1030 DPRINTFN(15, "%s: CMD complete status=%s (%d)\n",
1031 USBDEVNAME(sc->sc_dev), usbd_errstr(status), status);
1032
1033 unit->hci_flags &= ~BTF_XMIT_CMD;
1034
1035 if (--sc->sc_refcnt < 0) {
1036 DPRINTF("sc_refcnt=%d\n", sc->sc_refcnt);
1037 usb_detach_wakeup(USBDEV(sc->sc_dev));
1038 return;
1039 }
1040
1041 if (sc->sc_dying) {
1042 DPRINTF("sc_dying\n");
1043 return;
1044 }
1045
1046 if (status != USBD_NORMAL_COMPLETION) {
1047 DPRINTF("status=%s (%d)\n",
1048 usbd_errstr(status), status);
1049
1050 unit->hci_stats.err_tx++;
1051 return;
1052 }
1053
1054 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1055 unit->hci_stats.cmd_tx++;
1056 unit->hci_stats.byte_tx += count;
1057
1058 ubt_xmit_cmd_start(USBDEV(sc->sc_dev));
1059 }
1060
1061 static void
1062 ubt_xmit_acl_start(device_ptr_t self)
1063 {
1064 struct ubt_softc *sc = USBGETSOFTC(self);
1065 struct hci_unit *unit = &sc->sc_unit;
1066 struct mbuf *m;
1067 usbd_status status;
1068 int len;
1069
1070 if (sc->sc_dying)
1071 return;
1072
1073 if (MBUFQ_FIRST(&unit->hci_acltxq) == NULL)
1074 return;
1075
1076 sc->sc_refcnt++;
1077 unit->hci_flags |= BTF_XMIT_ACL;
1078
1079 MBUFQ_DEQUEUE(&unit->hci_acltxq, m);
1080 KASSERT(m != NULL);
1081
1082 DPRINTFN(15, "%s: xmit ACL packet (%d bytes)\n",
1083 USBDEVNAME(sc->sc_dev), m->m_pkthdr.len);
1084
1085 len = m->m_pkthdr.len - 1;
1086 if (len > UBT_BUFSIZ_ACL) {
1087 DPRINTF("%s: truncating ACL packet (%d => %d)!\n",
1088 USBDEVNAME(sc->sc_dev), len, UBT_BUFSIZ_ACL);
1089
1090 len = UBT_BUFSIZ_ACL;
1091 }
1092
1093 m_copydata(m, 1, len, sc->sc_aclwr_buf);
1094 m_freem(m);
1095
1096 unit->hci_stats.acl_tx++;
1097 unit->hci_stats.byte_tx += len;
1098
1099 usbd_setup_xfer(sc->sc_aclwr_xfer,
1100 sc->sc_aclwr_pipe,
1101 sc,
1102 sc->sc_aclwr_buf,
1103 len,
1104 USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
1105 UBT_ACL_TIMEOUT,
1106 ubt_xmit_acl_complete);
1107
1108 status = usbd_transfer(sc->sc_aclwr_xfer);
1109
1110 KASSERT(status != USBD_NORMAL_COMPLETION);
1111
1112 if (status != USBD_IN_PROGRESS) {
1113 DPRINTF("usbd_transfer status=%s (%d)\n",
1114 usbd_errstr(status), status);
1115
1116 sc->sc_refcnt--;
1117 unit->hci_flags &= ~BTF_XMIT_ACL;
1118 }
1119 }
1120
1121 static void
1122 ubt_xmit_acl_complete(usbd_xfer_handle xfer,
1123 usbd_private_handle h, usbd_status status)
1124 {
1125 struct ubt_softc *sc = h;
1126 struct hci_unit *unit = &sc->sc_unit;
1127
1128 DPRINTFN(15, "%s: ACL complete status=%s (%d)\n",
1129 USBDEVNAME(sc->sc_dev), usbd_errstr(status), status);
1130
1131 unit->hci_flags &= ~BTF_XMIT_ACL;
1132
1133 if (--sc->sc_refcnt < 0) {
1134 usb_detach_wakeup(USBDEV(sc->sc_dev));
1135 return;
1136 }
1137
1138 if (sc->sc_dying)
1139 return;
1140
1141 if (status != USBD_NORMAL_COMPLETION) {
1142 DPRINTF("status=%s (%d)\n",
1143 usbd_errstr(status), status);
1144
1145 unit->hci_stats.err_tx++;
1146
1147 if (status == USBD_STALLED)
1148 usbd_clear_endpoint_stall_async(sc->sc_aclwr_pipe);
1149 else
1150 return;
1151 }
1152
1153 ubt_xmit_acl_start(USBDEV(sc->sc_dev));
1154 }
1155
1156 static void
1157 ubt_xmit_sco_start(device_ptr_t self)
1158 {
1159 struct ubt_softc *sc = USBGETSOFTC(self);
1160 int i;
1161
1162 if (sc->sc_dying || sc->sc_scowr_size == 0)
1163 return;
1164
1165 for (i = 0 ; i < UBT_NXFERS ; i++) {
1166 if (sc->sc_scowr[i].busy)
1167 continue;
1168
1169 ubt_xmit_sco_start1(sc, &sc->sc_scowr[i]);
1170 }
1171 }
1172
1173 static void
1174 ubt_xmit_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc)
1175 {
1176 struct mbuf *m;
1177 uint8_t *buf;
1178 int num, len, size, space;
1179
1180 space = sc->sc_scowr_size * UBT_NFRAMES;
1181 buf = isoc->buf;
1182 len = 0;
1183
1184 /*
1185 * Fill the request buffer with data from the queue,
1186 * keeping any leftover packet on our private hook.
1187 *
1188 * Complete packets are passed back up to the stack
1189 * for disposal, since we can't rely on the controller
1190 * to tell us when it has finished with them.
1191 */
1192
1193 m = sc->sc_scowr_mbuf;
1194 while (space > 0) {
1195 if (m == NULL) {
1196 MBUFQ_DEQUEUE(&sc->sc_unit.hci_scotxq, m);
1197 if (m == NULL)
1198 break;
1199
1200 m_adj(m, 1); /* packet type */
1201 }
1202
1203 if (m->m_pkthdr.len > 0) {
1204 size = MIN(m->m_pkthdr.len, space);
1205
1206 m_copydata(m, 0, size, buf);
1207 m_adj(m, size);
1208
1209 buf += size;
1210 len += size;
1211 space -= size;
1212 }
1213
1214 if (m->m_pkthdr.len == 0) {
1215 sc->sc_unit.hci_stats.sco_tx++;
1216 hci_complete_sco(&sc->sc_unit, m);
1217 m = NULL;
1218 }
1219 }
1220 sc->sc_scowr_mbuf = m;
1221
1222 DPRINTFN(15, "isoc=%p, len=%d, space=%d\n", isoc, len, space);
1223
1224 if (len == 0) /* nothing to send */
1225 return;
1226
1227 sc->sc_refcnt++;
1228 sc->sc_unit.hci_flags |= BTF_XMIT_SCO;
1229 sc->sc_unit.hci_stats.byte_tx += len;
1230 isoc->busy = 1;
1231
1232 /*
1233 * calculate number of isoc frames and sizes
1234 */
1235
1236 for (num = 0 ; len > 0 ; num++) {
1237 size = MIN(sc->sc_scowr_size, len);
1238
1239 isoc->size[num] = size;
1240 len -= size;
1241 }
1242
1243 usbd_setup_isoc_xfer(isoc->xfer,
1244 sc->sc_scowr_pipe,
1245 isoc,
1246 isoc->size,
1247 num,
1248 USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
1249 ubt_xmit_sco_complete);
1250
1251 usbd_transfer(isoc->xfer);
1252 }
1253
1254 static void
1255 ubt_xmit_sco_complete(usbd_xfer_handle xfer,
1256 usbd_private_handle h, usbd_status status)
1257 {
1258 struct ubt_isoc_xfer *isoc = h;
1259 struct ubt_softc *sc;
1260 int i;
1261
1262 KASSERT(xfer == isoc->xfer);
1263 sc = isoc->softc;
1264
1265 DPRINTFN(15, "isoc=%p, status=%s (%d)\n",
1266 isoc, usbd_errstr(status), status);
1267
1268 isoc->busy = 0;
1269
1270 for (i = 0 ; ; i++) {
1271 if (i == UBT_NXFERS) {
1272 sc->sc_unit.hci_flags &= ~BTF_XMIT_SCO;
1273 break;
1274 }
1275
1276 if (sc->sc_scowr[i].busy)
1277 break;
1278 }
1279
1280 if (--sc->sc_refcnt < 0) {
1281 usb_detach_wakeup(USBDEV(sc->sc_dev));
1282 return;
1283 }
1284
1285 if (sc->sc_dying)
1286 return;
1287
1288 if (status != USBD_NORMAL_COMPLETION) {
1289 DPRINTF("status=%s (%d)\n",
1290 usbd_errstr(status), status);
1291
1292 sc->sc_unit.hci_stats.err_tx++;
1293
1294 if (status == USBD_STALLED)
1295 usbd_clear_endpoint_stall_async(sc->sc_scowr_pipe);
1296 else
1297 return;
1298 }
1299
1300 ubt_xmit_sco_start(USBDEV(sc->sc_dev));
1301 }
1302
1303 /*
1304 * load incoming data into an mbuf with
1305 * leading type byte
1306 */
1307 static struct mbuf *
1308 ubt_mbufload(uint8_t *buf, int count, uint8_t type)
1309 {
1310 struct mbuf *m;
1311
1312 MGETHDR(m, M_DONTWAIT, MT_DATA);
1313 if (m == NULL)
1314 return NULL;
1315
1316 *mtod(m, uint8_t *) = type;
1317 m->m_pkthdr.len = m->m_len = MHLEN;
1318 m_copyback(m, 1, count, buf); // (extends if necessary)
1319 if (m->m_pkthdr.len != MAX(MHLEN, count + 1)) {
1320 m_free(m);
1321 return NULL;
1322 }
1323
1324 m->m_pkthdr.len = count + 1;
1325 m->m_len = MIN(MHLEN, m->m_pkthdr.len);
1326
1327 return m;
1328 }
1329
1330 static void
1331 ubt_recv_event(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status)
1332 {
1333 struct ubt_softc *sc = h;
1334 struct mbuf *m;
1335 uint32_t count;
1336 void *buf;
1337
1338 DPRINTFN(15, "sc=%p status=%s (%d)\n",
1339 sc, usbd_errstr(status), status);
1340
1341 if (status != USBD_NORMAL_COMPLETION || sc->sc_dying)
1342 return;
1343
1344 usbd_get_xfer_status(xfer, NULL, &buf, &count, NULL);
1345
1346 if (count < sizeof(hci_event_hdr_t) - 1) {
1347 DPRINTF("dumped undersized event (count = %d)\n", count);
1348 sc->sc_unit.hci_stats.err_rx++;
1349 return;
1350 }
1351
1352 sc->sc_unit.hci_stats.evt_rx++;
1353 sc->sc_unit.hci_stats.byte_rx += count;
1354
1355 m = ubt_mbufload(buf, count, HCI_EVENT_PKT);
1356 if (m != NULL)
1357 hci_input_event(&sc->sc_unit, m);
1358 else
1359 sc->sc_unit.hci_stats.err_rx++;
1360 }
1361
1362 static void
1363 ubt_recv_acl_start(struct ubt_softc *sc)
1364 {
1365 usbd_status status;
1366
1367 DPRINTFN(15, "sc=%p\n", sc);
1368
1369 if (sc->sc_aclrd_busy || sc->sc_dying) {
1370 DPRINTF("sc_aclrd_busy=%d, sc_dying=%d\n",
1371 sc->sc_aclrd_busy,
1372 sc->sc_dying);
1373
1374 return;
1375 }
1376
1377 sc->sc_refcnt++;
1378 sc->sc_aclrd_busy = 1;
1379
1380 usbd_setup_xfer(sc->sc_aclrd_xfer,
1381 sc->sc_aclrd_pipe,
1382 sc,
1383 sc->sc_aclrd_buf,
1384 UBT_BUFSIZ_ACL,
1385 USBD_NO_COPY | USBD_SHORT_XFER_OK,
1386 USBD_NO_TIMEOUT,
1387 ubt_recv_acl_complete);
1388
1389 status = usbd_transfer(sc->sc_aclrd_xfer);
1390
1391 KASSERT(status != USBD_NORMAL_COMPLETION);
1392
1393 if (status != USBD_IN_PROGRESS) {
1394 DPRINTF("usbd_transfer status=%s (%d)\n",
1395 usbd_errstr(status), status);
1396
1397 sc->sc_refcnt--;
1398 sc->sc_aclrd_busy = 0;
1399 }
1400 }
1401
1402 static void
1403 ubt_recv_acl_complete(usbd_xfer_handle xfer,
1404 usbd_private_handle h, usbd_status status)
1405 {
1406 struct ubt_softc *sc = h;
1407 struct mbuf *m;
1408 uint32_t count;
1409 void *buf;
1410
1411 DPRINTFN(15, "sc=%p status=%s (%d)\n",
1412 sc, usbd_errstr(status), status);
1413
1414 sc->sc_aclrd_busy = 0;
1415
1416 if (--sc->sc_refcnt < 0) {
1417 DPRINTF("refcnt = %d\n", sc->sc_refcnt);
1418 usb_detach_wakeup(USBDEV(sc->sc_dev));
1419 return;
1420 }
1421
1422 if (sc->sc_dying) {
1423 DPRINTF("sc_dying\n");
1424 return;
1425 }
1426
1427 if (status != USBD_NORMAL_COMPLETION) {
1428 DPRINTF("status=%s (%d)\n",
1429 usbd_errstr(status), status);
1430
1431 sc->sc_unit.hci_stats.err_rx++;
1432
1433 if (status == USBD_STALLED)
1434 usbd_clear_endpoint_stall_async(sc->sc_aclrd_pipe);
1435 else
1436 return;
1437 } else {
1438 usbd_get_xfer_status(xfer, NULL, &buf, &count, NULL);
1439
1440 if (count < sizeof(hci_acldata_hdr_t) - 1) {
1441 DPRINTF("dumped undersized packet (%d)\n", count);
1442 sc->sc_unit.hci_stats.err_rx++;
1443 } else {
1444 sc->sc_unit.hci_stats.acl_rx++;
1445 sc->sc_unit.hci_stats.byte_rx += count;
1446
1447 m = ubt_mbufload(buf, count, HCI_ACL_DATA_PKT);
1448 if (m != NULL)
1449 hci_input_acl(&sc->sc_unit, m);
1450 else
1451 sc->sc_unit.hci_stats.err_rx++;
1452 }
1453 }
1454
1455 /* and restart */
1456 ubt_recv_acl_start(sc);
1457 }
1458
1459 static void
1460 ubt_recv_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc)
1461 {
1462 int i;
1463
1464 DPRINTFN(15, "sc=%p, isoc=%p\n", sc, isoc);
1465
1466 if (isoc->busy || sc->sc_dying || sc->sc_scord_size == 0) {
1467 DPRINTF("%s%s%s\n",
1468 isoc->busy ? " busy" : "",
1469 sc->sc_dying ? " dying" : "",
1470 sc->sc_scord_size == 0 ? " size=0" : "");
1471
1472 return;
1473 }
1474
1475 sc->sc_refcnt++;
1476 isoc->busy = 1;
1477
1478 for (i = 0 ; i < UBT_NFRAMES ; i++)
1479 isoc->size[i] = sc->sc_scord_size;
1480
1481 usbd_setup_isoc_xfer(isoc->xfer,
1482 sc->sc_scord_pipe,
1483 isoc,
1484 isoc->size,
1485 UBT_NFRAMES,
1486 USBD_NO_COPY | USBD_SHORT_XFER_OK,
1487 ubt_recv_sco_complete);
1488
1489 usbd_transfer(isoc->xfer);
1490 }
1491
1492 static void
1493 ubt_recv_sco_complete(usbd_xfer_handle xfer,
1494 usbd_private_handle h, usbd_status status)
1495 {
1496 struct ubt_isoc_xfer *isoc = h;
1497 struct ubt_softc *sc;
1498 struct mbuf *m;
1499 uint32_t count;
1500 uint8_t *ptr, *frame;
1501 int i, size, got, want;
1502
1503 KASSERT(isoc != NULL);
1504 KASSERT(isoc->xfer == xfer);
1505
1506 sc = isoc->softc;
1507 isoc->busy = 0;
1508
1509 if (--sc->sc_refcnt < 0) {
1510 DPRINTF("refcnt=%d\n", sc->sc_refcnt);
1511 usb_detach_wakeup(USBDEV(sc->sc_dev));
1512 return;
1513 }
1514
1515 if (sc->sc_dying) {
1516 DPRINTF("sc_dying\n");
1517 return;
1518 }
1519
1520 if (status != USBD_NORMAL_COMPLETION) {
1521 DPRINTF("status=%s (%d)\n",
1522 usbd_errstr(status), status);
1523
1524 sc->sc_unit.hci_stats.err_rx++;
1525
1526 if (status == USBD_STALLED) {
1527 usbd_clear_endpoint_stall_async(sc->sc_scord_pipe);
1528 goto restart;
1529 }
1530
1531 return;
1532 }
1533
1534 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1535 if (count == 0)
1536 goto restart;
1537
1538 DPRINTFN(15, "sc=%p, isoc=%p, count=%u\n",
1539 sc, isoc, count);
1540
1541 sc->sc_unit.hci_stats.byte_rx += count;
1542
1543 /*
1544 * Extract SCO packets from ISOC frames. The way we have it,
1545 * no SCO packet can be bigger than MHLEN. This is unlikely
1546 * to actually happen, but if we ran out of mbufs and lost
1547 * sync then we may get spurious data that makes it seem that
1548 * way, so we discard data that wont fit. This doesnt really
1549 * help with the lost sync situation alas.
1550 */
1551
1552 m = sc->sc_scord_mbuf;
1553 if (m != NULL) {
1554 sc->sc_scord_mbuf = NULL;
1555 ptr = mtod(m, uint8_t *) + m->m_pkthdr.len;
1556 got = m->m_pkthdr.len;
1557 want = sizeof(hci_scodata_hdr_t);
1558 if (got >= want)
1559 want += mtod(m, hci_scodata_hdr_t *)->length ;
1560 } else {
1561 ptr = NULL;
1562 got = 0;
1563 want = 0;
1564 }
1565
1566 for (i = 0 ; i < UBT_NFRAMES ; i++) {
1567 frame = isoc->buf + (i * sc->sc_scord_size);
1568
1569 while (isoc->size[i] > 0) {
1570 size = isoc->size[i];
1571
1572 if (m == NULL) {
1573 MGETHDR(m, M_DONTWAIT, MT_DATA);
1574 if (m == NULL) {
1575 aprint_error("%s: out of memory (xfer halted)\n",
1576 USBDEVNAME(sc->sc_dev));
1577
1578 sc->sc_unit.hci_stats.err_rx++;
1579 return; /* lost sync */
1580 }
1581
1582 ptr = mtod(m, uint8_t *);
1583 *ptr++ = HCI_SCO_DATA_PKT;
1584 got = 1;
1585 want = sizeof(hci_scodata_hdr_t);
1586 }
1587
1588 if (got + size > want)
1589 size = want - got;
1590
1591 if (got + size > MHLEN)
1592 memcpy(ptr, frame, MHLEN - got);
1593 else
1594 memcpy(ptr, frame, size);
1595
1596 ptr += size;
1597 got += size;
1598 frame += size;
1599
1600 if (got == want) {
1601 /*
1602 * If we only got a header, add the packet
1603 * length to our want count. Send complete
1604 * packets up to protocol stack.
1605 */
1606 if (want == sizeof(hci_scodata_hdr_t))
1607 want += mtod(m, hci_scodata_hdr_t *)->length;
1608
1609 if (got == want) {
1610 m->m_pkthdr.len = m->m_len = got;
1611 sc->sc_unit.hci_stats.sco_rx++;
1612 hci_input_sco(&sc->sc_unit, m);
1613 m = NULL;
1614 }
1615 }
1616
1617 isoc->size[i] -= size;
1618 }
1619 }
1620
1621 if (m != NULL) {
1622 m->m_pkthdr.len = m->m_len = got;
1623 sc->sc_scord_mbuf = m;
1624 }
1625
1626 restart: /* and restart */
1627 ubt_recv_sco_start1(sc, isoc);
1628 }
1629