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