1 /* $NetBSD: btsco.c,v 1.41 2019/06/08 08:02:38 isaki 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 #include <sys/cdefs.h> 35 __KERNEL_RCSID(0, "$NetBSD: btsco.c,v 1.41 2019/06/08 08:02:38 isaki Exp $"); 36 37 #include <sys/param.h> 38 #include <sys/audioio.h> 39 #include <sys/conf.h> 40 #include <sys/device.h> 41 #include <sys/fcntl.h> 42 #include <sys/kernel.h> 43 #include <sys/queue.h> 44 #include <sys/kmem.h> 45 #include <sys/mbuf.h> 46 #include <sys/proc.h> 47 #include <sys/socketvar.h> 48 #include <sys/systm.h> 49 #include <sys/intr.h> 50 51 #include <prop/proplib.h> 52 53 #include <netbt/bluetooth.h> 54 #include <netbt/rfcomm.h> 55 #include <netbt/sco.h> 56 57 #include <dev/audio/audio_if.h> 58 59 #include <dev/bluetooth/btdev.h> 60 #include <dev/bluetooth/btsco.h> 61 62 #undef DPRINTF 63 #undef DPRINTFN 64 65 #ifdef BTSCO_DEBUG 66 int btsco_debug = BTSCO_DEBUG; 67 #define DPRINTF(...) do { \ 68 if (btsco_debug) { \ 69 printf("%s: ", __func__); \ 70 printf(__VA_ARGS__); \ 71 } \ 72 } while (/* CONSTCOND */0) 73 74 #define DPRINTFN(n, ...) do { \ 75 if (btsco_debug > (n)) { \ 76 printf("%s: ", __func__); \ 77 printf(__VA_ARGS__); \ 78 } \ 79 } while (/* CONSTCOND */0) 80 #else 81 #define DPRINTF(...) 82 #define DPRINTFN(...) 83 #endif 84 85 /***************************************************************************** 86 * 87 * Bluetooth SCO Audio device 88 */ 89 90 /* btsco softc */ 91 struct btsco_softc { 92 uint16_t sc_flags; 93 const char *sc_name; /* our device_xname */ 94 95 device_t sc_audio; /* MI audio device */ 96 void *sc_intr; /* interrupt cookie */ 97 kcondvar_t sc_connect; /* connect wait */ 98 kmutex_t sc_lock; /* for audio */ 99 100 /* Bluetooth */ 101 bdaddr_t sc_laddr; /* local address */ 102 bdaddr_t sc_raddr; /* remote address */ 103 uint16_t sc_state; /* link state */ 104 struct sco_pcb *sc_sco; /* SCO handle */ 105 struct sco_pcb *sc_sco_l; /* SCO listen handle */ 106 uint16_t sc_mtu; /* SCO mtu */ 107 uint8_t sc_channel; /* RFCOMM channel */ 108 int sc_err; /* stored error */ 109 110 /* Receive */ 111 int sc_rx_want; /* bytes wanted */ 112 uint8_t *sc_rx_block; /* receive block */ 113 void (*sc_rx_intr)(void *); /* callback */ 114 void *sc_rx_intrarg; /* callback arg */ 115 struct mbuf *sc_rx_mbuf; /* leftover mbuf */ 116 117 /* Transmit */ 118 int sc_tx_size; /* bytes to send */ 119 int sc_tx_pending; /* packets pending */ 120 uint8_t *sc_tx_block; /* transmit block */ 121 void (*sc_tx_intr)(void *); /* callback */ 122 void *sc_tx_intrarg; /* callback arg */ 123 void *sc_tx_buf; /* transmit buffer */ 124 int sc_tx_refcnt; /* buffer refcnt */ 125 126 /* mixer data */ 127 int sc_vgs; /* speaker volume */ 128 int sc_vgm; /* mic volume */ 129 }; 130 131 /* sc_state */ 132 #define BTSCO_CLOSED 0 133 #define BTSCO_WAIT_CONNECT 1 134 #define BTSCO_OPEN 2 135 136 /* sc_flags */ 137 #define BTSCO_LISTEN (1 << 1) 138 139 /* autoconf(9) glue */ 140 static int btsco_match(device_t, cfdata_t, void *); 141 static void btsco_attach(device_t, device_t, void *); 142 static int btsco_detach(device_t, int); 143 144 CFATTACH_DECL_NEW(btsco, sizeof(struct btsco_softc), 145 btsco_match, btsco_attach, btsco_detach, NULL); 146 147 /* audio(9) glue */ 148 static int btsco_open(void *, int); 149 static void btsco_close(void *); 150 static int btsco_query_format(void *, audio_format_query_t *); 151 static int btsco_set_format(void *, int, 152 const audio_params_t *, const audio_params_t *, 153 audio_filter_reg_t *, audio_filter_reg_t *); 154 static int btsco_round_blocksize(void *, int, int, const audio_params_t *); 155 static int btsco_start_output(void *, void *, int, void (*)(void *), void *); 156 static int btsco_start_input(void *, void *, int, void (*)(void *), void *); 157 static int btsco_halt_output(void *); 158 static int btsco_halt_input(void *); 159 static int btsco_getdev(void *, struct audio_device *); 160 static int btsco_set_port(void *, mixer_ctrl_t *); 161 static int btsco_get_port(void *, mixer_ctrl_t *); 162 static int btsco_query_devinfo(void *, mixer_devinfo_t *); 163 static void *btsco_allocm(void *, int, size_t); 164 static void btsco_freem(void *, void *, size_t); 165 static int btsco_get_props(void *); 166 static int btsco_dev_ioctl(void *, u_long, void *, int, struct lwp *); 167 static void btsco_get_locks(void *, kmutex_t **, kmutex_t **); 168 169 static const struct audio_hw_if btsco_if = { 170 .open = btsco_open, 171 .close = btsco_close, 172 .query_format = btsco_query_format, 173 .set_format = btsco_set_format, 174 .round_blocksize = btsco_round_blocksize, 175 .start_output = btsco_start_output, 176 .start_input = btsco_start_input, 177 .halt_output = btsco_halt_output, 178 .halt_input = btsco_halt_input, 179 .getdev = btsco_getdev, 180 .set_port = btsco_set_port, 181 .get_port = btsco_get_port, 182 .query_devinfo = btsco_query_devinfo, 183 .allocm = btsco_allocm, 184 .freem = btsco_freem, 185 .get_props = btsco_get_props, 186 .dev_ioctl = btsco_dev_ioctl, 187 .get_locks = btsco_get_locks, 188 }; 189 190 static const struct audio_device btsco_device = { 191 "Bluetooth Audio", 192 "", 193 "btsco" 194 }; 195 196 /* Voice_Setting == 0x0060: 8000Hz, mono, 16-bit, slinear_le */ 197 static const struct audio_format btsco_format = { 198 .mode = AUMODE_PLAY | AUMODE_RECORD, 199 .encoding = AUDIO_ENCODING_SLINEAR_LE, 200 .validbits = 16, 201 .precision = 16, 202 .channels = 1, 203 .channel_mask = AUFMT_MONAURAL, 204 .frequency_type = 1, 205 .frequency = { 8000 }, 206 }; 207 208 /* bluetooth(9) glue for SCO */ 209 static void btsco_sco_connecting(void *); 210 static void btsco_sco_connected(void *); 211 static void btsco_sco_disconnected(void *, int); 212 static void *btsco_sco_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *); 213 static void btsco_sco_complete(void *, int); 214 static void btsco_sco_linkmode(void *, int); 215 static void btsco_sco_input(void *, struct mbuf *); 216 217 static const struct btproto btsco_sco_proto = { 218 btsco_sco_connecting, 219 btsco_sco_connected, 220 btsco_sco_disconnected, 221 btsco_sco_newconn, 222 btsco_sco_complete, 223 btsco_sco_linkmode, 224 btsco_sco_input, 225 }; 226 227 228 /***************************************************************************** 229 * 230 * btsco definitions 231 */ 232 233 /* 234 * btsco mixer class 235 */ 236 #define BTSCO_VGS 0 237 #define BTSCO_VGM 1 238 #define BTSCO_INPUT_CLASS 2 239 #define BTSCO_OUTPUT_CLASS 3 240 241 /* connect timeout */ 242 #define BTSCO_TIMEOUT (30 * hz) 243 244 /* misc btsco functions */ 245 static void btsco_extfree(struct mbuf *, void *, size_t, void *); 246 static void btsco_intr(void *); 247 248 249 /***************************************************************************** 250 * 251 * btsco autoconf(9) routines 252 */ 253 254 static int 255 btsco_match(device_t self, cfdata_t cfdata, void *aux) 256 { 257 prop_dictionary_t dict = aux; 258 prop_object_t obj; 259 260 obj = prop_dictionary_get(dict, BTDEVservice); 261 if (prop_string_equals_cstring(obj, "HSET")) 262 return 1; 263 264 if (prop_string_equals_cstring(obj, "HF")) 265 return 1; 266 267 return 0; 268 } 269 270 static void 271 btsco_attach(device_t parent, device_t self, void *aux) 272 { 273 struct btsco_softc *sc = device_private(self); 274 prop_dictionary_t dict = aux; 275 prop_object_t obj; 276 277 /* 278 * Init softc 279 */ 280 sc->sc_vgs = 200; 281 sc->sc_vgm = 200; 282 sc->sc_state = BTSCO_CLOSED; 283 sc->sc_name = device_xname(self); 284 cv_init(&sc->sc_connect, "connect"); 285 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 286 287 /* 288 * copy in our configuration info 289 */ 290 obj = prop_dictionary_get(dict, BTDEVladdr); 291 bdaddr_copy(&sc->sc_laddr, prop_data_data_nocopy(obj)); 292 293 obj = prop_dictionary_get(dict, BTDEVraddr); 294 bdaddr_copy(&sc->sc_raddr, prop_data_data_nocopy(obj)); 295 296 obj = prop_dictionary_get(dict, BTDEVservice); 297 if (prop_string_equals_cstring(obj, "HF")) { 298 sc->sc_flags |= BTSCO_LISTEN; 299 aprint_verbose(" listen mode"); 300 } 301 302 obj = prop_dictionary_get(dict, BTSCOchannel); 303 if (prop_object_type(obj) != PROP_TYPE_NUMBER 304 || prop_number_integer_value(obj) < RFCOMM_CHANNEL_MIN 305 || prop_number_integer_value(obj) > RFCOMM_CHANNEL_MAX) { 306 aprint_error(" invalid %s", BTSCOchannel); 307 return; 308 } 309 sc->sc_channel = prop_number_integer_value(obj); 310 311 aprint_verbose(" channel %d", sc->sc_channel); 312 aprint_normal("\n"); 313 314 DPRINTF("sc=%p\n", sc); 315 316 /* 317 * set up transmit interrupt 318 */ 319 sc->sc_intr = softint_establish(SOFTINT_NET, btsco_intr, sc); 320 if (sc->sc_intr == NULL) { 321 aprint_error_dev(self, "softint_establish failed\n"); 322 return; 323 } 324 325 /* 326 * attach audio device 327 */ 328 sc->sc_audio = audio_attach_mi(&btsco_if, sc, self); 329 if (sc->sc_audio == NULL) { 330 aprint_error_dev(self, "audio_attach_mi failed\n"); 331 return; 332 } 333 334 pmf_device_register(self, NULL, NULL); 335 } 336 337 static int 338 btsco_detach(device_t self, int flags) 339 { 340 struct btsco_softc *sc = device_private(self); 341 342 DPRINTF("sc=%p\n", sc); 343 344 pmf_device_deregister(self); 345 346 mutex_enter(bt_lock); 347 if (sc->sc_sco != NULL) { 348 DPRINTF("sc_sco=%p\n", sc->sc_sco); 349 sco_disconnect_pcb(sc->sc_sco, 0); 350 sco_detach_pcb(&sc->sc_sco); 351 sc->sc_sco = NULL; 352 } 353 354 if (sc->sc_sco_l != NULL) { 355 DPRINTF("sc_sco_l=%p\n", sc->sc_sco_l); 356 sco_detach_pcb(&sc->sc_sco_l); 357 sc->sc_sco_l = NULL; 358 } 359 mutex_exit(bt_lock); 360 361 if (sc->sc_audio != NULL) { 362 DPRINTF("sc_audio=%p\n", sc->sc_audio); 363 config_detach(sc->sc_audio, flags); 364 sc->sc_audio = NULL; 365 } 366 367 if (sc->sc_intr != NULL) { 368 softint_disestablish(sc->sc_intr); 369 sc->sc_intr = NULL; 370 } 371 372 mutex_enter(bt_lock); 373 if (sc->sc_rx_mbuf != NULL) { 374 m_freem(sc->sc_rx_mbuf); 375 sc->sc_rx_mbuf = NULL; 376 } 377 mutex_exit(bt_lock); 378 379 if (sc->sc_tx_refcnt > 0) { 380 aprint_error_dev(self, "tx_refcnt=%d!\n", sc->sc_tx_refcnt); 381 382 if ((flags & DETACH_FORCE) == 0) 383 return EAGAIN; 384 } 385 386 cv_destroy(&sc->sc_connect); 387 mutex_destroy(&sc->sc_lock); 388 389 return 0; 390 } 391 392 /***************************************************************************** 393 * 394 * bluetooth(9) methods for SCO 395 * 396 * All these are called from Bluetooth Protocol code, in a soft 397 * interrupt context at IPL_SOFTNET. 398 */ 399 400 static void 401 btsco_sco_connecting(void *arg) 402 { 403 /* struct btsco_softc *sc = arg; */ 404 405 /* dont care */ 406 } 407 408 static void 409 btsco_sco_connected(void *arg) 410 { 411 struct btsco_softc *sc = arg; 412 413 DPRINTF("%s\n", sc->sc_name); 414 415 KASSERT(sc->sc_sco != NULL); 416 KASSERT(sc->sc_state == BTSCO_WAIT_CONNECT); 417 418 /* 419 * If we are listening, no more need 420 */ 421 if (sc->sc_sco_l != NULL) 422 sco_detach_pcb(&sc->sc_sco_l); 423 424 sc->sc_state = BTSCO_OPEN; 425 cv_broadcast(&sc->sc_connect); 426 } 427 428 static void 429 btsco_sco_disconnected(void *arg, int err) 430 { 431 struct btsco_softc *sc = arg; 432 433 DPRINTF("%s sc_state %d\n", sc->sc_name, sc->sc_state); 434 435 KASSERT(sc->sc_sco != NULL); 436 437 sc->sc_err = err; 438 sco_detach_pcb(&sc->sc_sco); 439 440 switch (sc->sc_state) { 441 case BTSCO_CLOSED: /* dont think this can happen */ 442 break; 443 444 case BTSCO_WAIT_CONNECT: /* connect failed */ 445 cv_broadcast(&sc->sc_connect); 446 break; 447 448 case BTSCO_OPEN: /* link lost */ 449 /* 450 * If IO is in progress, tell the audio driver that it 451 * has completed so that when it tries to send more, we 452 * can indicate an error. 453 */ 454 mutex_enter(bt_lock); 455 if (sc->sc_tx_pending > 0) { 456 sc->sc_tx_pending = 0; 457 (*sc->sc_tx_intr)(sc->sc_tx_intrarg); 458 } 459 if (sc->sc_rx_want > 0) { 460 sc->sc_rx_want = 0; 461 (*sc->sc_rx_intr)(sc->sc_rx_intrarg); 462 } 463 mutex_exit(bt_lock); 464 break; 465 466 default: 467 UNKNOWN(sc->sc_state); 468 } 469 470 sc->sc_state = BTSCO_CLOSED; 471 } 472 473 static void * 474 btsco_sco_newconn(void *arg, struct sockaddr_bt *laddr, 475 struct sockaddr_bt *raddr) 476 { 477 struct btsco_softc *sc = arg; 478 479 DPRINTF("%s\n", sc->sc_name); 480 481 if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0 482 || sc->sc_state != BTSCO_WAIT_CONNECT 483 || sc->sc_sco != NULL) 484 return NULL; 485 486 sco_attach_pcb(&sc->sc_sco, &btsco_sco_proto, sc); 487 return sc->sc_sco; 488 } 489 490 static void 491 btsco_sco_complete(void *arg, int count) 492 { 493 struct btsco_softc *sc = arg; 494 495 DPRINTFN(10, "%s count %d\n", sc->sc_name, count); 496 497 if (sc->sc_tx_pending > 0) { 498 sc->sc_tx_pending -= count; 499 if (sc->sc_tx_pending == 0) 500 (*sc->sc_tx_intr)(sc->sc_tx_intrarg); 501 } 502 } 503 504 static void 505 btsco_sco_linkmode(void *arg, int new) 506 { 507 /* struct btsco_softc *sc = arg; */ 508 509 /* dont care */ 510 } 511 512 static void 513 btsco_sco_input(void *arg, struct mbuf *m) 514 { 515 struct btsco_softc *sc = arg; 516 int len; 517 518 DPRINTFN(10, "%s len=%d\n", sc->sc_name, m->m_pkthdr.len); 519 520 if (sc->sc_rx_want == 0) { 521 m_freem(m); 522 } else { 523 KASSERT(sc->sc_rx_intr != NULL); 524 KASSERT(sc->sc_rx_block != NULL); 525 526 len = MIN(sc->sc_rx_want, m->m_pkthdr.len); 527 m_copydata(m, 0, len, sc->sc_rx_block); 528 529 sc->sc_rx_want -= len; 530 sc->sc_rx_block += len; 531 532 if (len > m->m_pkthdr.len) { 533 if (sc->sc_rx_mbuf != NULL) 534 m_freem(sc->sc_rx_mbuf); 535 536 m_adj(m, len); 537 sc->sc_rx_mbuf = m; 538 } else { 539 m_freem(m); 540 } 541 542 if (sc->sc_rx_want == 0) 543 (*sc->sc_rx_intr)(sc->sc_rx_intrarg); 544 } 545 } 546 547 548 /***************************************************************************** 549 * 550 * audio(9) methods 551 * 552 */ 553 554 static int 555 btsco_open(void *hdl, int flags) 556 { 557 struct sockaddr_bt sa; 558 struct btsco_softc *sc = hdl; 559 struct sockopt sopt; 560 int err, timo; 561 562 DPRINTF("%s flags 0x%x\n", sc->sc_name, flags); 563 /* flags FREAD & FWRITE? */ 564 565 if (sc->sc_sco != NULL || sc->sc_sco_l != NULL) 566 return EIO; 567 568 KASSERT(mutex_owned(bt_lock)); 569 570 memset(&sa, 0, sizeof(sa)); 571 sa.bt_len = sizeof(sa); 572 sa.bt_family = AF_BLUETOOTH; 573 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); 574 575 if (sc->sc_flags & BTSCO_LISTEN) { 576 err = sco_attach_pcb(&sc->sc_sco_l, &btsco_sco_proto, sc); 577 if (err) 578 goto done; 579 580 err = sco_bind_pcb(sc->sc_sco_l, &sa); 581 if (err) { 582 sco_detach_pcb(&sc->sc_sco_l); 583 goto done; 584 } 585 586 err = sco_listen_pcb(sc->sc_sco_l); 587 if (err) { 588 sco_detach_pcb(&sc->sc_sco_l); 589 goto done; 590 } 591 592 timo = 0; /* no timeout */ 593 } else { 594 err = sco_attach_pcb(&sc->sc_sco, &btsco_sco_proto, sc); 595 if (err) 596 goto done; 597 598 err = sco_bind_pcb(sc->sc_sco, &sa); 599 if (err) { 600 sco_detach_pcb(&sc->sc_sco); 601 goto done; 602 } 603 604 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr); 605 err = sco_connect_pcb(sc->sc_sco, &sa); 606 if (err) { 607 sco_detach_pcb(&sc->sc_sco); 608 goto done; 609 } 610 611 timo = BTSCO_TIMEOUT; 612 } 613 614 sc->sc_state = BTSCO_WAIT_CONNECT; 615 while (err == 0 && sc->sc_state == BTSCO_WAIT_CONNECT) 616 err = cv_timedwait_sig(&sc->sc_connect, bt_lock, timo); 617 618 switch (sc->sc_state) { 619 case BTSCO_CLOSED: /* disconnected */ 620 err = sc->sc_err; 621 622 /* FALLTHROUGH */ 623 case BTSCO_WAIT_CONNECT: /* error */ 624 if (sc->sc_sco != NULL) 625 sco_detach_pcb(&sc->sc_sco); 626 627 if (sc->sc_sco_l != NULL) 628 sco_detach_pcb(&sc->sc_sco_l); 629 630 break; 631 632 case BTSCO_OPEN: /* hurrah */ 633 sockopt_init(&sopt, BTPROTO_SCO, SO_SCO_MTU, 0); 634 (void)sco_getopt(sc->sc_sco, &sopt); 635 (void)sockopt_get(&sopt, &sc->sc_mtu, sizeof(sc->sc_mtu)); 636 sockopt_destroy(&sopt); 637 break; 638 639 default: 640 UNKNOWN(sc->sc_state); 641 break; 642 } 643 644 done: 645 DPRINTF("done err=%d, sc_state=%d, sc_mtu=%d\n", 646 err, sc->sc_state, sc->sc_mtu); 647 return err; 648 } 649 650 static void 651 btsco_close(void *hdl) 652 { 653 struct btsco_softc *sc = hdl; 654 655 DPRINTF("%s\n", sc->sc_name); 656 657 KASSERT(mutex_owned(bt_lock)); 658 659 if (sc->sc_sco != NULL) { 660 sco_disconnect_pcb(sc->sc_sco, 0); 661 sco_detach_pcb(&sc->sc_sco); 662 } 663 664 if (sc->sc_sco_l != NULL) { 665 sco_detach_pcb(&sc->sc_sco_l); 666 } 667 668 if (sc->sc_rx_mbuf != NULL) { 669 m_freem(sc->sc_rx_mbuf); 670 sc->sc_rx_mbuf = NULL; 671 } 672 673 sc->sc_rx_want = 0; 674 sc->sc_rx_block = NULL; 675 sc->sc_rx_intr = NULL; 676 sc->sc_rx_intrarg = NULL; 677 678 sc->sc_tx_size = 0; 679 sc->sc_tx_block = NULL; 680 sc->sc_tx_pending = 0; 681 sc->sc_tx_intr = NULL; 682 sc->sc_tx_intrarg = NULL; 683 } 684 685 static int 686 btsco_query_format(void *hdl, audio_format_query_t *afp) 687 { 688 689 return audio_query_format(&btsco_format, 1, afp); 690 } 691 692 static int 693 btsco_set_format(void *hdl, int setmode, 694 const audio_params_t *play, const audio_params_t *rec, 695 audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) 696 { 697 698 /* We have only one format so nothing to do here. */ 699 return 0; 700 } 701 702 /* 703 * If we have an MTU value to use, round the blocksize to that. 704 */ 705 static int 706 btsco_round_blocksize(void *hdl, int bs, int mode, 707 const audio_params_t *param) 708 { 709 struct btsco_softc *sc = hdl; 710 711 if (sc->sc_mtu > 0) { 712 bs = (bs / sc->sc_mtu) * sc->sc_mtu; 713 if (bs == 0) 714 bs = sc->sc_mtu; 715 } 716 717 DPRINTF("%s mode=0x%x, bs=%d, sc_mtu=%d\n", 718 sc->sc_name, mode, bs, sc->sc_mtu); 719 720 return bs; 721 } 722 723 /* 724 * Start Output 725 * 726 * We dont want to be calling the network stack with bt_lock held 727 * so make a note of what is to be sent, and schedule an interrupt to 728 * bundle it up and queue it. 729 */ 730 static int 731 btsco_start_output(void *hdl, void *block, int blksize, 732 void (*intr)(void *), void *intrarg) 733 { 734 struct btsco_softc *sc = hdl; 735 736 DPRINTFN(5, "%s blksize %d\n", sc->sc_name, blksize); 737 738 if (sc->sc_sco == NULL) 739 return ENOTCONN; /* connection lost */ 740 741 sc->sc_tx_block = block; 742 sc->sc_tx_pending = 0; 743 sc->sc_tx_size = blksize; 744 sc->sc_tx_intr = intr; 745 sc->sc_tx_intrarg = intrarg; 746 747 kpreempt_disable(); 748 softint_schedule(sc->sc_intr); 749 kpreempt_enable(); 750 return 0; 751 } 752 753 /* 754 * Start Input 755 * 756 * When the SCO link is up, we are getting data in any case, so all we do 757 * is note what we want and where to put it and let the sco_input routine 758 * fill in the data. 759 * 760 * If there was any leftover data that didnt fit in the last block, retry 761 * it now. 762 */ 763 static int 764 btsco_start_input(void *hdl, void *block, int blksize, 765 void (*intr)(void *), void *intrarg) 766 { 767 struct btsco_softc *sc = hdl; 768 struct mbuf *m; 769 770 DPRINTFN(5, "%s blksize %d\n", sc->sc_name, blksize); 771 772 if (sc->sc_sco == NULL) 773 return ENOTCONN; 774 775 sc->sc_rx_want = blksize; 776 sc->sc_rx_block = block; 777 sc->sc_rx_intr = intr; 778 sc->sc_rx_intrarg = intrarg; 779 780 if (sc->sc_rx_mbuf != NULL) { 781 m = sc->sc_rx_mbuf; 782 sc->sc_rx_mbuf = NULL; 783 btsco_sco_input(sc, m); 784 } 785 786 return 0; 787 } 788 789 /* 790 * Halt Output 791 * 792 * This doesnt really halt the output, but it will look 793 * that way to the audio driver. The current block will 794 * still be transmitted. 795 */ 796 static int 797 btsco_halt_output(void *hdl) 798 { 799 struct btsco_softc *sc = hdl; 800 801 DPRINTFN(5, "%s\n", sc->sc_name); 802 803 sc->sc_tx_size = 0; 804 sc->sc_tx_block = NULL; 805 sc->sc_tx_pending = 0; 806 sc->sc_tx_intr = NULL; 807 sc->sc_tx_intrarg = NULL; 808 809 return 0; 810 } 811 812 /* 813 * Halt Input 814 * 815 * This doesnt really halt the input, but it will look 816 * that way to the audio driver. Incoming data will be 817 * discarded. 818 */ 819 static int 820 btsco_halt_input(void *hdl) 821 { 822 struct btsco_softc *sc = hdl; 823 824 DPRINTFN(5, "%s\n", sc->sc_name); 825 826 sc->sc_rx_want = 0; 827 sc->sc_rx_block = NULL; 828 sc->sc_rx_intr = NULL; 829 sc->sc_rx_intrarg = NULL; 830 831 if (sc->sc_rx_mbuf != NULL) { 832 m_freem(sc->sc_rx_mbuf); 833 sc->sc_rx_mbuf = NULL; 834 } 835 836 return 0; 837 } 838 839 static int 840 btsco_getdev(void *hdl, struct audio_device *ret) 841 { 842 843 *ret = btsco_device; 844 return 0; 845 } 846 847 static int 848 btsco_set_port(void *hdl, mixer_ctrl_t *mc) 849 { 850 struct btsco_softc *sc = hdl; 851 int err = 0; 852 853 DPRINTF("%s dev %d type %d\n", sc->sc_name, mc->dev, mc->type); 854 855 switch (mc->dev) { 856 case BTSCO_VGS: 857 if (mc->type != AUDIO_MIXER_VALUE || 858 mc->un.value.num_channels != 1) { 859 err = EINVAL; 860 break; 861 } 862 863 sc->sc_vgs = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 864 break; 865 866 case BTSCO_VGM: 867 if (mc->type != AUDIO_MIXER_VALUE || 868 mc->un.value.num_channels != 1) { 869 err = EINVAL; 870 break; 871 } 872 873 sc->sc_vgm = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 874 break; 875 876 default: 877 err = EINVAL; 878 break; 879 } 880 881 return err; 882 } 883 884 static int 885 btsco_get_port(void *hdl, mixer_ctrl_t *mc) 886 { 887 struct btsco_softc *sc = hdl; 888 int err = 0; 889 890 DPRINTF("%s dev %d\n", sc->sc_name, mc->dev); 891 892 switch (mc->dev) { 893 case BTSCO_VGS: 894 mc->type = AUDIO_MIXER_VALUE; 895 mc->un.value.num_channels = 1; 896 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_vgs; 897 break; 898 899 case BTSCO_VGM: 900 mc->type = AUDIO_MIXER_VALUE; 901 mc->un.value.num_channels = 1; 902 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_vgm; 903 break; 904 905 default: 906 err = EINVAL; 907 break; 908 } 909 910 return err; 911 } 912 913 static int 914 btsco_query_devinfo(void *hdl, mixer_devinfo_t *di) 915 { 916 /* struct btsco_softc *sc = hdl; */ 917 int err = 0; 918 919 switch(di->index) { 920 case BTSCO_VGS: 921 di->mixer_class = BTSCO_INPUT_CLASS; 922 di->next = di->prev = AUDIO_MIXER_LAST; 923 strcpy(di->label.name, AudioNspeaker); 924 di->type = AUDIO_MIXER_VALUE; 925 strcpy(di->un.v.units.name, AudioNvolume); 926 di->un.v.num_channels = 1; 927 di->un.v.delta = BTSCO_DELTA; 928 break; 929 930 case BTSCO_VGM: 931 di->mixer_class = BTSCO_INPUT_CLASS; 932 di->next = di->prev = AUDIO_MIXER_LAST; 933 strcpy(di->label.name, AudioNmicrophone); 934 di->type = AUDIO_MIXER_VALUE; 935 strcpy(di->un.v.units.name, AudioNvolume); 936 di->un.v.num_channels = 1; 937 di->un.v.delta = BTSCO_DELTA; 938 break; 939 940 case BTSCO_INPUT_CLASS: 941 di->mixer_class = BTSCO_INPUT_CLASS; 942 di->next = di->prev = AUDIO_MIXER_LAST; 943 strcpy(di->label.name, AudioCinputs); 944 di->type = AUDIO_MIXER_CLASS; 945 break; 946 947 default: 948 err = ENXIO; 949 break; 950 } 951 952 return err; 953 } 954 955 /* 956 * Allocate Ring Buffers. 957 */ 958 static void * 959 btsco_allocm(void *hdl, int direction, size_t size) 960 { 961 struct btsco_softc *sc = hdl; 962 void *addr; 963 964 DPRINTF("%s: size %zd direction %d\n", sc->sc_name, size, direction); 965 966 addr = kmem_alloc(size, KM_SLEEP); 967 968 if (direction == AUMODE_PLAY) { 969 sc->sc_tx_buf = addr; 970 sc->sc_tx_refcnt = 0; 971 } 972 973 return addr; 974 } 975 976 /* 977 * Free Ring Buffers. 978 * 979 * Because we used external memory for the tx mbufs, we dont 980 * want to free the memory until all the mbufs are done with 981 * 982 * Just to be sure, dont free if something is still pending. 983 * This would be a memory leak but at least there is a warning.. 984 */ 985 static void 986 btsco_freem(void *hdl, void *addr, size_t size) 987 { 988 struct btsco_softc *sc = hdl; 989 int count = hz / 2; 990 991 if (addr == sc->sc_tx_buf) { 992 DPRINTF("%s: tx_refcnt=%d\n", sc->sc_name, sc->sc_tx_refcnt); 993 994 sc->sc_tx_buf = NULL; 995 996 while (sc->sc_tx_refcnt> 0 && count-- > 0) 997 kpause("drain", false, 1, NULL); 998 999 if (sc->sc_tx_refcnt > 0) { 1000 aprint_error("%s: ring buffer unreleased!\n", sc->sc_name); 1001 return; 1002 } 1003 } 1004 1005 kmem_free(addr, size); 1006 } 1007 1008 static int 1009 btsco_get_props(void *hdl) 1010 { 1011 1012 return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE | 1013 AUDIO_PROP_FULLDUPLEX; 1014 } 1015 1016 static void 1017 btsco_get_locks(void *hdl, kmutex_t **intr, kmutex_t **thread) 1018 { 1019 struct btsco_softc *sc = hdl; 1020 1021 *thread = &sc->sc_lock; 1022 *intr = bt_lock; 1023 } 1024 1025 /* 1026 * Handle private ioctl. We pass information out about how to talk 1027 * to the device and mixer. 1028 */ 1029 static int 1030 btsco_dev_ioctl(void *hdl, u_long cmd, void *addr, int flag, 1031 struct lwp *l) 1032 { 1033 struct btsco_softc *sc = hdl; 1034 struct btsco_info *bi = (struct btsco_info *)addr; 1035 int err = 0; 1036 1037 DPRINTF("%s cmd 0x%lx flag %d\n", sc->sc_name, cmd, flag); 1038 1039 switch (cmd) { 1040 case BTSCO_GETINFO: 1041 memset(bi, 0, sizeof(*bi)); 1042 bdaddr_copy(&bi->laddr, &sc->sc_laddr); 1043 bdaddr_copy(&bi->raddr, &sc->sc_raddr); 1044 bi->channel = sc->sc_channel; 1045 bi->vgs = BTSCO_VGS; 1046 bi->vgm = BTSCO_VGM; 1047 break; 1048 1049 default: 1050 err = EPASSTHROUGH; 1051 break; 1052 } 1053 1054 return err; 1055 } 1056 1057 1058 /***************************************************************************** 1059 * 1060 * misc btsco functions 1061 * 1062 */ 1063 1064 /* 1065 * Our transmit interrupt. This is triggered when a new block is to be 1066 * sent. We send mtu sized chunks of the block as mbufs with external 1067 * storage to sco_send_pcb() 1068 */ 1069 static void 1070 btsco_intr(void *arg) 1071 { 1072 struct btsco_softc *sc = arg; 1073 struct mbuf *m; 1074 uint8_t *block; 1075 int mlen, size; 1076 1077 DPRINTFN(10, "%s block %p size %d\n", 1078 sc->sc_name, sc->sc_tx_block, sc->sc_tx_size); 1079 1080 if (sc->sc_sco == NULL) 1081 return; /* connection is lost */ 1082 1083 mutex_enter(bt_lock); 1084 block = sc->sc_tx_block; 1085 size = sc->sc_tx_size; 1086 sc->sc_tx_block = NULL; 1087 sc->sc_tx_size = 0; 1088 1089 while (size > 0) { 1090 MGETHDR(m, M_DONTWAIT, MT_DATA); 1091 if (m == NULL) 1092 break; 1093 1094 mlen = MIN(sc->sc_mtu, size); 1095 1096 /* I think M_DEVBUF is true but not relevant */ 1097 MEXTADD(m, block, mlen, M_DEVBUF, btsco_extfree, sc); 1098 if ((m->m_flags & M_EXT) == 0) { 1099 m_free(m); 1100 break; 1101 } 1102 sc->sc_tx_refcnt++; 1103 1104 m->m_pkthdr.len = m->m_len = mlen; 1105 sc->sc_tx_pending++; 1106 1107 if (sco_send_pcb(sc->sc_sco, m) > 0) { 1108 sc->sc_tx_pending--; 1109 break; 1110 } 1111 1112 block += mlen; 1113 size -= mlen; 1114 } 1115 mutex_exit(bt_lock); 1116 } 1117 1118 /* 1119 * Release the mbuf, we keep a reference count on the tx buffer so 1120 * that we dont release it before its free. 1121 */ 1122 static void 1123 btsco_extfree(struct mbuf *m, void *addr, size_t size, 1124 void *arg) 1125 { 1126 struct btsco_softc *sc = arg; 1127 1128 if (m != NULL) 1129 pool_cache_put(mb_cache, m); 1130 1131 sc->sc_tx_refcnt--; 1132 } 1133