ubt.c revision 1.9 1 /* $NetBSD: ubt.c,v 1.9 2004/01/02 02:36:25 dsainty Exp $ */
2
3 /*
4 * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart (at) augustsson.net) and
9 * David Sainty (David.Sainty (at) dtsp.co.nz).
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: ubt.c,v 1.9 2004/01/02 02:36:25 dsainty Exp $");
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
46 #include <sys/malloc.h>
47 #include <sys/device.h>
48 #include <sys/lock.h>
49 #include <sys/ioctl.h>
50 #include <sys/conf.h>
51 #include <sys/file.h>
52 #include <sys/poll.h>
53 #include <sys/select.h>
54 #include <sys/proc.h>
55
56 #include <dev/usb/ubtreg.h>
57 #include <dev/usb/usb.h>
58 #include <dev/usb/usbdi.h>
59 #include <dev/usb/usbdi_util.h>
60 #include <dev/usb/usbdevs.h>
61
62 #include <dev/bluetooth/bluetooth.h>
63
64 #ifdef UBT_DEBUG
65 #define DPRINTF(x) if (ubtdebug) logprintf x
66 #define DPRINTFN(n,x) if (ubtdebug>(n)) logprintf x
67 int ubtdebug = 49;
68 #else
69 #define DPRINTF(x)
70 #define DPRINTFN(n,x)
71 #endif
72
73 /*
74 * Protocol related definitions
75 */
76
77 struct ubt_softc {
78 USBBASEDEVICE sc_dev;
79 usbd_device_handle sc_udev;
80 usbd_interface_handle sc_ctl_iface;
81 usbd_interface_handle sc_isoc_iface;
82
83 /* Control */
84 usbd_pipe_handle sc_ctl_pipe;
85 usbd_xfer_handle sc_ctl_xfer;
86 u_int8_t *sc_ctl_buf;
87
88 /* Events */
89 int sc_evt_addr;
90 usbd_pipe_handle sc_evt_pipe;
91 usbd_xfer_handle sc_evt_xfer;
92 u_int8_t *sc_evt_buf;
93
94 /* ACL data (in) */
95 int sc_aclrd_addr;
96 usbd_pipe_handle sc_aclrd_pipe;
97 usbd_xfer_handle sc_aclrd_xfer;
98 u_int8_t *sc_aclrd_buf;
99 int sc_aclrd_running;
100
101 /* ACL data (out) */
102 int sc_aclwr_addr;
103 usbd_pipe_handle sc_aclwr_pipe;
104 usbd_xfer_handle sc_aclwr_xfer;
105 u_int8_t *sc_aclwr_buf;
106
107 struct device *sc_child;
108 struct btframe_callback_methods const *sc_cb;
109
110 unsigned int sc_blocked;
111
112 int sc_refcnt;
113 char sc_dying;
114 };
115
116 static int ubt_open(void *h, int flag, int mode, usb_proc_ptr p);
117 static int ubt_close(void *h, int flag, int mode, usb_proc_ptr p);
118
119 static u_int8_t* ubt_alloc_control(void*, size_t, struct btframe_buffer**);
120 static int ubt_send_control(void*, struct btframe_buffer*, size_t);
121
122 static u_int8_t* ubt_alloc_acldata(void*, size_t, struct btframe_buffer**);
123 static int ubt_send_acldata(void*, struct btframe_buffer*, size_t);
124
125 static u_int8_t* ubt_alloc_scodata(void*, size_t, struct btframe_buffer**);
126 static int ubt_send_scodata(void*, struct btframe_buffer*, size_t);
127
128 static int ubt_splraise(void);
129 static unsigned int ubt_blockcb(void *h, unsigned int cbblocks);
130 static unsigned int ubt_unblockcb(void *h, unsigned int cbblocks);
131
132 static void ubt_event_cb(usbd_xfer_handle, usbd_private_handle, usbd_status);
133 static void ubt_aclrd_cb(usbd_xfer_handle, usbd_private_handle, usbd_status);
134 static void ubt_aclrd_request(struct ubt_softc *);
135
136 static struct btframe_methods const ubt_methods = {
137 ubt_open, ubt_close,
138 {ubt_alloc_control, ubt_send_control},
139 {ubt_alloc_acldata, ubt_send_acldata},
140 {ubt_alloc_scodata, ubt_send_scodata},
141 ubt_splraise, ubt_blockcb, ubt_unblockcb
142 };
143
144 USB_DECLARE_DRIVER(ubt);
145
146 USB_MATCH(ubt)
147 {
148 USB_MATCH_START(ubt, uaa);
149 usb_interface_descriptor_t *id;
150
151 DPRINTFN(50,("ubt_match\n"));
152
153 if (uaa->iface == NULL)
154 return (UMATCH_NONE);
155
156 id = usbd_get_interface_descriptor(uaa->iface);
157 if (id != NULL &&
158 id->bInterfaceClass == UICLASS_WIRELESS &&
159 id->bInterfaceSubClass == UISUBCLASS_RF &&
160 id->bInterfaceProtocol == UIPROTO_BLUETOOTH)
161 return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
162 return (UMATCH_NONE);
163 }
164
165 USB_ATTACH(ubt)
166 {
167 USB_ATTACH_START(ubt, sc, uaa);
168 usbd_device_handle dev = uaa->device;
169 usbd_interface_handle iface = uaa->iface;
170 struct bt_attach_args bt;
171 usb_interface_descriptor_t const *id;
172 char devinfo[1024];
173 usb_endpoint_descriptor_t const *ed;
174 u_int8_t epcount;
175 int i;
176
177 DPRINTFN(10,("ubt_attach: sc=%p\n", sc));
178
179 usbd_devinfo(dev, 0, devinfo);
180 USB_ATTACH_SETUP;
181 printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
182
183 sc->sc_udev = dev;
184 sc->sc_ctl_iface = iface;
185
186 /*
187 * The control interface comes before the isoc interface
188 * according to the spec, so we find it first.
189 */
190 epcount = 0;
191 (void)usbd_endpoint_count(iface, &epcount);
192
193 sc->sc_evt_addr = -1;
194 sc->sc_aclrd_addr = -1;
195 sc->sc_aclwr_addr = -1;
196
197 for (i = 0; i < epcount; i++) {
198 ed = usbd_interface2endpoint_descriptor(iface, i);
199 if (ed == NULL) {
200 printf("%s: couldn't get ep %d\n",
201 USBDEVNAME(sc->sc_dev), i);
202 USB_ATTACH_ERROR_RETURN;
203 }
204
205 DPRINTFN(10, ("%s: addr=%d attr=%d\n", __func__,
206 (int)ed->bEndpointAddress,
207 (int)ed->bmAttributes));
208
209 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
210 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
211 sc->sc_evt_addr = ed->bEndpointAddress;
212 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
213 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
214 sc->sc_aclrd_addr = ed->bEndpointAddress;
215 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
216 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
217 sc->sc_aclwr_addr = ed->bEndpointAddress;
218 }
219 }
220
221 if (sc->sc_evt_addr == -1 ||
222 sc->sc_aclrd_addr == -1 || sc->sc_aclwr_addr == -1) {
223 printf("%s: missing endpoint\n", USBDEVNAME(sc->sc_dev));
224 USB_ATTACH_ERROR_RETURN;
225 }
226
227 /* XXX works because isoc comes after ctl */
228 /* Grab isoc interface as well. */
229 for (i = 0; i < uaa->nifaces; i++) {
230 if (uaa->ifaces[i] == NULL)
231 continue;
232 id = usbd_get_interface_descriptor(uaa->ifaces[i]);
233 if (id != NULL &&
234 id->bInterfaceClass == UICLASS_WIRELESS &&
235 id->bInterfaceSubClass == UISUBCLASS_RF &&
236 id->bInterfaceProtocol == UIPROTO_BLUETOOTH) {
237 sc->sc_isoc_iface = uaa->ifaces[i];
238 uaa->ifaces[i] = NULL;
239 }
240 }
241
242 printf("%s: has%s isoc data\n", USBDEVNAME(sc->sc_dev),
243 sc->sc_isoc_iface != NULL ? "" : " no");
244
245 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
246 USBDEV(sc->sc_dev));
247
248 bt.bt_methods = &ubt_methods;
249 bt.bt_cb = &sc->sc_cb;
250 bt.bt_handle = sc;
251
252 sc->sc_child = config_found(self, &bt, bt_print);
253
254 USB_ATTACH_SUCCESS_RETURN;
255 }
256
257 static void
258 ubt_abortdealloc(struct ubt_softc *sc)
259 {
260 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc));
261
262 if (sc->sc_evt_pipe != NULL) {
263 usbd_abort_pipe(sc->sc_evt_pipe);
264 usbd_close_pipe(sc->sc_evt_pipe);
265 sc->sc_evt_pipe = NULL;
266 }
267 if (sc->sc_evt_buf != NULL) {
268 free(sc->sc_evt_buf, M_USBDEV);
269 sc->sc_evt_buf = NULL;
270 }
271 if (sc->sc_aclrd_pipe != NULL) {
272 usbd_abort_pipe(sc->sc_aclrd_pipe);
273 usbd_close_pipe(sc->sc_aclrd_pipe);
274 sc->sc_aclrd_pipe = NULL;
275 }
276 if (sc->sc_aclwr_pipe != NULL) {
277 usbd_abort_pipe(sc->sc_aclwr_pipe);
278 usbd_close_pipe(sc->sc_aclwr_pipe);
279 sc->sc_aclwr_pipe = NULL;
280 }
281 if (sc->sc_aclrd_xfer != NULL) {
282 usbd_free_xfer(sc->sc_aclrd_xfer);
283 sc->sc_aclrd_xfer = NULL;
284 sc->sc_aclrd_buf = NULL;
285 }
286 if (sc->sc_aclwr_xfer != NULL) {
287 usbd_free_xfer(sc->sc_aclwr_xfer);
288 sc->sc_aclwr_xfer = NULL;
289 sc->sc_aclwr_buf = NULL;
290 }
291 }
292
293 USB_DETACH(ubt)
294 {
295 USB_DETACH_START(ubt, sc);
296 int s;
297 int rv = 0;
298
299 DPRINTF(("%s: sc=%p flags=%d\n", __func__, sc, flags));
300
301 sc->sc_dying = 1;
302
303 /* Abort all pipes. Causes processes waiting for transfer to wake. */
304 ubt_abortdealloc(sc);
305
306 DPRINTFN(1, ("%s: waiting for USB detach\n", __func__));
307 s = splusb();
308 if (--sc->sc_refcnt >= 0) {
309 /* Wait for processes to go away. */
310 usb_detach_wait(USBDEV(sc->sc_dev));
311 }
312 splx(s);
313 DPRINTFN(1, ("%s: USB detach complete\n", __func__));
314
315 if (sc->sc_child != NULL) {
316 DPRINTFN(1, ("%s: waiting for child detach\n", __func__));
317 rv = config_detach(sc->sc_child, flags);
318 sc->sc_child = NULL;
319 DPRINTFN(1, ("%s: child detach complete\n", __func__));
320 }
321
322 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
323 USBDEV(sc->sc_dev));
324
325 DPRINTFN(1, ("%s: driver detached\n", __func__));
326
327 return (rv);
328 }
329
330 int
331 ubt_activate(device_ptr_t self, enum devact act)
332 {
333 struct ubt_softc *sc = (struct ubt_softc *)self;
334 int error = 0;
335
336 switch (act) {
337 case DVACT_ACTIVATE:
338 return (EOPNOTSUPP);
339 break;
340
341 case DVACT_DEACTIVATE:
342 sc->sc_dying = 1;
343 if (sc->sc_child != NULL)
344 error = config_deactivate(sc->sc_child);
345 break;
346 }
347 return (error);
348 }
349
350 static int
351 ubt_open(void *h, int flag, int mode, usb_proc_ptr p)
352 {
353 struct ubt_softc *sc = h;
354 int error;
355 usbd_status err;
356
357 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc));
358
359 sc->sc_evt_buf = malloc(BTHCI_EVENT_MAX_LEN, M_USBDEV, M_NOWAIT);
360 if (sc->sc_evt_buf == NULL) {
361 error = ENOMEM;
362 goto bad0;
363 }
364
365 err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_evt_addr,
366 USBD_SHORT_XFER_OK, &sc->sc_evt_pipe,
367 sc, sc->sc_evt_buf, BTHCI_EVENT_MAX_LEN,
368 ubt_event_cb, UBT_EVENT_EP_INTERVAL);
369 if (err != USBD_NORMAL_COMPLETION) {
370 error = EIO;
371 goto bad1;
372 }
373
374 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_aclrd_addr,
375 0, &sc->sc_aclrd_pipe);
376 if (err != USBD_NORMAL_COMPLETION) {
377 error = EIO;
378 goto bad2;
379 }
380
381 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_aclwr_addr,
382 0, &sc->sc_aclwr_pipe);
383 if (err != USBD_NORMAL_COMPLETION) {
384 error = EIO;
385 goto bad3;
386 }
387
388 sc->sc_ctl_xfer = usbd_alloc_xfer(sc->sc_udev);
389 if (sc->sc_ctl_xfer == NULL) {
390 error = ENOMEM;
391 goto bad4;
392 }
393 sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev);
394 if (sc->sc_aclrd_xfer == NULL) {
395 error = ENOMEM;
396 goto bad5;
397 }
398 sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev);
399 if (sc->sc_aclwr_xfer == NULL) {
400 error = ENOMEM;
401 goto bad6;
402 }
403
404 /* Buffers */
405 sc->sc_ctl_buf = usbd_alloc_buffer(sc->sc_ctl_xfer,
406 BTHCI_COMMAND_MAX_LEN);
407 if (sc->sc_ctl_buf == NULL) {
408 error = ENOMEM;
409 goto bad7;
410 }
411 sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer,
412 BTHCI_ACL_DATA_MAX_LEN);
413 if (sc->sc_aclrd_buf == NULL) {
414 error = ENOMEM;
415 goto bad7;
416 }
417 sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer,
418 BTHCI_ACL_DATA_MAX_LEN);
419 if (sc->sc_aclwr_buf == NULL) {
420 error = ENOMEM;
421 goto bad7;
422 }
423
424 /* Start reading */
425 ubt_aclrd_request(sc);
426
427 return 0;
428
429 bad7:
430 usbd_free_xfer(sc->sc_aclwr_xfer);
431 sc->sc_aclwr_xfer = NULL;
432 bad6:
433 usbd_free_xfer(sc->sc_aclrd_xfer);
434 sc->sc_aclrd_xfer = NULL;
435 bad5:
436 usbd_free_xfer(sc->sc_ctl_xfer);
437 sc->sc_ctl_xfer = NULL;
438 bad4:
439 usbd_close_pipe(sc->sc_aclwr_pipe);
440 sc->sc_aclwr_pipe = NULL;
441 bad3:
442 usbd_close_pipe(sc->sc_aclrd_pipe);
443 sc->sc_aclrd_pipe = NULL;
444 bad2:
445 usbd_close_pipe(sc->sc_evt_pipe);
446 sc->sc_evt_pipe = NULL;
447 bad1:
448 free(sc->sc_evt_buf, M_USBDEV);
449 sc->sc_evt_buf = NULL;
450 bad0:
451 return error;
452 }
453
454 static int
455 ubt_close(void *h, int flag, int mode, usb_proc_ptr p)
456 {
457 struct ubt_softc *sc = h;
458
459 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc));
460
461 ubt_abortdealloc(sc);
462
463 return 0;
464 }
465
466 static u_int8_t*
467 ubt_alloc_control(void *h, size_t len, struct btframe_buffer **buf)
468 {
469 struct ubt_softc *sc = h;
470
471 /*
472 * We should be catching this earlier, but at the moment a
473 * user request can generate oversized allocations.
474 */
475 if (len > BTHCI_COMMAND_MAX_LEN)
476 return NULL;
477
478 *buf = (struct btframe_buffer*)sc->sc_ctl_buf;
479 return sc->sc_ctl_buf;
480 }
481
482 static int
483 ubt_send_control(void *h, struct btframe_buffer *buf, size_t len)
484 {
485 struct ubt_softc *sc = h;
486 usb_device_request_t req;
487 usbd_status status;
488
489 DPRINTFN(1,("%s: sc=%p\n", __func__, sc));
490
491 #ifdef DIAGNOSTIC
492 if ((u_int8_t*)buf != sc->sc_ctl_buf)
493 panic("ubt_control() called with wrong buffer");
494 #endif
495
496 if (sc->sc_dying)
497 return EIO;
498
499 if (len < BTHCI_COMMAND_MIN_LEN || len > BTHCI_COMMAND_MAX_LEN)
500 return EINVAL;
501
502 sc->sc_refcnt++;
503
504 memset(&req, 0, sizeof(req));
505 req.bmRequestType = UT_WRITE_CLASS_DEVICE;
506 USETW(req.wLength, len);
507
508 usbd_setup_default_xfer(sc->sc_ctl_xfer,
509 sc->sc_udev,
510 sc,
511 USBD_DEFAULT_TIMEOUT,
512 &req, sc->sc_ctl_buf, len,
513 USBD_SYNCHRONOUS | USBD_NO_COPY, NULL);
514
515 status = usbd_transfer(sc->sc_ctl_xfer);
516
517 if (--sc->sc_refcnt < 0)
518 usb_detach_wakeup(USBDEV(sc->sc_dev));
519
520 if (status != USBD_NORMAL_COMPLETION)
521 return EIO;
522
523 return 0;
524 }
525
526 static u_int8_t*
527 ubt_alloc_acldata(void *h, size_t len, struct btframe_buffer **buf)
528 {
529 struct ubt_softc *sc = h;
530
531 /*
532 * We should be catching this earlier, but at the moment a
533 * user request can generate oversized allocations.
534 */
535 if (len > BTHCI_ACL_DATA_MAX_LEN)
536 return NULL;
537
538 *buf = (struct btframe_buffer*)sc->sc_aclwr_buf;
539 return sc->sc_aclwr_buf;
540 }
541
542 static int
543 ubt_send_acldata(void *h, struct btframe_buffer *buf, size_t len)
544 {
545 struct ubt_softc *sc = h;
546 usbd_status status;
547
548 DPRINTFN(1,("%s: sc=%p\n", __func__, sc));
549
550 #ifdef DIAGNOSTIC
551 if ((u_int8_t*)buf != sc->sc_aclwr_buf)
552 panic("ubt_sendacldata() called with wrong buffer");
553 #endif
554
555 if (sc->sc_dying)
556 return EIO;
557
558 if (len < BTHCI_ACL_DATA_MIN_LEN || len > BTHCI_ACL_DATA_MAX_LEN)
559 return EINVAL;
560
561 sc->sc_refcnt++;
562
563 usbd_setup_xfer(sc->sc_aclwr_xfer,
564 sc->sc_aclwr_pipe,
565 (usbd_private_handle)sc,
566 sc->sc_aclwr_buf, len,
567 USBD_SYNCHRONOUS | USBD_NO_COPY,
568 USBD_DEFAULT_TIMEOUT,
569 NULL);
570
571 status = usbd_transfer(sc->sc_aclwr_xfer);
572
573 if (--sc->sc_refcnt < 0)
574 usb_detach_wakeup(USBDEV(sc->sc_dev));
575
576 if (status != USBD_NORMAL_COMPLETION)
577 return EIO;
578
579 return 0;
580 }
581
582 static u_int8_t*
583 ubt_alloc_scodata(void *h, size_t len, struct btframe_buffer **buf)
584 {
585 return NULL;
586 }
587
588 static int
589 ubt_send_scodata(void *h, struct btframe_buffer *buf, size_t len)
590 {
591 struct ubt_softc *sc = h;
592
593 DPRINTFN(1,("%s: sc=%p\n", __func__, sc));
594
595 if (sc->sc_dying)
596 return EIO;
597
598 return ENXIO;
599 }
600
601 static void
602 ubt_event_cb(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status)
603 {
604 struct ubt_softc *sc = h;
605 void *buf;
606 u_int32_t size;
607
608 DPRINTFN(1,("%s: sc=%p status=%s\n", __func__, sc,
609 usbd_errstr(status)));
610
611 if (status != USBD_NORMAL_COMPLETION || sc->sc_dying ||
612 sc->sc_child == NULL)
613 return;
614
615 usbd_get_xfer_status(xfer, NULL, &buf, &size, NULL);
616
617 sc->sc_cb->bt_recveventdata(sc->sc_child, buf, (size_t)size);
618 }
619
620 static void
621 ubt_aclrd_request(struct ubt_softc *sc)
622 {
623 usbd_status status;
624 int s;
625
626 DPRINTFN(1,("%s: sc=%p\n", __func__, sc));
627
628 if (sc->sc_dying)
629 return;
630
631 s = splusb();
632 if (sc->sc_aclrd_running) {
633 splx(s);
634 return;
635 }
636 sc->sc_aclrd_running = 1;
637 splx(s);
638
639 usbd_setup_xfer(sc->sc_aclrd_xfer, sc->sc_aclrd_pipe,
640 sc, sc->sc_aclrd_buf, BTHCI_ACL_DATA_MAX_LEN,
641 USBD_SHORT_XFER_OK | USBD_NO_COPY,
642 USBD_NO_TIMEOUT, ubt_aclrd_cb);
643
644 status = usbd_transfer(sc->sc_aclrd_xfer);
645
646 /* Cancellation is normal on device shutdown */
647 if (status == USBD_IN_PROGRESS || status == USBD_CANCELLED)
648 return;
649
650 DPRINTFN(1,("%s: read request failed: %s\n", __func__,
651 usbd_errstr(status)));
652
653 sc->sc_aclrd_running = 0;
654 sc->sc_blocked |= BT_CBBLOCK_ACL_DATA;
655 }
656
657 static void
658 ubt_aclrd_cb(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status)
659 {
660 struct ubt_softc *sc = h;
661 void *buf;
662 u_int32_t size;
663
664 DPRINTFN(1,("%s: sc=%p status=%s\n", __func__, sc,
665 usbd_errstr(status)));
666
667 sc->sc_aclrd_running = 0;
668
669 if (status != USBD_NORMAL_COMPLETION || sc->sc_dying ||
670 sc->sc_child == NULL)
671 return;
672
673 usbd_get_xfer_status(xfer, NULL, &buf, &size, NULL);
674
675 sc->sc_cb->bt_recvacldata(sc->sc_child, buf, (size_t)size);
676
677 /* Re-issue the request if not blocked */
678 if (!sc->sc_dying && !(sc->sc_blocked & BT_CBBLOCK_ACL_DATA))
679 ubt_aclrd_request(sc);
680 }
681
682 static unsigned int
683 ubt_blockcb(void *h, unsigned int cbblocks)
684 {
685 struct ubt_softc *sc = h;
686
687 sc->sc_blocked |= (cbblocks & BT_CBBLOCK_ACL_DATA);
688
689 return sc->sc_blocked;
690 }
691
692 static unsigned int
693 ubt_unblockcb(void *h, unsigned int cbblocks)
694 {
695 struct ubt_softc *sc = h;
696 unsigned int oblocks, changes;
697
698 oblocks = sc->sc_blocked;
699 sc->sc_blocked = oblocks & ~cbblocks;
700
701 changes = oblocks & cbblocks;
702
703 if (changes & BT_CBBLOCK_ACL_DATA)
704 /* Re-issue the request if action un-blocked reads */
705 ubt_aclrd_request(sc);
706
707 return sc->sc_blocked;
708 }
709
710 static int
711 ubt_splraise(void)
712 {
713 return splusb();
714 }
715