1 /* $NetBSD: ubt.c,v 1.7 2003/01/20 21:14:57 augustss 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@augustsson.net) and 9 * David Sainty (David.Sainty@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.7 2003/01/20 21:14:57 augustss 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 251 sc->sc_child = config_found(self, &bt, bt_print); 252 253 USB_ATTACH_SUCCESS_RETURN; 254 } 255 256 static void 257 ubt_abortdealloc(struct ubt_softc *sc) 258 { 259 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 260 261 if (sc->sc_evt_pipe != NULL) { 262 usbd_abort_pipe(sc->sc_evt_pipe); 263 usbd_close_pipe(sc->sc_evt_pipe); 264 sc->sc_evt_pipe = NULL; 265 } 266 if (sc->sc_evt_buf != NULL) { 267 free(sc->sc_evt_buf, M_USBDEV); 268 sc->sc_evt_buf = NULL; 269 } 270 if (sc->sc_aclrd_pipe != NULL) { 271 usbd_abort_pipe(sc->sc_aclrd_pipe); 272 usbd_close_pipe(sc->sc_aclrd_pipe); 273 sc->sc_aclrd_pipe = NULL; 274 } 275 if (sc->sc_aclwr_pipe != NULL) { 276 usbd_abort_pipe(sc->sc_aclwr_pipe); 277 usbd_close_pipe(sc->sc_aclwr_pipe); 278 sc->sc_aclwr_pipe = NULL; 279 } 280 if (sc->sc_aclrd_xfer != NULL) { 281 usbd_free_xfer(sc->sc_aclrd_xfer); 282 sc->sc_aclrd_xfer = NULL; 283 sc->sc_aclrd_buf = NULL; 284 } 285 if (sc->sc_aclwr_xfer != NULL) { 286 usbd_free_xfer(sc->sc_aclwr_xfer); 287 sc->sc_aclwr_xfer = NULL; 288 sc->sc_aclwr_buf = NULL; 289 } 290 } 291 292 USB_DETACH(ubt) 293 { 294 USB_DETACH_START(ubt, sc); 295 int s; 296 int rv = 0; 297 298 DPRINTF(("%s: sc=%p flags=%d\n", __func__, sc, flags)); 299 300 sc->sc_dying = 1; 301 302 /* Abort all pipes. Causes processes waiting for transfer to wake. */ 303 ubt_abortdealloc(sc); 304 305 DPRINTFN(1, ("%s: waiting for USB detach\n", __func__)); 306 s = splusb(); 307 if (--sc->sc_refcnt >= 0) { 308 /* Wait for processes to go away. */ 309 usb_detach_wait(USBDEV(sc->sc_dev)); 310 } 311 splx(s); 312 DPRINTFN(1, ("%s: USB detach complete\n", __func__)); 313 314 if (sc->sc_child != NULL) { 315 DPRINTFN(1, ("%s: waiting for child detach\n", __func__)); 316 rv = config_detach(sc->sc_child, flags); 317 sc->sc_child = NULL; 318 DPRINTFN(1, ("%s: child detach complete\n", __func__)); 319 } 320 321 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 322 USBDEV(sc->sc_dev)); 323 324 DPRINTFN(1, ("%s: driver detached\n", __func__)); 325 326 return (rv); 327 } 328 329 int 330 ubt_activate(device_ptr_t self, enum devact act) 331 { 332 struct ubt_softc *sc = (struct ubt_softc *)self; 333 int error = 0; 334 335 switch (act) { 336 case DVACT_ACTIVATE: 337 return (EOPNOTSUPP); 338 break; 339 340 case DVACT_DEACTIVATE: 341 sc->sc_dying = 1; 342 if (sc->sc_child != NULL) 343 error = config_deactivate(sc->sc_child); 344 break; 345 } 346 return (error); 347 } 348 349 static int 350 ubt_open(void *h, int flag, int mode, usb_proc_ptr p) 351 { 352 struct ubt_softc *sc = h; 353 int error; 354 usbd_status err; 355 356 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 357 358 sc->sc_evt_buf = malloc(BTHCI_EVENT_MAX_LEN, M_USBDEV, M_NOWAIT); 359 if (sc->sc_evt_buf == NULL) { 360 error = ENOMEM; 361 goto bad0; 362 } 363 364 err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_evt_addr, 365 USBD_SHORT_XFER_OK, &sc->sc_evt_pipe, 366 sc, sc->sc_evt_buf, BTHCI_EVENT_MAX_LEN, 367 ubt_event_cb, UBT_EVENT_EP_INTERVAL); 368 if (err != USBD_NORMAL_COMPLETION) { 369 error = EIO; 370 goto bad1; 371 } 372 373 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_aclrd_addr, 374 0, &sc->sc_aclrd_pipe); 375 if (err != USBD_NORMAL_COMPLETION) { 376 error = EIO; 377 goto bad2; 378 } 379 380 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_aclwr_addr, 381 0, &sc->sc_aclwr_pipe); 382 if (err != USBD_NORMAL_COMPLETION) { 383 error = EIO; 384 goto bad3; 385 } 386 387 sc->sc_ctl_xfer = usbd_alloc_xfer(sc->sc_udev); 388 if (sc->sc_ctl_xfer == NULL) { 389 error = ENOMEM; 390 goto bad4; 391 } 392 sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev); 393 if (sc->sc_aclrd_xfer == NULL) { 394 error = ENOMEM; 395 goto bad5; 396 } 397 sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev); 398 if (sc->sc_aclwr_xfer == NULL) { 399 error = ENOMEM; 400 goto bad6; 401 } 402 403 /* Buffers */ 404 sc->sc_ctl_buf = usbd_alloc_buffer(sc->sc_ctl_xfer, 405 BTHCI_COMMAND_MAX_LEN); 406 if (sc->sc_ctl_buf == NULL) { 407 error = ENOMEM; 408 goto bad7; 409 } 410 sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer, 411 BTHCI_ACL_DATA_MAX_LEN); 412 if (sc->sc_aclrd_buf == NULL) { 413 error = ENOMEM; 414 goto bad7; 415 } 416 sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer, 417 BTHCI_ACL_DATA_MAX_LEN); 418 if (sc->sc_aclwr_buf == NULL) { 419 error = ENOMEM; 420 goto bad7; 421 } 422 423 /* Start reading */ 424 ubt_aclrd_request(sc); 425 426 return 0; 427 428 bad7: 429 usbd_free_xfer(sc->sc_aclwr_xfer); 430 sc->sc_aclwr_xfer = NULL; 431 bad6: 432 usbd_free_xfer(sc->sc_aclrd_xfer); 433 sc->sc_aclrd_xfer = NULL; 434 bad5: 435 usbd_free_xfer(sc->sc_ctl_xfer); 436 sc->sc_ctl_xfer = NULL; 437 bad4: 438 usbd_close_pipe(sc->sc_aclwr_pipe); 439 sc->sc_aclwr_pipe = NULL; 440 bad3: 441 usbd_close_pipe(sc->sc_aclrd_pipe); 442 sc->sc_aclrd_pipe = NULL; 443 bad2: 444 usbd_close_pipe(sc->sc_evt_pipe); 445 sc->sc_evt_pipe = NULL; 446 bad1: 447 free(sc->sc_evt_buf, M_USBDEV); 448 sc->sc_evt_buf = NULL; 449 bad0: 450 return error; 451 } 452 453 static int 454 ubt_close(void *h, int flag, int mode, usb_proc_ptr p) 455 { 456 struct ubt_softc *sc = h; 457 458 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 459 460 ubt_abortdealloc(sc); 461 462 return 0; 463 } 464 465 static u_int8_t* 466 ubt_alloc_control(void *h, size_t len, struct btframe_buffer **buf) 467 { 468 struct ubt_softc *sc = h; 469 470 /* 471 * We should be catching this earlier, but at the moment a 472 * user request can generate oversized allocations. 473 */ 474 if (len > BTHCI_COMMAND_MAX_LEN) 475 return NULL; 476 477 *buf = (struct btframe_buffer*)sc->sc_ctl_buf; 478 return sc->sc_ctl_buf; 479 } 480 481 static int 482 ubt_send_control(void *h, struct btframe_buffer *buf, size_t len) 483 { 484 struct ubt_softc *sc = h; 485 usb_device_request_t req; 486 usbd_status status; 487 488 DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 489 490 #ifdef DIAGNOSTIC 491 if ((u_int8_t*)buf != sc->sc_ctl_buf) 492 panic("ubt_control() called with wrong buffer"); 493 #endif 494 495 if (sc->sc_dying) 496 return EIO; 497 498 if (len < BTHCI_COMMAND_MIN_LEN || len > BTHCI_COMMAND_MAX_LEN) 499 return EINVAL; 500 501 sc->sc_refcnt++; 502 503 memset(&req, 0, sizeof(req)); 504 req.bmRequestType = UT_WRITE_CLASS_DEVICE; 505 USETW(req.wLength, len); 506 507 usbd_setup_default_xfer(sc->sc_ctl_xfer, 508 sc->sc_udev, 509 sc, 510 USBD_DEFAULT_TIMEOUT, 511 &req, sc->sc_ctl_buf, len, 512 USBD_SYNCHRONOUS | USBD_NO_COPY, NULL); 513 514 status = usbd_transfer(sc->sc_ctl_xfer); 515 516 if (--sc->sc_refcnt < 0) 517 usb_detach_wakeup(USBDEV(sc->sc_dev)); 518 519 if (status != USBD_NORMAL_COMPLETION) 520 return EIO; 521 522 return 0; 523 } 524 525 static u_int8_t* 526 ubt_alloc_acldata(void *h, size_t len, struct btframe_buffer **buf) 527 { 528 struct ubt_softc *sc = h; 529 530 /* 531 * We should be catching this earlier, but at the moment a 532 * user request can generate oversized allocations. 533 */ 534 if (len > BTHCI_ACL_DATA_MAX_LEN) 535 return NULL; 536 537 *buf = (struct btframe_buffer*)sc->sc_aclwr_buf; 538 return sc->sc_aclwr_buf; 539 } 540 541 static int 542 ubt_send_acldata(void *h, struct btframe_buffer *buf, size_t len) 543 { 544 struct ubt_softc *sc = h; 545 usbd_status status; 546 547 DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 548 549 #ifdef DIAGNOSTIC 550 if ((u_int8_t*)buf != sc->sc_aclwr_buf) 551 panic("ubt_sendacldata() called with wrong buffer"); 552 #endif 553 554 if (sc->sc_dying) 555 return EIO; 556 557 if (len < BTHCI_ACL_DATA_MIN_LEN || len > BTHCI_ACL_DATA_MAX_LEN) 558 return EINVAL; 559 560 sc->sc_refcnt++; 561 562 usbd_setup_xfer(sc->sc_aclwr_xfer, 563 sc->sc_aclwr_pipe, 564 (usbd_private_handle)sc, 565 sc->sc_aclwr_buf, len, 566 USBD_SYNCHRONOUS | USBD_NO_COPY, 567 USBD_DEFAULT_TIMEOUT, 568 NULL); 569 570 status = usbd_transfer(sc->sc_aclwr_xfer); 571 572 if (--sc->sc_refcnt < 0) 573 usb_detach_wakeup(USBDEV(sc->sc_dev)); 574 575 if (status != USBD_NORMAL_COMPLETION) 576 return EIO; 577 578 return 0; 579 } 580 581 static u_int8_t* 582 ubt_alloc_scodata(void *h, size_t len, struct btframe_buffer **buf) 583 { 584 return NULL; 585 } 586 587 static int 588 ubt_send_scodata(void *h, struct btframe_buffer *buf, size_t len) 589 { 590 struct ubt_softc *sc = h; 591 592 DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 593 594 if (sc->sc_dying) 595 return EIO; 596 597 return ENXIO; 598 } 599 600 static void 601 ubt_event_cb(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status) 602 { 603 struct ubt_softc *sc = h; 604 void *buf; 605 u_int32_t size; 606 607 DPRINTFN(1,("%s: sc=%p status=%s\n", __func__, sc, 608 usbd_errstr(status))); 609 610 if (status != USBD_NORMAL_COMPLETION || sc->sc_dying || 611 sc->sc_child == NULL) 612 return; 613 614 usbd_get_xfer_status(xfer, NULL, &buf, &size, NULL); 615 616 sc->sc_cb->bt_recveventdata(sc->sc_child, buf, (size_t)size); 617 } 618 619 static void 620 ubt_aclrd_request(struct ubt_softc *sc) 621 { 622 usbd_status status; 623 int s; 624 625 DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 626 627 if (sc->sc_dying) 628 return; 629 630 s = splusb(); 631 if (sc->sc_aclrd_running) { 632 splx(s); 633 return; 634 } 635 sc->sc_aclrd_running = 1; 636 splx(s); 637 638 usbd_setup_xfer(sc->sc_aclrd_xfer, sc->sc_aclrd_pipe, 639 sc, sc->sc_aclrd_buf, BTHCI_ACL_DATA_MAX_LEN, 640 USBD_SHORT_XFER_OK | USBD_NO_COPY, 641 USBD_NO_TIMEOUT, ubt_aclrd_cb); 642 643 status = usbd_transfer(sc->sc_aclrd_xfer); 644 if (status == USBD_IN_PROGRESS || USBD_CANCELLED) 645 return; 646 647 DPRINTFN(1,("%s: read request failed: %s\n", __func__, 648 usbd_errstr(status))); 649 650 sc->sc_aclrd_running = 0; 651 sc->sc_blocked |= BT_CBBLOCK_ACL_DATA; 652 } 653 654 static void 655 ubt_aclrd_cb(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status) 656 { 657 struct ubt_softc *sc = h; 658 void *buf; 659 u_int32_t size; 660 661 DPRINTFN(1,("%s: sc=%p status=%s\n", __func__, sc, 662 usbd_errstr(status))); 663 664 sc->sc_aclrd_running = 0; 665 666 if (status != USBD_NORMAL_COMPLETION || sc->sc_dying || 667 sc->sc_child == NULL) 668 return; 669 670 usbd_get_xfer_status(xfer, NULL, &buf, &size, NULL); 671 672 sc->sc_cb->bt_recvacldata(sc->sc_child, buf, (size_t)size); 673 674 /* Re-issue the request if not blocked */ 675 if (!sc->sc_dying && !(sc->sc_blocked & BT_CBBLOCK_ACL_DATA)) 676 ubt_aclrd_request(sc); 677 } 678 679 static unsigned int 680 ubt_blockcb(void *h, unsigned int cbblocks) 681 { 682 struct ubt_softc *sc = h; 683 684 sc->sc_blocked |= (cbblocks & BT_CBBLOCK_ACL_DATA); 685 686 return sc->sc_blocked; 687 } 688 689 static unsigned int 690 ubt_unblockcb(void *h, unsigned int cbblocks) 691 { 692 struct ubt_softc *sc = h; 693 unsigned int oblocks, changes; 694 695 oblocks = sc->sc_blocked; 696 sc->sc_blocked = oblocks & ~cbblocks; 697 698 changes = oblocks & cbblocks; 699 700 if (changes & BT_CBBLOCK_ACL_DATA) 701 /* Re-issue the request if action un-blocked reads */ 702 ubt_aclrd_request(sc); 703 704 return sc->sc_blocked; 705 } 706 707 static int 708 ubt_splraise(void) 709 { 710 return splusb(); 711 } 712