Kernel part of bluetooth stack ported by Dmitry Komissaroff. Very much work
[dragonfly.git] / sys / dev / usbmisc / ubt / ubt.c
blob259abd7c40947b51299808d51c1b24225d39d309
1 /* $OpenBSD: ubt.c,v 1.9 2007/10/11 18:33:14 deraadt Exp $ */
2 /* $DragonFly: src/sys/dev/usbmisc/ubt/ubt.c,v 1.1 2007/12/30 20:02:56 hasso Exp $ */
4 /*-
5 * Copyright (c) 2006 Itronix Inc.
6 * All rights reserved.
8 * Written by Iain Hibbert for Itronix Inc.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of Itronix Inc. may not be used to endorse
19 * or promote products derived from this software without specific
20 * prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 * ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
35 * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
36 * All rights reserved.
38 * This code is derived from software contributed to The NetBSD Foundation
39 * by Lennart Augustsson (lennart@augustsson.net) and
40 * David Sainty (David.Sainty@dtsp.co.nz).
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
44 * are met:
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in the
49 * documentation and/or other materials provided with the distribution.
50 * 3. All advertising materials mentioning features or use of this software
51 * must display the following acknowledgement:
52 * This product includes software developed by the NetBSD
53 * Foundation, Inc. and its contributors.
54 * 4. Neither the name of The NetBSD Foundation nor the names of its
55 * contributors may be used to endorse or promote products derived
56 * from this software without specific prior written permission.
58 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
59 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
60 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
61 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
62 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
63 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
64 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
65 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
66 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
67 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
68 * POSSIBILITY OF SUCH DAMAGE.
71 * This driver originally written by Lennart Augustsson and David Sainty,
72 * but was mostly rewritten for the NetBSD Bluetooth protocol stack by
73 * Iain Hibbert for Itronix, Inc using the FreeBSD ng_ubt.c driver as a
74 * reference.
77 #include <sys/bus.h>
78 #include <sys/kernel.h>
79 #include <sys/proc.h>
81 #include <bus/usb/usb.h>
82 #include <bus/usb/usbdi.h>
83 #include <bus/usb/usbdi_util.h>
84 #include <bus/usb/usbdivar.h>
86 #include <netbt/bluetooth.h>
87 #include <netbt/hci.h>
89 /*******************************************************************************
91 * debugging stuff
93 #undef DPRINTF
94 #undef DPRINTFN
96 #ifdef UBT_DEBUG
97 int ubt_debug = UBT_DEBUG;
99 #define DPRINTF(fmt, args...) do { \
100 if (ubt_debug) \
101 kprintf("%s: "fmt, __func__ , ##args); \
102 } while (/* CONSTCOND */0)
104 #define DPRINTFN(n, fmt, args...) do { \
105 if (ubt_debug > (n)) \
106 kprintf("%s: "fmt, __func__ , ##args); \
107 } while (/* CONSTCOND */0)
109 #else
110 #define DPRINTF(...)
111 #define DPRINTFN(...)
112 #endif
114 /*******************************************************************************
116 * ubt softc structure
120 /* buffer sizes */
122 * NB: although ACL packets can extend to 65535 bytes, most devices
123 * have max_acl_size at much less (largest I have seen is 384)
125 #define UBT_BUFSIZ_CMD (HCI_CMD_PKT_SIZE - 1)
126 #define UBT_BUFSIZ_ACL (2048 - 1)
127 #define UBT_BUFSIZ_EVENT (HCI_EVENT_PKT_SIZE - 1)
129 /* Transmit timeouts */
131 #define UBT_CMD_TIMEOUT 100
132 #define UBT_ACL_TIMEOUT 100
135 * Specification says, that is must be 1ms, but it causes kernel panic.
136 * Setting interval to USBD_DEFAULT_INTERVAL is not working for some of
137 * us either.
138 * XXX: Make it sysctl.
140 #define UBT_INTR_TIMEOUT USBD_DEFAULT_INTERVAL
143 * ISOC transfers
145 * xfer buffer size depends on the frame size, and the number
146 * of frames per transfer is fixed, as each frame should be
147 * 1ms worth of data. This keeps the rate that xfers complete
148 * fairly constant. We use multiple xfers to keep the hardware
149 * busy
151 #define UBT_NXFERS 3 /* max xfers to queue */
152 #define UBT_NFRAMES 10 /* frames per xfer */
154 struct ubt_isoc_xfer {
155 struct ubt_softc *softc;
156 usbd_xfer_handle xfer;
157 uint8_t *buf;
158 uint16_t size[UBT_NFRAMES];
159 int busy;
162 struct ubt_softc {
163 device_t sc_dev;
164 usbd_device_handle sc_udev;
165 int sc_refcnt;
166 int sc_dying;
168 /* Control Interface */
169 usbd_interface_handle sc_iface0;
171 /* Commands (control) */
172 usbd_xfer_handle sc_cmd_xfer;
173 u_char *sc_cmd_buf;
175 /* Events (interrupt) */
176 int sc_evt_addr; /* endpoint address */
177 usbd_pipe_handle sc_evt_pipe;
178 u_char *sc_evt_buf;
181 /* ACL data (in) */
182 int sc_aclrd_addr; /* endpoint address */
183 usbd_pipe_handle sc_aclrd_pipe; /* read pipe */
184 usbd_xfer_handle sc_aclrd_xfer; /* read xfer */
185 u_char *sc_aclrd_buf; /* read buffer */
186 int sc_aclrd_busy; /* reading */
188 /* ACL data (out) */
189 int sc_aclwr_addr; /* endpoint address */
190 usbd_pipe_handle sc_aclwr_pipe; /* write pipe */
191 usbd_xfer_handle sc_aclwr_xfer; /* write xfer */
192 u_char *sc_aclwr_buf; /* write buffer */
194 /* ISOC interface */
195 usbd_interface_handle sc_iface1; /* ISOC interface */
196 struct sysctllog *sc_log; /* sysctl log */
197 int sc_config; /* current config no */
198 int sc_alt_config; /* no of alternates */
200 /* SCO data (in) */
201 int sc_scord_addr; /* endpoint address */
202 usbd_pipe_handle sc_scord_pipe; /* read pipe */
203 int sc_scord_size; /* frame length */
204 struct ubt_isoc_xfer sc_scord[UBT_NXFERS];
205 struct mbuf *sc_scord_mbuf; /* current packet */
207 /* SCO data (out) */
208 int sc_scowr_addr; /* endpoint address */
209 usbd_pipe_handle sc_scowr_pipe; /* write pipe */
210 int sc_scowr_size; /* frame length */
211 struct ubt_isoc_xfer sc_scowr[UBT_NXFERS];
212 struct mbuf *sc_scowr_mbuf; /* current packet */
214 /* Protocol structure */
215 struct hci_unit sc_unit;
217 /* Successfully attached */
218 int sc_ok;
222 * Bluetooth unit/USB callback routines
224 int ubt_enable(struct hci_unit *);
225 void ubt_disable(struct hci_unit *);
227 void ubt_xmit_cmd_start(struct hci_unit *);
228 void ubt_xmit_cmd_complete(usbd_xfer_handle,
229 usbd_private_handle, usbd_status);
231 void ubt_xmit_acl_start(struct hci_unit *);
232 void ubt_xmit_acl_complete(usbd_xfer_handle,
233 usbd_private_handle, usbd_status);
235 void ubt_xmit_sco_start(struct hci_unit *);
236 void ubt_xmit_sco_start1(struct ubt_softc *, struct ubt_isoc_xfer *);
237 void ubt_xmit_sco_complete(usbd_xfer_handle,
238 usbd_private_handle, usbd_status);
240 void ubt_recv_event(usbd_xfer_handle,
241 usbd_private_handle, usbd_status);
243 void ubt_recv_acl_start(struct ubt_softc *);
244 void ubt_recv_acl_complete(usbd_xfer_handle,
245 usbd_private_handle, usbd_status);
247 void ubt_recv_sco_start1(struct ubt_softc *, struct ubt_isoc_xfer *);
248 void ubt_recv_sco_complete(usbd_xfer_handle,
249 usbd_private_handle, usbd_status);
251 static device_probe_t ubt_match;
252 static device_attach_t ubt_attach;
253 static device_detach_t ubt_detach;
255 static devclass_t ubt_devclass;
257 static device_method_t ubt_methods[] = {
258 DEVMETHOD(device_probe, ubt_match),
259 DEVMETHOD(device_attach, ubt_attach),
260 DEVMETHOD(device_detach, ubt_detach),
261 {0,0},
262 {0,0}
265 static driver_t ubt_driver = {
266 "ubt",
267 ubt_methods,
268 sizeof(struct ubt_softc)
271 DRIVER_MODULE(ubt, uhub, ubt_driver, ubt_devclass, usbd_driver_load, 0);
272 MODULE_DEPEND(ubt, netbt, 1, 1, 1);
273 #if 0 /* not yet */
274 MODULE_DEPEND(ubt, bthub, 1, 1, 1);
275 #endif
276 MODULE_DEPEND(ubt, usb, 1, 1, 1);
278 static int ubt_set_isoc_config(struct ubt_softc *);
279 static void ubt_abortdealloc(struct ubt_softc *);
282 * Match against the whole device, since we want to take
283 * both interfaces. If a device should be ignored then add
285 * { VendorID, ProductID }
287 * to the ubt_ignore list.
289 static const struct usb_devno ubt_ignore[] = {
290 { USB_DEVICE(0x0a5c, 0x2000) }, /* Braodcom BCM2033 */
291 { USB_DEVICE(0x0a5c, 0x2033) }, /* Broadcom BCM2033 (no fw) */
292 { 0, 0 } /* end of list */
295 static int
296 ubt_match(device_t self)
299 struct usb_attach_arg *uaa = device_get_ivars(self);
300 usb_device_descriptor_t *dd = usbd_get_device_descriptor(uaa->device);
302 DPRINTFN(50, "ubt_match\n");
304 if (usb_lookup(ubt_ignore, uaa->vendor, uaa->product))
305 return UMATCH_NONE;
307 if (dd->bDeviceClass == UDCLASS_WIRELESS
308 && dd->bDeviceSubClass == UDSUBCLASS_RF
309 && dd->bDeviceProtocol == UDPROTO_BLUETOOTH)
310 return UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO;
311 return UMATCH_NONE;
314 static int
315 ubt_attach(device_t self)
317 struct ubt_softc *sc = device_get_softc(self);
318 struct usb_attach_arg *uaa = device_get_ivars(self);
320 usb_config_descriptor_t *cd;
321 usb_endpoint_descriptor_t *ed;
322 int err;
323 uint8_t count, i;
325 DPRINTFN(50, "ubt_attach: sc=%p\n", sc);
327 sc->sc_udev = uaa->device;
328 sc->sc_dev = self;
331 * Move the device into the configured state
333 err = usbd_set_config_index(sc->sc_udev, 0, 1);
334 if (err) {
335 kprintf("%s: failed to set configuration idx 0: %s\n",
336 device_get_nameunit(sc->sc_dev), usbd_errstr(err));
338 return ENXIO;
342 * Interface 0 must have 3 endpoints
343 * 1) Interrupt endpoint to receive HCI events
344 * 2) Bulk IN endpoint to receive ACL data
345 * 3) Bulk OUT endpoint to send ACL data
348 err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface0);
349 if (err) {
350 kprintf("%s: Could not get interface 0 handle %s (%d)\n",
351 device_get_nameunit(sc->sc_dev), usbd_errstr(err), err);
353 return ENXIO;
356 sc->sc_evt_addr = -1;
357 sc->sc_aclrd_addr = -1;
358 sc->sc_aclwr_addr = -1;
360 count = 0;
361 (void)usbd_endpoint_count(sc->sc_iface0, &count);
363 for (i = 0 ; i < count ; i++) {
364 int dir, type;
366 ed = usbd_interface2endpoint_descriptor(sc->sc_iface0, i);
367 if (ed == NULL) {
368 kprintf("%s: could not read endpoint descriptor %d\n",
369 device_get_nameunit(sc->sc_dev), i);
371 return ENXIO;
374 dir = UE_GET_DIR(ed->bEndpointAddress);
375 type = UE_GET_XFERTYPE(ed->bmAttributes);
377 if (dir == UE_DIR_IN && type == UE_INTERRUPT)
378 sc->sc_evt_addr = ed->bEndpointAddress;
379 else if (dir == UE_DIR_IN && type == UE_BULK)
380 sc->sc_aclrd_addr = ed->bEndpointAddress;
381 else if (dir == UE_DIR_OUT && type == UE_BULK)
382 sc->sc_aclwr_addr = ed->bEndpointAddress;
385 if (sc->sc_evt_addr == -1) {
386 kprintf("%s: missing INTERRUPT endpoint on interface 0\n",
387 device_get_nameunit(sc->sc_dev));
389 return ENXIO;
391 if (sc->sc_aclrd_addr == -1) {
392 kprintf("%s: missing BULK IN endpoint on interface 0\n",
393 device_get_nameunit(sc->sc_dev));
395 return ENXIO;
397 if (sc->sc_aclwr_addr == -1) {
398 kprintf("%s: missing BULK OUT endpoint on interface 0\n",
399 device_get_nameunit(sc->sc_dev));
401 return ENXIO;
405 * Interface 1 must have 2 endpoints
406 * 1) Isochronous IN endpoint to receive SCO data
407 * 2) Isochronous OUT endpoint to send SCO data
409 * and will have several configurations, which can be selected
410 * via a sysctl variable. We select config 0 to start, which
411 * means that no SCO data will be available.
414 err = usbd_device2interface_handle(sc->sc_udev, 1, &sc->sc_iface1);
415 if (err) {
416 kprintf("%s: Could not get interface 1 handle %s (%d)\n",
417 device_get_nameunit(sc->sc_dev), usbd_errstr(err), err);
419 return ENXIO;
422 cd = usbd_get_config_descriptor(sc->sc_udev);
423 if (cd == NULL) {
424 kprintf("%s: could not get config descriptor\n",
425 device_get_nameunit(sc->sc_dev));
427 return ENXIO;
430 sc->sc_alt_config = usbd_get_no_alts(cd, 1);
432 /* set initial config */
434 err = ubt_set_isoc_config(sc);
435 if (err) {
436 kprintf("%s: ISOC config failed\n",
437 device_get_nameunit(sc->sc_dev));
439 return ENXIO;
442 /* Attach HCI host's software */
444 /* Fill HCI part of struct with data */
445 sc->sc_unit.hci_softc = self;
446 sc->sc_unit.hci_devname = device_get_nameunit(sc->sc_dev);
447 sc->sc_unit.hci_enable = ubt_enable;
448 sc->sc_unit.hci_disable = ubt_disable;
449 sc->sc_unit.hci_start_cmd = ubt_xmit_cmd_start;
450 sc->sc_unit.hci_start_acl = ubt_xmit_acl_start;
451 sc->sc_unit.hci_start_sco = ubt_xmit_sco_start;
453 /* Attach to HCI software stack */
455 hci_attach(&sc->sc_unit);
457 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
458 sc->sc_dev);
459 sc->sc_ok = 1;
461 return 0;
464 static int
465 ubt_detach(device_t self)
468 struct ubt_softc *sc = device_get_softc(self);
470 DPRINTF("sc=%p \n", sc);
472 sc->sc_dying = 1;
474 if (!sc->sc_ok)
475 return 0;
477 /* Detach HCI interface */
479 hci_detach(&sc->sc_unit);
482 * Abort all pipes. Causes processes waiting for transfer to wake.
484 * Actually, hci_detach() above will call ubt_disable() which may
485 * call ubt_abortdealloc(), but lets be sure since doing it twice
486 * wont cause an error.
489 ubt_abortdealloc(sc);
491 /* wait for all processes to finish */
493 if (sc->sc_refcnt-- > 0)
494 usb_detach_wait(sc->sc_dev);
496 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
497 sc->sc_dev);
499 DPRINTFN(1, "driver detached\n");
501 return 0;
504 /* set ISOC configuration */
506 ubt_set_isoc_config(struct ubt_softc *sc)
508 usb_endpoint_descriptor_t *ed;
509 int rd_addr, wr_addr, rd_size, wr_size;
510 uint8_t count, i;
511 int err;
513 err = usbd_set_interface(sc->sc_iface1, sc->sc_config);
514 if (err != USBD_NORMAL_COMPLETION) {
515 kprintf(
516 "%s: Could not set config %d on ISOC interface. %s (%d)\n",
517 device_get_nameunit(sc->sc_dev), sc->sc_config, usbd_errstr(err), err);
519 return err == USBD_IN_USE ? EBUSY : EIO;
523 * We wont get past the above if there are any pipes open, so no
524 * need to worry about buf/xfer/pipe deallocation. If we get an
525 * error after this, the frame quantities will be 0 and no SCO
526 * data will be possible.
529 sc->sc_scord_size = rd_size = 0;
530 sc->sc_scord_addr = rd_addr = -1;
532 sc->sc_scowr_size = wr_size = 0;
533 sc->sc_scowr_addr = wr_addr = -1;
535 count = 0;
536 (void)usbd_endpoint_count(sc->sc_iface1, &count);
538 for (i = 0 ; i < count ; i++) {
539 ed = usbd_interface2endpoint_descriptor(sc->sc_iface1, i);
540 if (ed == NULL) {
541 kprintf("%s: could not read endpoint descriptor %d\n",
542 device_get_nameunit(sc->sc_dev), i);
544 return EIO;
547 DPRINTFN(5, "%s: endpoint type %02x (%02x) addr %02x (%s)\n",
548 device_get_nameunit(sc->sc_dev),
549 UE_GET_XFERTYPE(ed->bmAttributes),
550 UE_GET_ISO_TYPE(ed->bmAttributes),
551 ed->bEndpointAddress,
552 UE_GET_DIR(ed->bEndpointAddress) ? "in" : "out");
554 if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
555 continue;
557 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) {
558 rd_addr = ed->bEndpointAddress;
559 rd_size = UGETW(ed->wMaxPacketSize);
560 } else {
561 wr_addr = ed->bEndpointAddress;
562 wr_size = UGETW(ed->wMaxPacketSize);
566 if (rd_addr == -1) {
567 kprintf(
568 "%s: missing ISOC IN endpoint on interface config %d\n",
569 device_get_nameunit(sc->sc_dev), sc->sc_config);
571 return ENOENT;
573 if (wr_addr == -1) {
574 kprintf(
575 "%s: missing ISOC OUT endpoint on interface config %d\n",
576 device_get_nameunit(sc->sc_dev), sc->sc_config);
578 return ENOENT;
581 #ifdef DIAGNOSTIC
582 if (rd_size > MLEN) {
583 kprintf("%s: rd_size=%d exceeds MLEN\n",
584 device_get_nameunit(sc->sc_dev), rd_size);
586 return EOVERFLOW;
589 if (wr_size > MLEN) {
590 kprintf("%s: wr_size=%d exceeds MLEN\n",
591 device_get_nameunit(sc->sc_dev), wr_size);
593 return EOVERFLOW;
595 #endif
597 sc->sc_scord_size = rd_size;
598 sc->sc_scord_addr = rd_addr;
600 sc->sc_scowr_size = wr_size;
601 sc->sc_scowr_addr = wr_addr;
603 return 0;
606 void
607 ubt_abortdealloc(struct ubt_softc *sc)
609 int i;
611 DPRINTFN(1, "sc=%p\n", sc);
612 crit_enter();
613 /* Abort all pipes */
614 if (sc->sc_evt_pipe != NULL) {
615 usbd_abort_pipe(sc->sc_evt_pipe);
616 usbd_close_pipe(sc->sc_evt_pipe);
617 sc->sc_evt_pipe = NULL;
620 if (sc->sc_aclrd_pipe != NULL) {
621 usbd_abort_pipe(sc->sc_aclrd_pipe);
622 usbd_close_pipe(sc->sc_aclrd_pipe);
623 sc->sc_aclrd_pipe = NULL;
626 if (sc->sc_aclwr_pipe != NULL) {
627 usbd_abort_pipe(sc->sc_aclwr_pipe);
628 usbd_close_pipe(sc->sc_aclwr_pipe);
629 sc->sc_aclwr_pipe = NULL;
632 if (sc->sc_scord_pipe != NULL) {
633 usbd_abort_pipe(sc->sc_scord_pipe);
634 usbd_close_pipe(sc->sc_scord_pipe);
635 sc->sc_scord_pipe = NULL;
638 if (sc->sc_scowr_pipe != NULL) {
639 usbd_abort_pipe(sc->sc_scowr_pipe);
640 usbd_close_pipe(sc->sc_scowr_pipe);
641 sc->sc_scowr_pipe = NULL;
644 /* Free event buffer */
645 if (sc->sc_evt_buf != NULL) {
646 kfree(sc->sc_evt_buf, M_USBDEV);
647 sc->sc_evt_buf = NULL;
650 /* Free all xfers and xfer buffers (implicit) */
651 if (sc->sc_cmd_xfer != NULL) {
652 usbd_free_xfer(sc->sc_cmd_xfer);
653 sc->sc_cmd_xfer = NULL;
654 sc->sc_cmd_buf = NULL;
657 if (sc->sc_aclrd_xfer != NULL) {
658 usbd_free_xfer(sc->sc_aclrd_xfer);
659 sc->sc_aclrd_xfer = NULL;
660 sc->sc_aclrd_buf = NULL;
663 if (sc->sc_aclwr_xfer != NULL) {
664 usbd_free_xfer(sc->sc_aclwr_xfer);
665 sc->sc_aclwr_xfer = NULL;
666 sc->sc_aclwr_buf = NULL;
669 for (i = 0 ; i < UBT_NXFERS ; i++) {
670 if (sc->sc_scord[i].xfer != NULL) {
671 usbd_free_xfer(sc->sc_scord[i].xfer);
672 sc->sc_scord[i].xfer = NULL;
673 sc->sc_scord[i].buf = NULL;
676 if (sc->sc_scowr[i].xfer != NULL) {
677 usbd_free_xfer(sc->sc_scowr[i].xfer);
678 sc->sc_scowr[i].xfer = NULL;
679 sc->sc_scowr[i].buf = NULL;
683 /* Free partial SCO packets */
684 if (sc->sc_scord_mbuf != NULL) {
685 m_freem(sc->sc_scord_mbuf);
686 sc->sc_scord_mbuf = NULL;
689 if (sc->sc_scowr_mbuf != NULL) {
690 m_freem(sc->sc_scowr_mbuf);
691 sc->sc_scowr_mbuf = NULL;
693 crit_exit();
696 /*******************************************************************************
698 * Bluetooth Unit/USB callbacks
700 * All of this will be called at the IPL_ we specified above
703 ubt_enable(struct hci_unit *unit)
705 struct ubt_softc *sc = device_get_softc(unit->hci_softc);
706 usbd_status err;
707 int i, error;
709 DPRINTFN(1, "%s: sc=%p\n", __func__, sc);
711 if (unit->hci_flags & BTF_RUNNING)
712 return 0;
714 /* Events */
716 sc->sc_evt_buf = kmalloc(UBT_BUFSIZ_EVENT, M_USBDEV, M_NOWAIT);
717 if (sc->sc_evt_buf == NULL) {
718 error = ENOMEM;
719 goto bad;
722 err = usbd_open_pipe_intr(sc->sc_iface0,
723 sc->sc_evt_addr,
724 USBD_SHORT_XFER_OK,
725 &sc->sc_evt_pipe,
727 sc->sc_evt_buf,
728 UBT_BUFSIZ_EVENT,
729 ubt_recv_event,
730 UBT_INTR_TIMEOUT);
731 if (err != USBD_NORMAL_COMPLETION) {
732 error = EIO;
733 kprintf("can't open events pipe_intr\n");
734 goto bad;
737 /* Commands */
739 sc->sc_cmd_xfer = usbd_alloc_xfer(sc->sc_udev);
740 if (sc->sc_cmd_xfer == NULL) {
741 kprintf("can't allocate cmd_xfer\n");
742 error = ENOMEM;
743 goto bad;
745 sc->sc_cmd_buf = usbd_alloc_buffer(sc->sc_cmd_xfer, UBT_BUFSIZ_CMD);
746 if (sc->sc_cmd_buf == NULL) {
747 kprintf("can't allocate cmd_buf\n");
748 error = ENOMEM;
749 goto bad;
752 /* ACL read */
754 err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclrd_addr,
755 USBD_EXCLUSIVE_USE, &sc->sc_aclrd_pipe);
756 if (err != USBD_NORMAL_COMPLETION) {
757 kprintf("can't open aclrd pipe\n");
758 error = EIO;
759 goto bad;
761 sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev);
762 if (sc->sc_aclrd_xfer == NULL) {
763 kprintf("can't allocate aclrd_xfer\n");
764 error = ENOMEM;
765 goto bad;
767 sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer, UBT_BUFSIZ_ACL);
768 if (sc->sc_aclrd_buf == NULL) {
769 kprintf("can't allocate aclrd_buf\n");
770 error = ENOMEM;
771 goto bad;
773 sc->sc_aclrd_busy = 0;
774 ubt_recv_acl_start(sc);
776 /* ACL write */
778 err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclwr_addr,
779 USBD_EXCLUSIVE_USE, &sc->sc_aclwr_pipe);
780 if (err != USBD_NORMAL_COMPLETION) {
781 kprintf("can't open aclwr pipe\n");
782 error = EIO;
783 goto bad;
785 sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev);
786 if (sc->sc_aclwr_xfer == NULL) {
787 kprintf("can't allocate aclwr_xfer\n");
788 error = ENOMEM;
789 goto bad;
791 sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer, UBT_BUFSIZ_ACL);
792 if (sc->sc_aclwr_buf == NULL) {
793 kprintf("can't allocate aclwr_buf\n");
794 error = ENOMEM;
795 goto bad;
798 /* SCO read */
800 if (sc->sc_scord_size > 0) {
801 err = usbd_open_pipe(sc->sc_iface1, sc->sc_scord_addr,
802 USBD_EXCLUSIVE_USE, &sc->sc_scord_pipe);
803 if (err != USBD_NORMAL_COMPLETION) {
804 error = EIO;
805 goto bad;
808 for (i = 0 ; i < UBT_NXFERS ; i++) {
809 sc->sc_scord[i].xfer = usbd_alloc_xfer(sc->sc_udev);
810 if (sc->sc_scord[i].xfer == NULL) {
811 error = ENOMEM;
812 goto bad;
814 sc->sc_scord[i].buf = usbd_alloc_buffer(sc->sc_scord[i].xfer,
815 sc->sc_scord_size * UBT_NFRAMES);
816 if (sc->sc_scord[i].buf == NULL) {
817 error = ENOMEM;
818 goto bad;
820 sc->sc_scord[i].softc = sc;
821 sc->sc_scord[i].busy = 0;
822 ubt_recv_sco_start1(sc, &sc->sc_scord[i]);
826 /* SCO write */
828 if (sc->sc_scowr_size > 0) {
829 err = usbd_open_pipe(sc->sc_iface1, sc->sc_scowr_addr,
830 USBD_EXCLUSIVE_USE, &sc->sc_scowr_pipe);
831 if (err != USBD_NORMAL_COMPLETION) {
832 error = EIO;
833 goto bad;
836 for (i = 0 ; i < UBT_NXFERS ; i++) {
837 sc->sc_scowr[i].xfer = usbd_alloc_xfer(sc->sc_udev);
838 if (sc->sc_scowr[i].xfer == NULL) {
839 error = ENOMEM;
840 goto bad;
842 sc->sc_scowr[i].buf = usbd_alloc_buffer(sc->sc_scowr[i].xfer,
843 sc->sc_scowr_size * UBT_NFRAMES);
844 if (sc->sc_scowr[i].buf == NULL) {
845 error = ENOMEM;
846 goto bad;
848 sc->sc_scowr[i].softc = sc;
849 sc->sc_scowr[i].busy = 0;
853 unit->hci_flags &= ~BTF_XMIT;
854 unit->hci_flags |= BTF_RUNNING;
856 return 0;
858 bad:
859 kprintf("ubt_enable: something going wrong... :( \n");
860 ubt_abortdealloc(sc);
861 return error;
864 void
865 ubt_disable(struct hci_unit *unit)
867 struct ubt_softc *sc = device_get_softc(unit->hci_softc);
869 DPRINTFN(1, "sc=%p\n", sc);
871 if ((unit->hci_flags & BTF_RUNNING) == 0)
872 return;
874 ubt_abortdealloc(sc);
876 unit->hci_flags &= ~BTF_RUNNING;
879 void
880 ubt_xmit_cmd_start(struct hci_unit *unit)
882 struct ubt_softc *sc = device_get_softc(unit->hci_softc);
883 usb_device_request_t req;
884 usbd_status status;
885 struct mbuf *m;
886 int len;
888 if (sc->sc_dying)
889 return;
893 if (IF_QEMPTY(&unit->hci_cmdq))
894 return;
895 IF_DEQUEUE(&unit->hci_cmdq, m);
896 DPRINTFN(15, " %s: xmit CMD packet (%d bytes)\n",
897 unit->hci_devname, m->m_pkthdr.len);
899 sc->sc_refcnt++;
901 unit->hci_flags |= BTF_XMIT_CMD;
903 len = m->m_pkthdr.len - 1;
904 m_copydata(m, 1, len, sc->sc_cmd_buf);
905 m_freem(m);
907 memset(&req, 0, sizeof(req));
908 req.bmRequestType = UT_WRITE_CLASS_DEVICE;
909 USETW(req.wLength, len);
911 usbd_setup_default_xfer(sc->sc_cmd_xfer,
912 sc->sc_udev,
913 unit,
914 UBT_CMD_TIMEOUT,
915 &req,
916 sc->sc_cmd_buf,
917 len,
918 USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
919 ubt_xmit_cmd_complete);
921 status = usbd_transfer(sc->sc_cmd_xfer);
923 KKASSERT(status != USBD_NORMAL_COMPLETION);
925 if (status != USBD_IN_PROGRESS) {
926 DPRINTF("usbd_transfer status=%s (%d)\n",
927 usbd_errstr(status), status);
928 sc->sc_refcnt--;
929 unit->hci_flags &= ~BTF_XMIT_CMD;
934 void
935 ubt_xmit_cmd_complete(usbd_xfer_handle xfer,
936 usbd_private_handle h, usbd_status status)
938 struct hci_unit *unit = h;
939 struct ubt_softc *sc = device_get_softc(unit->hci_softc);
940 uint32_t count;
942 DPRINTFN(15, " %s: CMD complete status=%s (%d)\n",
943 unit->hci_devname, usbd_errstr(status), status);
945 unit->hci_flags &= ~BTF_XMIT_CMD;
947 if (--sc->sc_refcnt < 0) {
948 DPRINTF("sc_refcnt=%d\n", sc->sc_refcnt);
949 usb_detach_wakeup(sc->sc_dev);
950 return;
953 if (sc->sc_dying) {
954 DPRINTF("sc_dying\n");
955 return;
958 if (status != USBD_NORMAL_COMPLETION) {
959 DPRINTF("status=%s (%d)\n",
960 usbd_errstr(status), status);
961 unit->hci_stats.err_tx++;
962 return;
965 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
967 unit->hci_stats.cmd_tx++;
968 unit->hci_stats.byte_tx += count;
970 ubt_xmit_cmd_start(unit);
973 void
974 ubt_xmit_acl_start(struct hci_unit *unit)
976 struct ubt_softc *sc = device_get_softc(unit->hci_softc);
977 struct mbuf *m;
978 usbd_status status;
979 int len;
981 if (sc->sc_dying)
982 return;
985 if (IF_QEMPTY(&unit->hci_acltxq))
986 return;
988 sc->sc_refcnt++;
989 unit->hci_flags |= BTF_XMIT_ACL;
991 IF_DEQUEUE(&unit->hci_acltxq, m);
993 DPRINTFN(15, "%s: xmit ACL packet (%d bytes)\n",
994 unit->hci_devname, m->m_pkthdr.len);
996 len = m->m_pkthdr.len - 1;
997 if (len > UBT_BUFSIZ_ACL) {
998 DPRINTF("%s: truncating ACL packet (%d => %d)!\n",
999 unit->hci_devname, len, UBT_BUFSIZ_ACL);
1001 len = UBT_BUFSIZ_ACL;
1004 m_copydata(m, 1, len, sc->sc_aclwr_buf);
1005 m_freem(m);
1007 unit->hci_stats.acl_tx++;
1008 unit->hci_stats.byte_tx += len;
1010 usbd_setup_xfer(sc->sc_aclwr_xfer,
1011 sc->sc_aclwr_pipe,
1012 unit,
1013 sc->sc_aclwr_buf,
1014 len,
1015 USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
1016 UBT_ACL_TIMEOUT,
1017 ubt_xmit_acl_complete);
1019 status = usbd_transfer(sc->sc_aclwr_xfer);
1021 KKASSERT(status != USBD_NORMAL_COMPLETION);
1023 if (status != USBD_IN_PROGRESS) {
1024 DPRINTF("usbd_transfer status=%s (%d)\n",
1025 usbd_errstr(status), status);
1027 sc->sc_refcnt--;
1028 unit->hci_flags &= ~BTF_XMIT_ACL;
1033 void
1034 ubt_xmit_acl_complete(usbd_xfer_handle xfer,
1035 usbd_private_handle h, usbd_status status)
1037 struct hci_unit *unit = h;
1038 struct ubt_softc *sc = device_get_softc(unit->hci_softc);
1040 DPRINTFN(15, "%s: ACL complete status=%s (%d)\n",
1041 unit->hci_devname, usbd_errstr(status), status);
1043 unit->hci_flags &= ~BTF_XMIT_ACL;
1045 if (--sc->sc_refcnt < 0) {
1046 usb_detach_wakeup(sc->sc_dev);
1047 return;
1050 if (sc->sc_dying)
1051 return;
1053 if (status != USBD_NORMAL_COMPLETION) {
1054 DPRINTF("status=%s (%d)\n",
1055 usbd_errstr(status), status);
1057 unit->hci_stats.err_tx++;
1059 if (status == USBD_STALLED)
1060 usbd_clear_endpoint_stall_async(sc->sc_aclwr_pipe);
1061 else
1062 return;
1065 ubt_xmit_acl_start(unit);
1069 void
1070 ubt_xmit_sco_start(struct hci_unit *unit)
1072 struct ubt_softc *sc = device_get_softc(unit->hci_softc);
1073 int i;
1075 if (sc->sc_dying || sc->sc_scowr_size == 0)
1076 return;
1078 for (i = 0 ; i < UBT_NXFERS ; i++) {
1079 if (sc->sc_scowr[i].busy)
1080 continue;
1082 ubt_xmit_sco_start1(sc, &sc->sc_scowr[i]);
1086 void
1087 ubt_xmit_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc)
1089 struct mbuf *m;
1090 uint8_t *buf;
1091 int num, len, size, space;
1093 if (sc->sc_dying)
1094 return;
1096 space = sc->sc_scowr_size * UBT_NFRAMES;
1097 buf = isoc->buf;
1098 len = 0;
1101 * Fill the request buffer with data from the queue,
1102 * keeping any leftover packet on our private hook.
1104 * Complete packets are passed back up to the stack
1105 * for disposal, since we can't rely on the controller
1106 * to tell us when it has finished with them.
1109 m = sc->sc_scowr_mbuf;
1110 while (space > 0) {
1111 if (m == NULL) {
1112 crit_enter();
1113 IF_DEQUEUE(&sc->sc_unit.hci_scotxq, m);
1114 crit_exit();
1115 if (m == NULL)
1116 break;
1118 m_adj(m, 1); /* packet type */
1122 if (m->m_pkthdr.len > 0) {
1123 size = MIN(m->m_pkthdr.len, space);
1125 m_copydata(m, 0, size, buf);
1126 m_adj(m, size);
1128 buf += size;
1129 len += size;
1130 space -= size;
1133 if (m->m_pkthdr.len == 0) {
1134 sc->sc_unit.hci_stats.sco_tx++;
1135 hci_complete_sco(&sc->sc_unit, m);
1136 m = NULL;
1139 sc->sc_scowr_mbuf = m;
1141 DPRINTFN(15, "isoc=%p, len=%d, space=%d\n", isoc, len, space);
1143 if (len == 0) /* nothing to send */
1145 return;
1147 sc->sc_refcnt++;
1148 sc->sc_unit.hci_flags |= BTF_XMIT_SCO;
1149 sc->sc_unit.hci_stats.byte_tx += len;
1150 isoc->busy = 1;
1153 * calculate number of isoc frames and sizes
1156 for (num = 0 ; len > 0 ; num++) {
1157 size = MIN(sc->sc_scowr_size, len);
1159 isoc->size[num] = size;
1160 len -= size;
1163 usbd_setup_isoc_xfer(isoc->xfer,
1164 sc->sc_scowr_pipe,
1165 isoc,
1166 isoc->size,
1167 num,
1168 USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
1169 ubt_xmit_sco_complete);
1171 usbd_transfer(isoc->xfer);
1174 void
1175 ubt_xmit_sco_complete(usbd_xfer_handle xfer,
1176 usbd_private_handle h, usbd_status status)
1178 struct ubt_isoc_xfer *isoc = h;
1179 struct ubt_softc *sc;
1180 int i;
1182 KKASSERT(xfer == isoc->xfer);
1183 sc = isoc->softc;
1185 DPRINTFN(15, "isoc=%p, status=%s (%d)\n",
1186 isoc, usbd_errstr(status), status);
1188 isoc->busy = 0;
1190 for (i = 0 ; ; i++) {
1191 if (i == UBT_NXFERS) {
1192 sc->sc_unit.hci_flags &= ~BTF_XMIT_SCO;
1193 break;
1196 if (sc->sc_scowr[i].busy)
1197 break;
1200 if (--sc->sc_refcnt < 0) {
1201 usb_detach_wakeup(sc->sc_dev);
1202 return;
1205 if (sc->sc_dying)
1206 return;
1208 if (status != USBD_NORMAL_COMPLETION) {
1209 DPRINTF("status=%s (%d)\n",
1210 usbd_errstr(status), status);
1212 sc->sc_unit.hci_stats.err_tx++;
1214 if (status == USBD_STALLED)
1215 usbd_clear_endpoint_stall_async(sc->sc_scowr_pipe);
1216 else
1217 return;
1220 ubt_xmit_sco_start(&sc->sc_unit);
1224 * Load incoming data into an mbuf with leading type byte.
1226 static struct mbuf *
1227 ubt_mbufload(uint8_t *buf, int count, uint8_t type)
1229 struct mbuf *m;
1230 MGETHDR(m, MB_DONTWAIT, MT_DATA);
1231 if (m == NULL) {kprintf(" MGETHDR return NULL\n");
1232 return NULL; }
1233 *mtod(m, uint8_t *) = type;
1234 m->m_pkthdr.len = m->m_len = MHLEN;
1235 m_copyback(m, 1, count, buf); /* (extends if necessary)*/
1236 if (m->m_pkthdr.len != MAX(MHLEN, count + 1)) {
1237 m_free(m);
1238 kprintf(" m->m_pkthdr.len != MAX() \n");
1239 return NULL;
1241 m->m_pkthdr.len = count + 1;
1242 m->m_len = MIN(MHLEN, m->m_pkthdr.len);
1243 return m;
1246 void
1247 ubt_recv_event(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status)
1249 struct ubt_softc *sc = h;
1250 struct mbuf *m;
1251 uint32_t count;
1252 void *buf;
1254 DPRINTFN(15, "sc=%p status=%s (%d)\n",
1255 sc, usbd_errstr(status), status);
1257 if (status != USBD_NORMAL_COMPLETION || sc->sc_dying)
1258 return;
1260 usbd_get_xfer_status(xfer, NULL, &buf, &count, NULL);
1262 if (count < sizeof(hci_event_hdr_t) - 1) {
1263 DPRINTF("dumped undersized event (count = %d)\n", count);
1264 sc->sc_unit.hci_stats.err_rx++;
1265 return;
1268 sc->sc_unit.hci_stats.evt_rx++;
1269 sc->sc_unit.hci_stats.byte_rx += count;
1271 m = ubt_mbufload(buf, count, HCI_EVENT_PKT);
1272 if (m != NULL){
1273 hci_input_event(&sc->sc_unit, m);
1275 else
1276 sc->sc_unit.hci_stats.err_rx++;
1279 void
1280 ubt_recv_acl_start(struct ubt_softc *sc)
1282 usbd_status status;
1284 DPRINTFN(15, "sc=%p\n", sc);
1286 if (sc->sc_aclrd_busy || sc->sc_dying) {
1287 DPRINTF("sc_aclrd_busy=%d, sc_dying=%d\n",
1288 sc->sc_aclrd_busy,
1289 sc->sc_dying);
1291 return;
1294 sc->sc_refcnt++;
1295 sc->sc_aclrd_busy = 1;
1297 usbd_setup_xfer(sc->sc_aclrd_xfer,
1298 sc->sc_aclrd_pipe,
1300 sc->sc_aclrd_buf,
1301 UBT_BUFSIZ_ACL,
1302 USBD_NO_COPY | USBD_SHORT_XFER_OK,
1303 USBD_NO_TIMEOUT,
1304 ubt_recv_acl_complete);
1306 status = usbd_transfer(sc->sc_aclrd_xfer);
1308 KKASSERT(status != USBD_NORMAL_COMPLETION);
1310 if (status != USBD_IN_PROGRESS) {
1311 DPRINTF("usbd_transfer status=%s (%d)\n",
1312 usbd_errstr(status), status);
1314 sc->sc_refcnt--;
1315 sc->sc_aclrd_busy = 0;
1319 void
1320 ubt_recv_acl_complete(usbd_xfer_handle xfer,
1321 usbd_private_handle h, usbd_status status)
1323 struct ubt_softc *sc = h;
1324 struct mbuf *m;
1325 uint32_t count;
1326 void *buf;
1328 DPRINTFN(15, "sc=%p status=%s (%d)\n",
1329 sc, usbd_errstr(status), status);
1331 sc->sc_aclrd_busy = 0;
1333 if (--sc->sc_refcnt < 0) {
1334 DPRINTF("refcnt = %d\n", sc->sc_refcnt);
1335 usb_detach_wakeup(sc->sc_dev);
1336 return;
1339 if (sc->sc_dying) {
1340 DPRINTF("sc_dying\n");
1341 return;
1344 if (status != USBD_NORMAL_COMPLETION) {
1345 DPRINTF("status=%s (%d)\n",
1346 usbd_errstr(status), status);
1348 sc->sc_unit.hci_stats.err_rx++;
1350 if (status == USBD_STALLED)
1351 usbd_clear_endpoint_stall_async(sc->sc_aclrd_pipe);
1352 else
1353 return;
1354 } else {
1355 usbd_get_xfer_status(xfer, NULL, &buf, &count, NULL);
1357 if (count < sizeof(hci_acldata_hdr_t) - 1) {
1358 DPRINTF("dumped undersized packet (%d)\n", count);
1359 sc->sc_unit.hci_stats.err_rx++;
1360 } else {
1361 sc->sc_unit.hci_stats.acl_rx++;
1362 sc->sc_unit.hci_stats.byte_rx += count;
1364 m = ubt_mbufload(buf, count, HCI_ACL_DATA_PKT);
1365 if (m != NULL)
1366 hci_input_acl(&sc->sc_unit, m);
1367 else
1368 sc->sc_unit.hci_stats.err_rx++;
1372 /* and restart */
1373 ubt_recv_acl_start(sc);
1376 void
1377 ubt_recv_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc)
1379 int i;
1381 DPRINTFN(15, "sc=%p, isoc=%p\n", sc, isoc);
1383 if (isoc->busy || sc->sc_dying || sc->sc_scord_size == 0) {
1384 DPRINTF("%s%s%s\n",
1385 isoc->busy ? " busy" : "",
1386 sc->sc_dying ? " dying" : "",
1387 sc->sc_scord_size == 0 ? " size=0" : "");
1389 return;
1392 sc->sc_refcnt++;
1393 isoc->busy = 1;
1395 for (i = 0 ; i < UBT_NFRAMES ; i++)
1396 isoc->size[i] = sc->sc_scord_size;
1398 usbd_setup_isoc_xfer(isoc->xfer,
1399 sc->sc_scord_pipe,
1400 isoc,
1401 isoc->size,
1402 UBT_NFRAMES,
1403 USBD_NO_COPY | USBD_SHORT_XFER_OK,
1404 ubt_recv_sco_complete);
1406 usbd_transfer(isoc->xfer);
1409 void
1410 ubt_recv_sco_complete(usbd_xfer_handle xfer,
1411 usbd_private_handle h, usbd_status status)
1413 struct ubt_isoc_xfer *isoc = h;
1414 struct ubt_softc *sc;
1415 struct mbuf *m;
1416 uint32_t count;
1417 uint8_t *ptr, *frame;
1418 int i, size, got, want;
1420 KKASSERT(isoc != NULL);
1421 KKASSERT(isoc->xfer == xfer);
1423 sc = isoc->softc;
1424 isoc->busy = 0;
1426 if (--sc->sc_refcnt < 0) {
1427 DPRINTF("refcnt=%d\n", sc->sc_refcnt);
1428 usb_detach_wakeup(sc->sc_dev);
1429 return;
1432 if (sc->sc_dying) {
1433 DPRINTF("sc_dying\n");
1434 return;
1437 if (status != USBD_NORMAL_COMPLETION) {
1438 DPRINTF("status=%s (%d)\n",
1439 usbd_errstr(status), status);
1441 sc->sc_unit.hci_stats.err_rx++;
1443 if (status == USBD_STALLED) {
1444 usbd_clear_endpoint_stall_async(sc->sc_scord_pipe);
1445 goto restart;
1448 return;
1451 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1452 if (count == 0)
1453 goto restart;
1455 DPRINTFN(15, "sc=%p, isoc=%p, count=%u\n",
1456 sc, isoc, count);
1458 sc->sc_unit.hci_stats.byte_rx += count;
1461 * Extract SCO packets from ISOC frames. The way we have it,
1462 * no SCO packet can be bigger than MHLEN. This is unlikely
1463 * to actually happen, but if we ran out of mbufs and lost
1464 * sync then we may get spurious data that makes it seem that
1465 * way, so we discard data that wont fit. This doesnt really
1466 * help with the lost sync situation alas.
1469 m = sc->sc_scord_mbuf;
1470 if (m != NULL) {
1471 sc->sc_scord_mbuf = NULL;
1472 ptr = mtod(m, uint8_t *) + m->m_pkthdr.len;
1473 got = m->m_pkthdr.len;
1474 want = sizeof(hci_scodata_hdr_t);
1475 if (got >= want)
1476 want += mtod(m, hci_scodata_hdr_t *)->length ;
1477 } else {
1478 ptr = NULL;
1479 got = 0;
1480 want = 0;
1483 for (i = 0 ; i < UBT_NFRAMES ; i++) {
1484 frame = isoc->buf + (i * sc->sc_scord_size);
1486 while (isoc->size[i] > 0) {
1487 size = isoc->size[i];
1489 if (m == NULL) {
1490 MGETHDR(m, MB_DONTWAIT, MT_DATA);
1491 if (m == NULL) {
1492 kprintf("%s: out of memory (xfer halted)\n",
1493 device_get_nameunit(sc->sc_dev));
1495 sc->sc_unit.hci_stats.err_rx++;
1496 return; /* lost sync */
1499 ptr = mtod(m, uint8_t *);
1500 *ptr++ = HCI_SCO_DATA_PKT;
1501 got = 1;
1502 want = sizeof(hci_scodata_hdr_t);
1505 if (got + size > want)
1506 size = want - got;
1508 if (got + size > MHLEN)
1509 memcpy(ptr, frame, MHLEN - got);
1510 else
1511 memcpy(ptr, frame, size);
1513 ptr += size;
1514 got += size;
1515 frame += size;
1517 if (got == want) {
1519 * If we only got a header, add the packet
1520 * length to our want count. Send complete
1521 * packets up to protocol stack.
1523 if (want == sizeof(hci_scodata_hdr_t))
1524 want += mtod(m, hci_scodata_hdr_t *)->length;
1526 if (got == want) {
1527 m->m_pkthdr.len = m->m_len = got;
1528 sc->sc_unit.hci_stats.sco_rx++;
1529 hci_input_sco(&sc->sc_unit, m);
1530 m = NULL;
1534 isoc->size[i] -= size;
1538 if (m != NULL) {
1539 m->m_pkthdr.len = m->m_len = got;
1540 sc->sc_scord_mbuf = m;
1543 restart: /* and restart */
1544 ubt_recv_sco_start1(sc, isoc);