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