1 /* $NetBSD: btsco.c,v 1.43 2024/07/05 04:31:50 rin 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.43 2024/07/05 04:31:50 rin 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_string(obj, "HSET")) 262 return 1; 263 264 if (prop_string_equals_string(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_value(obj)); 292 293 obj = prop_dictionary_get(dict, BTDEVraddr); 294 bdaddr_copy(&sc->sc_raddr, prop_data_value(obj)); 295 296 obj = prop_dictionary_get(dict, BTDEVservice); 297 if (prop_string_equals_string(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_signed_value(obj) < RFCOMM_CHANNEL_MIN 305 || prop_number_signed_value(obj) > RFCOMM_CHANNEL_MAX) { 306 aprint_error(" invalid %s", BTSCOchannel); 307 return; 308 } 309 sc->sc_channel = prop_number_signed_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 m_freem(sc->sc_rx_mbuf); 374 sc->sc_rx_mbuf = NULL; 375 mutex_exit(bt_lock); 376 377 if (sc->sc_tx_refcnt > 0) { 378 aprint_error_dev(self, "tx_refcnt=%d!\n", sc->sc_tx_refcnt); 379 380 if ((flags & DETACH_FORCE) == 0) 381 return EAGAIN; 382 } 383 384 cv_destroy(&sc->sc_connect); 385 mutex_destroy(&sc->sc_lock); 386 387 return 0; 388 } 389 390 /***************************************************************************** 391 * 392 * bluetooth(9) methods for SCO 393 * 394 * All these are called from Bluetooth Protocol code, in a soft 395 * interrupt context at IPL_SOFTNET. 396 */ 397 398 static void 399 btsco_sco_connecting(void *arg) 400 { 401 /* struct btsco_softc *sc = arg; */ 402 403 /* dont care */ 404 } 405 406 static void 407 btsco_sco_connected(void *arg) 408 { 409 struct btsco_softc *sc = arg; 410 411 DPRINTF("%s\n", sc->sc_name); 412 413 KASSERT(sc->sc_sco != NULL); 414 KASSERT(sc->sc_state == BTSCO_WAIT_CONNECT); 415 416 /* 417 * If we are listening, no more need 418 */ 419 if (sc->sc_sco_l != NULL) 420 sco_detach_pcb(&sc->sc_sco_l); 421 422 sc->sc_state = BTSCO_OPEN; 423 cv_broadcast(&sc->sc_connect); 424 } 425 426 static void 427 btsco_sco_disconnected(void *arg, int err) 428 { 429 struct btsco_softc *sc = arg; 430 431 DPRINTF("%s sc_state %d\n", sc->sc_name, sc->sc_state); 432 433 KASSERT(sc->sc_sco != NULL); 434 435 sc->sc_err = err; 436 sco_detach_pcb(&sc->sc_sco); 437 438 switch (sc->sc_state) { 439 case BTSCO_CLOSED: /* dont think this can happen */ 440 break; 441 442 case BTSCO_WAIT_CONNECT: /* connect failed */ 443 cv_broadcast(&sc->sc_connect); 444 break; 445 446 case BTSCO_OPEN: /* link lost */ 447 /* 448 * If IO is in progress, tell the audio driver that it 449 * has completed so that when it tries to send more, we 450 * can indicate an error. 451 */ 452 mutex_enter(bt_lock); 453 if (sc->sc_tx_pending > 0) { 454 sc->sc_tx_pending = 0; 455 (*sc->sc_tx_intr)(sc->sc_tx_intrarg); 456 } 457 if (sc->sc_rx_want > 0) { 458 sc->sc_rx_want = 0; 459 (*sc->sc_rx_intr)(sc->sc_rx_intrarg); 460 } 461 mutex_exit(bt_lock); 462 break; 463 464 default: 465 UNKNOWN(sc->sc_state); 466 } 467 468 sc->sc_state = BTSCO_CLOSED; 469 } 470 471 static void * 472 btsco_sco_newconn(void *arg, struct sockaddr_bt *laddr, 473 struct sockaddr_bt *raddr) 474 { 475 struct btsco_softc *sc = arg; 476 477 DPRINTF("%s\n", sc->sc_name); 478 479 if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0 480 || sc->sc_state != BTSCO_WAIT_CONNECT 481 || sc->sc_sco != NULL) 482 return NULL; 483 484 sco_attach_pcb(&sc->sc_sco, &btsco_sco_proto, sc); 485 return sc->sc_sco; 486 } 487 488 static void 489 btsco_sco_complete(void *arg, int count) 490 { 491 struct btsco_softc *sc = arg; 492 493 DPRINTFN(10, "%s count %d\n", sc->sc_name, count); 494 495 if (sc->sc_tx_pending > 0) { 496 sc->sc_tx_pending -= count; 497 if (sc->sc_tx_pending == 0) 498 (*sc->sc_tx_intr)(sc->sc_tx_intrarg); 499 } 500 } 501 502 static void 503 btsco_sco_linkmode(void *arg, int new) 504 { 505 /* struct btsco_softc *sc = arg; */ 506 507 /* dont care */ 508 } 509 510 static void 511 btsco_sco_input(void *arg, struct mbuf *m) 512 { 513 struct btsco_softc *sc = arg; 514 int len; 515 516 DPRINTFN(10, "%s len=%d\n", sc->sc_name, m->m_pkthdr.len); 517 518 if (sc->sc_rx_want == 0) { 519 m_freem(m); 520 } else { 521 KASSERT(sc->sc_rx_intr != NULL); 522 KASSERT(sc->sc_rx_block != NULL); 523 524 len = MIN(sc->sc_rx_want, m->m_pkthdr.len); 525 m_copydata(m, 0, len, sc->sc_rx_block); 526 527 sc->sc_rx_want -= len; 528 sc->sc_rx_block += len; 529 530 if (len > m->m_pkthdr.len) { 531 m_freem(sc->sc_rx_mbuf); 532 533 m_adj(m, len); 534 sc->sc_rx_mbuf = m; 535 } else { 536 m_freem(m); 537 } 538 539 if (sc->sc_rx_want == 0) 540 (*sc->sc_rx_intr)(sc->sc_rx_intrarg); 541 } 542 } 543 544 545 /***************************************************************************** 546 * 547 * audio(9) methods 548 * 549 */ 550 551 static int 552 btsco_open(void *hdl, int flags) 553 { 554 struct sockaddr_bt sa; 555 struct btsco_softc *sc = hdl; 556 struct sockopt sopt; 557 int err, timo; 558 559 DPRINTF("%s flags 0x%x\n", sc->sc_name, flags); 560 /* flags FREAD & FWRITE? */ 561 562 if (sc->sc_sco != NULL || sc->sc_sco_l != NULL) 563 return EIO; 564 565 KASSERT(mutex_owned(bt_lock)); 566 567 memset(&sa, 0, sizeof(sa)); 568 sa.bt_len = sizeof(sa); 569 sa.bt_family = AF_BLUETOOTH; 570 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); 571 572 if (sc->sc_flags & BTSCO_LISTEN) { 573 err = sco_attach_pcb(&sc->sc_sco_l, &btsco_sco_proto, sc); 574 if (err) 575 goto done; 576 577 err = sco_bind_pcb(sc->sc_sco_l, &sa); 578 if (err) { 579 sco_detach_pcb(&sc->sc_sco_l); 580 goto done; 581 } 582 583 err = sco_listen_pcb(sc->sc_sco_l); 584 if (err) { 585 sco_detach_pcb(&sc->sc_sco_l); 586 goto done; 587 } 588 589 timo = 0; /* no timeout */ 590 } else { 591 err = sco_attach_pcb(&sc->sc_sco, &btsco_sco_proto, sc); 592 if (err) 593 goto done; 594 595 err = sco_bind_pcb(sc->sc_sco, &sa); 596 if (err) { 597 sco_detach_pcb(&sc->sc_sco); 598 goto done; 599 } 600 601 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr); 602 err = sco_connect_pcb(sc->sc_sco, &sa); 603 if (err) { 604 sco_detach_pcb(&sc->sc_sco); 605 goto done; 606 } 607 608 timo = BTSCO_TIMEOUT; 609 } 610 611 sc->sc_state = BTSCO_WAIT_CONNECT; 612 while (err == 0 && sc->sc_state == BTSCO_WAIT_CONNECT) 613 err = cv_timedwait_sig(&sc->sc_connect, bt_lock, timo); 614 615 switch (sc->sc_state) { 616 case BTSCO_CLOSED: /* disconnected */ 617 err = sc->sc_err; 618 619 /* FALLTHROUGH */ 620 case BTSCO_WAIT_CONNECT: /* error */ 621 if (sc->sc_sco != NULL) 622 sco_detach_pcb(&sc->sc_sco); 623 624 if (sc->sc_sco_l != NULL) 625 sco_detach_pcb(&sc->sc_sco_l); 626 627 break; 628 629 case BTSCO_OPEN: /* hurrah */ 630 sockopt_init(&sopt, BTPROTO_SCO, SO_SCO_MTU, 0); 631 (void)sco_getopt(sc->sc_sco, &sopt); 632 (void)sockopt_get(&sopt, &sc->sc_mtu, sizeof(sc->sc_mtu)); 633 sockopt_destroy(&sopt); 634 break; 635 636 default: 637 UNKNOWN(sc->sc_state); 638 break; 639 } 640 641 done: 642 DPRINTF("done err=%d, sc_state=%d, sc_mtu=%d\n", 643 err, sc->sc_state, sc->sc_mtu); 644 return err; 645 } 646 647 static void 648 btsco_close(void *hdl) 649 { 650 struct btsco_softc *sc = hdl; 651 652 DPRINTF("%s\n", sc->sc_name); 653 654 KASSERT(mutex_owned(bt_lock)); 655 656 if (sc->sc_sco != NULL) { 657 sco_disconnect_pcb(sc->sc_sco, 0); 658 sco_detach_pcb(&sc->sc_sco); 659 } 660 661 if (sc->sc_sco_l != NULL) { 662 sco_detach_pcb(&sc->sc_sco_l); 663 } 664 665 m_freem(sc->sc_rx_mbuf); 666 sc->sc_rx_mbuf = NULL; 667 668 sc->sc_rx_want = 0; 669 sc->sc_rx_block = NULL; 670 sc->sc_rx_intr = NULL; 671 sc->sc_rx_intrarg = NULL; 672 673 sc->sc_tx_size = 0; 674 sc->sc_tx_block = NULL; 675 sc->sc_tx_pending = 0; 676 sc->sc_tx_intr = NULL; 677 sc->sc_tx_intrarg = NULL; 678 } 679 680 static int 681 btsco_query_format(void *hdl, audio_format_query_t *afp) 682 { 683 684 return audio_query_format(&btsco_format, 1, afp); 685 } 686 687 static int 688 btsco_set_format(void *hdl, int setmode, 689 const audio_params_t *play, const audio_params_t *rec, 690 audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) 691 { 692 693 /* We have only one format so nothing to do here. */ 694 return 0; 695 } 696 697 /* 698 * If we have an MTU value to use, round the blocksize to that. 699 */ 700 static int 701 btsco_round_blocksize(void *hdl, int bs, int mode, 702 const audio_params_t *param) 703 { 704 struct btsco_softc *sc = hdl; 705 706 if (sc->sc_mtu > 0) { 707 bs = (bs / sc->sc_mtu) * sc->sc_mtu; 708 if (bs == 0) 709 bs = sc->sc_mtu; 710 } 711 712 DPRINTF("%s mode=0x%x, bs=%d, sc_mtu=%d\n", 713 sc->sc_name, mode, bs, sc->sc_mtu); 714 715 return bs; 716 } 717 718 /* 719 * Start Output 720 * 721 * We dont want to be calling the network stack with bt_lock held 722 * so make a note of what is to be sent, and schedule an interrupt to 723 * bundle it up and queue it. 724 */ 725 static int 726 btsco_start_output(void *hdl, void *block, int blksize, 727 void (*intr)(void *), void *intrarg) 728 { 729 struct btsco_softc *sc = hdl; 730 731 DPRINTFN(5, "%s blksize %d\n", sc->sc_name, blksize); 732 733 if (sc->sc_sco == NULL) 734 return ENOTCONN; /* connection lost */ 735 736 sc->sc_tx_block = block; 737 sc->sc_tx_pending = 0; 738 sc->sc_tx_size = blksize; 739 sc->sc_tx_intr = intr; 740 sc->sc_tx_intrarg = intrarg; 741 742 kpreempt_disable(); 743 softint_schedule(sc->sc_intr); 744 kpreempt_enable(); 745 return 0; 746 } 747 748 /* 749 * Start Input 750 * 751 * When the SCO link is up, we are getting data in any case, so all we do 752 * is note what we want and where to put it and let the sco_input routine 753 * fill in the data. 754 * 755 * If there was any leftover data that didnt fit in the last block, retry 756 * it now. 757 */ 758 static int 759 btsco_start_input(void *hdl, void *block, int blksize, 760 void (*intr)(void *), void *intrarg) 761 { 762 struct btsco_softc *sc = hdl; 763 struct mbuf *m; 764 765 DPRINTFN(5, "%s blksize %d\n", sc->sc_name, blksize); 766 767 if (sc->sc_sco == NULL) 768 return ENOTCONN; 769 770 sc->sc_rx_want = blksize; 771 sc->sc_rx_block = block; 772 sc->sc_rx_intr = intr; 773 sc->sc_rx_intrarg = intrarg; 774 775 if (sc->sc_rx_mbuf != NULL) { 776 m = sc->sc_rx_mbuf; 777 sc->sc_rx_mbuf = NULL; 778 btsco_sco_input(sc, m); 779 } 780 781 return 0; 782 } 783 784 /* 785 * Halt Output 786 * 787 * This doesnt really halt the output, but it will look 788 * that way to the audio driver. The current block will 789 * still be transmitted. 790 */ 791 static int 792 btsco_halt_output(void *hdl) 793 { 794 struct btsco_softc *sc = hdl; 795 796 DPRINTFN(5, "%s\n", sc->sc_name); 797 798 sc->sc_tx_size = 0; 799 sc->sc_tx_block = NULL; 800 sc->sc_tx_pending = 0; 801 sc->sc_tx_intr = NULL; 802 sc->sc_tx_intrarg = NULL; 803 804 return 0; 805 } 806 807 /* 808 * Halt Input 809 * 810 * This doesnt really halt the input, but it will look 811 * that way to the audio driver. Incoming data will be 812 * discarded. 813 */ 814 static int 815 btsco_halt_input(void *hdl) 816 { 817 struct btsco_softc *sc = hdl; 818 819 DPRINTFN(5, "%s\n", sc->sc_name); 820 821 sc->sc_rx_want = 0; 822 sc->sc_rx_block = NULL; 823 sc->sc_rx_intr = NULL; 824 sc->sc_rx_intrarg = NULL; 825 826 m_freem(sc->sc_rx_mbuf); 827 sc->sc_rx_mbuf = NULL; 828 829 return 0; 830 } 831 832 static int 833 btsco_getdev(void *hdl, struct audio_device *ret) 834 { 835 836 *ret = btsco_device; 837 return 0; 838 } 839 840 static int 841 btsco_set_port(void *hdl, mixer_ctrl_t *mc) 842 { 843 struct btsco_softc *sc = hdl; 844 int err = 0; 845 846 DPRINTF("%s dev %d type %d\n", sc->sc_name, mc->dev, mc->type); 847 848 switch (mc->dev) { 849 case BTSCO_VGS: 850 if (mc->type != AUDIO_MIXER_VALUE || 851 mc->un.value.num_channels != 1) { 852 err = EINVAL; 853 break; 854 } 855 856 sc->sc_vgs = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 857 break; 858 859 case BTSCO_VGM: 860 if (mc->type != AUDIO_MIXER_VALUE || 861 mc->un.value.num_channels != 1) { 862 err = EINVAL; 863 break; 864 } 865 866 sc->sc_vgm = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 867 break; 868 869 default: 870 err = EINVAL; 871 break; 872 } 873 874 return err; 875 } 876 877 static int 878 btsco_get_port(void *hdl, mixer_ctrl_t *mc) 879 { 880 struct btsco_softc *sc = hdl; 881 int err = 0; 882 883 DPRINTF("%s dev %d\n", sc->sc_name, mc->dev); 884 885 switch (mc->dev) { 886 case BTSCO_VGS: 887 mc->type = AUDIO_MIXER_VALUE; 888 mc->un.value.num_channels = 1; 889 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_vgs; 890 break; 891 892 case BTSCO_VGM: 893 mc->type = AUDIO_MIXER_VALUE; 894 mc->un.value.num_channels = 1; 895 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_vgm; 896 break; 897 898 default: 899 err = EINVAL; 900 break; 901 } 902 903 return err; 904 } 905 906 static int 907 btsco_query_devinfo(void *hdl, mixer_devinfo_t *di) 908 { 909 /* struct btsco_softc *sc = hdl; */ 910 int err = 0; 911 912 switch(di->index) { 913 case BTSCO_VGS: 914 di->mixer_class = BTSCO_INPUT_CLASS; 915 di->next = di->prev = AUDIO_MIXER_LAST; 916 strcpy(di->label.name, AudioNspeaker); 917 di->type = AUDIO_MIXER_VALUE; 918 strcpy(di->un.v.units.name, AudioNvolume); 919 di->un.v.num_channels = 1; 920 di->un.v.delta = BTSCO_DELTA; 921 break; 922 923 case BTSCO_VGM: 924 di->mixer_class = BTSCO_INPUT_CLASS; 925 di->next = di->prev = AUDIO_MIXER_LAST; 926 strcpy(di->label.name, AudioNmicrophone); 927 di->type = AUDIO_MIXER_VALUE; 928 strcpy(di->un.v.units.name, AudioNvolume); 929 di->un.v.num_channels = 1; 930 di->un.v.delta = BTSCO_DELTA; 931 break; 932 933 case BTSCO_INPUT_CLASS: 934 di->mixer_class = BTSCO_INPUT_CLASS; 935 di->next = di->prev = AUDIO_MIXER_LAST; 936 strcpy(di->label.name, AudioCinputs); 937 di->type = AUDIO_MIXER_CLASS; 938 break; 939 940 default: 941 err = ENXIO; 942 break; 943 } 944 945 return err; 946 } 947 948 /* 949 * Allocate Ring Buffers. 950 */ 951 static void * 952 btsco_allocm(void *hdl, int direction, size_t size) 953 { 954 struct btsco_softc *sc = hdl; 955 void *addr; 956 957 DPRINTF("%s: size %zd direction %d\n", sc->sc_name, size, direction); 958 959 addr = kmem_alloc(size, KM_SLEEP); 960 961 if (direction == AUMODE_PLAY) { 962 sc->sc_tx_buf = addr; 963 sc->sc_tx_refcnt = 0; 964 } 965 966 return addr; 967 } 968 969 /* 970 * Free Ring Buffers. 971 * 972 * Because we used external memory for the tx mbufs, we dont 973 * want to free the memory until all the mbufs are done with 974 * 975 * Just to be sure, dont free if something is still pending. 976 * This would be a memory leak but at least there is a warning.. 977 */ 978 static void 979 btsco_freem(void *hdl, void *addr, size_t size) 980 { 981 struct btsco_softc *sc = hdl; 982 int count = hz / 2; 983 984 if (addr == sc->sc_tx_buf) { 985 DPRINTF("%s: tx_refcnt=%d\n", sc->sc_name, sc->sc_tx_refcnt); 986 987 sc->sc_tx_buf = NULL; 988 989 while (sc->sc_tx_refcnt> 0 && count-- > 0) 990 kpause("drain", false, 1, NULL); 991 992 if (sc->sc_tx_refcnt > 0) { 993 aprint_error("%s: ring buffer unreleased!\n", sc->sc_name); 994 return; 995 } 996 } 997 998 kmem_free(addr, size); 999 } 1000 1001 static int 1002 btsco_get_props(void *hdl) 1003 { 1004 1005 return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE | 1006 AUDIO_PROP_FULLDUPLEX; 1007 } 1008 1009 static void 1010 btsco_get_locks(void *hdl, kmutex_t **intr, kmutex_t **thread) 1011 { 1012 struct btsco_softc *sc = hdl; 1013 1014 *thread = &sc->sc_lock; 1015 *intr = bt_lock; 1016 } 1017 1018 /* 1019 * Handle private ioctl. We pass information out about how to talk 1020 * to the device and mixer. 1021 */ 1022 static int 1023 btsco_dev_ioctl(void *hdl, u_long cmd, void *addr, int flag, 1024 struct lwp *l) 1025 { 1026 struct btsco_softc *sc = hdl; 1027 struct btsco_info *bi = (struct btsco_info *)addr; 1028 int err = 0; 1029 1030 DPRINTF("%s cmd 0x%lx flag %d\n", sc->sc_name, cmd, flag); 1031 1032 switch (cmd) { 1033 case BTSCO_GETINFO: 1034 memset(bi, 0, sizeof(*bi)); 1035 bdaddr_copy(&bi->laddr, &sc->sc_laddr); 1036 bdaddr_copy(&bi->raddr, &sc->sc_raddr); 1037 bi->channel = sc->sc_channel; 1038 bi->vgs = BTSCO_VGS; 1039 bi->vgm = BTSCO_VGM; 1040 break; 1041 1042 default: 1043 err = EPASSTHROUGH; 1044 break; 1045 } 1046 1047 return err; 1048 } 1049 1050 1051 /***************************************************************************** 1052 * 1053 * misc btsco functions 1054 * 1055 */ 1056 1057 /* 1058 * Our transmit interrupt. This is triggered when a new block is to be 1059 * sent. We send mtu sized chunks of the block as mbufs with external 1060 * storage to sco_send_pcb() 1061 */ 1062 static void 1063 btsco_intr(void *arg) 1064 { 1065 struct btsco_softc *sc = arg; 1066 struct mbuf *m; 1067 uint8_t *block; 1068 int mlen, size; 1069 1070 DPRINTFN(10, "%s block %p size %d\n", 1071 sc->sc_name, sc->sc_tx_block, sc->sc_tx_size); 1072 1073 if (sc->sc_sco == NULL) 1074 return; /* connection is lost */ 1075 1076 mutex_enter(bt_lock); 1077 block = sc->sc_tx_block; 1078 size = sc->sc_tx_size; 1079 sc->sc_tx_block = NULL; 1080 sc->sc_tx_size = 0; 1081 1082 while (size > 0) { 1083 MGETHDR(m, M_DONTWAIT, MT_DATA); 1084 if (m == NULL) 1085 break; 1086 1087 mlen = MIN(sc->sc_mtu, size); 1088 1089 /* I think M_DEVBUF is true but not relevant */ 1090 MEXTADD(m, block, mlen, M_DEVBUF, btsco_extfree, sc); 1091 if ((m->m_flags & M_EXT) == 0) { 1092 m_free(m); 1093 break; 1094 } 1095 sc->sc_tx_refcnt++; 1096 1097 m->m_pkthdr.len = m->m_len = mlen; 1098 sc->sc_tx_pending++; 1099 1100 if (sco_send_pcb(sc->sc_sco, m) > 0) { 1101 sc->sc_tx_pending--; 1102 break; 1103 } 1104 1105 block += mlen; 1106 size -= mlen; 1107 } 1108 mutex_exit(bt_lock); 1109 } 1110 1111 /* 1112 * Release the mbuf, we keep a reference count on the tx buffer so 1113 * that we dont release it before its free. 1114 */ 1115 static void 1116 btsco_extfree(struct mbuf *m, void *addr, size_t size, 1117 void *arg) 1118 { 1119 struct btsco_softc *sc = arg; 1120 1121 if (m != NULL) 1122 pool_cache_put(mb_cache, m); 1123 1124 sc->sc_tx_refcnt--; 1125 } 1126