1 /* $DragonFly: src/sys/dev/usbmisc/ubt/ubt.c,v 1.3 2008/03/18 13:41:42 hasso Exp $ */
2 /* $OpenBSD: src/sys/dev/usb/ubt.c,v 1.11 2008/02/24 21:34:48 uwe Exp $ */
3 /* $NetBSD: ubt.c,v 1.30 2007/12/16 19:01:37 christos Exp $ */
6 * Copyright (c) 2006 Itronix Inc.
9 * Written by Iain Hibbert for Itronix Inc.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of Itronix Inc. may not be used to endorse
20 * or promote products derived from this software without specific
21 * prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
36 * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
37 * All rights reserved.
39 * This code is derived from software contributed to The NetBSD Foundation
40 * by Lennart Augustsson (lennart@augustsson.net) and
41 * David Sainty (David.Sainty@dtsp.co.nz).
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 3. All advertising materials mentioning features or use of this software
52 * must display the following acknowledgement:
53 * This product includes software developed by the NetBSD
54 * Foundation, Inc. and its contributors.
55 * 4. Neither the name of The NetBSD Foundation nor the names of its
56 * contributors may be used to endorse or promote products derived
57 * from this software without specific prior written permission.
59 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
60 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
61 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
62 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
63 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
64 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
65 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
66 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
67 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
68 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
69 * POSSIBILITY OF SUCH DAMAGE.
72 * This driver originally written by Lennart Augustsson and David Sainty,
73 * but was mostly rewritten for the NetBSD Bluetooth protocol stack by
74 * Iain Hibbert for Itronix, Inc using the FreeBSD ng_ubt.c driver as a
79 #include <sys/kernel.h>
81 #include <sys/sysctl.h>
83 #include <bus/usb/usb.h>
84 #include <bus/usb/usbdi.h>
85 #include <bus/usb/usbdi_util.h>
86 #include <bus/usb/usbdivar.h>
88 #include <netbt/bluetooth.h>
89 #include <netbt/hci.h>
91 /*******************************************************************************
99 int ubt_debug
= UBT_DEBUG
;
101 #define DPRINTF(fmt, args...) do { \
103 kprintf("%s: "fmt, __func__ , ##args); \
104 } while (/* CONSTCOND */0)
106 #define DPRINTFN(n, fmt, args...) do { \
107 if (ubt_debug > (n)) \
108 kprintf("%s: "fmt, __func__ , ##args); \
109 } while (/* CONSTCOND */0)
113 #define DPRINTFN(...)
116 /*******************************************************************************
118 * ubt softc structure
124 * NB: although ACL packets can extend to 65535 bytes, most devices
125 * have max_acl_size at much less (largest I have seen is 384)
127 #define UBT_BUFSIZ_CMD (HCI_CMD_PKT_SIZE - 1)
128 #define UBT_BUFSIZ_ACL (2048 - 1)
129 #define UBT_BUFSIZ_EVENT (HCI_EVENT_PKT_SIZE - 1)
131 /* Transmit timeouts */
133 #define UBT_CMD_TIMEOUT 100
134 #define UBT_ACL_TIMEOUT 100
137 * Specification says, that is must be 1ms, but it causes kernel panic.
138 * Setting interval to USBD_DEFAULT_INTERVAL is not working for some of
140 * XXX: Make it sysctl.
142 #define UBT_INTR_TIMEOUT USBD_DEFAULT_INTERVAL
147 * xfer buffer size depends on the frame size, and the number
148 * of frames per transfer is fixed, as each frame should be
149 * 1ms worth of data. This keeps the rate that xfers complete
150 * fairly constant. We use multiple xfers to keep the hardware
153 #define UBT_NXFERS 3 /* max xfers to queue */
154 #define UBT_NFRAMES 10 /* frames per xfer */
156 struct ubt_isoc_xfer
{
157 struct ubt_softc
*softc
;
158 usbd_xfer_handle xfer
;
160 uint16_t size
[UBT_NFRAMES
];
166 usbd_device_handle sc_udev
;
171 /* Control Interface */
172 usbd_interface_handle sc_iface0
;
174 /* Commands (control) */
175 usbd_xfer_handle sc_cmd_xfer
;
177 int sc_cmd_busy
; /* write active */
178 struct ifqueue sc_cmd_queue
; /* output queue */
180 /* Events (interrupt) */
181 int sc_evt_addr
; /* endpoint address */
182 usbd_pipe_handle sc_evt_pipe
;
187 int sc_aclrd_addr
; /* endpoint address */
188 usbd_pipe_handle sc_aclrd_pipe
; /* read pipe */
189 usbd_xfer_handle sc_aclrd_xfer
; /* read xfer */
190 u_char
*sc_aclrd_buf
; /* read buffer */
191 int sc_aclrd_busy
; /* reading */
194 int sc_aclwr_addr
; /* endpoint address */
195 usbd_pipe_handle sc_aclwr_pipe
; /* write pipe */
196 usbd_xfer_handle sc_aclwr_xfer
; /* write xfer */
197 u_char
*sc_aclwr_buf
; /* write buffer */
198 int sc_aclwr_busy
; /* write active */
199 struct ifqueue sc_aclwr_queue
;/* output queue */
202 usbd_interface_handle sc_iface1
; /* ISOC interface */
203 struct sysctllog
*sc_log
; /* sysctl log */
204 int sc_config
; /* current config no */
205 int sc_alt_config
; /* no of alternates */
208 int sc_scord_addr
; /* endpoint address */
209 usbd_pipe_handle sc_scord_pipe
; /* read pipe */
210 int sc_scord_size
; /* frame length */
211 struct ubt_isoc_xfer sc_scord
[UBT_NXFERS
];
212 struct mbuf
*sc_scord_mbuf
; /* current packet */
215 int sc_scowr_addr
; /* endpoint address */
216 usbd_pipe_handle sc_scowr_pipe
; /* write pipe */
217 int sc_scowr_size
; /* frame length */
218 struct ubt_isoc_xfer sc_scowr
[UBT_NXFERS
];
219 struct mbuf
*sc_scowr_mbuf
; /* current packet */
220 int sc_scowr_busy
; /* write active */
221 struct ifqueue sc_scowr_queue
;/* output queue */
223 /* Protocol structure */
224 struct hci_unit
*sc_unit
;
225 struct bt_stats sc_stats
;
227 /* Successfully attached */
230 struct sysctl_ctx_list sysctl_ctx
;
231 struct sysctl_oid
*sysctl_tree
;
235 * Bluetooth unit/USB callback routines
237 int ubt_enable(struct device
*);
238 void ubt_disable(struct device
*);
240 void ubt_xmit_cmd(struct device
*, struct mbuf
*);
241 void ubt_xmit_cmd_start(struct ubt_softc
*);
242 void ubt_xmit_cmd_complete(usbd_xfer_handle
,
243 usbd_private_handle
, usbd_status
);
245 void ubt_xmit_acl(struct device
*, struct mbuf
*);
246 void ubt_xmit_acl_start(struct ubt_softc
*);
247 void ubt_xmit_acl_complete(usbd_xfer_handle
,
248 usbd_private_handle
, usbd_status
);
250 void ubt_xmit_sco(struct device
*, struct mbuf
*);
251 void ubt_xmit_sco_start(struct ubt_softc
*);
252 void ubt_xmit_sco_start1(struct ubt_softc
*, struct ubt_isoc_xfer
*);
253 void ubt_xmit_sco_complete(usbd_xfer_handle
,
254 usbd_private_handle
, usbd_status
);
256 void ubt_recv_event(usbd_xfer_handle
,
257 usbd_private_handle
, usbd_status
);
259 void ubt_recv_acl_start(struct ubt_softc
*);
260 void ubt_recv_acl_complete(usbd_xfer_handle
,
261 usbd_private_handle
, usbd_status
);
263 void ubt_recv_sco_start1(struct ubt_softc
*, struct ubt_isoc_xfer
*);
264 void ubt_recv_sco_complete(usbd_xfer_handle
,
265 usbd_private_handle
, usbd_status
);
267 void ubt_stats(struct device
*, struct bt_stats
*, int);
269 static device_probe_t ubt_match
;
270 static device_attach_t ubt_attach
;
271 static device_detach_t ubt_detach
;
273 static devclass_t ubt_devclass
;
275 static device_method_t ubt_methods
[] = {
276 DEVMETHOD(device_probe
, ubt_match
),
277 DEVMETHOD(device_attach
, ubt_attach
),
278 DEVMETHOD(device_detach
, ubt_detach
),
283 static driver_t ubt_driver
= {
286 sizeof(struct ubt_softc
)
289 DRIVER_MODULE(ubt
, uhub
, ubt_driver
, ubt_devclass
, usbd_driver_load
, 0);
290 MODULE_DEPEND(ubt
, netbt
, 1, 1, 1);
292 MODULE_DEPEND(ubt
, bthub
, 1, 1, 1);
294 MODULE_DEPEND(ubt
, usb
, 1, 1, 1);
296 const struct hci_if ubt_hci
= {
297 .enable
= ubt_enable
,
298 .disable
= ubt_disable
,
299 .output_cmd
= ubt_xmit_cmd
,
300 .output_acl
= ubt_xmit_acl
,
301 .output_sco
= ubt_xmit_sco
,
302 .get_stats
= ubt_stats
,
305 static int ubt_set_isoc_config(struct ubt_softc
*);
306 static int ubt_sysctl_config(SYSCTL_HANDLER_ARGS
);
307 static void ubt_abortdealloc(struct ubt_softc
*);
310 * Match against the whole device, since we want to take
311 * both interfaces. If a device should be ignored then add
313 * { VendorID, ProductID }
315 * to the ubt_ignore list.
317 static const struct usb_devno ubt_ignore
[] = {
318 { USB_DEVICE(0x0a5c, 0x2033) }, /* Broadcom BCM2033 */
319 { 0, 0 } /* end of list */
323 ubt_match(device_t self
)
325 struct usb_attach_arg
*uaa
= device_get_ivars(self
);
326 usb_device_descriptor_t
*dd
= usbd_get_device_descriptor(uaa
->device
);
328 DPRINTFN(50, "ubt_match\n");
330 if (usb_lookup(ubt_ignore
, uaa
->vendor
, uaa
->product
))
333 if (dd
->bDeviceClass
== UDCLASS_WIRELESS
334 && dd
->bDeviceSubClass
== UDSUBCLASS_RF
335 && dd
->bDeviceProtocol
== UDPROTO_BLUETOOTH
)
336 return UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO
;
341 ubt_attach(device_t self
)
343 struct ubt_softc
*sc
= device_get_softc(self
);
344 struct usb_attach_arg
*uaa
= device_get_ivars(self
);
346 usb_config_descriptor_t
*cd
;
347 usb_endpoint_descriptor_t
*ed
;
351 DPRINTFN(50, "ubt_attach: sc=%p\n", sc
);
353 sc
->sc_udev
= uaa
->device
;
357 * Move the device into the configured state
359 err
= usbd_set_config_index(sc
->sc_udev
, 0, 1);
361 kprintf("%s: failed to set configuration idx 0: %s\n",
362 device_get_nameunit(sc
->sc_dev
), usbd_errstr(err
));
368 * Interface 0 must have 3 endpoints
369 * 1) Interrupt endpoint to receive HCI events
370 * 2) Bulk IN endpoint to receive ACL data
371 * 3) Bulk OUT endpoint to send ACL data
373 err
= usbd_device2interface_handle(sc
->sc_udev
, 0, &sc
->sc_iface0
);
375 kprintf("%s: Could not get interface 0 handle %s (%d)\n",
376 device_get_nameunit(sc
->sc_dev
), usbd_errstr(err
), err
);
381 sc
->sc_evt_addr
= -1;
382 sc
->sc_aclrd_addr
= -1;
383 sc
->sc_aclwr_addr
= -1;
386 (void)usbd_endpoint_count(sc
->sc_iface0
, &count
);
388 for (i
= 0 ; i
< count
; i
++) {
391 ed
= usbd_interface2endpoint_descriptor(sc
->sc_iface0
, i
);
393 kprintf("%s: could not read endpoint descriptor %d\n",
394 device_get_nameunit(sc
->sc_dev
), i
);
399 dir
= UE_GET_DIR(ed
->bEndpointAddress
);
400 type
= UE_GET_XFERTYPE(ed
->bmAttributes
);
402 if (dir
== UE_DIR_IN
&& type
== UE_INTERRUPT
)
403 sc
->sc_evt_addr
= ed
->bEndpointAddress
;
404 else if (dir
== UE_DIR_IN
&& type
== UE_BULK
)
405 sc
->sc_aclrd_addr
= ed
->bEndpointAddress
;
406 else if (dir
== UE_DIR_OUT
&& type
== UE_BULK
)
407 sc
->sc_aclwr_addr
= ed
->bEndpointAddress
;
410 if (sc
->sc_evt_addr
== -1) {
411 kprintf("%s: missing INTERRUPT endpoint on interface 0\n",
412 device_get_nameunit(sc
->sc_dev
));
416 if (sc
->sc_aclrd_addr
== -1) {
417 kprintf("%s: missing BULK IN endpoint on interface 0\n",
418 device_get_nameunit(sc
->sc_dev
));
422 if (sc
->sc_aclwr_addr
== -1) {
423 kprintf("%s: missing BULK OUT endpoint on interface 0\n",
424 device_get_nameunit(sc
->sc_dev
));
430 * Interface 1 must have 2 endpoints
431 * 1) Isochronous IN endpoint to receive SCO data
432 * 2) Isochronous OUT endpoint to send SCO data
434 * and will have several configurations, which can be selected
435 * via a sysctl variable. We select config 0 to start, which
436 * means that no SCO data will be available.
438 err
= usbd_device2interface_handle(sc
->sc_udev
, 1, &sc
->sc_iface1
);
440 kprintf("%s: Could not get interface 1 handle %s (%d)\n",
441 device_get_nameunit(sc
->sc_dev
), usbd_errstr(err
), err
);
446 cd
= usbd_get_config_descriptor(sc
->sc_udev
);
448 kprintf("%s: could not get config descriptor\n",
449 device_get_nameunit(sc
->sc_dev
));
454 sc
->sc_alt_config
= usbd_get_no_alts(cd
, 1);
456 /* set initial config */
457 err
= ubt_set_isoc_config(sc
);
459 kprintf("%s: ISOC config failed\n",
460 device_get_nameunit(sc
->sc_dev
));
466 sc
->sc_unit
= hci_attach(&ubt_hci
, sc
->sc_dev
, 0);
468 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH
, sc
->sc_udev
,
473 sysctl_ctx_init(&sc
->sysctl_ctx
);
474 sc
->sysctl_tree
= SYSCTL_ADD_NODE(&sc
->sysctl_ctx
,
475 SYSCTL_STATIC_CHILDREN(_hw
),
477 device_get_nameunit(sc
->sc_dev
),
480 if (sc
->sysctl_tree
== NULL
) {
481 /* Failure isn't fatal */
482 device_printf(sc
->sc_dev
, "Unable to create sysctl tree\n");
486 SYSCTL_ADD_PROC(&sc
->sysctl_ctx
, SYSCTL_CHILDREN(sc
->sysctl_tree
),
487 OID_AUTO
, "config", CTLTYPE_INT
|CTLFLAG_RW
, (void *)sc
,
488 0, ubt_sysctl_config
, "I", "Configuration number");
489 SYSCTL_ADD_INT(&sc
->sysctl_ctx
, SYSCTL_CHILDREN(sc
->sysctl_tree
),
490 OID_AUTO
, "alt_config", CTLFLAG_RD
, &sc
->sc_alt_config
,
491 0, "Number of alternate configurations");
492 SYSCTL_ADD_INT(&sc
->sysctl_ctx
, SYSCTL_CHILDREN(sc
->sysctl_tree
),
493 OID_AUTO
, "sco_rxsize", CTLFLAG_RD
, &sc
->sc_scord_size
,
494 0, "Max SCO receive size");
495 SYSCTL_ADD_INT(&sc
->sysctl_ctx
, SYSCTL_CHILDREN(sc
->sysctl_tree
),
496 OID_AUTO
, "sco_wrsize", CTLFLAG_RD
, &sc
->sc_scowr_size
,
497 0, "Max SCO transmit size");
503 ubt_detach(device_t self
)
506 struct ubt_softc
*sc
= device_get_softc(self
);
508 DPRINTF("sc=%p \n", sc
);
515 /* Detach HCI interface */
517 hci_detach(sc
->sc_unit
);
522 * Abort all pipes. Causes processes waiting for transfer to wake.
524 * Actually, hci_detach() above will call ubt_disable() which may
525 * call ubt_abortdealloc(), but lets be sure since doing it twice
526 * wont cause an error.
528 ubt_abortdealloc(sc
);
530 /* wait for all processes to finish */
531 if (sc
->sc_refcnt
-- > 0)
532 usb_detach_wait(sc
->sc_dev
);
534 if (sc
->sysctl_tree
!= NULL
) {
535 sc
->sysctl_tree
= NULL
;
536 sysctl_ctx_free(&sc
->sysctl_ctx
);
539 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH
, sc
->sc_udev
,
542 DPRINTFN(1, "driver detached\n");
547 /* set ISOC configuration */
549 ubt_set_isoc_config(struct ubt_softc
*sc
)
551 usb_endpoint_descriptor_t
*ed
;
552 int rd_addr
, wr_addr
, rd_size
, wr_size
;
556 err
= usbd_set_interface(sc
->sc_iface1
, sc
->sc_config
);
557 if (err
!= USBD_NORMAL_COMPLETION
) {
559 "%s: Could not set config %d on ISOC interface. %s (%d)\n",
560 device_get_nameunit(sc
->sc_dev
), sc
->sc_config
, usbd_errstr(err
), err
);
562 return err
== USBD_IN_USE
? EBUSY
: EIO
;
566 * We wont get past the above if there are any pipes open, so no
567 * need to worry about buf/xfer/pipe deallocation. If we get an
568 * error after this, the frame quantities will be 0 and no SCO
569 * data will be possible.
572 sc
->sc_scord_size
= rd_size
= 0;
573 sc
->sc_scord_addr
= rd_addr
= -1;
575 sc
->sc_scowr_size
= wr_size
= 0;
576 sc
->sc_scowr_addr
= wr_addr
= -1;
579 (void)usbd_endpoint_count(sc
->sc_iface1
, &count
);
581 for (i
= 0 ; i
< count
; i
++) {
582 ed
= usbd_interface2endpoint_descriptor(sc
->sc_iface1
, i
);
584 kprintf("%s: could not read endpoint descriptor %d\n",
585 device_get_nameunit(sc
->sc_dev
), i
);
590 DPRINTFN(5, "%s: endpoint type %02x (%02x) addr %02x (%s)\n",
591 device_get_nameunit(sc
->sc_dev
),
592 UE_GET_XFERTYPE(ed
->bmAttributes
),
593 UE_GET_ISO_TYPE(ed
->bmAttributes
),
594 ed
->bEndpointAddress
,
595 UE_GET_DIR(ed
->bEndpointAddress
) ? "in" : "out");
597 if (UE_GET_XFERTYPE(ed
->bmAttributes
) != UE_ISOCHRONOUS
)
600 if (UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_IN
) {
601 rd_addr
= ed
->bEndpointAddress
;
602 rd_size
= UGETW(ed
->wMaxPacketSize
);
604 wr_addr
= ed
->bEndpointAddress
;
605 wr_size
= UGETW(ed
->wMaxPacketSize
);
611 "%s: missing ISOC IN endpoint on interface config %d\n",
612 device_get_nameunit(sc
->sc_dev
), sc
->sc_config
);
618 "%s: missing ISOC OUT endpoint on interface config %d\n",
619 device_get_nameunit(sc
->sc_dev
), sc
->sc_config
);
625 if (rd_size
> MLEN
) {
626 kprintf("%s: rd_size=%d exceeds MLEN\n",
627 device_get_nameunit(sc
->sc_dev
), rd_size
);
632 if (wr_size
> MLEN
) {
633 kprintf("%s: wr_size=%d exceeds MLEN\n",
634 device_get_nameunit(sc
->sc_dev
), wr_size
);
640 sc
->sc_scord_size
= rd_size
;
641 sc
->sc_scord_addr
= rd_addr
;
643 sc
->sc_scowr_size
= wr_size
;
644 sc
->sc_scowr_addr
= wr_addr
;
650 ubt_sysctl_config(SYSCTL_HANDLER_ARGS
)
652 struct ubt_softc
*sc
= (struct ubt_softc
*)arg1
;
656 error
= sysctl_handle_int(oidp
, &t
, sizeof(t
), req
);
657 if (error
|| req
->newptr
== NULL
)
660 if (t
< 0 || t
>= sc
->sc_alt_config
)
663 /* This may not change when the unit is enabled */
668 return ubt_set_isoc_config(sc
);
672 ubt_abortdealloc(struct ubt_softc
*sc
)
676 DPRINTFN(1, "sc=%p\n", sc
);
679 /* Abort all pipes */
680 if (sc
->sc_evt_pipe
!= NULL
) {
681 usbd_abort_pipe(sc
->sc_evt_pipe
);
682 usbd_close_pipe(sc
->sc_evt_pipe
);
683 sc
->sc_evt_pipe
= NULL
;
686 if (sc
->sc_aclrd_pipe
!= NULL
) {
687 usbd_abort_pipe(sc
->sc_aclrd_pipe
);
688 usbd_close_pipe(sc
->sc_aclrd_pipe
);
689 sc
->sc_aclrd_pipe
= NULL
;
692 if (sc
->sc_aclwr_pipe
!= NULL
) {
693 usbd_abort_pipe(sc
->sc_aclwr_pipe
);
694 usbd_close_pipe(sc
->sc_aclwr_pipe
);
695 sc
->sc_aclwr_pipe
= NULL
;
698 if (sc
->sc_scord_pipe
!= NULL
) {
699 usbd_abort_pipe(sc
->sc_scord_pipe
);
700 usbd_close_pipe(sc
->sc_scord_pipe
);
701 sc
->sc_scord_pipe
= NULL
;
704 if (sc
->sc_scowr_pipe
!= NULL
) {
705 usbd_abort_pipe(sc
->sc_scowr_pipe
);
706 usbd_close_pipe(sc
->sc_scowr_pipe
);
707 sc
->sc_scowr_pipe
= NULL
;
710 /* Free event buffer */
711 if (sc
->sc_evt_buf
!= NULL
) {
712 kfree(sc
->sc_evt_buf
, M_USBDEV
);
713 sc
->sc_evt_buf
= NULL
;
716 /* Free all xfers and xfer buffers (implicit) */
717 if (sc
->sc_cmd_xfer
!= NULL
) {
718 usbd_free_xfer(sc
->sc_cmd_xfer
);
719 sc
->sc_cmd_xfer
= NULL
;
720 sc
->sc_cmd_buf
= NULL
;
723 if (sc
->sc_aclrd_xfer
!= NULL
) {
724 usbd_free_xfer(sc
->sc_aclrd_xfer
);
725 sc
->sc_aclrd_xfer
= NULL
;
726 sc
->sc_aclrd_buf
= NULL
;
729 if (sc
->sc_aclwr_xfer
!= NULL
) {
730 usbd_free_xfer(sc
->sc_aclwr_xfer
);
731 sc
->sc_aclwr_xfer
= NULL
;
732 sc
->sc_aclwr_buf
= NULL
;
735 for (i
= 0 ; i
< UBT_NXFERS
; i
++) {
736 if (sc
->sc_scord
[i
].xfer
!= NULL
) {
737 usbd_free_xfer(sc
->sc_scord
[i
].xfer
);
738 sc
->sc_scord
[i
].xfer
= NULL
;
739 sc
->sc_scord
[i
].buf
= NULL
;
742 if (sc
->sc_scowr
[i
].xfer
!= NULL
) {
743 usbd_free_xfer(sc
->sc_scowr
[i
].xfer
);
744 sc
->sc_scowr
[i
].xfer
= NULL
;
745 sc
->sc_scowr
[i
].buf
= NULL
;
749 /* Free partial SCO packets */
750 if (sc
->sc_scord_mbuf
!= NULL
) {
751 m_freem(sc
->sc_scord_mbuf
);
752 sc
->sc_scord_mbuf
= NULL
;
755 if (sc
->sc_scowr_mbuf
!= NULL
) {
756 m_freem(sc
->sc_scowr_mbuf
);
757 sc
->sc_scowr_mbuf
= NULL
;
760 /* Empty mbuf queues */
761 IF_DRAIN(&sc
->sc_cmd_queue
);
762 IF_DRAIN(&sc
->sc_aclwr_queue
);
763 IF_DRAIN(&sc
->sc_scowr_queue
);
768 /*******************************************************************************
770 * Bluetooth Unit/USB callbacks
772 * All of this will be called at the IPL_ we specified above
775 ubt_enable(struct device
*self
)
777 struct ubt_softc
*sc
= device_get_softc(self
);
781 DPRINTFN(1, "%s: sc=%p\n", __func__
, sc
);
789 sc
->sc_evt_buf
= kmalloc(UBT_BUFSIZ_EVENT
, M_USBDEV
, M_NOWAIT
);
790 if (sc
->sc_evt_buf
== NULL
) {
795 err
= usbd_open_pipe_intr(sc
->sc_iface0
,
804 if (err
!= USBD_NORMAL_COMPLETION
) {
806 kprintf("can't open events pipe_intr\n");
811 sc
->sc_cmd_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
812 if (sc
->sc_cmd_xfer
== NULL
) {
813 kprintf("can't allocate cmd_xfer\n");
817 sc
->sc_cmd_buf
= usbd_alloc_buffer(sc
->sc_cmd_xfer
, UBT_BUFSIZ_CMD
);
818 if (sc
->sc_cmd_buf
== NULL
) {
819 kprintf("can't allocate cmd_buf\n");
826 err
= usbd_open_pipe(sc
->sc_iface0
, sc
->sc_aclrd_addr
,
827 USBD_EXCLUSIVE_USE
, &sc
->sc_aclrd_pipe
);
828 if (err
!= USBD_NORMAL_COMPLETION
) {
829 kprintf("can't open aclrd pipe\n");
833 sc
->sc_aclrd_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
834 if (sc
->sc_aclrd_xfer
== NULL
) {
835 kprintf("can't allocate aclrd_xfer\n");
839 sc
->sc_aclrd_buf
= usbd_alloc_buffer(sc
->sc_aclrd_xfer
, UBT_BUFSIZ_ACL
);
840 if (sc
->sc_aclrd_buf
== NULL
) {
841 kprintf("can't allocate aclrd_buf\n");
845 sc
->sc_aclrd_busy
= 0;
846 ubt_recv_acl_start(sc
);
849 err
= usbd_open_pipe(sc
->sc_iface0
, sc
->sc_aclwr_addr
,
850 USBD_EXCLUSIVE_USE
, &sc
->sc_aclwr_pipe
);
851 if (err
!= USBD_NORMAL_COMPLETION
) {
852 kprintf("can't open aclwr pipe\n");
856 sc
->sc_aclwr_xfer
= usbd_alloc_xfer(sc
->sc_udev
);
857 if (sc
->sc_aclwr_xfer
== NULL
) {
858 kprintf("can't allocate aclwr_xfer\n");
862 sc
->sc_aclwr_buf
= usbd_alloc_buffer(sc
->sc_aclwr_xfer
, UBT_BUFSIZ_ACL
);
863 if (sc
->sc_aclwr_buf
== NULL
) {
864 kprintf("can't allocate aclwr_buf\n");
868 sc
->sc_aclwr_busy
= 0;
871 if (sc
->sc_scord_size
> 0) {
872 err
= usbd_open_pipe(sc
->sc_iface1
, sc
->sc_scord_addr
,
873 USBD_EXCLUSIVE_USE
, &sc
->sc_scord_pipe
);
874 if (err
!= USBD_NORMAL_COMPLETION
) {
879 for (i
= 0 ; i
< UBT_NXFERS
; i
++) {
880 sc
->sc_scord
[i
].xfer
= usbd_alloc_xfer(sc
->sc_udev
);
881 if (sc
->sc_scord
[i
].xfer
== NULL
) {
885 sc
->sc_scord
[i
].buf
= usbd_alloc_buffer(sc
->sc_scord
[i
].xfer
,
886 sc
->sc_scord_size
* UBT_NFRAMES
);
887 if (sc
->sc_scord
[i
].buf
== NULL
) {
891 sc
->sc_scord
[i
].softc
= sc
;
892 sc
->sc_scord
[i
].busy
= 0;
893 ubt_recv_sco_start1(sc
, &sc
->sc_scord
[i
]);
898 if (sc
->sc_scowr_size
> 0) {
899 err
= usbd_open_pipe(sc
->sc_iface1
, sc
->sc_scowr_addr
,
900 USBD_EXCLUSIVE_USE
, &sc
->sc_scowr_pipe
);
901 if (err
!= USBD_NORMAL_COMPLETION
) {
906 for (i
= 0 ; i
< UBT_NXFERS
; i
++) {
907 sc
->sc_scowr
[i
].xfer
= usbd_alloc_xfer(sc
->sc_udev
);
908 if (sc
->sc_scowr
[i
].xfer
== NULL
) {
912 sc
->sc_scowr
[i
].buf
= usbd_alloc_buffer(sc
->sc_scowr
[i
].xfer
,
913 sc
->sc_scowr_size
* UBT_NFRAMES
);
914 if (sc
->sc_scowr
[i
].buf
== NULL
) {
918 sc
->sc_scowr
[i
].softc
= sc
;
919 sc
->sc_scowr
[i
].busy
= 0;
922 sc
->sc_scowr_busy
= 0;
930 ubt_abortdealloc(sc
);
936 ubt_disable(struct device
*self
)
938 struct ubt_softc
*sc
= device_get_softc(self
);
940 DPRINTFN(1, "sc=%p\n", sc
);
942 if (sc
->sc_enabled
== 0)
945 ubt_abortdealloc(sc
);
950 ubt_xmit_cmd(struct device
*self
, struct mbuf
*m
)
952 struct ubt_softc
*sc
= device_get_softc(self
);
954 KKASSERT(sc
->sc_enabled
);
957 IF_ENQUEUE(&sc
->sc_cmd_queue
, m
);
959 if (sc
->sc_cmd_busy
== 0)
960 ubt_xmit_cmd_start(sc
);
966 ubt_xmit_cmd_start(struct ubt_softc
*sc
)
968 usb_device_request_t req
;
976 if (IF_QEMPTY(&sc
->sc_cmd_queue
))
979 IF_DEQUEUE(&sc
->sc_cmd_queue
, m
);
981 DPRINTFN(15, " %s: xmit CMD packet (%d bytes)\n",
982 device_get_nameunit(sc
->sc_dev
), m
->m_pkthdr
.len
);
988 len
= m
->m_pkthdr
.len
- 1;
989 m_copydata(m
, 1, len
, sc
->sc_cmd_buf
);
992 memset(&req
, 0, sizeof(req
));
993 req
.bmRequestType
= UT_WRITE_CLASS_DEVICE
;
994 USETW(req
.wLength
, len
);
996 usbd_setup_default_xfer(sc
->sc_cmd_xfer
,
1003 USBD_NO_COPY
| USBD_FORCE_SHORT_XFER
,
1004 ubt_xmit_cmd_complete
);
1006 status
= usbd_transfer(sc
->sc_cmd_xfer
);
1008 KKASSERT(status
!= USBD_NORMAL_COMPLETION
);
1010 if (status
!= USBD_IN_PROGRESS
) {
1011 DPRINTF("usbd_transfer status=%s (%d)\n",
1012 usbd_errstr(status
), status
);
1014 sc
->sc_cmd_busy
= 0;
1020 ubt_xmit_cmd_complete(usbd_xfer_handle xfer
,
1021 usbd_private_handle h
, usbd_status status
)
1023 struct ubt_softc
*sc
= h
;
1026 DPRINTFN(15, " %s: CMD complete status=%s (%d)\n",
1027 device_get_nameunit(sc
->sc_dev
), usbd_errstr(status
), status
);
1029 sc
->sc_cmd_busy
= 0;
1031 if (--sc
->sc_refcnt
< 0) {
1032 DPRINTF("sc_refcnt=%d\n", sc
->sc_refcnt
);
1033 usb_detach_wakeup(sc
->sc_dev
);
1038 DPRINTF("sc_dying\n");
1042 if (status
!= USBD_NORMAL_COMPLETION
) {
1043 DPRINTF("status=%s (%d)\n",
1044 usbd_errstr(status
), status
);
1045 sc
->sc_stats
.err_tx
++;
1049 usbd_get_xfer_status(xfer
, NULL
, NULL
, &count
, NULL
);
1050 sc
->sc_stats
.cmd_tx
++;
1051 sc
->sc_stats
.byte_tx
+= count
;
1053 ubt_xmit_cmd_start(sc
);
1057 ubt_xmit_acl(struct device
*self
, struct mbuf
*m
)
1059 struct ubt_softc
*sc
= device_get_softc(self
);
1061 KKASSERT(sc
->sc_enabled
);
1064 IF_ENQUEUE(&sc
->sc_aclwr_queue
, m
);
1066 if (sc
->sc_aclwr_busy
== 0)
1067 ubt_xmit_acl_start(sc
);
1073 ubt_xmit_acl_start(struct ubt_softc
*sc
)
1083 if (IF_QEMPTY(&sc
->sc_aclwr_queue
))
1087 sc
->sc_aclwr_busy
= 1;
1089 IF_DEQUEUE(&sc
->sc_aclwr_queue
, m
);
1090 KKASSERT(m
!= NULL
);
1092 DPRINTFN(15, "%s: xmit ACL packet (%d bytes)\n",
1093 device_get_nameunit(sc
->sc_dev
), m
->m_pkthdr
.len
);
1095 len
= m
->m_pkthdr
.len
- 1;
1096 if (len
> UBT_BUFSIZ_ACL
) {
1097 DPRINTF("%s: truncating ACL packet (%d => %d)!\n",
1098 device_get_nameunit(sc
->sc_dev
), len
, UBT_BUFSIZ_ACL
);
1100 len
= UBT_BUFSIZ_ACL
;
1103 m_copydata(m
, 1, len
, sc
->sc_aclwr_buf
);
1106 sc
->sc_stats
.acl_tx
++;
1107 sc
->sc_stats
.byte_tx
+= len
;
1109 usbd_setup_xfer(sc
->sc_aclwr_xfer
,
1114 USBD_NO_COPY
| USBD_FORCE_SHORT_XFER
,
1116 ubt_xmit_acl_complete
);
1118 status
= usbd_transfer(sc
->sc_aclwr_xfer
);
1120 KKASSERT(status
!= USBD_NORMAL_COMPLETION
);
1122 if (status
!= USBD_IN_PROGRESS
) {
1123 DPRINTF("usbd_transfer status=%s (%d)\n",
1124 usbd_errstr(status
), status
);
1127 sc
->sc_aclwr_busy
= 0;
1133 ubt_xmit_acl_complete(usbd_xfer_handle xfer
,
1134 usbd_private_handle h
, usbd_status status
)
1136 struct ubt_softc
*sc
= h
;
1138 DPRINTFN(15, "%s: ACL complete status=%s (%d)\n",
1139 device_get_nameunit(sc
->sc_dev
), usbd_errstr(status
), status
);
1141 sc
->sc_aclwr_busy
= 0;
1143 if (--sc
->sc_refcnt
< 0) {
1144 usb_detach_wakeup(sc
->sc_dev
);
1151 if (status
!= USBD_NORMAL_COMPLETION
) {
1152 DPRINTF("status=%s (%d)\n",
1153 usbd_errstr(status
), status
);
1155 sc
->sc_stats
.err_tx
++;
1157 if (status
== USBD_STALLED
)
1158 usbd_clear_endpoint_stall_async(sc
->sc_aclwr_pipe
);
1163 ubt_xmit_acl_start(sc
);
1168 ubt_xmit_sco(struct device
*self
, struct mbuf
*m
)
1170 struct ubt_softc
*sc
= device_get_softc(self
);
1172 KKASSERT(sc
->sc_enabled
);
1175 IF_ENQUEUE(&sc
->sc_scowr_queue
, m
);
1177 if (sc
->sc_scowr_busy
== 0)
1178 ubt_xmit_sco_start(sc
);
1184 ubt_xmit_sco_start(struct ubt_softc
*sc
)
1188 if (sc
->sc_dying
|| sc
->sc_scowr_size
== 0)
1191 for (i
= 0 ; i
< UBT_NXFERS
; i
++) {
1192 if (sc
->sc_scowr
[i
].busy
)
1195 ubt_xmit_sco_start1(sc
, &sc
->sc_scowr
[i
]);
1200 ubt_xmit_sco_start1(struct ubt_softc
*sc
, struct ubt_isoc_xfer
*isoc
)
1204 int num
, len
, size
, space
;
1209 space
= sc
->sc_scowr_size
* UBT_NFRAMES
;
1214 * Fill the request buffer with data from the queue,
1215 * keeping any leftover packet on our private hook.
1217 * Complete packets are passed back up to the stack
1218 * for disposal, since we can't rely on the controller
1219 * to tell us when it has finished with them.
1222 m
= sc
->sc_scowr_mbuf
;
1226 IF_DEQUEUE(&sc
->sc_scowr_queue
, m
);
1231 m_adj(m
, 1); /* packet type */
1235 if (m
->m_pkthdr
.len
> 0) {
1236 size
= MIN(m
->m_pkthdr
.len
, space
);
1238 m_copydata(m
, 0, size
, buf
);
1246 if (m
->m_pkthdr
.len
== 0) {
1247 sc
->sc_stats
.sco_tx
++;
1248 if (!hci_complete_sco(sc
->sc_unit
, m
))
1249 sc
->sc_stats
.err_tx
++;
1254 sc
->sc_scowr_mbuf
= m
;
1256 DPRINTFN(15, "isoc=%p, len=%d, space=%d\n", isoc
, len
, space
);
1258 if (len
== 0) /* nothing to send */
1263 sc
->sc_scowr_busy
= 1;
1264 sc
->sc_stats
.byte_tx
+= len
;
1268 * calculate number of isoc frames and sizes
1271 for (num
= 0 ; len
> 0 ; num
++) {
1272 size
= MIN(sc
->sc_scowr_size
, len
);
1274 isoc
->size
[num
] = size
;
1278 usbd_setup_isoc_xfer(isoc
->xfer
,
1283 USBD_NO_COPY
| USBD_FORCE_SHORT_XFER
,
1284 ubt_xmit_sco_complete
);
1286 usbd_transfer(isoc
->xfer
);
1290 ubt_xmit_sco_complete(usbd_xfer_handle xfer
,
1291 usbd_private_handle h
, usbd_status status
)
1293 struct ubt_isoc_xfer
*isoc
= h
;
1294 struct ubt_softc
*sc
;
1297 KKASSERT(xfer
== isoc
->xfer
);
1300 DPRINTFN(15, "isoc=%p, status=%s (%d)\n",
1301 isoc
, usbd_errstr(status
), status
);
1305 for (i
= 0 ; ; i
++) {
1306 if (i
== UBT_NXFERS
) {
1307 sc
->sc_scowr_busy
= 0;
1311 if (sc
->sc_scowr
[i
].busy
)
1315 if (--sc
->sc_refcnt
< 0) {
1316 usb_detach_wakeup(sc
->sc_dev
);
1323 if (status
!= USBD_NORMAL_COMPLETION
) {
1324 DPRINTF("status=%s (%d)\n",
1325 usbd_errstr(status
), status
);
1327 sc
->sc_stats
.err_tx
++;
1329 if (status
== USBD_STALLED
)
1330 usbd_clear_endpoint_stall_async(sc
->sc_scowr_pipe
);
1335 ubt_xmit_sco_start(sc
);
1339 * Load incoming data into an mbuf with leading type byte.
1341 static struct mbuf
*
1342 ubt_mbufload(uint8_t *buf
, int count
, uint8_t type
)
1345 MGETHDR(m
, MB_DONTWAIT
, MT_DATA
);
1346 if (m
== NULL
) {kprintf(" MGETHDR return NULL\n");
1348 *mtod(m
, uint8_t *) = type
;
1349 m
->m_pkthdr
.len
= m
->m_len
= MHLEN
;
1350 m_copyback(m
, 1, count
, buf
); /* (extends if necessary)*/
1351 if (m
->m_pkthdr
.len
!= MAX(MHLEN
, count
+ 1)) {
1353 kprintf(" m->m_pkthdr.len != MAX() \n");
1356 m
->m_pkthdr
.len
= count
+ 1;
1357 m
->m_len
= MIN(MHLEN
, m
->m_pkthdr
.len
);
1362 ubt_recv_event(usbd_xfer_handle xfer
, usbd_private_handle h
, usbd_status status
)
1364 struct ubt_softc
*sc
= h
;
1369 DPRINTFN(15, "sc=%p status=%s (%d)\n",
1370 sc
, usbd_errstr(status
), status
);
1372 if (status
!= USBD_NORMAL_COMPLETION
|| sc
->sc_dying
)
1375 usbd_get_xfer_status(xfer
, NULL
, &buf
, &count
, NULL
);
1377 if (count
< sizeof(hci_event_hdr_t
) - 1) {
1378 DPRINTF("dumped undersized event (count = %d)\n", count
);
1379 sc
->sc_stats
.err_rx
++;
1383 sc
->sc_stats
.evt_rx
++;
1384 sc
->sc_stats
.byte_rx
+= count
;
1386 m
= ubt_mbufload(buf
, count
, HCI_EVENT_PKT
);
1387 if (m
== NULL
|| !hci_input_event(sc
->sc_unit
, m
))
1388 sc
->sc_stats
.err_rx
++;
1392 ubt_recv_acl_start(struct ubt_softc
*sc
)
1396 DPRINTFN(15, "sc=%p\n", sc
);
1398 if (sc
->sc_aclrd_busy
|| sc
->sc_dying
) {
1399 DPRINTF("sc_aclrd_busy=%d, sc_dying=%d\n",
1407 sc
->sc_aclrd_busy
= 1;
1409 usbd_setup_xfer(sc
->sc_aclrd_xfer
,
1414 USBD_NO_COPY
| USBD_SHORT_XFER_OK
,
1416 ubt_recv_acl_complete
);
1418 status
= usbd_transfer(sc
->sc_aclrd_xfer
);
1420 KKASSERT(status
!= USBD_NORMAL_COMPLETION
);
1422 if (status
!= USBD_IN_PROGRESS
) {
1423 DPRINTF("usbd_transfer status=%s (%d)\n",
1424 usbd_errstr(status
), status
);
1427 sc
->sc_aclrd_busy
= 0;
1432 ubt_recv_acl_complete(usbd_xfer_handle xfer
,
1433 usbd_private_handle h
, usbd_status status
)
1435 struct ubt_softc
*sc
= h
;
1440 DPRINTFN(15, "sc=%p status=%s (%d)\n",
1441 sc
, usbd_errstr(status
), status
);
1443 sc
->sc_aclrd_busy
= 0;
1445 if (--sc
->sc_refcnt
< 0) {
1446 DPRINTF("refcnt = %d\n", sc
->sc_refcnt
);
1447 usb_detach_wakeup(sc
->sc_dev
);
1452 DPRINTF("sc_dying\n");
1456 if (status
!= USBD_NORMAL_COMPLETION
) {
1457 DPRINTF("status=%s (%d)\n",
1458 usbd_errstr(status
), status
);
1460 sc
->sc_stats
.err_rx
++;
1462 if (status
== USBD_STALLED
)
1463 usbd_clear_endpoint_stall_async(sc
->sc_aclrd_pipe
);
1467 usbd_get_xfer_status(xfer
, NULL
, &buf
, &count
, NULL
);
1469 if (count
< sizeof(hci_acldata_hdr_t
) - 1) {
1470 DPRINTF("dumped undersized packet (%d)\n", count
);
1471 sc
->sc_stats
.err_rx
++;
1473 sc
->sc_stats
.acl_rx
++;
1474 sc
->sc_stats
.byte_rx
+= count
;
1476 m
= ubt_mbufload(buf
, count
, HCI_ACL_DATA_PKT
);
1477 if (m
== NULL
|| !hci_input_acl(sc
->sc_unit
, m
))
1478 sc
->sc_stats
.err_rx
++;
1483 ubt_recv_acl_start(sc
);
1487 ubt_recv_sco_start1(struct ubt_softc
*sc
, struct ubt_isoc_xfer
*isoc
)
1491 DPRINTFN(15, "sc=%p, isoc=%p\n", sc
, isoc
);
1493 if (isoc
->busy
|| sc
->sc_dying
|| sc
->sc_scord_size
== 0) {
1495 isoc
->busy
? " busy" : "",
1496 sc
->sc_dying
? " dying" : "",
1497 sc
->sc_scord_size
== 0 ? " size=0" : "");
1505 for (i
= 0 ; i
< UBT_NFRAMES
; i
++)
1506 isoc
->size
[i
] = sc
->sc_scord_size
;
1508 usbd_setup_isoc_xfer(isoc
->xfer
,
1513 USBD_NO_COPY
| USBD_SHORT_XFER_OK
,
1514 ubt_recv_sco_complete
);
1516 usbd_transfer(isoc
->xfer
);
1520 ubt_recv_sco_complete(usbd_xfer_handle xfer
,
1521 usbd_private_handle h
, usbd_status status
)
1523 struct ubt_isoc_xfer
*isoc
= h
;
1524 struct ubt_softc
*sc
;
1527 uint8_t *ptr
, *frame
;
1528 int i
, size
, got
, want
;
1530 KKASSERT(isoc
!= NULL
);
1531 KKASSERT(isoc
->xfer
== xfer
);
1536 if (--sc
->sc_refcnt
< 0) {
1537 DPRINTF("refcnt=%d\n", sc
->sc_refcnt
);
1538 usb_detach_wakeup(sc
->sc_dev
);
1543 DPRINTF("sc_dying\n");
1547 if (status
!= USBD_NORMAL_COMPLETION
) {
1548 DPRINTF("status=%s (%d)\n",
1549 usbd_errstr(status
), status
);
1551 sc
->sc_stats
.err_rx
++;
1553 if (status
== USBD_STALLED
) {
1554 usbd_clear_endpoint_stall_async(sc
->sc_scord_pipe
);
1561 usbd_get_xfer_status(xfer
, NULL
, NULL
, &count
, NULL
);
1565 DPRINTFN(15, "sc=%p, isoc=%p, count=%u\n",
1568 sc
->sc_stats
.byte_rx
+= count
;
1571 * Extract SCO packets from ISOC frames. The way we have it,
1572 * no SCO packet can be bigger than MHLEN. This is unlikely
1573 * to actually happen, but if we ran out of mbufs and lost
1574 * sync then we may get spurious data that makes it seem that
1575 * way, so we discard data that wont fit. This doesnt really
1576 * help with the lost sync situation alas.
1579 m
= sc
->sc_scord_mbuf
;
1581 sc
->sc_scord_mbuf
= NULL
;
1582 ptr
= mtod(m
, uint8_t *) + m
->m_pkthdr
.len
;
1583 got
= m
->m_pkthdr
.len
;
1584 want
= sizeof(hci_scodata_hdr_t
);
1586 want
+= mtod(m
, hci_scodata_hdr_t
*)->length
;
1593 for (i
= 0 ; i
< UBT_NFRAMES
; i
++) {
1594 frame
= isoc
->buf
+ (i
* sc
->sc_scord_size
);
1596 while (isoc
->size
[i
] > 0) {
1597 size
= isoc
->size
[i
];
1600 MGETHDR(m
, MB_DONTWAIT
, MT_DATA
);
1602 kprintf("%s: out of memory (xfer halted)\n",
1603 device_get_nameunit(sc
->sc_dev
));
1605 sc
->sc_stats
.err_rx
++;
1606 return; /* lost sync */
1609 ptr
= mtod(m
, uint8_t *);
1610 *ptr
++ = HCI_SCO_DATA_PKT
;
1612 want
= sizeof(hci_scodata_hdr_t
);
1615 if (got
+ size
> want
)
1618 if (got
+ size
> MHLEN
)
1619 memcpy(ptr
, frame
, MHLEN
- got
);
1621 memcpy(ptr
, frame
, size
);
1629 * If we only got a header, add the packet
1630 * length to our want count. Send complete
1631 * packets up to protocol stack.
1633 if (want
== sizeof(hci_scodata_hdr_t
))
1634 want
+= mtod(m
, hci_scodata_hdr_t
*)->length
;
1637 m
->m_pkthdr
.len
= m
->m_len
= got
;
1638 sc
->sc_stats
.sco_rx
++;
1639 if (!hci_input_sco(sc
->sc_unit
, m
))
1640 sc
->sc_stats
.err_rx
++;
1646 isoc
->size
[i
] -= size
;
1651 m
->m_pkthdr
.len
= m
->m_len
= got
;
1652 sc
->sc_scord_mbuf
= m
;
1655 restart
: /* and restart */
1656 ubt_recv_sco_start1(sc
, isoc
);
1660 ubt_stats(struct device
*self
, struct bt_stats
*dest
, int flush
)
1662 struct ubt_softc
*sc
= device_get_softc(self
);
1665 memcpy(dest
, &sc
->sc_stats
, sizeof(struct bt_stats
));
1668 memset(&sc
->sc_stats
, 0, sizeof(struct bt_stats
));