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