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