ubt.c revision 1.18 1 /* $NetBSD: ubt.c,v 1.18 2006/09/19 20:34:33 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.18 2006/09/19 20:34:33 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 /* This may not change when the unit is enabled */
709 if (sc->sc_unit.hci_flags & BTF_RUNNING)
710 return EBUSY;
711
712 sc->sc_config = t;
713 return ubt_set_isoc_config(sc);
714 }
715
716 static void
717 ubt_abortdealloc(struct ubt_softc *sc)
718 {
719 int i;
720
721 DPRINTFN(1, "sc=%p\n", sc);
722
723 /* Abort all pipes */
724 if (sc->sc_evt_pipe != NULL) {
725 usbd_abort_pipe(sc->sc_evt_pipe);
726 usbd_close_pipe(sc->sc_evt_pipe);
727 sc->sc_evt_pipe = NULL;
728 }
729
730 if (sc->sc_aclrd_pipe != NULL) {
731 usbd_abort_pipe(sc->sc_aclrd_pipe);
732 usbd_close_pipe(sc->sc_aclrd_pipe);
733 sc->sc_aclrd_pipe = NULL;
734 }
735
736 if (sc->sc_aclwr_pipe != NULL) {
737 usbd_abort_pipe(sc->sc_aclwr_pipe);
738 usbd_close_pipe(sc->sc_aclwr_pipe);
739 sc->sc_aclwr_pipe = NULL;
740 }
741
742 if (sc->sc_scord_pipe != NULL) {
743 usbd_abort_pipe(sc->sc_scord_pipe);
744 usbd_close_pipe(sc->sc_scord_pipe);
745 sc->sc_scord_pipe = NULL;
746 }
747
748 if (sc->sc_scowr_pipe != NULL) {
749 usbd_abort_pipe(sc->sc_scowr_pipe);
750 usbd_close_pipe(sc->sc_scowr_pipe);
751 sc->sc_scowr_pipe = NULL;
752 }
753
754 /* Free event buffer */
755 if (sc->sc_evt_buf != NULL) {
756 free(sc->sc_evt_buf, M_USBDEV);
757 sc->sc_evt_buf = NULL;
758 }
759
760 /* Free all xfers and xfer buffers (implicit) */
761 if (sc->sc_cmd_xfer != NULL) {
762 usbd_free_xfer(sc->sc_cmd_xfer);
763 sc->sc_cmd_xfer = NULL;
764 sc->sc_cmd_buf = NULL;
765 }
766
767 if (sc->sc_aclrd_xfer != NULL) {
768 usbd_free_xfer(sc->sc_aclrd_xfer);
769 sc->sc_aclrd_xfer = NULL;
770 sc->sc_aclrd_buf = NULL;
771 }
772
773 if (sc->sc_aclwr_xfer != NULL) {
774 usbd_free_xfer(sc->sc_aclwr_xfer);
775 sc->sc_aclwr_xfer = NULL;
776 sc->sc_aclwr_buf = NULL;
777 }
778
779 for (i = 0 ; i < UBT_NXFERS ; i++) {
780 if (sc->sc_scord[i].xfer != NULL) {
781 usbd_free_xfer(sc->sc_scord[i].xfer);
782 sc->sc_scord[i].xfer = NULL;
783 sc->sc_scord[i].buf = NULL;
784 }
785
786 if (sc->sc_scowr[i].xfer != NULL) {
787 usbd_free_xfer(sc->sc_scowr[i].xfer);
788 sc->sc_scowr[i].xfer = NULL;
789 sc->sc_scowr[i].buf = NULL;
790 }
791 }
792
793 /* Free partial SCO packets */
794 if (sc->sc_scord_mbuf != NULL) {
795 m_freem(sc->sc_scord_mbuf);
796 sc->sc_scord_mbuf = NULL;
797 }
798
799 if (sc->sc_scowr_mbuf != NULL) {
800 m_freem(sc->sc_scowr_mbuf);
801 sc->sc_scowr_mbuf = NULL;
802 }
803 }
804
805 /*******************************************************************************
806 *
807 * Bluetooth Unit/USB callbacks
808 *
809 * All of this will be called at the IPL_ we specified above
810 */
811 static int
812 ubt_enable(struct hci_unit *unit)
813 {
814 struct ubt_softc *sc = unit->hci_softc;
815 usbd_status err;
816 int i, error;
817
818 DPRINTFN(1, "sc=%p\n", sc);
819
820 if (unit->hci_flags & BTF_RUNNING)
821 return 0;
822
823 /* Events */
824 sc->sc_evt_buf = malloc(UBT_BUFSIZ_EVENT, M_USBDEV, M_NOWAIT);
825 if (sc->sc_evt_buf == NULL) {
826 error = ENOMEM;
827 goto bad;
828 }
829 err = usbd_open_pipe_intr(sc->sc_iface0,
830 sc->sc_evt_addr,
831 USBD_SHORT_XFER_OK,
832 &sc->sc_evt_pipe,
833 sc,
834 sc->sc_evt_buf,
835 UBT_BUFSIZ_EVENT,
836 ubt_recv_event,
837 UBT_EVENT_INTERVAL);
838 if (err != USBD_NORMAL_COMPLETION) {
839 error = EIO;
840 goto bad;
841 }
842
843 /* Commands */
844 sc->sc_cmd_xfer = usbd_alloc_xfer(sc->sc_udev);
845 if (sc->sc_cmd_xfer == NULL) {
846 error = ENOMEM;
847 goto bad;
848 }
849 sc->sc_cmd_buf = usbd_alloc_buffer(sc->sc_cmd_xfer, UBT_BUFSIZ_CMD);
850 if (sc->sc_cmd_buf == NULL) {
851 error = ENOMEM;
852 goto bad;
853 }
854
855 /* ACL read */
856 err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclrd_addr,
857 USBD_EXCLUSIVE_USE, &sc->sc_aclrd_pipe);
858 if (err != USBD_NORMAL_COMPLETION) {
859 error = EIO;
860 goto bad;
861 }
862 sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev);
863 if (sc->sc_aclrd_xfer == NULL) {
864 error = ENOMEM;
865 goto bad;
866 }
867 sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer, UBT_BUFSIZ_ACL);
868 if (sc->sc_aclrd_buf == NULL) {
869 error = ENOMEM;
870 goto bad;
871 }
872 sc->sc_aclrd_busy = 0;
873 ubt_recv_acl_start(sc);
874
875 /* ACL write */
876 err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclwr_addr,
877 USBD_EXCLUSIVE_USE, &sc->sc_aclwr_pipe);
878 if (err != USBD_NORMAL_COMPLETION) {
879 error = EIO;
880 goto bad;
881 }
882 sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev);
883 if (sc->sc_aclwr_xfer == NULL) {
884 error = ENOMEM;
885 goto bad;
886 }
887 sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer, UBT_BUFSIZ_ACL);
888 if (sc->sc_aclwr_buf == NULL) {
889 error = ENOMEM;
890 goto bad;
891 }
892
893 /* SCO read */
894 if (sc->sc_scord_size > 0) {
895 err = usbd_open_pipe(sc->sc_iface1, sc->sc_scord_addr,
896 USBD_EXCLUSIVE_USE, &sc->sc_scord_pipe);
897 if (err != USBD_NORMAL_COMPLETION) {
898 error = EIO;
899 goto bad;
900 }
901
902 for (i = 0 ; i < UBT_NXFERS ; i++) {
903 sc->sc_scord[i].xfer = usbd_alloc_xfer(sc->sc_udev);
904 if (sc->sc_scord[i].xfer == NULL) {
905 error = ENOMEM;
906 goto bad;
907 }
908 sc->sc_scord[i].buf = usbd_alloc_buffer(sc->sc_scord[i].xfer,
909 sc->sc_scord_size * UBT_NFRAMES);
910 if (sc->sc_scord[i].buf == NULL) {
911 error = ENOMEM;
912 goto bad;
913 }
914 sc->sc_scord[i].softc = sc;
915 sc->sc_scord[i].busy = 0;
916 ubt_recv_sco_start1(sc, &sc->sc_scord[i]);
917 }
918 }
919
920 /* SCO write */
921 if (sc->sc_scowr_size > 0) {
922 err = usbd_open_pipe(sc->sc_iface1, sc->sc_scowr_addr,
923 USBD_EXCLUSIVE_USE, &sc->sc_scowr_pipe);
924 if (err != USBD_NORMAL_COMPLETION) {
925 error = EIO;
926 goto bad;
927 }
928
929 for (i = 0 ; i < UBT_NXFERS ; i++) {
930 sc->sc_scowr[i].xfer = usbd_alloc_xfer(sc->sc_udev);
931 if (sc->sc_scowr[i].xfer == NULL) {
932 error = ENOMEM;
933 goto bad;
934 }
935 sc->sc_scowr[i].buf = usbd_alloc_buffer(sc->sc_scowr[i].xfer,
936 sc->sc_scowr_size * UBT_NFRAMES);
937 if (sc->sc_scowr[i].buf == NULL) {
938 error = ENOMEM;
939 goto bad;
940 }
941 sc->sc_scowr[i].softc = sc;
942 sc->sc_scowr[i].busy = 0;
943 }
944 }
945
946 unit->hci_flags &= ~BTF_XMIT;
947 unit->hci_flags |= BTF_RUNNING;
948 return 0;
949
950 bad:
951 ubt_abortdealloc(sc);
952 return error;
953 }
954
955 static void
956 ubt_disable(struct hci_unit *unit)
957 {
958 struct ubt_softc *sc = unit->hci_softc;
959
960 DPRINTFN(1, "sc=%p\n", sc);
961
962 if ((unit->hci_flags & BTF_RUNNING) == 0)
963 return;
964
965 ubt_abortdealloc(sc);
966
967 unit->hci_flags &= ~BTF_RUNNING;
968 }
969
970 static void
971 ubt_xmit_cmd_start(struct hci_unit *unit)
972 {
973 struct ubt_softc *sc = unit->hci_softc;
974 usb_device_request_t req;
975 usbd_status status;
976 struct mbuf *m;
977 int len;
978
979 if (sc->sc_dying)
980 return;
981
982 if (MBUFQ_FIRST(&unit->hci_cmdq) == NULL)
983 return;
984
985 MBUFQ_DEQUEUE(&unit->hci_cmdq, m);
986 KASSERT(m != NULL);
987
988 DPRINTFN(15, "%s: xmit CMD packet (%d bytes)\n",
989 unit->hci_devname, m->m_pkthdr.len);
990
991 sc->sc_refcnt++;
992 unit->hci_flags |= BTF_XMIT_CMD;
993
994 len = m->m_pkthdr.len - 1;
995 m_copydata(m, 1, len, sc->sc_cmd_buf);
996 m_freem(m);
997
998 memset(&req, 0, sizeof(req));
999 req.bmRequestType = UT_WRITE_CLASS_DEVICE;
1000 USETW(req.wLength, len);
1001
1002 usbd_setup_default_xfer(sc->sc_cmd_xfer,
1003 sc->sc_udev,
1004 unit,
1005 UBT_CMD_TIMEOUT,
1006 &req,
1007 sc->sc_cmd_buf,
1008 len,
1009 USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
1010 ubt_xmit_cmd_complete);
1011
1012 status = usbd_transfer(sc->sc_cmd_xfer);
1013
1014 KASSERT(status != USBD_NORMAL_COMPLETION);
1015
1016 if (status != USBD_IN_PROGRESS) {
1017 DPRINTF("usbd_transfer status=%s (%d)\n",
1018 usbd_errstr(status), status);
1019
1020 sc->sc_refcnt--;
1021 unit->hci_flags &= ~BTF_XMIT_CMD;
1022 }
1023 }
1024
1025 static void
1026 ubt_xmit_cmd_complete(usbd_xfer_handle xfer,
1027 usbd_private_handle h, usbd_status status)
1028 {
1029 struct hci_unit *unit = h;
1030 struct ubt_softc *sc = unit->hci_softc;
1031 uint32_t count;
1032
1033 DPRINTFN(15, "%s: CMD complete status=%s (%d)\n",
1034 unit->hci_devname, usbd_errstr(status), status);
1035
1036 unit->hci_flags &= ~BTF_XMIT_CMD;
1037
1038 if (--sc->sc_refcnt < 0) {
1039 DPRINTF("sc_refcnt=%d\n", sc->sc_refcnt);
1040 usb_detach_wakeup(USBDEV(sc->sc_dev));
1041 return;
1042 }
1043
1044 if (sc->sc_dying) {
1045 DPRINTF("sc_dying\n");
1046 return;
1047 }
1048
1049 if (status != USBD_NORMAL_COMPLETION) {
1050 DPRINTF("status=%s (%d)\n",
1051 usbd_errstr(status), status);
1052
1053 unit->hci_stats.err_tx++;
1054 return;
1055 }
1056
1057 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1058 unit->hci_stats.cmd_tx++;
1059 unit->hci_stats.byte_tx += count;
1060
1061 ubt_xmit_cmd_start(unit);
1062 }
1063
1064 static void
1065 ubt_xmit_acl_start(struct hci_unit *unit)
1066 {
1067 struct ubt_softc *sc = unit->hci_softc;
1068 struct mbuf *m;
1069 usbd_status status;
1070 int len;
1071
1072 if (sc->sc_dying)
1073 return;
1074
1075 if (MBUFQ_FIRST(&unit->hci_acltxq) == NULL)
1076 return;
1077
1078 sc->sc_refcnt++;
1079 unit->hci_flags |= BTF_XMIT_ACL;
1080
1081 MBUFQ_DEQUEUE(&unit->hci_acltxq, m);
1082 KASSERT(m != NULL);
1083
1084 DPRINTFN(15, "%s: xmit ACL packet (%d bytes)\n",
1085 unit->hci_devname, m->m_pkthdr.len);
1086
1087 len = m->m_pkthdr.len - 1;
1088 if (len > UBT_BUFSIZ_ACL) {
1089 DPRINTF("%s: truncating ACL packet (%d => %d)!\n",
1090 unit->hci_devname, len, UBT_BUFSIZ_ACL);
1091
1092 len = UBT_BUFSIZ_ACL;
1093 }
1094
1095 m_copydata(m, 1, len, sc->sc_aclwr_buf);
1096 m_freem(m);
1097
1098 unit->hci_stats.acl_tx++;
1099 unit->hci_stats.byte_tx += len;
1100
1101 usbd_setup_xfer(sc->sc_aclwr_xfer,
1102 sc->sc_aclwr_pipe,
1103 unit,
1104 sc->sc_aclwr_buf,
1105 len,
1106 USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
1107 UBT_ACL_TIMEOUT,
1108 ubt_xmit_acl_complete);
1109
1110 status = usbd_transfer(sc->sc_aclwr_xfer);
1111
1112 KASSERT(status != USBD_NORMAL_COMPLETION);
1113
1114 if (status != USBD_IN_PROGRESS) {
1115 DPRINTF("usbd_transfer status=%s (%d)\n",
1116 usbd_errstr(status), status);
1117
1118 sc->sc_refcnt--;
1119 unit->hci_flags &= ~BTF_XMIT_ACL;
1120 }
1121 }
1122
1123 static void
1124 ubt_xmit_acl_complete(usbd_xfer_handle xfer,
1125 usbd_private_handle h, usbd_status status)
1126 {
1127 struct hci_unit *unit = h;
1128 struct ubt_softc *sc = unit->hci_softc;
1129
1130 DPRINTFN(15, "%s: ACL complete status=%s (%d)\n",
1131 unit->hci_devname, usbd_errstr(status), status);
1132
1133 unit->hci_flags &= ~BTF_XMIT_ACL;
1134
1135 if (--sc->sc_refcnt < 0) {
1136 usb_detach_wakeup(USBDEV(sc->sc_dev));
1137 return;
1138 }
1139
1140 if (sc->sc_dying)
1141 return;
1142
1143 if (status != USBD_NORMAL_COMPLETION) {
1144 DPRINTF("status=%s (%d)\n",
1145 usbd_errstr(status), status);
1146
1147 unit->hci_stats.err_tx++;
1148
1149 if (status == USBD_STALLED)
1150 usbd_clear_endpoint_stall_async(sc->sc_aclwr_pipe);
1151 else
1152 return;
1153 }
1154
1155 ubt_xmit_acl_start(unit);
1156 }
1157
1158 static void
1159 ubt_xmit_sco_start(struct hci_unit *unit)
1160 {
1161 struct ubt_softc *sc = unit->hci_softc;
1162 int i;
1163
1164 if (sc->sc_dying || sc->sc_scowr_size == 0)
1165 return;
1166
1167 for (i = 0 ; i < UBT_NXFERS ; i++) {
1168 if (sc->sc_scowr[i].busy)
1169 continue;
1170
1171 ubt_xmit_sco_start1(sc, &sc->sc_scowr[i]);
1172 }
1173 }
1174
1175 static void
1176 ubt_xmit_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc)
1177 {
1178 struct mbuf *m;
1179 uint8_t *buf;
1180 int num, len, size, space;
1181
1182 space = sc->sc_scowr_size * UBT_NFRAMES;
1183 buf = isoc->buf;
1184 len = 0;
1185
1186 /*
1187 * Fill the request buffer with data from the queue,
1188 * keeping any leftover packet on our private hook.
1189 *
1190 * Complete packets are passed back up to the stack
1191 * for disposal, since we can't rely on the controller
1192 * to tell us when it has finished with them.
1193 */
1194
1195 m = sc->sc_scowr_mbuf;
1196 while (space > 0) {
1197 if (m == NULL) {
1198 MBUFQ_DEQUEUE(&sc->sc_unit.hci_scotxq, m);
1199 if (m == NULL)
1200 break;
1201
1202 m_adj(m, 1); /* packet type */
1203 }
1204
1205 if (m->m_pkthdr.len > 0) {
1206 size = MIN(m->m_pkthdr.len, space);
1207
1208 m_copydata(m, 0, size, buf);
1209 m_adj(m, size);
1210
1211 buf += size;
1212 len += size;
1213 space -= size;
1214 }
1215
1216 if (m->m_pkthdr.len == 0) {
1217 sc->sc_unit.hci_stats.sco_tx++;
1218 hci_complete_sco(&sc->sc_unit, m);
1219 m = NULL;
1220 }
1221 }
1222 sc->sc_scowr_mbuf = m;
1223
1224 DPRINTFN(15, "isoc=%p, len=%d, space=%d\n", isoc, len, space);
1225
1226 if (len == 0) /* nothing to send */
1227 return;
1228
1229 sc->sc_refcnt++;
1230 sc->sc_unit.hci_flags |= BTF_XMIT_SCO;
1231 sc->sc_unit.hci_stats.byte_tx += len;
1232 isoc->busy = 1;
1233
1234 /*
1235 * calculate number of isoc frames and sizes
1236 */
1237
1238 for (num = 0 ; len > 0 ; num++) {
1239 size = MIN(sc->sc_scowr_size, len);
1240
1241 isoc->size[num] = size;
1242 len -= size;
1243 }
1244
1245 usbd_setup_isoc_xfer(isoc->xfer,
1246 sc->sc_scowr_pipe,
1247 isoc,
1248 isoc->size,
1249 num,
1250 USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
1251 ubt_xmit_sco_complete);
1252
1253 usbd_transfer(isoc->xfer);
1254 }
1255
1256 static void
1257 ubt_xmit_sco_complete(usbd_xfer_handle xfer,
1258 usbd_private_handle h, usbd_status status)
1259 {
1260 struct ubt_isoc_xfer *isoc = h;
1261 struct ubt_softc *sc;
1262 int i;
1263
1264 KASSERT(xfer == isoc->xfer);
1265 sc = isoc->softc;
1266
1267 DPRINTFN(15, "isoc=%p, status=%s (%d)\n",
1268 isoc, usbd_errstr(status), status);
1269
1270 isoc->busy = 0;
1271
1272 for (i = 0 ; ; i++) {
1273 if (i == UBT_NXFERS) {
1274 sc->sc_unit.hci_flags &= ~BTF_XMIT_SCO;
1275 break;
1276 }
1277
1278 if (sc->sc_scowr[i].busy)
1279 break;
1280 }
1281
1282 if (--sc->sc_refcnt < 0) {
1283 usb_detach_wakeup(USBDEV(sc->sc_dev));
1284 return;
1285 }
1286
1287 if (sc->sc_dying)
1288 return;
1289
1290 if (status != USBD_NORMAL_COMPLETION) {
1291 DPRINTF("status=%s (%d)\n",
1292 usbd_errstr(status), status);
1293
1294 sc->sc_unit.hci_stats.err_tx++;
1295
1296 if (status == USBD_STALLED)
1297 usbd_clear_endpoint_stall_async(sc->sc_scowr_pipe);
1298 else
1299 return;
1300 }
1301
1302 ubt_xmit_sco_start(&sc->sc_unit);
1303 }
1304
1305 /*
1306 * load incoming data into an mbuf with
1307 * leading type byte
1308 */
1309 static struct mbuf *
1310 ubt_mbufload(uint8_t *buf, int count, uint8_t type)
1311 {
1312 struct mbuf *m;
1313
1314 MGETHDR(m, M_DONTWAIT, MT_DATA);
1315 if (m == NULL)
1316 return NULL;
1317
1318 *mtod(m, uint8_t *) = type;
1319 m->m_pkthdr.len = m->m_len = MHLEN;
1320 m_copyback(m, 1, count, buf); // (extends if necessary)
1321 if (m->m_pkthdr.len != MAX(MHLEN, count + 1)) {
1322 m_free(m);
1323 return NULL;
1324 }
1325
1326 m->m_pkthdr.len = count + 1;
1327 m->m_len = MIN(MHLEN, m->m_pkthdr.len);
1328
1329 return m;
1330 }
1331
1332 static void
1333 ubt_recv_event(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status)
1334 {
1335 struct ubt_softc *sc = h;
1336 struct mbuf *m;
1337 uint32_t count;
1338 void *buf;
1339
1340 DPRINTFN(15, "sc=%p status=%s (%d)\n",
1341 sc, usbd_errstr(status), status);
1342
1343 if (status != USBD_NORMAL_COMPLETION || sc->sc_dying)
1344 return;
1345
1346 usbd_get_xfer_status(xfer, NULL, &buf, &count, NULL);
1347
1348 if (count < sizeof(hci_event_hdr_t) - 1) {
1349 DPRINTF("dumped undersized event (count = %d)\n", count);
1350 sc->sc_unit.hci_stats.err_rx++;
1351 return;
1352 }
1353
1354 sc->sc_unit.hci_stats.evt_rx++;
1355 sc->sc_unit.hci_stats.byte_rx += count;
1356
1357 m = ubt_mbufload(buf, count, HCI_EVENT_PKT);
1358 if (m != NULL)
1359 hci_input_event(&sc->sc_unit, m);
1360 else
1361 sc->sc_unit.hci_stats.err_rx++;
1362 }
1363
1364 static void
1365 ubt_recv_acl_start(struct ubt_softc *sc)
1366 {
1367 usbd_status status;
1368
1369 DPRINTFN(15, "sc=%p\n", sc);
1370
1371 if (sc->sc_aclrd_busy || sc->sc_dying) {
1372 DPRINTF("sc_aclrd_busy=%d, sc_dying=%d\n",
1373 sc->sc_aclrd_busy,
1374 sc->sc_dying);
1375
1376 return;
1377 }
1378
1379 sc->sc_refcnt++;
1380 sc->sc_aclrd_busy = 1;
1381
1382 usbd_setup_xfer(sc->sc_aclrd_xfer,
1383 sc->sc_aclrd_pipe,
1384 sc,
1385 sc->sc_aclrd_buf,
1386 UBT_BUFSIZ_ACL,
1387 USBD_NO_COPY | USBD_SHORT_XFER_OK,
1388 USBD_NO_TIMEOUT,
1389 ubt_recv_acl_complete);
1390
1391 status = usbd_transfer(sc->sc_aclrd_xfer);
1392
1393 KASSERT(status != USBD_NORMAL_COMPLETION);
1394
1395 if (status != USBD_IN_PROGRESS) {
1396 DPRINTF("usbd_transfer status=%s (%d)\n",
1397 usbd_errstr(status), status);
1398
1399 sc->sc_refcnt--;
1400 sc->sc_aclrd_busy = 0;
1401 }
1402 }
1403
1404 static void
1405 ubt_recv_acl_complete(usbd_xfer_handle xfer,
1406 usbd_private_handle h, usbd_status status)
1407 {
1408 struct ubt_softc *sc = h;
1409 struct mbuf *m;
1410 uint32_t count;
1411 void *buf;
1412
1413 DPRINTFN(15, "sc=%p status=%s (%d)\n",
1414 sc, usbd_errstr(status), status);
1415
1416 sc->sc_aclrd_busy = 0;
1417
1418 if (--sc->sc_refcnt < 0) {
1419 DPRINTF("refcnt = %d\n", sc->sc_refcnt);
1420 usb_detach_wakeup(USBDEV(sc->sc_dev));
1421 return;
1422 }
1423
1424 if (sc->sc_dying) {
1425 DPRINTF("sc_dying\n");
1426 return;
1427 }
1428
1429 if (status != USBD_NORMAL_COMPLETION) {
1430 DPRINTF("status=%s (%d)\n",
1431 usbd_errstr(status), status);
1432
1433 sc->sc_unit.hci_stats.err_rx++;
1434
1435 if (status == USBD_STALLED)
1436 usbd_clear_endpoint_stall_async(sc->sc_aclrd_pipe);
1437 else
1438 return;
1439 } else {
1440 usbd_get_xfer_status(xfer, NULL, &buf, &count, NULL);
1441
1442 if (count < sizeof(hci_acldata_hdr_t) - 1) {
1443 DPRINTF("dumped undersized packet (%d)\n", count);
1444 sc->sc_unit.hci_stats.err_rx++;
1445 } else {
1446 sc->sc_unit.hci_stats.acl_rx++;
1447 sc->sc_unit.hci_stats.byte_rx += count;
1448
1449 m = ubt_mbufload(buf, count, HCI_ACL_DATA_PKT);
1450 if (m != NULL)
1451 hci_input_acl(&sc->sc_unit, m);
1452 else
1453 sc->sc_unit.hci_stats.err_rx++;
1454 }
1455 }
1456
1457 /* and restart */
1458 ubt_recv_acl_start(sc);
1459 }
1460
1461 static void
1462 ubt_recv_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc)
1463 {
1464 int i;
1465
1466 DPRINTFN(15, "sc=%p, isoc=%p\n", sc, isoc);
1467
1468 if (isoc->busy || sc->sc_dying || sc->sc_scord_size == 0) {
1469 DPRINTF("%s%s%s\n",
1470 isoc->busy ? " busy" : "",
1471 sc->sc_dying ? " dying" : "",
1472 sc->sc_scord_size == 0 ? " size=0" : "");
1473
1474 return;
1475 }
1476
1477 sc->sc_refcnt++;
1478 isoc->busy = 1;
1479
1480 for (i = 0 ; i < UBT_NFRAMES ; i++)
1481 isoc->size[i] = sc->sc_scord_size;
1482
1483 usbd_setup_isoc_xfer(isoc->xfer,
1484 sc->sc_scord_pipe,
1485 isoc,
1486 isoc->size,
1487 UBT_NFRAMES,
1488 USBD_NO_COPY | USBD_SHORT_XFER_OK,
1489 ubt_recv_sco_complete);
1490
1491 usbd_transfer(isoc->xfer);
1492 }
1493
1494 static void
1495 ubt_recv_sco_complete(usbd_xfer_handle xfer,
1496 usbd_private_handle h, usbd_status status)
1497 {
1498 struct ubt_isoc_xfer *isoc = h;
1499 struct ubt_softc *sc;
1500 struct mbuf *m;
1501 uint32_t count;
1502 uint8_t *ptr, *frame;
1503 int i, size, got, want;
1504
1505 KASSERT(isoc != NULL);
1506 KASSERT(isoc->xfer == xfer);
1507
1508 sc = isoc->softc;
1509 isoc->busy = 0;
1510
1511 if (--sc->sc_refcnt < 0) {
1512 DPRINTF("refcnt=%d\n", sc->sc_refcnt);
1513 usb_detach_wakeup(USBDEV(sc->sc_dev));
1514 return;
1515 }
1516
1517 if (sc->sc_dying) {
1518 DPRINTF("sc_dying\n");
1519 return;
1520 }
1521
1522 if (status != USBD_NORMAL_COMPLETION) {
1523 DPRINTF("status=%s (%d)\n",
1524 usbd_errstr(status), status);
1525
1526 sc->sc_unit.hci_stats.err_rx++;
1527
1528 if (status == USBD_STALLED) {
1529 usbd_clear_endpoint_stall_async(sc->sc_scord_pipe);
1530 goto restart;
1531 }
1532
1533 return;
1534 }
1535
1536 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1537 if (count == 0)
1538 goto restart;
1539
1540 DPRINTFN(15, "sc=%p, isoc=%p, count=%u\n",
1541 sc, isoc, count);
1542
1543 sc->sc_unit.hci_stats.byte_rx += count;
1544
1545 /*
1546 * Extract SCO packets from ISOC frames. The way we have it,
1547 * no SCO packet can be bigger than MHLEN. This is unlikely
1548 * to actually happen, but if we ran out of mbufs and lost
1549 * sync then we may get spurious data that makes it seem that
1550 * way, so we discard data that wont fit. This doesnt really
1551 * help with the lost sync situation alas.
1552 */
1553
1554 m = sc->sc_scord_mbuf;
1555 if (m != NULL) {
1556 sc->sc_scord_mbuf = NULL;
1557 ptr = mtod(m, uint8_t *) + m->m_pkthdr.len;
1558 got = m->m_pkthdr.len;
1559 want = sizeof(hci_scodata_hdr_t);
1560 if (got >= want)
1561 want += mtod(m, hci_scodata_hdr_t *)->length ;
1562 } else {
1563 ptr = NULL;
1564 got = 0;
1565 want = 0;
1566 }
1567
1568 for (i = 0 ; i < UBT_NFRAMES ; i++) {
1569 frame = isoc->buf + (i * sc->sc_scord_size);
1570
1571 while (isoc->size[i] > 0) {
1572 size = isoc->size[i];
1573
1574 if (m == NULL) {
1575 MGETHDR(m, M_DONTWAIT, MT_DATA);
1576 if (m == NULL) {
1577 printf("%s: out of memory (xfer halted)\n",
1578 USBDEVNAME(sc->sc_dev));
1579
1580 sc->sc_unit.hci_stats.err_rx++;
1581 return; /* lost sync */
1582 }
1583
1584 ptr = mtod(m, uint8_t *);
1585 *ptr++ = HCI_SCO_DATA_PKT;
1586 got = 1;
1587 want = sizeof(hci_scodata_hdr_t);
1588 }
1589
1590 if (got + size > want)
1591 size = want - got;
1592
1593 if (got + size > MHLEN)
1594 memcpy(ptr, frame, MHLEN - got);
1595 else
1596 memcpy(ptr, frame, size);
1597
1598 ptr += size;
1599 got += size;
1600 frame += size;
1601
1602 if (got == want) {
1603 /*
1604 * If we only got a header, add the packet
1605 * length to our want count. Send complete
1606 * packets up to protocol stack.
1607 */
1608 if (want == sizeof(hci_scodata_hdr_t))
1609 want += mtod(m, hci_scodata_hdr_t *)->length;
1610
1611 if (got == want) {
1612 m->m_pkthdr.len = m->m_len = got;
1613 sc->sc_unit.hci_stats.sco_rx++;
1614 hci_input_sco(&sc->sc_unit, m);
1615 m = NULL;
1616 }
1617 }
1618
1619 isoc->size[i] -= size;
1620 }
1621 }
1622
1623 if (m != NULL) {
1624 m->m_pkthdr.len = m->m_len = got;
1625 sc->sc_scord_mbuf = m;
1626 }
1627
1628 restart: /* and restart */
1629 ubt_recv_sco_start1(sc, isoc);
1630 }
1631