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