1 /* $NetBSD: ubt.c,v 1.11 2004/04/23 17:25:25 itojun 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.11 2004/04/23 17:25:25 itojun 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 int sc_refcnt; 111 char sc_dying; 112 }; 113 114 static int ubt_open(void *h, int flag, int mode, usb_proc_ptr p); 115 static int ubt_close(void *h, int flag, int mode, usb_proc_ptr p); 116 117 static u_int8_t* ubt_alloc_control(void*, size_t, struct btframe_buffer**); 118 static int ubt_send_control(void*, struct btframe_buffer*, size_t); 119 120 static u_int8_t* ubt_alloc_acldata(void*, size_t, struct btframe_buffer**); 121 static int ubt_send_acldata(void*, struct btframe_buffer*, size_t); 122 123 static u_int8_t* ubt_alloc_scodata(void*, size_t, struct btframe_buffer**); 124 static int ubt_send_scodata(void*, struct btframe_buffer*, size_t); 125 126 static int ubt_splraise(void); 127 128 static void ubt_event_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); 129 static void ubt_aclrd_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); 130 static void ubt_aclrd_request(struct ubt_softc *); 131 132 static struct btframe_methods const ubt_methods = { 133 ubt_open, ubt_close, 134 {ubt_alloc_control, ubt_send_control}, 135 {ubt_alloc_acldata, ubt_send_acldata}, 136 {ubt_alloc_scodata, ubt_send_scodata}, 137 ubt_splraise 138 }; 139 140 USB_DECLARE_DRIVER(ubt); 141 142 USB_MATCH(ubt) 143 { 144 USB_MATCH_START(ubt, uaa); 145 usb_interface_descriptor_t *id; 146 147 DPRINTFN(50,("ubt_match\n")); 148 149 if (uaa->iface == NULL) 150 return (UMATCH_NONE); 151 152 id = usbd_get_interface_descriptor(uaa->iface); 153 if (id != NULL && 154 id->bInterfaceClass == UICLASS_WIRELESS && 155 id->bInterfaceSubClass == UISUBCLASS_RF && 156 id->bInterfaceProtocol == UIPROTO_BLUETOOTH) 157 return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); 158 return (UMATCH_NONE); 159 } 160 161 USB_ATTACH(ubt) 162 { 163 USB_ATTACH_START(ubt, sc, uaa); 164 usbd_device_handle dev = uaa->device; 165 usbd_interface_handle iface = uaa->iface; 166 struct bt_attach_args bt; 167 usb_interface_descriptor_t const *id; 168 char devinfo[1024]; 169 usb_endpoint_descriptor_t const *ed; 170 u_int8_t epcount; 171 int i; 172 173 DPRINTFN(10,("ubt_attach: sc=%p\n", sc)); 174 175 usbd_devinfo(dev, 0, devinfo, sizeof(devinfo)); 176 USB_ATTACH_SETUP; 177 printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); 178 179 sc->sc_udev = dev; 180 sc->sc_ctl_iface = iface; 181 182 /* 183 * The control interface comes before the isoc interface 184 * according to the spec, so we find it first. 185 */ 186 epcount = 0; 187 (void)usbd_endpoint_count(iface, &epcount); 188 189 sc->sc_evt_addr = -1; 190 sc->sc_aclrd_addr = -1; 191 sc->sc_aclwr_addr = -1; 192 193 for (i = 0; i < epcount; i++) { 194 ed = usbd_interface2endpoint_descriptor(iface, i); 195 if (ed == NULL) { 196 printf("%s: couldn't get ep %d\n", 197 USBDEVNAME(sc->sc_dev), i); 198 USB_ATTACH_ERROR_RETURN; 199 } 200 201 DPRINTFN(10, ("%s: addr=%d attr=%d\n", __func__, 202 (int)ed->bEndpointAddress, 203 (int)ed->bmAttributes)); 204 205 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 206 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 207 sc->sc_evt_addr = ed->bEndpointAddress; 208 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 209 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 210 sc->sc_aclrd_addr = ed->bEndpointAddress; 211 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 212 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 213 sc->sc_aclwr_addr = ed->bEndpointAddress; 214 } 215 } 216 217 if (sc->sc_evt_addr == -1 || 218 sc->sc_aclrd_addr == -1 || sc->sc_aclwr_addr == -1) { 219 printf("%s: missing endpoint\n", USBDEVNAME(sc->sc_dev)); 220 USB_ATTACH_ERROR_RETURN; 221 } 222 223 /* XXX works because isoc comes after ctl */ 224 /* Grab isoc interface as well. */ 225 for (i = 0; i < uaa->nifaces; i++) { 226 if (uaa->ifaces[i] == NULL) 227 continue; 228 id = usbd_get_interface_descriptor(uaa->ifaces[i]); 229 if (id != NULL && 230 id->bInterfaceClass == UICLASS_WIRELESS && 231 id->bInterfaceSubClass == UISUBCLASS_RF && 232 id->bInterfaceProtocol == UIPROTO_BLUETOOTH) { 233 sc->sc_isoc_iface = uaa->ifaces[i]; 234 uaa->ifaces[i] = NULL; 235 } 236 } 237 238 printf("%s: has%s isoc data\n", USBDEVNAME(sc->sc_dev), 239 sc->sc_isoc_iface != NULL ? "" : " no"); 240 241 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 242 USBDEV(sc->sc_dev)); 243 244 bt.bt_methods = &ubt_methods; 245 bt.bt_cb = &sc->sc_cb; 246 bt.bt_handle = sc; 247 248 sc->sc_child = config_found(self, &bt, bt_print); 249 250 USB_ATTACH_SUCCESS_RETURN; 251 } 252 253 static void 254 ubt_abortdealloc(struct ubt_softc *sc) 255 { 256 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 257 258 if (sc->sc_evt_pipe != NULL) { 259 usbd_abort_pipe(sc->sc_evt_pipe); 260 usbd_close_pipe(sc->sc_evt_pipe); 261 sc->sc_evt_pipe = NULL; 262 } 263 if (sc->sc_evt_buf != NULL) { 264 free(sc->sc_evt_buf, M_USBDEV); 265 sc->sc_evt_buf = NULL; 266 } 267 if (sc->sc_aclrd_pipe != NULL) { 268 usbd_abort_pipe(sc->sc_aclrd_pipe); 269 usbd_close_pipe(sc->sc_aclrd_pipe); 270 sc->sc_aclrd_pipe = NULL; 271 } 272 if (sc->sc_aclwr_pipe != NULL) { 273 usbd_abort_pipe(sc->sc_aclwr_pipe); 274 usbd_close_pipe(sc->sc_aclwr_pipe); 275 sc->sc_aclwr_pipe = NULL; 276 } 277 if (sc->sc_aclrd_xfer != NULL) { 278 usbd_free_xfer(sc->sc_aclrd_xfer); 279 sc->sc_aclrd_xfer = NULL; 280 sc->sc_aclrd_buf = NULL; 281 } 282 if (sc->sc_aclwr_xfer != NULL) { 283 usbd_free_xfer(sc->sc_aclwr_xfer); 284 sc->sc_aclwr_xfer = NULL; 285 sc->sc_aclwr_buf = NULL; 286 } 287 } 288 289 USB_DETACH(ubt) 290 { 291 USB_DETACH_START(ubt, sc); 292 int s; 293 int rv = 0; 294 295 DPRINTF(("%s: sc=%p flags=%d\n", __func__, sc, flags)); 296 297 sc->sc_dying = 1; 298 299 /* Abort all pipes. Causes processes waiting for transfer to wake. */ 300 ubt_abortdealloc(sc); 301 302 DPRINTFN(1, ("%s: waiting for USB detach\n", __func__)); 303 s = splusb(); 304 if (--sc->sc_refcnt >= 0) { 305 /* Wait for processes to go away. */ 306 usb_detach_wait(USBDEV(sc->sc_dev)); 307 } 308 splx(s); 309 DPRINTFN(1, ("%s: USB detach complete\n", __func__)); 310 311 if (sc->sc_child != NULL) { 312 DPRINTFN(1, ("%s: waiting for child detach\n", __func__)); 313 rv = config_detach(sc->sc_child, flags); 314 sc->sc_child = NULL; 315 DPRINTFN(1, ("%s: child detach complete\n", __func__)); 316 } 317 318 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 319 USBDEV(sc->sc_dev)); 320 321 DPRINTFN(1, ("%s: driver detached\n", __func__)); 322 323 return (rv); 324 } 325 326 int 327 ubt_activate(device_ptr_t self, enum devact act) 328 { 329 struct ubt_softc *sc = (struct ubt_softc *)self; 330 int error = 0; 331 332 switch (act) { 333 case DVACT_ACTIVATE: 334 return (EOPNOTSUPP); 335 break; 336 337 case DVACT_DEACTIVATE: 338 sc->sc_dying = 1; 339 if (sc->sc_child != NULL) 340 error = config_deactivate(sc->sc_child); 341 break; 342 } 343 return (error); 344 } 345 346 static int 347 ubt_open(void *h, int flag, int mode, usb_proc_ptr p) 348 { 349 struct ubt_softc *sc = h; 350 int error; 351 usbd_status err; 352 353 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 354 355 sc->sc_evt_buf = malloc(BTHCI_EVENT_MAX_LEN, M_USBDEV, M_NOWAIT); 356 if (sc->sc_evt_buf == NULL) { 357 error = ENOMEM; 358 goto bad0; 359 } 360 361 err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_evt_addr, 362 USBD_SHORT_XFER_OK, &sc->sc_evt_pipe, 363 sc, sc->sc_evt_buf, BTHCI_EVENT_MAX_LEN, 364 ubt_event_cb, UBT_EVENT_EP_INTERVAL); 365 if (err != USBD_NORMAL_COMPLETION) { 366 error = EIO; 367 goto bad1; 368 } 369 370 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_aclrd_addr, 371 0, &sc->sc_aclrd_pipe); 372 if (err != USBD_NORMAL_COMPLETION) { 373 error = EIO; 374 goto bad2; 375 } 376 377 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_aclwr_addr, 378 0, &sc->sc_aclwr_pipe); 379 if (err != USBD_NORMAL_COMPLETION) { 380 error = EIO; 381 goto bad3; 382 } 383 384 sc->sc_ctl_xfer = usbd_alloc_xfer(sc->sc_udev); 385 if (sc->sc_ctl_xfer == NULL) { 386 error = ENOMEM; 387 goto bad4; 388 } 389 sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev); 390 if (sc->sc_aclrd_xfer == NULL) { 391 error = ENOMEM; 392 goto bad5; 393 } 394 sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev); 395 if (sc->sc_aclwr_xfer == NULL) { 396 error = ENOMEM; 397 goto bad6; 398 } 399 400 /* Buffers */ 401 sc->sc_ctl_buf = usbd_alloc_buffer(sc->sc_ctl_xfer, 402 BTHCI_COMMAND_MAX_LEN); 403 if (sc->sc_ctl_buf == NULL) { 404 error = ENOMEM; 405 goto bad7; 406 } 407 sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer, 408 BTHCI_ACL_DATA_MAX_LEN); 409 if (sc->sc_aclrd_buf == NULL) { 410 error = ENOMEM; 411 goto bad7; 412 } 413 sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer, 414 BTHCI_ACL_DATA_MAX_LEN); 415 if (sc->sc_aclwr_buf == NULL) { 416 error = ENOMEM; 417 goto bad7; 418 } 419 420 /* Start reading */ 421 ubt_aclrd_request(sc); 422 423 return 0; 424 425 bad7: 426 usbd_free_xfer(sc->sc_aclwr_xfer); 427 sc->sc_aclwr_xfer = NULL; 428 bad6: 429 usbd_free_xfer(sc->sc_aclrd_xfer); 430 sc->sc_aclrd_xfer = NULL; 431 bad5: 432 usbd_free_xfer(sc->sc_ctl_xfer); 433 sc->sc_ctl_xfer = NULL; 434 bad4: 435 usbd_close_pipe(sc->sc_aclwr_pipe); 436 sc->sc_aclwr_pipe = NULL; 437 bad3: 438 usbd_close_pipe(sc->sc_aclrd_pipe); 439 sc->sc_aclrd_pipe = NULL; 440 bad2: 441 usbd_close_pipe(sc->sc_evt_pipe); 442 sc->sc_evt_pipe = NULL; 443 bad1: 444 free(sc->sc_evt_buf, M_USBDEV); 445 sc->sc_evt_buf = NULL; 446 bad0: 447 return error; 448 } 449 450 static int 451 ubt_close(void *h, int flag, int mode, usb_proc_ptr p) 452 { 453 struct ubt_softc *sc = h; 454 455 DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); 456 457 ubt_abortdealloc(sc); 458 459 return 0; 460 } 461 462 static u_int8_t* 463 ubt_alloc_control(void *h, size_t len, struct btframe_buffer **buf) 464 { 465 struct ubt_softc *sc = h; 466 467 /* 468 * We should be catching this earlier, but at the moment a 469 * user request can generate oversized allocations. 470 */ 471 if (len > BTHCI_COMMAND_MAX_LEN) 472 return NULL; 473 474 *buf = (struct btframe_buffer*)sc->sc_ctl_buf; 475 return sc->sc_ctl_buf; 476 } 477 478 static int 479 ubt_send_control(void *h, struct btframe_buffer *buf, size_t len) 480 { 481 struct ubt_softc *sc = h; 482 usb_device_request_t req; 483 usbd_status status; 484 485 DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 486 487 #ifdef DIAGNOSTIC 488 if ((u_int8_t*)buf != sc->sc_ctl_buf) 489 panic("ubt_control() called with wrong buffer"); 490 #endif 491 492 if (sc->sc_dying) 493 return EIO; 494 495 if (len < BTHCI_COMMAND_MIN_LEN || len > BTHCI_COMMAND_MAX_LEN) 496 return EINVAL; 497 498 sc->sc_refcnt++; 499 500 memset(&req, 0, sizeof(req)); 501 req.bmRequestType = UT_WRITE_CLASS_DEVICE; 502 USETW(req.wLength, len); 503 504 usbd_setup_default_xfer(sc->sc_ctl_xfer, 505 sc->sc_udev, 506 sc, 507 USBD_DEFAULT_TIMEOUT, 508 &req, sc->sc_ctl_buf, len, 509 USBD_SYNCHRONOUS | USBD_NO_COPY, NULL); 510 511 status = usbd_transfer(sc->sc_ctl_xfer); 512 513 if (--sc->sc_refcnt < 0) 514 usb_detach_wakeup(USBDEV(sc->sc_dev)); 515 516 if (status != USBD_NORMAL_COMPLETION) 517 return EIO; 518 519 return 0; 520 } 521 522 static u_int8_t* 523 ubt_alloc_acldata(void *h, size_t len, struct btframe_buffer **buf) 524 { 525 struct ubt_softc *sc = h; 526 527 /* 528 * We should be catching this earlier, but at the moment a 529 * user request can generate oversized allocations. 530 */ 531 if (len > BTHCI_ACL_DATA_MAX_LEN) 532 return NULL; 533 534 *buf = (struct btframe_buffer*)sc->sc_aclwr_buf; 535 return sc->sc_aclwr_buf; 536 } 537 538 static int 539 ubt_send_acldata(void *h, struct btframe_buffer *buf, size_t len) 540 { 541 struct ubt_softc *sc = h; 542 usbd_status status; 543 544 DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 545 546 #ifdef DIAGNOSTIC 547 if ((u_int8_t*)buf != sc->sc_aclwr_buf) 548 panic("ubt_sendacldata() called with wrong buffer"); 549 #endif 550 551 if (sc->sc_dying) 552 return EIO; 553 554 if (len < BTHCI_ACL_DATA_MIN_LEN || len > BTHCI_ACL_DATA_MAX_LEN) 555 return EINVAL; 556 557 sc->sc_refcnt++; 558 559 usbd_setup_xfer(sc->sc_aclwr_xfer, 560 sc->sc_aclwr_pipe, 561 (usbd_private_handle)sc, 562 sc->sc_aclwr_buf, len, 563 USBD_SYNCHRONOUS | USBD_NO_COPY, 564 USBD_DEFAULT_TIMEOUT, 565 NULL); 566 567 status = usbd_transfer(sc->sc_aclwr_xfer); 568 569 if (--sc->sc_refcnt < 0) 570 usb_detach_wakeup(USBDEV(sc->sc_dev)); 571 572 if (status != USBD_NORMAL_COMPLETION) 573 return EIO; 574 575 return 0; 576 } 577 578 static u_int8_t* 579 ubt_alloc_scodata(void *h, size_t len, struct btframe_buffer **buf) 580 { 581 return NULL; 582 } 583 584 static int 585 ubt_send_scodata(void *h, struct btframe_buffer *buf, size_t len) 586 { 587 struct ubt_softc *sc = h; 588 589 DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 590 591 if (sc->sc_dying) 592 return EIO; 593 594 return ENXIO; 595 } 596 597 static void 598 ubt_event_cb(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status) 599 { 600 struct ubt_softc *sc = h; 601 void *buf; 602 u_int32_t size; 603 604 DPRINTFN(1,("%s: sc=%p status=%s\n", __func__, sc, 605 usbd_errstr(status))); 606 607 if (status != USBD_NORMAL_COMPLETION || sc->sc_dying || 608 sc->sc_child == NULL) 609 return; 610 611 usbd_get_xfer_status(xfer, NULL, &buf, &size, NULL); 612 613 sc->sc_cb->bt_recveventdata(sc->sc_child, buf, (size_t)size); 614 } 615 616 static void 617 ubt_aclrd_request(struct ubt_softc *sc) 618 { 619 usbd_status status; 620 int s; 621 622 DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); 623 624 if (sc->sc_dying) 625 return; 626 627 s = splusb(); 628 if (sc->sc_aclrd_running) { 629 splx(s); 630 return; 631 } 632 sc->sc_aclrd_running = 1; 633 splx(s); 634 635 usbd_setup_xfer(sc->sc_aclrd_xfer, sc->sc_aclrd_pipe, 636 sc, sc->sc_aclrd_buf, BTHCI_ACL_DATA_MAX_LEN, 637 USBD_SHORT_XFER_OK | USBD_NO_COPY, 638 USBD_NO_TIMEOUT, ubt_aclrd_cb); 639 640 status = usbd_transfer(sc->sc_aclrd_xfer); 641 642 /* Cancellation is normal on device shutdown */ 643 if (status == USBD_IN_PROGRESS || status == USBD_CANCELLED) 644 return; 645 646 DPRINTFN(1,("%s: read request failed: %s\n", __func__, 647 usbd_errstr(status))); 648 649 sc->sc_aclrd_running = 0; 650 /* XXX now what!? */ 651 } 652 653 static void 654 ubt_aclrd_cb(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status) 655 { 656 struct ubt_softc *sc = h; 657 void *buf; 658 u_int32_t size; 659 660 DPRINTFN(1,("%s: sc=%p status=%s\n", __func__, sc, 661 usbd_errstr(status))); 662 663 sc->sc_aclrd_running = 0; 664 665 if (status != USBD_NORMAL_COMPLETION || sc->sc_dying || 666 sc->sc_child == NULL) 667 return; 668 669 usbd_get_xfer_status(xfer, NULL, &buf, &size, NULL); 670 671 sc->sc_cb->bt_recvacldata(sc->sc_child, buf, (size_t)size); 672 673 /* Re-issue the request */ 674 if (!sc->sc_dying) 675 ubt_aclrd_request(sc); 676 } 677 678 static int 679 ubt_splraise(void) 680 { 681 return splusb(); 682 } 683