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