xref: /openbsd/sys/dev/audio.c (revision 404b540a)
1 /*	$OpenBSD: audio.c,v 1.105 2009/10/13 19:33:16 pirofti Exp $	*/
2 /*	$NetBSD: audio.c,v 1.119 1999/11/09 16:50:47 augustss Exp $	*/
3 
4 /*
5  * Copyright (c) 1991-1993 Regents of the University of California.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the Computer Systems
19  *	Engineering Group at Lawrence Berkeley Laboratory.
20  * 4. Neither the name of the University nor of the Laboratory may be used
21  *    to endorse or promote products derived from this software without
22  *    specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 /*
38  * This is a (partially) SunOS-compatible /dev/audio driver for NetBSD.
39  *
40  * This code tries to do something half-way sensible with
41  * half-duplex hardware, such as with the SoundBlaster hardware.  With
42  * half-duplex hardware allowing O_RDWR access doesn't really make
43  * sense.  However, closing and opening the device to "turn around the
44  * line" is relatively expensive and costs a card reset (which can
45  * take some time, at least for the SoundBlaster hardware).  Instead
46  * we allow O_RDWR access, and provide an ioctl to set the "mode",
47  * i.e. playing or recording.
48  *
49  * If you write to a half-duplex device in record mode, the data is
50  * tossed.  If you read from the device in play mode, you get silence
51  * filled buffers at the rate at which samples are naturally
52  * generated.
53  *
54  * If you try to set both play and record mode on a half-duplex
55  * device, playing takes precedence.
56  */
57 
58 /*
59  * Todo:
60  * - Add softaudio() isr processing for wakeup, poll, signals,
61  *   and silence fill.
62  */
63 
64 #include "audio.h"
65 #if NAUDIO > 0
66 
67 #include <sys/param.h>
68 #include <sys/ioctl.h>
69 #include <sys/fcntl.h>
70 #include <sys/vnode.h>
71 #include <sys/selinfo.h>
72 #include <sys/poll.h>
73 #include <sys/malloc.h>
74 #include <sys/proc.h>
75 #include <sys/systm.h>
76 #include <sys/syslog.h>
77 #include <sys/kernel.h>
78 #include <sys/signalvar.h>
79 #include <sys/conf.h>
80 #include <sys/audioio.h>
81 #include <sys/device.h>
82 
83 #include <dev/audio_if.h>
84 #include <dev/audiovar.h>
85 
86 #include <dev/rndvar.h>
87 
88 #include <machine/endian.h>
89 
90 #include "wskbd.h"	/* NWSKBD (mixer tuning using keyboard) */
91 
92 #ifdef AUDIO_DEBUG
93 #define DPRINTF(x)	if (audiodebug) printf x
94 #define DPRINTFN(n,x)	if (audiodebug>(n)) printf x
95 int	audiodebug = 0;
96 #else
97 #define DPRINTF(x)
98 #define DPRINTFN(n,x)
99 #endif
100 
101 #define ROUNDSIZE(x) x &= -16	/* round to nice boundary */
102 
103 #define AUDIO_BPS(bits)	((bits) <= 8 ? 1 : (((bits) <= 16) ? 2 : 4))
104 
105 int	audio_blk_ms = AUDIO_BLK_MS;
106 
107 int	audiosetinfo(struct audio_softc *, struct audio_info *);
108 int	audiogetinfo(struct audio_softc *, struct audio_info *);
109 int	audiogetbufinfo(struct audio_softc *, struct audio_bufinfo *, int);
110 int	audio_open(dev_t, struct audio_softc *, int, int, struct proc *);
111 int	audio_close(dev_t, int, int, struct proc *);
112 int	audio_read(dev_t, struct uio *, int);
113 int	audio_write(dev_t, struct uio *, int);
114 int	audio_ioctl(dev_t, u_long, caddr_t, int, struct proc *);
115 int	audio_poll(dev_t, int, struct proc *);
116 paddr_t	audio_mmap(dev_t, off_t, int);
117 
118 int	mixer_open(dev_t, struct audio_softc *, int, int, struct proc *);
119 int	mixer_close(dev_t, int, int, struct proc *);
120 int	mixer_ioctl(dev_t, u_long, caddr_t, int, struct proc *);
121 static	void mixer_remove(struct audio_softc *, struct proc *p);
122 static	void mixer_signal(struct audio_softc *);
123 
124 void	audio_init_record(struct audio_softc *);
125 void	audio_init_play(struct audio_softc *);
126 int	audiostartr(struct audio_softc *);
127 int	audiostartp(struct audio_softc *);
128 void	audio_rint(void *);
129 void	audio_pint(void *);
130 int	audio_check_params(struct audio_params *);
131 
132 void	audio_set_blksize(struct audio_softc *, int, int);
133 void	audio_calc_blksize(struct audio_softc *, int);
134 void	audio_fill_silence(struct audio_params *, u_char *, u_char *, int);
135 int	audio_silence_copyout(struct audio_softc *, int, struct uio *);
136 
137 void	audio_init_ringbuffer(struct audio_ringbuffer *);
138 int	audio_initbufs(struct audio_softc *);
139 void	audio_calcwater(struct audio_softc *);
140 static __inline int audio_sleep_timo(int *, char *, int);
141 static __inline int audio_sleep(int *, char *);
142 static __inline void audio_wakeup(int *);
143 void	audio_selwakeup(struct audio_softc *sc, int play);
144 int	audio_drain(struct audio_softc *);
145 void	audio_clear(struct audio_softc *);
146 static __inline void audio_pint_silence(struct audio_softc *, struct audio_ringbuffer *, u_char *, int);
147 
148 int	audio_alloc_ring(struct audio_softc *, struct audio_ringbuffer *, int, int);
149 void	audio_free_ring(struct audio_softc *, struct audio_ringbuffer *);
150 
151 int	audioprint(void *, const char *);
152 
153 int	audioprobe(struct device *, void *, void *);
154 void	audioattach(struct device *, struct device *, void *);
155 int	audiodetach(struct device *, int);
156 int	audioactivate(struct device *, int);
157 
158 struct portname {
159 	char	*name;
160 	int	mask;
161 };
162 static struct portname itable[] = {
163 	{ AudioNmicrophone,	AUDIO_MICROPHONE },
164 	{ AudioNline,		AUDIO_LINE_IN },
165 	{ AudioNcd,		AUDIO_CD },
166 	{ 0 }
167 };
168 static struct portname otable[] = {
169 	{ AudioNspeaker,	AUDIO_SPEAKER },
170 	{ AudioNheadphone,	AUDIO_HEADPHONE },
171 	{ AudioNline,		AUDIO_LINE_OUT },
172 	{ 0 }
173 };
174 struct gainpref {
175 	char *class, *device;
176 };
177 static struct gainpref ipreftab[] = {
178 	{ AudioCinputs, AudioNvolume },
179 	{ AudioCinputs, AudioNinput  },
180 	{ AudioCinputs, AudioNrecord },
181 	{ AudioCrecord, AudioNvolume },
182 	{ AudioCrecord, AudioNrecord },
183 	{ NULL, NULL}
184 };
185 static struct gainpref opreftab[] = {
186 	{ AudioCoutputs, AudioNoutput },
187 	{ AudioCoutputs, AudioNdac },
188 	{ AudioCinputs,  AudioNdac },
189 	{ AudioCoutputs, AudioNmaster },
190 	{ NULL, NULL}
191 };
192 static struct gainpref mpreftab[] = {
193 	{ AudioCoutputs, AudioNmonitor },
194 	{ AudioCmonitor, AudioNmonitor },
195 	{ NULL, NULL}
196 };
197 
198 void	au_gain_match(struct audio_softc *, struct gainpref *,
199 		mixer_devinfo_t *, mixer_devinfo_t *, int *, int *);
200 void	au_check_ports(struct audio_softc *, struct au_mixer_ports *,
201 		            mixer_devinfo_t *, mixer_devinfo_t *,
202 		            char *, char *, struct portname *);
203 int	au_set_gain(struct audio_softc *, struct au_mixer_ports *,
204 			 int, int);
205 void	au_get_gain(struct audio_softc *, struct au_mixer_ports *,
206 			 u_int *, u_char *);
207 int	au_set_port(struct audio_softc *, struct au_mixer_ports *,
208 			 u_int);
209 int	au_get_port(struct audio_softc *, struct au_mixer_ports *);
210 int	au_set_mute(struct audio_softc *, struct au_mixer_ports *, u_char);
211 int	au_get_mute(struct audio_softc *, struct au_mixer_ports *, u_char *);
212 int	au_get_lr_value(struct audio_softc *, mixer_ctrl_t *,
213 			     int *, int *r);
214 int	au_set_lr_value(struct audio_softc *, mixer_ctrl_t *,
215 			     int, int);
216 int	au_portof(struct audio_softc *, char *);
217 
218 
219 /* The default audio mode: 8 kHz mono ulaw */
220 struct audio_params audio_default =
221 	{ 8000, AUDIO_ENCODING_ULAW, 8, 1, 0, 1 };
222 
223 struct cfattach audio_ca = {
224 	sizeof(struct audio_softc), audioprobe, audioattach,
225 	audiodetach, audioactivate
226 };
227 
228 struct cfdriver audio_cd = {
229 	NULL, "audio", DV_DULL
230 };
231 
232 void filt_audiowdetach(struct knote *);
233 int filt_audiowrite(struct knote *, long);
234 
235 struct filterops audiowrite_filtops =
236 	{ 1, NULL, filt_audiowdetach, filt_audiowrite};
237 
238 void filt_audiordetach(struct knote *);
239 int filt_audioread(struct knote *, long);
240 
241 struct filterops audioread_filtops =
242 	{ 1, NULL, filt_audiordetach, filt_audioread};
243 
244 #if NWSKBD > 0
245 /* Mixer manipulation using keyboard */
246 int wskbd_set_mixervolume(long);
247 #endif
248 
249 int
250 audioprobe(struct device *parent, void *match, void *aux)
251 {
252 	struct audio_attach_args *sa = aux;
253 
254 	DPRINTF(("audioprobe: type=%d sa=%p hw=%p\n",
255 		   sa->type, sa, sa->hwif));
256 	return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0;
257 }
258 
259 void
260 audioattach(struct device *parent, struct device *self, void *aux)
261 {
262 	struct audio_softc *sc = (void *)self;
263 	struct audio_attach_args *sa = aux;
264 	struct audio_hw_if *hwp = sa->hwif;
265 	void *hdlp = sa->hdl;
266 	int error;
267 	mixer_devinfo_t mi, cl;
268 	int ipref, opref, mpref;
269 
270 	printf("\n");
271 
272 #ifdef DIAGNOSTIC
273 	if (hwp == 0 ||
274 	    hwp->open == 0 ||
275 	    hwp->close == 0 ||
276 	    hwp->query_encoding == 0 ||
277 	    hwp->set_params == 0 ||
278 	    (hwp->start_output == 0 && hwp->trigger_output == 0) ||
279 	    (hwp->start_input == 0 && hwp->trigger_input == 0) ||
280 	    hwp->halt_output == 0 ||
281 	    hwp->halt_input == 0 ||
282 	    hwp->getdev == 0 ||
283 	    hwp->set_port == 0 ||
284 	    hwp->get_port == 0 ||
285 	    hwp->query_devinfo == 0 ||
286 	    hwp->get_props == 0) {
287 		printf("audio: missing method\n");
288 		sc->hw_if = 0;
289 		return;
290 	}
291 #endif
292 
293 	sc->hw_if = hwp;
294 	sc->hw_hdl = hdlp;
295 	sc->sc_dev = parent;
296 	sc->sc_async_mixer = NULL;
297 
298 	error = audio_alloc_ring(sc, &sc->sc_pr, AUMODE_PLAY, AU_RING_SIZE);
299 	if (error) {
300 		sc->hw_if = 0;
301 		printf("audio: could not allocate play buffer\n");
302 		return;
303 	}
304 	error = audio_alloc_ring(sc, &sc->sc_rr, AUMODE_RECORD, AU_RING_SIZE);
305 	if (error) {
306 		audio_free_ring(sc, &sc->sc_pr);
307 		sc->hw_if = 0;
308 		printf("audio: could not allocate record buffer\n");
309 		return;
310 	}
311 
312 	/*
313 	 * Set default softc params
314 	 */
315 
316 	if (hwp->get_default_params) {
317 		hwp->get_default_params(sc, AUMODE_PLAY, &sc->sc_pparams);
318 		hwp->get_default_params(sc, AUMODE_RECORD, &sc->sc_rparams);
319 	} else {
320 		sc->sc_pparams = audio_default;
321 		sc->sc_rparams = audio_default;
322 	}
323 
324 	/* Set up some default values */
325 	sc->sc_rr.blkset = sc->sc_pr.blkset = 0;
326 	audio_calc_blksize(sc, AUMODE_RECORD);
327 	audio_calc_blksize(sc, AUMODE_PLAY);
328 	audio_init_ringbuffer(&sc->sc_rr);
329 	audio_init_ringbuffer(&sc->sc_pr);
330 	audio_calcwater(sc);
331 
332 	ipref = opref = mpref = -1;
333 	sc->sc_inports.index = -1;
334 	sc->sc_inports.nports = 0;
335 	sc->sc_inports.isenum = 0;
336 	sc->sc_inports.allports = 0;
337 	sc->sc_inports.master = -1;
338 	sc->sc_outports.index = -1;
339 	sc->sc_outports.nports = 0;
340 	sc->sc_outports.isenum = 0;
341 	sc->sc_outports.allports = 0;
342 	sc->sc_outports.master = -1;
343 	sc->sc_monitor_port = -1;
344 	for(mi.index = 0; ; mi.index++) {
345 		if (hwp->query_devinfo(hdlp, &mi) != 0)
346 			break;
347 		if (mi.type == AUDIO_MIXER_CLASS)
348 			continue;
349 		cl.index = mi.mixer_class;
350 		if (hwp->query_devinfo(hdlp, &cl) != 0)
351 			continue;
352 
353 		au_gain_match(sc, ipreftab, &cl, &mi, &sc->sc_inports.master, &ipref);
354 		au_gain_match(sc, opreftab, &cl, &mi, &sc->sc_outports.master, &opref);
355 		au_gain_match(sc, mpreftab, &cl, &mi, &sc->sc_monitor_port, &mpref);
356 
357 		au_check_ports(sc, &sc->sc_inports,  &cl, &mi,
358 		    AudioCrecord, AudioNsource, itable);
359 		au_check_ports(sc, &sc->sc_outports, &cl, &mi,
360 		    AudioCoutputs, AudioNselect, otable);
361 	}
362 	DPRINTF(("audio_attach: inputs ports=0x%x, output ports=0x%x\n",
363 		 sc->sc_inports.allports, sc->sc_outports.allports));
364 }
365 
366 int
367 audioactivate(struct device *self, int act)
368 {
369 	struct audio_softc *sc = (struct audio_softc *)self;
370 
371 	switch (act) {
372 	case DVACT_ACTIVATE:
373 		break;
374 
375 	case DVACT_DEACTIVATE:
376 		sc->sc_dying = 1;
377 		break;
378 	}
379 	return (0);
380 }
381 
382 int
383 audiodetach(struct device *self, int flags)
384 {
385 	struct audio_softc *sc = (struct audio_softc *)self;
386 	int maj, mn;
387 	int s;
388 
389 	DPRINTF(("audio_detach: sc=%p flags=%d\n", sc, flags));
390 
391 	sc->sc_dying = 1;
392 
393 	wakeup(&sc->sc_wchan);
394 	wakeup(&sc->sc_rchan);
395 	s = splaudio();
396 	if (--sc->sc_refcnt >= 0) {
397 		if (tsleep(&sc->sc_refcnt, PZERO, "auddet", hz * 120))
398 			printf("audiodetach: %s didn't detach\n",
399 			    sc->dev.dv_xname);
400 	}
401 	splx(s);
402 
403 	/* free resources */
404 	audio_free_ring(sc, &sc->sc_pr);
405 	audio_free_ring(sc, &sc->sc_rr);
406 
407 	/* locate the major number */
408 	for (maj = 0; maj < nchrdev; maj++)
409 		if (cdevsw[maj].d_open == audioopen)
410 			break;
411 
412 	/* Nuke the vnodes for any open instances (calls close). */
413 	mn = self->dv_unit;
414 	vdevgone(maj, mn | SOUND_DEVICE,    mn | SOUND_DEVICE, VCHR);
415 	vdevgone(maj, mn | AUDIO_DEVICE,    mn | AUDIO_DEVICE, VCHR);
416 	vdevgone(maj, mn | AUDIOCTL_DEVICE, mn | AUDIOCTL_DEVICE, VCHR);
417 	vdevgone(maj, mn | MIXER_DEVICE,    mn | MIXER_DEVICE, VCHR);
418 
419 	return (0);
420 }
421 
422 int
423 au_portof(struct audio_softc *sc, char *name)
424 {
425 	mixer_devinfo_t mi;
426 
427 	for(mi.index = 0;
428 	    sc->hw_if->query_devinfo(sc->hw_hdl, &mi) == 0;
429 	    mi.index++)
430 		if (strcmp(mi.label.name, name) == 0)
431 			return mi.index;
432 	return -1;
433 }
434 
435 void
436 au_check_ports(struct audio_softc *sc, struct au_mixer_ports *ports,
437     mixer_devinfo_t *cl, mixer_devinfo_t *mi, char *cname, char *mname,
438     struct portname *tbl)
439 {
440 	int i, j;
441 
442 	if (strcmp(cl->label.name, cname) != 0 ||
443 	    strcmp(mi->label.name, mname) != 0)
444 		return;
445 	if (mi->type == AUDIO_MIXER_ENUM) {
446 	    ports->index = mi->index;
447 	    for(i = 0; tbl[i].name; i++) {
448 		for(j = 0; j < mi->un.e.num_mem; j++) {
449 		    if (strcmp(mi->un.e.member[j].label.name,
450 			    tbl[i].name) == 0) {
451 			ports->aumask[ports->nports] = tbl[i].mask;
452 			ports->misel [ports->nports] = mi->un.e.member[j].ord;
453 			ports->miport[ports->nports++] =
454 				au_portof(sc, mi->un.e.member[j].label.name);
455 			ports->allports |= tbl[i].mask;
456 		    }
457 		}
458 	    }
459 	    ports->isenum = 1;
460 	} else if (mi->type == AUDIO_MIXER_SET) {
461 	    ports->index = mi->index;
462 	    for(i = 0; tbl[i].name; i++) {
463 		for(j = 0; j < mi->un.s.num_mem; j++) {
464 		    if (strcmp(mi->un.s.member[j].label.name,
465 			    tbl[i].name) == 0) {
466 			ports->aumask[ports->nports] = tbl[i].mask;
467 			ports->misel [ports->nports] = mi->un.s.member[j].mask;
468 			ports->miport[ports->nports++] =
469 				au_portof(sc, mi->un.s.member[j].label.name);
470 			ports->allports |= tbl[i].mask;
471 		    }
472 		}
473 	    }
474 	}
475 }
476 
477 /*
478  * check if the given (class, device) is better
479  * than the current setting (*index), if so, set the
480  * current setting.
481  */
482 void
483 au_gain_match(struct audio_softc *sc, struct gainpref *tbl,
484     mixer_devinfo_t *cls, mixer_devinfo_t *dev, int *index, int *pref)
485 {
486 	int i;
487 
488 	for (i = *pref + 1; tbl[i].class != NULL; i++) {
489 		if (strcmp(tbl[i].class, cls->label.name) == 0 &&
490 		    strcmp(tbl[i].device, dev->label.name) == 0) {
491 			if (*pref < i) {
492 				DPRINTF(("au_gain_match: found %s.%s\n",
493 				    cls->label.name, dev->label.name));
494 				*index = dev->index;
495 				*pref = i;
496 			}
497 			break;
498 		}
499 	}
500 }
501 
502 /*
503  * Called from hardware driver.  This is where the MI audio driver gets
504  * probed/attached to the hardware driver.
505  */
506 struct device *
507 audio_attach_mi(struct audio_hw_if *ahwp, void *hdlp, struct device *dev)
508 {
509 	struct audio_attach_args arg;
510 
511 #ifdef DIAGNOSTIC
512 	if (ahwp == NULL) {
513 		printf ("audio_attach_mi: NULL\n");
514 		return 0;
515 	}
516 #endif
517 
518 	arg.type = AUDIODEV_TYPE_AUDIO;
519 	arg.hwif = ahwp;
520 	arg.hdl = hdlp;
521 	return config_found(dev, &arg, audioprint);
522 }
523 
524 #if NAUDIO > 0
525 int
526 audioprint(void *aux, const char *pnp)
527 {
528 	struct audio_attach_args *arg = aux;
529 	const char *type;
530 
531 	if (pnp != NULL) {
532 		switch (arg->type) {
533 		case AUDIODEV_TYPE_AUDIO:
534 			type = "audio";
535 			break;
536 		case AUDIODEV_TYPE_OPL:
537 			type = "opl";
538 			break;
539 		case AUDIODEV_TYPE_MPU:
540 			type = "mpu";
541 			break;
542 		default:
543 			panic("audioprint: unknown type %d", arg->type);
544 		}
545 		printf("%s at %s", type, pnp);
546 	}
547 	return (UNCONF);
548 }
549 
550 #endif /* NAUDIO > 0 */
551 
552 #ifdef AUDIO_DEBUG
553 void	audio_printsc(struct audio_softc *);
554 void	audio_print_params(char *, struct audio_params *);
555 
556 void
557 audio_printsc(struct audio_softc *sc)
558 {
559 	printf("hwhandle %p hw_if %p ", sc->hw_hdl, sc->hw_if);
560 	printf("open 0x%x mode 0x%x\n", sc->sc_open, sc->sc_mode);
561 	printf("rchan 0x%x wchan 0x%x ", sc->sc_rchan, sc->sc_wchan);
562 	printf("rring used 0x%x pring used=%d\n", sc->sc_rr.used, sc->sc_pr.used);
563 	printf("rbus 0x%x pbus 0x%x ", sc->sc_rbus, sc->sc_pbus);
564 	printf("pblksz %d, rblksz %d", sc->sc_pr.blksize, sc->sc_rr.blksize);
565 	printf("hiwat %d lowat %d\n", sc->sc_pr.usedhigh, sc->sc_pr.usedlow);
566 }
567 
568 void
569 audio_print_params(char *s, struct audio_params *p)
570 {
571 	printf("audio: %s sr=%ld, enc=%d, chan=%d, prec=%d\n", s,
572 	    p->sample_rate, p->encoding, p->channels, p->precision);
573 }
574 #endif
575 
576 int
577 audio_alloc_ring(struct audio_softc *sc, struct audio_ringbuffer *r,
578     int direction, int bufsize)
579 {
580 	struct audio_hw_if *hw = sc->hw_if;
581 	void *hdl = sc->hw_hdl;
582 	/*
583 	 * Alloc DMA play and record buffers
584 	 */
585 	if (bufsize < AUMINBUF)
586 		bufsize = AUMINBUF;
587 	ROUNDSIZE(bufsize);
588 	if (hw->round_buffersize)
589 		bufsize = hw->round_buffersize(hdl, direction, bufsize);
590 	r->bufsize = bufsize;
591 	if (hw->allocm)
592 		r->start = hw->allocm(hdl, direction, r->bufsize, M_DEVBUF,
593 		    M_WAITOK);
594 	else
595 		r->start = malloc(bufsize, M_DEVBUF, M_WAITOK);
596 	if (r->start == 0)
597 		return ENOMEM;
598 	return 0;
599 }
600 
601 void
602 audio_free_ring(struct audio_softc *sc, struct audio_ringbuffer *r)
603 {
604 	if (sc->hw_if->freem) {
605 		sc->hw_if->freem(sc->hw_hdl, r->start, M_DEVBUF);
606 	} else {
607 		free(r->start, M_DEVBUF);
608 	}
609 }
610 
611 int
612 audioopen(dev_t dev, int flags, int ifmt, struct proc *p)
613 {
614 	int unit = AUDIOUNIT(dev);
615 	struct audio_softc *sc;
616 	int error;
617 
618 	if (unit >= audio_cd.cd_ndevs ||
619 	    (sc = audio_cd.cd_devs[unit]) == NULL)
620 		return ENXIO;
621 
622 	if (sc->sc_dying)
623 		return (EIO);
624 
625 	if (!sc->hw_if)
626 		return (ENXIO);
627 
628 	sc->sc_refcnt ++;
629 	switch (AUDIODEV(dev)) {
630 	case SOUND_DEVICE:
631 	case AUDIO_DEVICE:
632 	case AUDIOCTL_DEVICE:
633 		error = audio_open(dev, sc, flags, ifmt, p);
634 		break;
635 	case MIXER_DEVICE:
636 		error = mixer_open(dev, sc, flags, ifmt, p);
637 		break;
638 	default:
639 		error = ENXIO;
640 		break;
641 	}
642 
643 	if (--sc->sc_refcnt < 0)
644 		wakeup(&sc->sc_refcnt);
645 
646 	return (error);
647 }
648 
649 int
650 audioclose(dev_t dev, int flags, int ifmt, struct proc *p)
651 {
652 
653 	switch (AUDIODEV(dev)) {
654 	case SOUND_DEVICE:
655 	case AUDIO_DEVICE:
656 		return (audio_close(dev, flags, ifmt, p));
657 	case MIXER_DEVICE:
658 		return (mixer_close(dev, flags, ifmt, p));
659 	case AUDIOCTL_DEVICE:
660 		return 0;
661 	default:
662 		return (ENXIO);
663 	}
664 }
665 
666 int
667 audioread(dev_t dev, struct uio *uio, int ioflag)
668 {
669 	int unit = AUDIOUNIT(dev);
670 	struct audio_softc *sc;
671 	int error;
672 
673 	if (unit >= audio_cd.cd_ndevs ||
674 	    (sc = audio_cd.cd_devs[unit]) == NULL)
675 		return ENXIO;
676 
677 	if (sc->sc_dying)
678 		return (EIO);
679 
680 	sc->sc_refcnt ++;
681 	switch (AUDIODEV(dev)) {
682 	case SOUND_DEVICE:
683 	case AUDIO_DEVICE:
684 		error = audio_read(dev, uio, ioflag);
685 		break;
686 	case AUDIOCTL_DEVICE:
687 	case MIXER_DEVICE:
688 		error = ENODEV;
689 		break;
690 	default:
691 		error = ENXIO;
692 		break;
693 	}
694 
695 	if (--sc->sc_refcnt < 0)
696 		wakeup(&sc->sc_refcnt);
697 	return (error);
698 }
699 
700 int
701 audiowrite(dev_t dev, struct uio *uio, int ioflag)
702 {
703 	int unit = AUDIOUNIT(dev);
704 	struct audio_softc *sc;
705 	int error;
706 
707 	if (unit >= audio_cd.cd_ndevs ||
708 	    (sc = audio_cd.cd_devs[unit]) == NULL)
709 		return ENXIO;
710 
711 	if (sc->sc_dying)
712 		return (EIO);
713 
714 	sc->sc_refcnt ++;
715 	switch (AUDIODEV(dev)) {
716 	case SOUND_DEVICE:
717 	case AUDIO_DEVICE:
718 		error = audio_write(dev, uio, ioflag);
719 		break;
720 	case AUDIOCTL_DEVICE:
721 	case MIXER_DEVICE:
722 		error = ENODEV;
723 		break;
724 	default:
725 		error = ENXIO;
726 		break;
727 	}
728 
729 	if (--sc->sc_refcnt < 0)
730 		wakeup(&sc->sc_refcnt);
731 	return (error);
732 }
733 
734 int
735 audioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
736 {
737 	int unit = AUDIOUNIT(dev);
738 	struct audio_softc *sc;
739 	int error;
740 
741 	if (unit >= audio_cd.cd_ndevs ||
742 	    (sc = audio_cd.cd_devs[unit]) == NULL)
743 		return ENXIO;
744 
745 	if (sc->sc_dying)
746 		return (EIO);
747 
748 	sc->sc_refcnt ++;
749 	switch (AUDIODEV(dev)) {
750 	case SOUND_DEVICE:
751 	case AUDIO_DEVICE:
752 	case AUDIOCTL_DEVICE:
753 		error = audio_ioctl(dev, cmd, addr, flag, p);
754 		break;
755 	case MIXER_DEVICE:
756 		error = mixer_ioctl(dev, cmd, addr, flag, p);
757 		break;
758 	default:
759 		error = ENXIO;
760 		break;
761 	}
762 
763 	if (--sc->sc_refcnt < 0)
764 		wakeup(&sc->sc_refcnt);
765 	return (error);
766 }
767 
768 int
769 audiopoll(dev_t dev, int events, struct proc *p)
770 {
771 	int unit = AUDIOUNIT(dev);
772 	struct audio_softc *sc;
773 	int error;
774 
775 	if (unit >= audio_cd.cd_ndevs ||
776 	    (sc = audio_cd.cd_devs[unit]) == NULL)
777 		return POLLERR;
778 
779 	if (sc->sc_dying)
780 		return POLLERR;
781 
782 	sc->sc_refcnt ++;
783 	switch (AUDIODEV(dev)) {
784 	case SOUND_DEVICE:
785 	case AUDIO_DEVICE:
786 		error = audio_poll(dev, events, p);
787 		break;
788 	case AUDIOCTL_DEVICE:
789 	case MIXER_DEVICE:
790 		error = 0;
791 		break;
792 	default:
793 		error = 0;
794 		break;
795 	}
796 
797 	if (--sc->sc_refcnt < 0)
798 		wakeup(&sc->sc_refcnt);
799 	return (error);
800 }
801 
802 paddr_t
803 audiommap(dev_t dev, off_t off, int prot)
804 {
805 	int unit = AUDIOUNIT(dev);
806 	struct audio_softc *sc;
807 	int ret;
808 
809 	if (unit >= audio_cd.cd_ndevs ||
810 	    (sc = audio_cd.cd_devs[unit]) == NULL)
811 		return (-1);
812 
813 	if (sc->sc_dying)
814 		return (-1);
815 
816 	sc->sc_refcnt ++;
817 	switch (AUDIODEV(dev)) {
818 	case SOUND_DEVICE:
819 	case AUDIO_DEVICE:
820 		ret = audio_mmap(dev, off, prot);
821 		break;
822 	case AUDIOCTL_DEVICE:
823 	case MIXER_DEVICE:
824 		ret = -1;
825 		break;
826 	default:
827 		ret = -1;
828 		break;
829 	}
830 
831 	if (--sc->sc_refcnt < 0)
832 		wakeup(&sc->sc_refcnt);
833 	return (ret);
834 }
835 
836 /*
837  * Audio driver
838  */
839 void
840 audio_init_ringbuffer(struct audio_ringbuffer *rp)
841 {
842 	int nblks;
843 	int blksize = rp->blksize;
844 
845 	if (blksize < AUMINBLK)
846 		blksize = AUMINBLK;
847 	nblks = rp->bufsize / blksize;
848 	if (nblks < AUMINNOBLK) {
849 		nblks = AUMINNOBLK;
850 		blksize = rp->bufsize / nblks;
851 		ROUNDSIZE(blksize);
852 	}
853 	DPRINTF(("audio_init_ringbuffer: blksize=%d\n", blksize));
854 	rp->blksize = blksize;
855 	rp->maxblks = nblks;
856 	rp->used = 0;
857 	rp->end = rp->start + nblks * blksize;
858 	rp->inp = rp->outp = rp->start;
859 	rp->stamp = 0;
860 	rp->stamp_last = 0;
861 	rp->drops = 0;
862 	rp->pdrops = 0;
863 	rp->mmapped = 0;
864 }
865 
866 int
867 audio_initbufs(struct audio_softc *sc)
868 {
869 	struct audio_hw_if *hw = sc->hw_if;
870 	int error;
871 
872 	DPRINTF(("audio_initbufs: mode=0x%x\n", sc->sc_mode));
873 	audio_init_ringbuffer(&sc->sc_rr);
874 	if (hw->init_input && (sc->sc_mode & AUMODE_RECORD)) {
875 		error = hw->init_input(sc->hw_hdl, sc->sc_rr.start,
876 		    sc->sc_rr.end - sc->sc_rr.start);
877 		if (error)
878 			return error;
879 	}
880 
881 	audio_init_ringbuffer(&sc->sc_pr);
882 	sc->sc_sil_count = 0;
883 	if (hw->init_output && (sc->sc_mode & AUMODE_PLAY)) {
884 		error = hw->init_output(sc->hw_hdl, sc->sc_pr.start,
885 					sc->sc_pr.end - sc->sc_pr.start);
886 		if (error)
887 			return error;
888 	}
889 
890 #ifdef AUDIO_INTR_TIME
891 	sc->sc_pnintr = 0;
892 	sc->sc_pblktime = (u_long)(
893 	    (u_long)sc->sc_pr.blksize * 100000 /
894 	    (u_long)(AUDIO_BPS(sc->sc_pparams.precision) *
895 		sc->sc_pparams.channels *
896 		sc->sc_pparams.sample_rate)) * 10;
897 	DPRINTF(("audio: play blktime = %lu for %d\n",
898 		 sc->sc_pblktime, sc->sc_pr.blksize));
899 	sc->sc_rnintr = 0;
900 	sc->sc_rblktime = (u_long)(
901 	    (u_long)sc->sc_rr.blksize * 100000 /
902 	    (u_long)(AUDIO_BPS(sc->sc_rparams.precision) *
903 		sc->sc_rparams.channels *
904 		sc->sc_rparams.sample_rate)) * 10;
905 	DPRINTF(("audio: record blktime = %lu for %d\n",
906 		 sc->sc_rblktime, sc->sc_rr.blksize));
907 #endif
908 
909 	return 0;
910 }
911 
912 void
913 audio_calcwater(struct audio_softc *sc)
914 {
915 	int hiwat, lowat;
916 
917 	hiwat = (sc->sc_pr.end - sc->sc_pr.start) / sc->sc_pr.blksize;
918 	lowat = hiwat * 3 / 4;
919 	if (lowat == hiwat)
920 		lowat = hiwat - 1;
921 	sc->sc_pr.usedhigh = hiwat * sc->sc_pr.blksize;
922 	sc->sc_pr.usedlow = lowat * sc->sc_pr.blksize;
923 	sc->sc_rr.usedhigh = sc->sc_rr.end - sc->sc_rr.start;
924 	sc->sc_rr.usedlow = 0;
925 }
926 
927 static __inline int
928 audio_sleep_timo(int *chan, char *label, int timo)
929 {
930 	int st;
931 
932 	if (!label)
933 		label = "audio";
934 
935 	DPRINTFN(3, ("audio_sleep_timo: chan=%p, label=%s, timo=%d\n",
936 	    chan, label, timo));
937 	*chan = 1;
938 	st = tsleep(chan, PWAIT | PCATCH, label, timo);
939 	*chan = 0;
940 #ifdef AUDIO_DEBUG
941 	if (st != 0)
942 	    printf("audio_sleep: woke up st=%d\n", st);
943 #endif
944 	return (st);
945 }
946 
947 static __inline int
948 audio_sleep(int *chan, char *label)
949 {
950 	return audio_sleep_timo(chan, label, 0);
951 }
952 
953 /* call at splaudio() */
954 static __inline void
955 audio_wakeup(int *chan)
956 {
957 	DPRINTFN(3, ("audio_wakeup: chan=%p, *chan=%d\n", chan, *chan));
958 	if (*chan) {
959 		wakeup(chan);
960 		*chan = 0;
961 	}
962 }
963 
964 int
965 audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
966     struct proc *p)
967 {
968 	int error;
969 	int mode;
970 	struct audio_info ai;
971 
972 	DPRINTF(("audio_open: dev=0x%x flags=0x%x sc=%p hdl=%p\n", dev, flags, sc, sc->hw_hdl));
973 
974 	if (ISDEVAUDIOCTL(dev))
975 		return 0;
976 
977 	if ((sc->sc_open & (AUOPEN_READ|AUOPEN_WRITE)) != 0)
978 		return (EBUSY);
979 
980 	error = sc->hw_if->open(sc->hw_hdl, flags);
981 	if (error)
982 		return (error);
983 
984 	sc->sc_async_audio = 0;
985 	sc->sc_rchan = 0;
986 	sc->sc_wchan = 0;
987 	sc->sc_sil_count = 0;
988 	sc->sc_rbus = 0;
989 	sc->sc_pbus = 0;
990 	sc->sc_eof = 0;
991 	sc->sc_playdrop = 0;
992 
993 	sc->sc_full_duplex = 0;
994 /* doesn't always work right on SB.
995 		(flags & (FWRITE|FREAD)) == (FWRITE|FREAD) &&
996 		(sc->hw_if->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX);
997 */
998 
999 	mode = 0;
1000 	if (flags & FREAD) {
1001 		sc->sc_open |= AUOPEN_READ;
1002 		mode |= AUMODE_RECORD;
1003 	}
1004 	if (flags & FWRITE) {
1005 		sc->sc_open |= AUOPEN_WRITE;
1006 		mode |= AUMODE_PLAY | AUMODE_PLAY_ALL;
1007 	}
1008 
1009 	/*
1010 	 * Multiplex device: /dev/audio (default) and /dev/sound (last)
1011 	 * The /dev/audio is always (re)set to the default parameters.
1012 	 * For the other devices, you get what they were last set to.
1013 	 */
1014 	if (ISDEVAUDIO(dev)) {
1015 		/* /dev/audio */
1016 		if (sc->hw_if->get_default_params) {
1017 			sc->hw_if->get_default_params(sc, AUMODE_PLAY,
1018 			    &sc->sc_pparams);
1019 			sc->hw_if->get_default_params(sc, AUMODE_RECORD,
1020 			    &sc->sc_rparams);
1021 		} else {
1022 			sc->sc_rparams = audio_default;
1023 			sc->sc_pparams = audio_default;
1024 		}
1025 	}
1026 #ifdef DIAGNOSTIC
1027 	/*
1028 	 * Sample rate and precision are supposed to be set to proper
1029 	 * default values by the hardware driver, so that it may give
1030 	 * us these values.
1031 	 */
1032 	if (sc->sc_rparams.precision == 0 || sc->sc_pparams.precision == 0) {
1033 		printf("audio_open: 0 precision\n");
1034 		error = EINVAL;
1035 		goto bad;
1036 	}
1037 #endif
1038 
1039 	AUDIO_INITINFO(&ai);
1040 	ai.record.sample_rate = sc->sc_rparams.sample_rate;
1041 	ai.record.encoding    = sc->sc_rparams.encoding;
1042 	ai.record.channels    = sc->sc_rparams.channels;
1043 	ai.record.precision   = sc->sc_rparams.precision;
1044 	ai.record.pause	      = 0;
1045 	ai.play.sample_rate   = sc->sc_pparams.sample_rate;
1046 	ai.play.encoding       = sc->sc_pparams.encoding;
1047 	ai.play.channels      = sc->sc_pparams.channels;
1048 	ai.play.precision     = sc->sc_pparams.precision;
1049 	ai.play.pause	      = 0;
1050 	ai.mode		      = mode;
1051 	sc->sc_rr.blkset = sc->sc_pr.blkset = 0; /* Block sizes not set yet */
1052 	sc->sc_pr.blksize = sc->sc_rr.blksize = 0; /* force recalculation */
1053 	error = audiosetinfo(sc, &ai);
1054 	if (error)
1055 		goto bad;
1056 
1057 	DPRINTF(("audio_open: done sc_mode = 0x%x\n", sc->sc_mode));
1058 
1059 	return 0;
1060 
1061 bad:
1062 	sc->hw_if->close(sc->hw_hdl);
1063 	sc->sc_open = 0;
1064 	sc->sc_mode = 0;
1065 	sc->sc_full_duplex = 0;
1066 	return error;
1067 }
1068 
1069 /*
1070  * Must be called from task context.
1071  */
1072 void
1073 audio_init_record(struct audio_softc *sc)
1074 {
1075 	int s = splaudio();
1076 
1077 	if (sc->hw_if->speaker_ctl &&
1078 	    (!sc->sc_full_duplex || (sc->sc_mode & AUMODE_PLAY) == 0))
1079 		sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_OFF);
1080 	splx(s);
1081 }
1082 
1083 /*
1084  * Must be called from task context.
1085  */
1086 void
1087 audio_init_play(struct audio_softc *sc)
1088 {
1089 	int s = splaudio();
1090 
1091 	sc->sc_wstamp = sc->sc_pr.stamp;
1092 	if (sc->hw_if->speaker_ctl)
1093 		sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_ON);
1094 	splx(s);
1095 }
1096 
1097 int
1098 audio_drain(struct audio_softc *sc)
1099 {
1100 	int error, drops;
1101 	struct audio_ringbuffer *cb = &sc->sc_pr;
1102 	int s;
1103 
1104 	DPRINTF(("audio_drain: enter busy=%d used=%d\n",
1105 	    sc->sc_pbus, sc->sc_pr.used));
1106 	if (sc->sc_pr.mmapped || sc->sc_pr.used <= 0)
1107 		return 0;
1108 	if (!sc->sc_pbus) {
1109 		/* We've never started playing, probably because the
1110 		 * block was too short.  Pad it and start now.
1111 		 */
1112 		int cc;
1113 		u_char *inp = cb->inp;
1114 
1115 		cc = cb->blksize - (inp - cb->start) % cb->blksize;
1116 		if (sc->sc_pparams.sw_code) {
1117 			int ncc = cc / sc->sc_pparams.factor;
1118 			audio_fill_silence(&sc->sc_pparams, cb->start, inp, ncc);
1119 			sc->sc_pparams.sw_code(sc->hw_hdl, inp, ncc);
1120 		} else
1121 			audio_fill_silence(&sc->sc_pparams, cb->start, inp, cc);
1122 		inp += cc;
1123 		if (inp >= cb->end)
1124 			inp = cb->start;
1125 		s = splaudio();
1126 		cb->used += cc;
1127 		cb->inp = inp;
1128 		error = audiostartp(sc);
1129 		splx(s);
1130 		if (error)
1131 			return error;
1132 	}
1133 	/*
1134 	 * Play until a silence block has been played, then we
1135 	 * know all has been drained.
1136 	 * XXX This should be done some other way to avoid
1137 	 * playing silence.
1138 	 */
1139 	drops = cb->drops;
1140 	error = 0;
1141 	s = splaudio();
1142 	while (cb->drops == drops && !error) {
1143 		DPRINTF(("audio_drain: used=%d, drops=%ld\n", sc->sc_pr.used, cb->drops));
1144 		/*
1145 		 * When the process is exiting, it ignores all signals and
1146 		 * we can't interrupt this sleep, so we set a timeout just in case.
1147 		 */
1148 		error = audio_sleep_timo(&sc->sc_wchan, "aud_dr", 30*hz);
1149 		if (sc->sc_dying)
1150 			error = EIO;
1151 	}
1152 	splx(s);
1153 	return error;
1154 }
1155 
1156 /*
1157  * Close an audio chip.
1158  */
1159 /* ARGSUSED */
1160 int
1161 audio_close(dev_t dev, int flags, int ifmt, struct proc *p)
1162 {
1163 	int unit = AUDIOUNIT(dev);
1164 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1165 	struct audio_hw_if *hw = sc->hw_if;
1166 	int s;
1167 
1168 	DPRINTF(("audio_close: unit=%d flags=0x%x\n", unit, flags));
1169 
1170 	s = splaudio();
1171 	/* Stop recording. */
1172 	if ((flags & FREAD) && sc->sc_rbus) {
1173 		/*
1174 		 * XXX Some drivers (e.g. SB) use the same routine
1175 		 * to halt input and output so don't halt input if
1176 		 * in full duplex mode.  These drivers should be fixed.
1177 		 */
1178 		if (!sc->sc_full_duplex || sc->hw_if->halt_input != sc->hw_if->halt_output)
1179 			sc->hw_if->halt_input(sc->hw_hdl);
1180 		sc->sc_rbus = 0;
1181 	}
1182 	/*
1183 	 * Block until output drains, but allow ^C interrupt.
1184 	 */
1185 	sc->sc_pr.usedlow = sc->sc_pr.blksize;	/* avoid excessive wakeups */
1186 	/*
1187 	 * If there is pending output, let it drain (unless
1188 	 * the output is paused).
1189 	 */
1190 	if ((flags & FWRITE) && sc->sc_pbus) {
1191 		if (!sc->sc_pr.pause && !audio_drain(sc) && hw->drain)
1192 			(void)hw->drain(sc->hw_hdl);
1193 		sc->hw_if->halt_output(sc->hw_hdl);
1194 		sc->sc_pbus = 0;
1195 	}
1196 
1197 	hw->close(sc->hw_hdl);
1198 
1199 	/*
1200 	 * If flags has neither read nor write then reset both
1201 	 * directions. Encountered when someone runs revoke(2).
1202 	 */
1203 
1204 	if ((flags & FREAD) || ((flags & (FREAD|FWRITE)) == 0)) {
1205 		sc->sc_open &= ~AUOPEN_READ;
1206 		sc->sc_mode &= ~AUMODE_RECORD;
1207 	}
1208 	if ((flags & FWRITE) || ((flags & (FREAD|FWRITE)) == 0)) {
1209 		sc->sc_open &= ~AUOPEN_WRITE;
1210 		sc->sc_mode &= ~(AUMODE_PLAY|AUMODE_PLAY_ALL);
1211 	}
1212 
1213 	sc->sc_async_audio = 0;
1214 	sc->sc_full_duplex = 0;
1215 	splx(s);
1216 	DPRINTF(("audio_close: done\n"));
1217 
1218 	return (0);
1219 }
1220 
1221 int
1222 audio_read(dev_t dev, struct uio *uio, int ioflag)
1223 {
1224 	int unit = AUDIOUNIT(dev);
1225 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1226 	struct audio_ringbuffer *cb = &sc->sc_rr;
1227 	u_char *outp;
1228 	int error, s, cc, n, resid;
1229 
1230 	if (cb->mmapped)
1231 		return EINVAL;
1232 
1233 	DPRINTFN(1,("audio_read: cc=%d mode=%d\n",
1234 	    uio->uio_resid, sc->sc_mode));
1235 
1236 	error = 0;
1237 	/*
1238 	 * If hardware is half-duplex and currently playing, return
1239 	 * silence blocks based on the number of blocks we have output.
1240 	 */
1241 	if (!sc->sc_full_duplex &&
1242 	    (sc->sc_mode & AUMODE_PLAY)) {
1243 		while (uio->uio_resid > 0 && !error) {
1244 			s = splaudio();
1245 			for(;;) {
1246 				cc = sc->sc_pr.stamp - sc->sc_wstamp;
1247 				if (cc > 0)
1248 					break;
1249 				DPRINTF(("audio_read: stamp=%lu, wstamp=%lu\n",
1250 					 sc->sc_pr.stamp, sc->sc_wstamp));
1251 				if (ioflag & IO_NDELAY) {
1252 					splx(s);
1253 					return EWOULDBLOCK;
1254 				}
1255 				error = audio_sleep(&sc->sc_rchan, "aud_hr");
1256 				if (sc->sc_dying)
1257 					error = EIO;
1258 				if (error) {
1259 					splx(s);
1260 					return error;
1261 				}
1262 			}
1263 			splx(s);
1264 
1265 			if (uio->uio_resid < cc / sc->sc_rparams.factor)
1266 				cc = uio->uio_resid * sc->sc_rparams.factor;
1267 			DPRINTFN(1, ("audio_read: reading in write mode, cc=%d\n", cc));
1268 			error = audio_silence_copyout(sc,
1269 			    cc / sc->sc_rparams.factor, uio);
1270 			sc->sc_wstamp += cc;
1271 		}
1272 		return (error);
1273 	}
1274 	while (uio->uio_resid > 0) {
1275 		s = splaudio();
1276 		while (cb->used <= 0) {
1277 			if (!sc->sc_rbus && !sc->sc_rr.pause) {
1278 				error = audiostartr(sc);
1279 				if (error) {
1280 					splx(s);
1281 					return error;
1282 				}
1283 			}
1284 			if (ioflag & IO_NDELAY) {
1285 				splx(s);
1286 				return (EWOULDBLOCK);
1287 			}
1288 			DPRINTFN(2, ("audio_read: sleep used=%d\n", cb->used));
1289 			error = audio_sleep(&sc->sc_rchan, "aud_rd");
1290 			if (sc->sc_dying)
1291 				error = EIO;
1292 			if (error) {
1293 				splx(s);
1294 				return error;
1295 			}
1296 		}
1297 		resid = uio->uio_resid * sc->sc_rparams.factor;
1298 		outp = cb->outp;
1299 		cc = cb->used - cb->usedlow; /* maximum to read */
1300 		n = cb->end - outp;
1301 		if (cc > n)
1302 			cc = n;		/* don't read beyond end of buffer */
1303 
1304 		if (cc > resid)
1305 			cc = resid;	/* and no more than we want */
1306 		cb->used -= cc;
1307 		cb->outp += cc;
1308 		if (cb->outp >= cb->end)
1309 			cb->outp = cb->start;
1310 		splx(s);
1311 		DPRINTFN(1,("audio_read: outp=%p, cc=%d\n", outp, cc));
1312 		if (sc->sc_rparams.sw_code)
1313 			sc->sc_rparams.sw_code(sc->hw_hdl, outp, cc);
1314 		error = uiomove(outp, cc / sc->sc_rparams.factor, uio);
1315 		if (error)
1316 			return error;
1317 	}
1318 	return 0;
1319 }
1320 
1321 void
1322 audio_clear(struct audio_softc *sc)
1323 {
1324 	int s = splaudio();
1325 
1326 	if (sc->sc_rbus) {
1327 		audio_wakeup(&sc->sc_rchan);
1328 		sc->hw_if->halt_input(sc->hw_hdl);
1329 		sc->sc_rbus = 0;
1330 	}
1331 	if (sc->sc_pbus) {
1332 		audio_wakeup(&sc->sc_wchan);
1333 		sc->hw_if->halt_output(sc->hw_hdl);
1334 		sc->sc_pbus = 0;
1335 	}
1336 	splx(s);
1337 }
1338 
1339 void
1340 audio_set_blksize(struct audio_softc *sc, int mode, int fpb) {
1341 	struct audio_hw_if *hw = sc->hw_if;
1342 	struct audio_params *parm;
1343 	struct audio_ringbuffer *rb;
1344 	int bs, fs, maxbs;
1345 
1346 	if (mode == AUMODE_PLAY) {
1347 		parm = &sc->sc_pparams;
1348 		rb = &sc->sc_pr;
1349 	} else {
1350 		parm = &sc->sc_rparams;
1351 		rb = &sc->sc_rr;
1352 	}
1353 
1354 	fs = parm->channels * AUDIO_BPS(parm->precision);
1355 	bs = fpb * fs;
1356 	maxbs = rb->bufsize / 2;
1357 	if (bs > maxbs)
1358 		bs = (maxbs / fs) * fs;
1359 
1360 	ROUNDSIZE(bs);
1361 	if (hw->round_blocksize)
1362 		bs = hw->round_blocksize(sc->hw_hdl, bs);
1363 	rb->blksize = bs;
1364 
1365 	DPRINTF(("audio_set_blksize: %s blksize=%d\n",
1366 		 mode == AUMODE_PLAY ? "play" : "record", bs));
1367 }
1368 
1369 void
1370 audio_calc_blksize(struct audio_softc *sc, int mode)
1371 {
1372 	struct audio_params *param;
1373 
1374 	if (mode == AUMODE_PLAY) {
1375 		if (sc->sc_pr.blkset)
1376 			return;
1377 		param = &sc->sc_pparams;
1378 	} else {
1379 		if (sc->sc_rr.blkset)
1380 			return;
1381 		param = &sc->sc_rparams;
1382 	}
1383 	audio_set_blksize(sc, mode, param->sample_rate * audio_blk_ms / 1000);
1384 }
1385 
1386 void
1387 audio_fill_silence(struct audio_params *params, u_char *start, u_char *p, int n)
1388 {
1389 	size_t rounderr;
1390 	int i, samplesz, nsamples;
1391 	u_char auzero[4] = {0, 0, 0, 0};
1392 
1393 	/*
1394 	 * p may point the middle of a sample; round it to the
1395 	 * beginning of the sample, so we overwrite partially written
1396 	 * ones.
1397 	 */
1398 	samplesz = AUDIO_BPS(params->precision);
1399 	rounderr = (p - start) % samplesz;
1400 	p -= rounderr;
1401 	n += rounderr;
1402 	nsamples = n / samplesz;
1403 
1404 	switch (params->encoding) {
1405 	case AUDIO_ENCODING_SLINEAR_LE:
1406 	case AUDIO_ENCODING_SLINEAR_BE:
1407 		break;
1408 	case AUDIO_ENCODING_ULAW:
1409 		auzero[0] = 0x7f;
1410 		break;
1411 	case AUDIO_ENCODING_ALAW:
1412 		auzero[0] = 0x55;
1413 		break;
1414 	case AUDIO_ENCODING_ULINEAR_LE:
1415 		auzero[samplesz - 1] = 0x80;
1416 		break;
1417 	case AUDIO_ENCODING_ULINEAR_BE:
1418 		auzero[0] = 0x80;
1419 		break;
1420 	case AUDIO_ENCODING_MPEG_L1_STREAM:
1421 	case AUDIO_ENCODING_MPEG_L1_PACKETS:
1422 	case AUDIO_ENCODING_MPEG_L1_SYSTEM:
1423 	case AUDIO_ENCODING_MPEG_L2_STREAM:
1424 	case AUDIO_ENCODING_MPEG_L2_PACKETS:
1425 	case AUDIO_ENCODING_MPEG_L2_SYSTEM:
1426 	case AUDIO_ENCODING_ADPCM: /* is this right XXX */
1427 		break;
1428 	default:
1429 		DPRINTF(("audio: bad encoding %d\n", params->encoding));
1430 		break;
1431 	}
1432 	while (--nsamples >= 0) {
1433 		for (i = 0; i < samplesz; i++)
1434 			*p++ = auzero[i];
1435 	}
1436 }
1437 
1438 int
1439 audio_silence_copyout(struct audio_softc *sc, int n, struct uio *uio)
1440 {
1441 	int error;
1442 	int k;
1443 	u_char zerobuf[128];
1444 
1445 	audio_fill_silence(&sc->sc_rparams, zerobuf, zerobuf, sizeof zerobuf);
1446 
1447 	error = 0;
1448 	while (n > 0 && uio->uio_resid > 0 && !error) {
1449 		k = min(n, min(uio->uio_resid, sizeof zerobuf));
1450 		error = uiomove(zerobuf, k, uio);
1451 		n -= k;
1452 	}
1453 	return (error);
1454 }
1455 
1456 int
1457 audio_write(dev_t dev, struct uio *uio, int ioflag)
1458 {
1459 	int unit = AUDIOUNIT(dev);
1460 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1461 	struct audio_ringbuffer *cb = &sc->sc_pr;
1462 	u_char *inp;
1463 	int error, s, n, cc, resid, avail;
1464 
1465 	DPRINTFN(2, ("audio_write: sc=%p(unit=%d) count=%d used=%d(hi=%d)\n", sc, unit,
1466 		 uio->uio_resid, sc->sc_pr.used, sc->sc_pr.usedhigh));
1467 
1468 	if (cb->mmapped)
1469 		return EINVAL;
1470 
1471 	if (uio->uio_resid == 0) {
1472 		sc->sc_eof++;
1473 		return 0;
1474 	}
1475 
1476 	/*
1477 	 * If half-duplex and currently recording, throw away data.
1478 	 */
1479 	if (!sc->sc_full_duplex &&
1480 	    (sc->sc_mode & AUMODE_RECORD)) {
1481 		uio->uio_offset += uio->uio_resid;
1482 		uio->uio_resid = 0;
1483 		DPRINTF(("audio_write: half-dpx read busy\n"));
1484 		return (0);
1485 	}
1486 
1487 	if (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) {
1488 		n = min(sc->sc_playdrop, uio->uio_resid * sc->sc_pparams.factor);
1489 		DPRINTF(("audio_write: playdrop %d\n", n));
1490 		uio->uio_offset += n / sc->sc_pparams.factor;
1491 		uio->uio_resid -= n / sc->sc_pparams.factor;
1492 		sc->sc_playdrop -= n;
1493 		if (uio->uio_resid == 0)
1494 			return 0;
1495 	}
1496 
1497 	DPRINTFN(1, ("audio_write: sr=%ld, enc=%d, prec=%d, chan=%d, sw=%p, fact=%d\n",
1498 	    sc->sc_pparams.sample_rate, sc->sc_pparams.encoding,
1499 	    sc->sc_pparams.precision, sc->sc_pparams.channels,
1500 	    sc->sc_pparams.sw_code, sc->sc_pparams.factor));
1501 
1502 	while (uio->uio_resid > 0) {
1503 		s = splaudio();
1504 		while (cb->used >= cb->usedhigh) {
1505 			DPRINTFN(2, ("audio_write: sleep used=%d lowat=%d hiwat=%d\n",
1506 				 cb->used, cb->usedlow, cb->usedhigh));
1507 			if (ioflag & IO_NDELAY) {
1508 				splx(s);
1509 				return (EWOULDBLOCK);
1510 			}
1511 			error = audio_sleep(&sc->sc_wchan, "aud_wr");
1512 			if (sc->sc_dying)
1513 				error = EIO;
1514 			if (error) {
1515 				splx(s);
1516 				return error;
1517 			}
1518 		}
1519 		resid = uio->uio_resid * sc->sc_pparams.factor;
1520 		avail = cb->end - cb->inp;
1521 		inp = cb->inp;
1522 		cc = cb->usedhigh - cb->used;
1523 		if (cc > resid)
1524 			cc = resid;
1525 		if (cc > avail)
1526 			cc = avail;
1527 		cb->inp += cc;
1528 		if (cb->inp >= cb->end)
1529 			cb->inp = cb->start;
1530 		cb->used += cc;
1531 		/*
1532 		 * This is a very suboptimal way of keeping track of
1533 		 * silence in the buffer, but it is simple.
1534 		 */
1535 		sc->sc_sil_count = 0;
1536 		if (!sc->sc_pbus && !cb->pause && cb->used >= cb->blksize) {
1537 			error = audiostartp(sc);
1538 			if (error) {
1539 				splx(s);
1540 				return error;
1541 			}
1542 		}
1543 		splx(s);
1544 		cc /= sc->sc_pparams.factor;
1545 		DPRINTFN(1, ("audio_write: uiomove cc=%d inp=%p, left=%d\n",
1546 		    cc, inp, uio->uio_resid));
1547 		error = uiomove(inp, cc, uio);
1548 		if (error)
1549 			return 0;
1550 		if (sc->sc_pparams.sw_code) {
1551 			sc->sc_pparams.sw_code(sc->hw_hdl, inp, cc);
1552 			DPRINTFN(1, ("audio_write: expanded cc=%d\n", cc));
1553 		}
1554 	}
1555 	return 0;
1556 }
1557 
1558 int
1559 audio_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
1560 {
1561 	int unit = AUDIOUNIT(dev);
1562 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1563 	struct audio_hw_if *hw = sc->hw_if;
1564 	struct audio_offset *ao;
1565 	struct audio_info ai;
1566 	int error = 0, s, offs, fd;
1567 	int rbus, pbus;
1568 
1569 	DPRINTF(("audio_ioctl(%d,'%c',%d)\n",
1570 	    IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff));
1571 	switch (cmd) {
1572 	case FIONBIO:
1573 		/* All handled in the upper FS layer. */
1574 		break;
1575 
1576 	case FIOASYNC:
1577 		if (*(int *)addr) {
1578 			if (sc->sc_async_audio)
1579 				return (EBUSY);
1580 			sc->sc_async_audio = p;
1581 			DPRINTF(("audio_ioctl: FIOASYNC %p\n", p));
1582 		} else
1583 			sc->sc_async_audio = 0;
1584 		break;
1585 
1586 	case AUDIO_FLUSH:
1587 		DPRINTF(("AUDIO_FLUSH\n"));
1588 		rbus = sc->sc_rbus;
1589 		pbus = sc->sc_pbus;
1590 		audio_clear(sc);
1591 		s = splaudio();
1592 		error = audio_initbufs(sc);
1593 		if (error) {
1594 			splx(s);
1595 			return error;
1596 		}
1597 		sc->sc_rr.pause = 0;
1598 		sc->sc_pr.pause = 0;
1599 		if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_pbus && pbus)
1600 			error = audiostartp(sc);
1601 		if (!error &&
1602 		    (sc->sc_mode & AUMODE_RECORD) && !sc->sc_rbus && rbus)
1603 			error = audiostartr(sc);
1604 		splx(s);
1605 		break;
1606 
1607 	/*
1608 	 * Number of read (write) samples dropped.  We don't know where or
1609 	 * when they were dropped.
1610 	 *
1611 	 * The audio_ringbuffer->drops count is the number of buffer
1612 	 * sample size bytes.  Convert it to userland sample size bytes,
1613 	 * then convert to samples.  There is no easy way to get the
1614 	 * buffer sample size, but the userland sample size can be
1615 	 * calculated with userland channels and userland precision.
1616 	 *
1617 	 * original formula:
1618 	 *  sc->sc_rr.drops /
1619 	 *  sc->sc_rparams.factor /
1620 	 *  (sc->sc_rparams.channels * AUDIO_BPS(sc->sc_rparams.precision))
1621 	 */
1622 	case AUDIO_RERROR:
1623 		*(int *)addr = sc->sc_rr.drops /
1624 		    (sc->sc_rparams.factor * sc->sc_rparams.channels *
1625 		    AUDIO_BPS(sc->sc_rparams.precision));
1626 		break;
1627 
1628 	case AUDIO_PERROR:
1629 		*(int *)addr = sc->sc_pr.drops /
1630 		    (sc->sc_pparams.factor * sc->sc_pparams.channels *
1631 		    AUDIO_BPS(sc->sc_pparams.precision));
1632 		break;
1633 
1634 	/*
1635 	 * Offsets into buffer.
1636 	 */
1637 	case AUDIO_GETIOFFS:
1638 		s = splaudio();
1639 		/* figure out where next DMA will start */
1640 		ao = (struct audio_offset *)addr;
1641 		ao->samples = sc->sc_rr.stamp / sc->sc_rparams.factor;
1642 		ao->deltablks = (sc->sc_rr.stamp - sc->sc_rr.stamp_last) / sc->sc_rr.blksize;
1643 		sc->sc_rr.stamp_last = sc->sc_rr.stamp;
1644 		ao->offset = (sc->sc_rr.inp - sc->sc_rr.start) / sc->sc_rparams.factor;
1645 		splx(s);
1646 		break;
1647 
1648 	case AUDIO_GETOOFFS:
1649 		s = splaudio();
1650 		/* figure out where next DMA will start */
1651 		ao = (struct audio_offset *)addr;
1652 		offs = sc->sc_pr.outp - sc->sc_pr.start + sc->sc_pr.blksize;
1653 		if (sc->sc_pr.start + offs >= sc->sc_pr.end)
1654 			offs = 0;
1655 		ao->samples = sc->sc_pr.stamp / sc->sc_pparams.factor;
1656 		ao->deltablks = (sc->sc_pr.stamp - sc->sc_pr.stamp_last) / sc->sc_pr.blksize;
1657 		sc->sc_pr.stamp_last = sc->sc_pr.stamp;
1658 		ao->offset = offs / sc->sc_pparams.factor;
1659 		splx(s);
1660 		break;
1661 
1662 	/*
1663 	 * How many bytes will elapse until mike hears the first
1664 	 * sample of what we write next?
1665 	 */
1666 	case AUDIO_WSEEK:
1667 		*(u_long *)addr = sc->sc_pr.used / sc->sc_pparams.factor;
1668 		break;
1669 
1670 	case AUDIO_SETINFO:
1671 		DPRINTF(("AUDIO_SETINFO mode=0x%x\n", sc->sc_mode));
1672 		error = audiosetinfo(sc, (struct audio_info *)addr);
1673 		break;
1674 
1675 	case AUDIO_GETINFO:
1676 		DPRINTF(("AUDIO_GETINFO\n"));
1677 		error = audiogetinfo(sc, (struct audio_info *)addr);
1678 		break;
1679 
1680 	case AUDIO_DRAIN:
1681 		DPRINTF(("AUDIO_DRAIN\n"));
1682 		error = audio_drain(sc);
1683 		if (!error && hw->drain)
1684 		    error = hw->drain(sc->hw_hdl);
1685 		break;
1686 
1687 	case AUDIO_GETDEV:
1688 		DPRINTF(("AUDIO_GETDEV\n"));
1689 		error = hw->getdev(sc->hw_hdl, (audio_device_t *)addr);
1690 		break;
1691 
1692 	case AUDIO_GETENC:
1693 		DPRINTF(("AUDIO_GETENC\n"));
1694 		/* Pass read/write info down to query_encoding */
1695 		((struct audio_encoding *)addr)->flags = sc->sc_open;
1696 		error = hw->query_encoding(sc->hw_hdl, (struct audio_encoding *)addr);
1697 		break;
1698 
1699 	case AUDIO_GETFD:
1700 		DPRINTF(("AUDIO_GETFD\n"));
1701 		*(int *)addr = sc->sc_full_duplex;
1702 		break;
1703 
1704 	case AUDIO_SETFD:
1705 		DPRINTF(("AUDIO_SETFD\n"));
1706 		fd = *(int *)addr;
1707 		if (hw->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX) {
1708 			if (hw->setfd)
1709 				error = hw->setfd(sc->hw_hdl, fd);
1710 			else
1711 				error = 0;
1712 			if (!error) {
1713 				sc->sc_full_duplex = fd;
1714 				if (fd) {
1715 					AUDIO_INITINFO(&ai);
1716 					ai.mode = sc->sc_mode |
1717 					    (AUMODE_PLAY | AUMODE_RECORD);
1718 					error = audiosetinfo(sc, &ai);
1719 				}
1720 			}
1721 		} else {
1722 			if (fd)
1723 				error = ENOTTY;
1724 			else
1725 				error = 0;
1726 		}
1727 		break;
1728 
1729 	case AUDIO_GETPROPS:
1730 		DPRINTF(("AUDIO_GETPROPS\n"));
1731 		*(int *)addr = hw->get_props(sc->hw_hdl);
1732 		break;
1733 
1734 	case AUDIO_GETPRINFO:
1735 		DPRINTF(("AUDIO_GETPRINFO\n"));
1736 		error = audiogetbufinfo(sc, (struct audio_bufinfo *)addr,
1737 		    AUMODE_PLAY);
1738 		break;
1739 
1740 	case AUDIO_GETRRINFO:
1741 		DPRINTF(("AUDIO_GETRRINFO\n"));
1742 		error = audiogetbufinfo(sc, (struct audio_bufinfo *)addr,
1743 		    AUMODE_RECORD);
1744 		break;
1745 
1746 	default:
1747 		DPRINTF(("audio_ioctl: unknown ioctl\n"));
1748 		error = ENOTTY;
1749 		break;
1750 	}
1751 	DPRINTF(("audio_ioctl(%d,'%c',%d) result %d\n",
1752 	    IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff, error));
1753 	return (error);
1754 }
1755 
1756 void
1757 audio_selwakeup(struct audio_softc *sc, int play)
1758 {
1759 	struct selinfo *si;
1760 
1761 	si = play? &sc->sc_wsel : &sc->sc_rsel;
1762 
1763 	audio_wakeup(play? &sc->sc_wchan : &sc->sc_rchan);
1764 	selwakeup(si);
1765 	if (sc->sc_async_audio)
1766 		psignal(sc->sc_async_audio, SIGIO);
1767 	KNOTE(&si->si_note, 0);
1768 }
1769 
1770 #define	AUDIO_FILTREAD(sc) ( \
1771     (!sc->sc_full_duplex && (sc->sc_mode & AUMODE_PLAY)) ? \
1772     sc->sc_pr.stamp > sc->sc_wstamp : sc->sc_rr.used > sc->sc_rr.usedlow)
1773 
1774 #define	AUDIO_FILTWRITE(sc) ( \
1775     (!sc->sc_full_duplex && (sc->sc_mode & AUMODE_RECORD)) ||		\
1776     (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) || 	\
1777     (sc->sc_pr.used < (sc->sc_pr.usedlow + sc->sc_pr.blksize)))
1778 
1779 int
1780 audio_poll(dev_t dev, int events, struct proc *p)
1781 {
1782 	int unit = AUDIOUNIT(dev);
1783 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1784 	int revents = 0, s = splaudio();
1785 
1786 	DPRINTF(("audio_poll: events=0x%x mode=%d\n", events, sc->sc_mode));
1787 
1788 	if (events & (POLLIN | POLLRDNORM)) {
1789 		if (AUDIO_FILTREAD(sc))
1790 			revents |= events & (POLLIN | POLLRDNORM);
1791 	}
1792 	if (events & (POLLOUT | POLLWRNORM)) {
1793 		if (AUDIO_FILTWRITE(sc))
1794 			revents |= events & (POLLOUT | POLLWRNORM);
1795 	}
1796 	if (revents == 0) {
1797 		if (events & (POLLIN | POLLRDNORM))
1798 			selrecord(p, &sc->sc_rsel);
1799 		if (events & (POLLOUT | POLLWRNORM))
1800 			selrecord(p, &sc->sc_wsel);
1801 	}
1802 	splx(s);
1803 	return (revents);
1804 }
1805 
1806 paddr_t
1807 audio_mmap(dev_t dev, off_t off, int prot)
1808 {
1809 	int s;
1810 	int unit = AUDIOUNIT(dev);
1811 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1812 	struct audio_hw_if *hw = sc->hw_if;
1813 	struct audio_ringbuffer *cb;
1814 
1815 	DPRINTF(("audio_mmap: off=%d, prot=%d\n", off, prot));
1816 
1817 	if (!(hw->get_props(sc->hw_hdl) & AUDIO_PROP_MMAP) || !hw->mappage)
1818 		return -1;
1819 #if 0
1820 /* XXX
1821  * The idea here was to use the protection to determine if
1822  * we are mapping the read or write buffer, but it fails.
1823  * The VM system is broken in (at least) two ways.
1824  * 1) If you map memory VM_PROT_WRITE you SIGSEGV
1825  *    when writing to it, so VM_PROT_READ|VM_PROT_WRITE
1826  *    has to be used for mmapping the play buffer.
1827  * 2) Even if calling mmap() with VM_PROT_READ|VM_PROT_WRITE
1828  *    audio_mmap will get called at some point with VM_PROT_READ
1829  *    only.
1830  * So, alas, we always map the play buffer for now.
1831  */
1832 	if (prot == (VM_PROT_READ|VM_PROT_WRITE) ||
1833 	    prot == VM_PROT_WRITE)
1834 		cb = &sc->sc_pr;
1835 	else if (prot == VM_PROT_READ)
1836 		cb = &sc->sc_rr;
1837 	else
1838 		return -1;
1839 #else
1840 	cb = &sc->sc_pr;
1841 #endif
1842 
1843 	if ((u_int)off >= cb->bufsize)
1844 		return -1;
1845 	if (!cb->mmapped) {
1846 		cb->mmapped = 1;
1847 		if (cb == &sc->sc_pr) {
1848 			audio_fill_silence(&sc->sc_pparams, cb->start, cb->start, cb->bufsize);
1849 			s = splaudio();
1850 			if (!sc->sc_pbus && !sc->sc_pr.pause)
1851 				(void)audiostartp(sc);
1852 			splx(s);
1853 		} else {
1854 			s = splaudio();
1855 			if (!sc->sc_rbus && !sc->sc_rr.pause)
1856 				(void)audiostartr(sc);
1857 			splx(s);
1858 		}
1859 	}
1860 
1861 	return hw->mappage(sc->hw_hdl, cb->start, off, prot);
1862 }
1863 
1864 int
1865 audiostartr(struct audio_softc *sc)
1866 {
1867 	int error;
1868 
1869 	DPRINTF(("audiostartr: start=%p used=%d(hi=%d) mmapped=%d\n",
1870 		 sc->sc_rr.start, sc->sc_rr.used, sc->sc_rr.usedhigh,
1871 		 sc->sc_rr.mmapped));
1872 
1873 	if (sc->hw_if->trigger_input)
1874 		error = sc->hw_if->trigger_input(sc->hw_hdl, sc->sc_rr.start,
1875 		    sc->sc_rr.end, sc->sc_rr.blksize,
1876 		    audio_rint, (void *)sc, &sc->sc_rparams);
1877 	else
1878 		error = sc->hw_if->start_input(sc->hw_hdl, sc->sc_rr.start,
1879 		    sc->sc_rr.blksize, audio_rint, (void *)sc);
1880 	if (error) {
1881 		DPRINTF(("audiostartr failed: %d\n", error));
1882 		return error;
1883 	}
1884 	sc->sc_rbus = 1;
1885 	return 0;
1886 }
1887 
1888 int
1889 audiostartp(struct audio_softc *sc)
1890 {
1891 	int error;
1892 
1893 	DPRINTF(("audiostartp: start=%p used=%d(hi=%d) mmapped=%d\n",
1894 		 sc->sc_pr.start, sc->sc_pr.used, sc->sc_pr.usedhigh,
1895 		 sc->sc_pr.mmapped));
1896 
1897 	if (!sc->sc_pr.mmapped && sc->sc_pr.used < sc->sc_pr.blksize)
1898 		return 0;
1899 
1900 	if (sc->hw_if->trigger_output)
1901 		error = sc->hw_if->trigger_output(sc->hw_hdl, sc->sc_pr.start,
1902 		    sc->sc_pr.end, sc->sc_pr.blksize,
1903 		    audio_pint, (void *)sc, &sc->sc_pparams);
1904 	else
1905 		error = sc->hw_if->start_output(sc->hw_hdl, sc->sc_pr.outp,
1906 		    sc->sc_pr.blksize, audio_pint, (void *)sc);
1907 	if (error) {
1908 		DPRINTF(("audiostartp failed: %d\n", error));
1909 		return error;
1910 	}
1911 	sc->sc_pbus = 1;
1912 	return 0;
1913 }
1914 
1915 /*
1916  * When the play interrupt routine finds that the write isn't keeping
1917  * the buffer filled it will insert silence in the buffer to make up
1918  * for this.  The part of the buffer that is filled with silence
1919  * is kept track of in a very approximate way: it starts at sc_sil_start
1920  * and extends sc_sil_count bytes.  If there is already silence in
1921  * the requested area nothing is done; so when the whole buffer is
1922  * silent nothing happens.  When the writer starts again sc_sil_count
1923  * is set to 0.
1924  */
1925 /* XXX
1926  * Putting silence into the output buffer should not really be done
1927  * at splaudio, but there is no softaudio level to do it at yet.
1928  */
1929 static __inline void
1930 audio_pint_silence(struct audio_softc *sc, struct audio_ringbuffer *cb,
1931     u_char *inp, int cc)
1932 {
1933 	u_char *s, *e, *p, *q;
1934 
1935 	if (sc->sc_sil_count > 0) {
1936 		s = sc->sc_sil_start; /* start of silence */
1937 		e = s + sc->sc_sil_count; /* end of silence, may be beyond end */
1938 		p = inp;	/* adjusted pointer to area to fill */
1939 		if (p < s)
1940 			p += cb->end - cb->start;
1941 		q = p+cc;
1942 		/* Check if there is already silence. */
1943 		if (!(s <= p && p <  e &&
1944 		      s <= q && q <= e)) {
1945 			if (s <= p)
1946 				sc->sc_sil_count = max(sc->sc_sil_count, q-s);
1947 			DPRINTFN(5, ("audio_pint_silence: fill cc=%d inp=%p, count=%d size=%d\n",
1948 			    cc, inp, sc->sc_sil_count, (int)(cb->end - cb->start)));
1949 
1950 			if (sc->sc_pparams.sw_code) {
1951 				int ncc = cc / sc->sc_pparams.factor;
1952 				audio_fill_silence(&sc->sc_pparams, cb->start, inp, ncc);
1953 				sc->sc_pparams.sw_code(sc->hw_hdl, inp, ncc);
1954 			} else
1955 				audio_fill_silence(&sc->sc_pparams, cb->start, inp, cc);
1956 
1957 		} else {
1958 			DPRINTFN(5, ("audio_pint_silence: already silent cc=%d inp=%p\n", cc, inp));
1959 
1960 		}
1961 	} else {
1962 		sc->sc_sil_start = inp;
1963 		sc->sc_sil_count = cc;
1964 		DPRINTFN(5, ("audio_pint_silence: start fill %p %d\n",
1965 		    inp, cc));
1966 
1967 		if (sc->sc_pparams.sw_code) {
1968 			int ncc = cc / sc->sc_pparams.factor;
1969 			audio_fill_silence(&sc->sc_pparams, cb->start, inp, ncc);
1970 			sc->sc_pparams.sw_code(sc->hw_hdl, inp, ncc);
1971 		} else
1972 			audio_fill_silence(&sc->sc_pparams, cb->start, inp, cc);
1973 
1974 	}
1975 }
1976 
1977 /*
1978  * Called from HW driver module on completion of dma output.
1979  * Start output of new block, wrap in ring buffer if needed.
1980  * If no more buffers to play, output zero instead.
1981  * Do a wakeup if necessary.
1982  */
1983 void
1984 audio_pint(void *v)
1985 {
1986 	struct audio_softc *sc = v;
1987 	struct audio_hw_if *hw = sc->hw_if;
1988 	struct audio_ringbuffer *cb = &sc->sc_pr;
1989 	u_char *inp;
1990 	int cc;
1991 	int blksize;
1992 	int error;
1993 
1994 	if (!sc->sc_open)
1995 		return;		/* ignore interrupt if not open */
1996 
1997 	blksize = cb->blksize;
1998 
1999 	add_audio_randomness((long)cb);
2000 
2001 	cb->outp += blksize;
2002 	if (cb->outp >= cb->end)
2003 		cb->outp = cb->start;
2004 	cb->stamp += blksize;
2005 	if (cb->mmapped) {
2006 		DPRINTFN(5, ("audio_pint: mmapped outp=%p cc=%d inp=%p\n",
2007 		    cb->outp, blksize, cb->inp));
2008 		if (!hw->trigger_output)
2009 			(void)hw->start_output(sc->hw_hdl, cb->outp,
2010 			    blksize, audio_pint, (void *)sc);
2011 		return;
2012 	}
2013 
2014 #ifdef AUDIO_INTR_TIME
2015 	{
2016 		struct timeval tv;
2017 		u_long t;
2018 		microtime(&tv);
2019 		t = tv.tv_usec + 1000000 * tv.tv_sec;
2020 		if (sc->sc_pnintr) {
2021 			long lastdelta, totdelta;
2022 			lastdelta = t - sc->sc_plastintr - sc->sc_pblktime;
2023 			if (lastdelta > sc->sc_pblktime / 3) {
2024 				printf("audio: play interrupt(%d) off relative by %ld us (%lu)\n",
2025 				    sc->sc_pnintr, lastdelta, sc->sc_pblktime);
2026 			}
2027 			totdelta = t - sc->sc_pfirstintr - sc->sc_pblktime * sc->sc_pnintr;
2028 			if (totdelta > sc->sc_pblktime) {
2029 				printf("audio: play interrupt(%d) off absolute by %ld us (%lu) (LOST)\n",
2030 				    sc->sc_pnintr, totdelta, sc->sc_pblktime);
2031 				sc->sc_pnintr++; /* avoid repeated messages */
2032 			}
2033 		} else
2034 			sc->sc_pfirstintr = t;
2035 		sc->sc_plastintr = t;
2036 		sc->sc_pnintr++;
2037 	}
2038 #endif
2039 
2040 	cb->used -= blksize;
2041 	if (cb->used < blksize) {
2042 		/* we don't have a full block to use */
2043 		inp = cb->inp;
2044 		cc = blksize - (inp - cb->start) % blksize;
2045 		if (cb->pause)
2046 			cb->pdrops += cc;
2047 		else {
2048 			cb->drops += cc;
2049 			sc->sc_playdrop += cc;
2050 		}
2051 		audio_pint_silence(sc, cb, inp, cc);
2052 		inp += cc;
2053 		if (inp >= cb->end)
2054 			inp = cb->start;
2055 		cb->inp = inp;
2056 		cb->used += cc;
2057 
2058 		/* Clear next block so we keep ahead of the DMA. */
2059 		if (cb->used + cc < cb->usedhigh)
2060 			audio_pint_silence(sc, cb, inp, blksize);
2061 	}
2062 
2063 	DPRINTFN(5, ("audio_pint: outp=%p cc=%d\n", cb->outp, blksize));
2064 	if (!hw->trigger_output) {
2065 		error = hw->start_output(sc->hw_hdl, cb->outp, blksize,
2066 		    audio_pint, (void *)sc);
2067 		if (error) {
2068 			/* XXX does this really help? */
2069 			DPRINTF(("audio_pint restart failed: %d\n", error));
2070 			audio_clear(sc);
2071 		}
2072 	}
2073 
2074 	DPRINTFN(2, ("audio_pint: mode=%d pause=%d used=%d lowat=%d\n",
2075 	    sc->sc_mode, cb->pause, cb->used, cb->usedlow));
2076 	if ((sc->sc_mode & AUMODE_PLAY) && !cb->pause &&
2077 	    cb->used <= cb->usedlow)
2078 		audio_selwakeup(sc, 1);
2079 
2080 	/* Possible to return one or more "phantom blocks" now. */
2081 	if (!sc->sc_full_duplex && sc->sc_rchan)
2082 		audio_selwakeup(sc, 0);
2083 }
2084 
2085 /*
2086  * Called from HW driver module on completion of dma input.
2087  * Mark it as input in the ring buffer (fiddle pointers).
2088  * Do a wakeup if necessary.
2089  */
2090 void
2091 audio_rint(void *v)
2092 {
2093 	struct audio_softc *sc = v;
2094 	struct audio_hw_if *hw = sc->hw_if;
2095 	struct audio_ringbuffer *cb = &sc->sc_rr;
2096 	int blksize;
2097 	int error;
2098 
2099 	if (!sc->sc_open)
2100 		return;		/* ignore interrupt if not open */
2101 
2102 	add_audio_randomness((long)cb);
2103 
2104 	blksize = cb->blksize;
2105 
2106 	cb->inp += blksize;
2107 	if (cb->inp >= cb->end)
2108 		cb->inp = cb->start;
2109 	cb->stamp += blksize;
2110 	if (cb->mmapped) {
2111 		DPRINTFN(2, ("audio_rint: mmapped inp=%p cc=%d\n",
2112 		    cb->inp, blksize));
2113 		if (!hw->trigger_input)
2114 			(void)hw->start_input(sc->hw_hdl, cb->inp, blksize,
2115 			    audio_rint, (void *)sc);
2116 		return;
2117 	}
2118 
2119 #ifdef AUDIO_INTR_TIME
2120 	{
2121 		struct timeval tv;
2122 		u_long t;
2123 		microtime(&tv);
2124 		t = tv.tv_usec + 1000000 * tv.tv_sec;
2125 		if (sc->sc_rnintr) {
2126 			long lastdelta, totdelta;
2127 			lastdelta = t - sc->sc_rlastintr - sc->sc_rblktime;
2128 			if (lastdelta > sc->sc_rblktime / 5) {
2129 				printf("audio: record interrupt(%d) off relative by %ld us (%lu)\n",
2130 				    sc->sc_rnintr, lastdelta, sc->sc_rblktime);
2131 			}
2132 			totdelta = t - sc->sc_rfirstintr - sc->sc_rblktime * sc->sc_rnintr;
2133 			if (totdelta > sc->sc_rblktime / 2) {
2134 				sc->sc_rnintr++;
2135 				printf("audio: record interrupt(%d) off absolute by %ld us (%lu)\n",
2136 				    sc->sc_rnintr, totdelta, sc->sc_rblktime);
2137 				sc->sc_rnintr++; /* avoid repeated messages */
2138 			}
2139 		} else
2140 			sc->sc_rfirstintr = t;
2141 		sc->sc_rlastintr = t;
2142 		sc->sc_rnintr++;
2143 	}
2144 #endif
2145 
2146 	cb->used += blksize;
2147 	if (cb->pause) {
2148 		DPRINTFN(1, ("audio_rint: pdrops %lu\n", cb->pdrops));
2149 		cb->pdrops += blksize;
2150 		cb->outp += blksize;
2151 		if (cb->outp >= cb->end)
2152 			cb->outp = cb->start;
2153 		cb->used -= blksize;
2154 	} else if (cb->used >= cb->usedhigh) {
2155 		DPRINTFN(1, ("audio_rint: drops %lu\n", cb->drops));
2156 		cb->drops += blksize;
2157 		cb->outp += blksize;
2158 		if (cb->outp >= cb->end)
2159 			cb->outp = cb->start;
2160 		cb->used -= blksize;
2161 	}
2162 
2163 	DPRINTFN(2, ("audio_rint: inp=%p cc=%d used=%d\n",
2164 	    cb->inp, blksize, cb->used));
2165 	if (!hw->trigger_input) {
2166 		error = hw->start_input(sc->hw_hdl, cb->inp, blksize,
2167 		    audio_rint, (void *)sc);
2168 		if (error) {
2169 			/* XXX does this really help? */
2170 			DPRINTF(("audio_rint: restart failed: %d\n", error));
2171 			audio_clear(sc);
2172 		}
2173 	}
2174 
2175 	audio_selwakeup(sc, 0);
2176 }
2177 
2178 int
2179 audio_check_params(struct audio_params *p)
2180 {
2181 	if (p->channels < 1 || p->channels > 12)
2182 		return (EINVAL);
2183 
2184 	if (p->precision < 8 || p->precision > 32)
2185 		return (EINVAL);
2186 
2187 	if (p->encoding == AUDIO_ENCODING_PCM16) {
2188 		if (p->precision == 8)
2189 			p->encoding = AUDIO_ENCODING_ULINEAR;
2190 		else
2191 			p->encoding = AUDIO_ENCODING_SLINEAR;
2192 	} else if (p->encoding == AUDIO_ENCODING_PCM8) {
2193 		if (p->precision == 8)
2194 			p->encoding = AUDIO_ENCODING_ULINEAR;
2195 		else
2196 			return EINVAL;
2197 	}
2198 
2199 	if (p->encoding == AUDIO_ENCODING_SLINEAR)
2200 #if BYTE_ORDER == LITTLE_ENDIAN
2201 		p->encoding = AUDIO_ENCODING_SLINEAR_LE;
2202 #else
2203 		p->encoding = AUDIO_ENCODING_SLINEAR_BE;
2204 #endif
2205 	if (p->encoding == AUDIO_ENCODING_ULINEAR)
2206 #if BYTE_ORDER == LITTLE_ENDIAN
2207 		p->encoding = AUDIO_ENCODING_ULINEAR_LE;
2208 #else
2209 		p->encoding = AUDIO_ENCODING_ULINEAR_BE;
2210 #endif
2211 
2212 	switch (p->encoding) {
2213 	case AUDIO_ENCODING_ULAW:
2214 	case AUDIO_ENCODING_ALAW:
2215 	case AUDIO_ENCODING_ADPCM:
2216 		if (p->precision != 8)
2217 			p->precision = 8;
2218 		break;
2219 	case AUDIO_ENCODING_SLINEAR_LE:
2220 	case AUDIO_ENCODING_SLINEAR_BE:
2221 	case AUDIO_ENCODING_ULINEAR_LE:
2222 	case AUDIO_ENCODING_ULINEAR_BE:
2223 	case AUDIO_ENCODING_MPEG_L1_STREAM:
2224 	case AUDIO_ENCODING_MPEG_L1_PACKETS:
2225 	case AUDIO_ENCODING_MPEG_L1_SYSTEM:
2226 	case AUDIO_ENCODING_MPEG_L2_STREAM:
2227 	case AUDIO_ENCODING_MPEG_L2_PACKETS:
2228 	case AUDIO_ENCODING_MPEG_L2_SYSTEM:
2229 		break;
2230 	default:
2231 		return (EINVAL);
2232 	}
2233 
2234 	return (0);
2235 }
2236 
2237 int
2238 au_set_lr_value(struct audio_softc *sc, mixer_ctrl_t *ct, int l, int r)
2239 {
2240 	ct->type = AUDIO_MIXER_VALUE;
2241 	ct->un.value.num_channels = 2;
2242 	ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l;
2243 	ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r;
2244 	if (sc->hw_if->set_port(sc->hw_hdl, ct) == 0)
2245 		return 0;
2246 	ct->un.value.num_channels = 1;
2247 	ct->un.value.level[AUDIO_MIXER_LEVEL_MONO] = (l+r)/2;
2248 	return sc->hw_if->set_port(sc->hw_hdl, ct);
2249 }
2250 
2251 int
2252 au_get_mute(struct audio_softc *sc, struct au_mixer_ports *ports, u_char *mute)
2253 {
2254 	mixer_devinfo_t mi;
2255 	mixer_ctrl_t ct;
2256 	int error;
2257 
2258 	*mute = 0;
2259 
2260 	 /* if no master, silently ignore request */
2261 	if (ports->master == -1)
2262 		return 0;
2263 
2264 	mi.index = ports->master;
2265 	error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
2266 	if (error != 0)
2267 		return error;
2268 
2269 	/* master mute control should be the next device, if it exists */
2270 	if (mi.next < 0)
2271 		return 0;
2272 
2273 	ct.dev = mi.next;
2274 	ct.type = AUDIO_MIXER_ENUM;
2275 	error = sc->hw_if->get_port(sc->hw_hdl, &ct);
2276 	if (error != 0)
2277 		return error;
2278 
2279 	*mute = ct.un.ord;
2280 
2281 	return error;
2282 }
2283 
2284 int
2285 au_set_mute(struct audio_softc *sc, struct au_mixer_ports *ports, u_char mute)
2286 {
2287 	mixer_devinfo_t mi;
2288 	mixer_ctrl_t ct;
2289 	int error;
2290 
2291 	 /* if no master, silently ignore request */
2292 	if (ports->master == -1)
2293 		return 0;
2294 
2295 	mi.index = ports->master;
2296 	error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
2297 	if (error != 0)
2298 		return error;
2299 
2300 	/* master mute control should be the next device, if it exists */
2301 	if (mi.next < 0)
2302 		return 0;
2303 
2304 	ct.dev = mi.next;
2305 	ct.type = AUDIO_MIXER_ENUM;
2306 	error = sc->hw_if->get_port(sc->hw_hdl, &ct);
2307 	if (error != 0)
2308 		return error;
2309 
2310 	DPRINTF(("au_set_mute: mute (old): %d, mute (new): %d\n",
2311 	    ct.un.ord, mute));
2312 
2313 	ct.un.ord = (mute != 0 ? 1 : 0);
2314 	error = sc->hw_if->set_port(sc->hw_hdl, &ct);
2315 
2316 	if (!error)
2317 		mixer_signal(sc);
2318 	return error;
2319 }
2320 
2321 int
2322 au_set_gain(struct audio_softc *sc, struct au_mixer_ports *ports, int gain,
2323     int balance)
2324 {
2325 	mixer_ctrl_t ct;
2326 	int i, error;
2327 	int l, r;
2328 	u_int mask;
2329 	int nset;
2330 
2331 	/* XXX silently adjust to within limits or return EINVAL ? */
2332 	if (gain > AUDIO_MAX_GAIN)
2333 		gain = AUDIO_MAX_GAIN;
2334 	else if (gain < AUDIO_MIN_GAIN)
2335 		gain = AUDIO_MIN_GAIN;
2336 
2337 	if (balance == AUDIO_MID_BALANCE) {
2338 		l = r = gain;
2339 	} else if (balance < AUDIO_MID_BALANCE) {
2340 		r = gain;
2341 		l = (balance * gain) / AUDIO_MID_BALANCE;
2342 	} else {
2343 		l = gain;
2344 		r = ((AUDIO_RIGHT_BALANCE - balance) * gain)
2345 		    / AUDIO_MID_BALANCE;
2346 	}
2347 	DPRINTF(("au_set_gain: gain=%d balance=%d, l=%d r=%d\n",
2348 		 gain, balance, l, r));
2349 
2350 	if (ports->index == -1) {
2351 	usemaster:
2352 		if (ports->master == -1)
2353 			return 0; /* just ignore it silently */
2354 		ct.dev = ports->master;
2355 		error = au_set_lr_value(sc, &ct, l, r);
2356 	} else {
2357 		ct.dev = ports->index;
2358 		if (ports->isenum) {
2359 			ct.type = AUDIO_MIXER_ENUM;
2360 			error = sc->hw_if->get_port(sc->hw_hdl, &ct);
2361 			if (error)
2362 				return error;
2363 			for(i = 0; i < ports->nports; i++) {
2364 				if (ports->misel[i] == ct.un.ord) {
2365 					ct.dev = ports->miport[i];
2366 					if (ct.dev == -1 ||
2367 					    au_set_lr_value(sc, &ct, l, r))
2368 						goto usemaster;
2369 					else
2370 						break;
2371 				}
2372 			}
2373 		} else {
2374 			ct.type = AUDIO_MIXER_SET;
2375 			error = sc->hw_if->get_port(sc->hw_hdl, &ct);
2376 			if (error)
2377 				return error;
2378 			mask = ct.un.mask;
2379 			nset = 0;
2380 			for(i = 0; i < ports->nports; i++) {
2381 				if (ports->misel[i] & mask) {
2382 				    ct.dev = ports->miport[i];
2383 				    if (ct.dev != -1 &&
2384 					au_set_lr_value(sc, &ct, l, r) == 0)
2385 					    nset++;
2386 				}
2387 			}
2388 			if (nset == 0)
2389 				goto usemaster;
2390 		}
2391 	}
2392 	if (!error)
2393 		mixer_signal(sc);
2394 	return error;
2395 }
2396 
2397 int
2398 au_get_lr_value(struct audio_softc *sc, mixer_ctrl_t *ct, int *l, int *r)
2399 {
2400 	int error;
2401 
2402 	ct->un.value.num_channels = 2;
2403 	if (sc->hw_if->get_port(sc->hw_hdl, ct) == 0) {
2404 		*l = ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
2405 		*r = ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
2406 	} else {
2407 		ct->un.value.num_channels = 1;
2408 		error = sc->hw_if->get_port(sc->hw_hdl, ct);
2409 		if (error)
2410 			return error;
2411 		*r = *l = ct->un.value.level[AUDIO_MIXER_LEVEL_MONO];
2412 	}
2413 	return 0;
2414 }
2415 
2416 void
2417 au_get_gain(struct audio_softc *sc, struct au_mixer_ports *ports, u_int *pgain,
2418     u_char *pbalance)
2419 {
2420 	mixer_ctrl_t ct;
2421 	int i, l, r, n;
2422 	int lgain = AUDIO_MAX_GAIN/2, rgain = AUDIO_MAX_GAIN/2;
2423 
2424 	if (ports->index == -1) {
2425 	usemaster:
2426 		if (ports->master == -1)
2427 			goto bad;
2428 		ct.dev = ports->master;
2429 		ct.type = AUDIO_MIXER_VALUE;
2430 		if (au_get_lr_value(sc, &ct, &lgain, &rgain))
2431 			goto bad;
2432 	} else {
2433 		ct.dev = ports->index;
2434 		if (ports->isenum) {
2435 			ct.type = AUDIO_MIXER_ENUM;
2436 			if (sc->hw_if->get_port(sc->hw_hdl, &ct))
2437 				goto bad;
2438 			ct.type = AUDIO_MIXER_VALUE;
2439 			for(i = 0; i < ports->nports; i++) {
2440 				if (ports->misel[i] == ct.un.ord) {
2441 					ct.dev = ports->miport[i];
2442 					if (ct.dev == -1 ||
2443 					    au_get_lr_value(sc, &ct,
2444 							    &lgain, &rgain))
2445 						goto usemaster;
2446 					else
2447 						break;
2448 				}
2449 			}
2450 		} else {
2451 			ct.type = AUDIO_MIXER_SET;
2452 			if (sc->hw_if->get_port(sc->hw_hdl, &ct))
2453 				goto bad;
2454 			ct.type = AUDIO_MIXER_VALUE;
2455 			lgain = rgain = n = 0;
2456 			for(i = 0; i < ports->nports; i++) {
2457 				if (ports->misel[i] & ct.un.mask) {
2458 					ct.dev = ports->miport[i];
2459 					if (ct.dev == -1 ||
2460 					    au_get_lr_value(sc, &ct, &l, &r))
2461 						goto usemaster;
2462 					else {
2463 						lgain += l;
2464 						rgain += r;
2465 						n++;
2466 					}
2467 				}
2468 			}
2469 			if (n != 0) {
2470 				lgain /= n;
2471 				rgain /= n;
2472 			}
2473 		}
2474 	}
2475 bad:
2476 	if (lgain == rgain) {	/* handles lgain==rgain==0 */
2477 		*pgain = lgain;
2478 		*pbalance = AUDIO_MID_BALANCE;
2479 	} else if (lgain < rgain) {
2480 		*pgain = rgain;
2481 		*pbalance = (AUDIO_MID_BALANCE * lgain) / rgain;
2482 	} else /* lgain > rgain */ {
2483 		*pgain = lgain;
2484 		*pbalance = AUDIO_RIGHT_BALANCE -
2485 			    (AUDIO_MID_BALANCE * rgain) / lgain;
2486 	}
2487 }
2488 
2489 int
2490 au_set_port(struct audio_softc *sc, struct au_mixer_ports *ports, u_int port)
2491 {
2492 	mixer_ctrl_t ct;
2493 	int i, error;
2494 
2495 	if (port == 0)	/* allow this special case */
2496 		return 0;
2497 
2498 	if (ports->index == -1)
2499 		return EINVAL;
2500 	ct.dev = ports->index;
2501 	if (ports->isenum) {
2502 		if (port & (port-1))
2503 			return EINVAL; /* Only one port allowed */
2504 		ct.type = AUDIO_MIXER_ENUM;
2505 		error = EINVAL;
2506 		for(i = 0; i < ports->nports; i++)
2507 			if (ports->aumask[i] == port) {
2508 				ct.un.ord = ports->misel[i];
2509 				error = sc->hw_if->set_port(sc->hw_hdl, &ct);
2510 				break;
2511 			}
2512 	} else {
2513 		ct.type = AUDIO_MIXER_SET;
2514 		ct.un.mask = 0;
2515 		for(i = 0; i < ports->nports; i++)
2516 			if (ports->aumask[i] & port)
2517 				ct.un.mask |= ports->misel[i];
2518 		if (port != 0 && ct.un.mask == 0)
2519 			error = EINVAL;
2520 		else
2521 			error = sc->hw_if->set_port(sc->hw_hdl, &ct);
2522 	}
2523 	if (!error)
2524 		mixer_signal(sc);
2525 	return error;
2526 }
2527 
2528 int
2529 au_get_port(struct audio_softc *sc, struct au_mixer_ports *ports)
2530 {
2531 	mixer_ctrl_t ct;
2532 	int i, aumask;
2533 
2534 	if (ports->index == -1)
2535 		return 0;
2536 	ct.dev = ports->index;
2537 	ct.type = ports->isenum ? AUDIO_MIXER_ENUM : AUDIO_MIXER_SET;
2538 	if (sc->hw_if->get_port(sc->hw_hdl, &ct))
2539 		return 0;
2540 	aumask = 0;
2541 	if (ports->isenum) {
2542 		for(i = 0; i < ports->nports; i++)
2543 			if (ct.un.ord == ports->misel[i])
2544 				aumask = ports->aumask[i];
2545 	} else {
2546 		for(i = 0; i < ports->nports; i++)
2547 			if (ct.un.mask & ports->misel[i])
2548 				aumask |= ports->aumask[i];
2549 	}
2550 	return aumask;
2551 }
2552 
2553 int
2554 audiosetinfo(struct audio_softc *sc, struct audio_info *ai)
2555 {
2556 	struct audio_prinfo *r = &ai->record, *p = &ai->play;
2557 	int cleared;
2558 	int s, setmode, modechange = 0;
2559 	int error;
2560 	struct audio_hw_if *hw = sc->hw_if;
2561 	struct audio_params pp, rp;
2562 	int np, nr;
2563 	unsigned int blks;
2564 	int oldpblksize, oldrblksize;
2565 	int rbus, pbus;
2566 	int fpb;
2567 	int fs;
2568 	u_int gain;
2569 	u_char balance;
2570 
2571 	if (hw == 0)		/* HW has not attached */
2572 		return(ENXIO);
2573 
2574 	rbus = sc->sc_rbus;
2575 	pbus = sc->sc_pbus;
2576 	error = 0;
2577 	cleared = 0;
2578 
2579 	pp = sc->sc_pparams;	/* Temporary encoding storage in */
2580 	rp = sc->sc_rparams;	/* case setting the modes fails. */
2581 	nr = np = 0;
2582 
2583 	if (p->sample_rate != ~0) {
2584 		pp.sample_rate = p->sample_rate;
2585 		np++;
2586 	}
2587 	if (r->sample_rate != ~0) {
2588 		rp.sample_rate = r->sample_rate;
2589 		nr++;
2590 	}
2591 	if (p->encoding != ~0) {
2592 		pp.encoding = p->encoding;
2593 		np++;
2594 	}
2595 	if (r->encoding != ~0) {
2596 		rp.encoding = r->encoding;
2597 		nr++;
2598 	}
2599 	if (p->precision != ~0) {
2600 		pp.precision = p->precision;
2601 		np++;
2602 	}
2603 	if (r->precision != ~0) {
2604 		rp.precision = r->precision;
2605 		nr++;
2606 	}
2607 	if (p->channels != ~0) {
2608 		pp.channels = p->channels;
2609 		np++;
2610 	}
2611 	if (r->channels != ~0) {
2612 		rp.channels = r->channels;
2613 		nr++;
2614 	}
2615 #ifdef AUDIO_DEBUG
2616 	if (audiodebug && nr)
2617 	    audio_print_params("Setting record params", &rp);
2618 	if (audiodebug && np)
2619 	    audio_print_params("Setting play params", &pp);
2620 #endif
2621 	if (nr && (error = audio_check_params(&rp)))
2622 		return error;
2623 	if (np && (error = audio_check_params(&pp)))
2624 		return error;
2625 	setmode = 0;
2626 	if (nr) {
2627 		if (!cleared)
2628 			audio_clear(sc);
2629 		modechange = cleared = 1;
2630 		rp.sw_code = 0;
2631 		rp.factor = 1;
2632 		setmode |= AUMODE_RECORD;
2633 	}
2634 	if (np) {
2635 		if (!cleared)
2636 			audio_clear(sc);
2637 		modechange = cleared = 1;
2638 		pp.sw_code = 0;
2639 		pp.factor = 1;
2640 		setmode |= AUMODE_PLAY;
2641 	}
2642 
2643 	if (ai->mode != ~0) {
2644 		if (!cleared)
2645 			audio_clear(sc);
2646 		modechange = cleared = 1;
2647 		sc->sc_mode = ai->mode;
2648 		if (sc->sc_mode & AUMODE_PLAY_ALL)
2649 			sc->sc_mode |= AUMODE_PLAY;
2650 		if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_full_duplex)
2651 			/* Play takes precedence */
2652 			sc->sc_mode &= ~AUMODE_RECORD;
2653 	}
2654 
2655 	if (modechange) {
2656 		int indep = hw->get_props(sc->hw_hdl) & AUDIO_PROP_INDEPENDENT;
2657 		if (!indep) {
2658 			if (setmode == AUMODE_RECORD)
2659 				pp = rp;
2660 			else
2661 				rp = pp;
2662 		}
2663 		error = hw->set_params(sc->hw_hdl, setmode,
2664 		    sc->sc_mode & (AUMODE_PLAY | AUMODE_RECORD), &pp, &rp);
2665 		if (error)
2666 			return (error);
2667 		if (!indep) {
2668 			if (setmode == AUMODE_RECORD) {
2669 				pp.sample_rate = rp.sample_rate;
2670 				pp.encoding    = rp.encoding;
2671 				pp.channels    = rp.channels;
2672 				pp.precision   = rp.precision;
2673 			} else if (setmode == AUMODE_PLAY) {
2674 				rp.sample_rate = pp.sample_rate;
2675 				rp.encoding    = pp.encoding;
2676 				rp.channels    = pp.channels;
2677 				rp.precision   = pp.precision;
2678 			}
2679 		}
2680 		sc->sc_rparams = rp;
2681 		sc->sc_pparams = pp;
2682 	}
2683 
2684 	oldpblksize = sc->sc_pr.blksize;
2685 	oldrblksize = sc->sc_rr.blksize;
2686 
2687 	/*
2688 	 * allow old-style blocksize changes, for compatibility;
2689 	 * individual play/record block sizes have precedence
2690 	 */
2691 	if (ai->blocksize != ~0) {
2692 		if (r->block_size == ~0)
2693 			r->block_size = ai->blocksize;
2694 		if (p->block_size == ~0)
2695 			p->block_size = ai->blocksize;
2696 	}
2697 	if (r->block_size != ~0) {
2698 		sc->sc_rr.blkset = 0;
2699 		if (!cleared)
2700 			audio_clear(sc);
2701 		cleared = 1;
2702 		nr++;
2703 	}
2704 	if (p->block_size != ~0) {
2705 		sc->sc_pr.blkset = 0;
2706 		if (!cleared)
2707 			audio_clear(sc);
2708 		cleared = 1;
2709 		np++;
2710 	}
2711 	if (nr) {
2712 		if (r->block_size == ~0 || r->block_size == 0) {
2713 			fpb = rp.sample_rate * audio_blk_ms / 1000;
2714 		} else {
2715 			fs = rp.channels * AUDIO_BPS(rp.precision);
2716 			fpb = (r->block_size * rp.factor) / fs;
2717 		}
2718 		if (sc->sc_rr.blkset == 0)
2719 			audio_set_blksize(sc, AUMODE_RECORD, fpb);
2720 	}
2721 	if (np) {
2722 		if (p->block_size == ~0 || p->block_size == 0) {
2723 			fpb = pp.sample_rate * audio_blk_ms / 1000;
2724 		} else {
2725 			fs = pp.channels * AUDIO_BPS(pp.precision);
2726 			fpb = (p->block_size * pp.factor) / fs;
2727 		}
2728 		if (sc->sc_pr.blkset == 0)
2729 			audio_set_blksize(sc, AUMODE_PLAY, fpb);
2730 	}
2731 	if (r->block_size != ~0 && r->block_size != 0)
2732 		sc->sc_rr.blkset = 1;
2733 	if (p->block_size != ~0 && p->block_size != 0)
2734 		sc->sc_pr.blkset = 1;
2735 
2736 #ifdef AUDIO_DEBUG
2737 	if (audiodebug > 1 && nr)
2738 	    audio_print_params("After setting record params", &sc->sc_rparams);
2739 	if (audiodebug > 1 && np)
2740 	    audio_print_params("After setting play params", &sc->sc_pparams);
2741 #endif
2742 
2743 	if (p->port != ~0) {
2744 		if (!cleared)
2745 			audio_clear(sc);
2746 		cleared = 1;
2747 
2748 		error = au_set_port(sc, &sc->sc_outports, p->port);
2749 		if (error)
2750 			return(error);
2751 	}
2752 	if (r->port != ~0) {
2753 		if (!cleared)
2754 			audio_clear(sc);
2755 		cleared = 1;
2756 
2757 		error = au_set_port(sc, &sc->sc_inports, r->port);
2758 		if (error)
2759 			return(error);
2760 	}
2761 	if (p->gain != ~0) {
2762 		au_get_gain(sc, &sc->sc_outports, &gain, &balance);
2763 		error = au_set_gain(sc, &sc->sc_outports, p->gain, balance);
2764 		if (error)
2765 			return(error);
2766 	}
2767 	if ((r->gain != ~0) && (r->port != 0)) {
2768 		au_get_gain(sc, &sc->sc_inports, &gain, &balance);
2769 		error = au_set_gain(sc, &sc->sc_inports, r->gain, balance);
2770 		if (error)
2771 			return(error);
2772 	}
2773 
2774 	if (p->balance != (u_char)~0) {
2775 		au_get_gain(sc, &sc->sc_outports, &gain, &balance);
2776 		error = au_set_gain(sc, &sc->sc_outports, gain, p->balance);
2777 		if (error)
2778 			return(error);
2779 	}
2780 	if ((r->balance != (u_char)~0) && (r->port != 0)) {
2781 		au_get_gain(sc, &sc->sc_inports, &gain, &balance);
2782 		error = au_set_gain(sc, &sc->sc_inports, gain, r->balance);
2783 		if (error)
2784 			return(error);
2785 	}
2786 
2787 	if (ai->output_muted != (u_char)~0) {
2788 		error = au_set_mute(sc, &sc->sc_outports, ai->output_muted);
2789 		if (error)
2790 			return(error);
2791 	}
2792 
2793 	if (ai->monitor_gain != ~0 &&
2794 	    sc->sc_monitor_port != -1) {
2795 		mixer_ctrl_t ct;
2796 
2797 		ct.dev = sc->sc_monitor_port;
2798 		ct.type = AUDIO_MIXER_VALUE;
2799 		ct.un.value.num_channels = 1;
2800 		ct.un.value.level[AUDIO_MIXER_LEVEL_MONO] = ai->monitor_gain;
2801 		error = sc->hw_if->set_port(sc->hw_hdl, &ct);
2802 		if (error)
2803 			return(error);
2804 	}
2805 
2806 	if (ai->mode != ~0) {
2807 		if (sc->sc_mode & AUMODE_PLAY)
2808 			audio_init_play(sc);
2809 		if (sc->sc_mode & AUMODE_RECORD)
2810 			audio_init_record(sc);
2811 	}
2812 
2813 	if (hw->commit_settings) {
2814 		error = hw->commit_settings(sc->hw_hdl);
2815 		if (error)
2816 			return (error);
2817 	}
2818 
2819 	if (cleared) {
2820 		s = splaudio();
2821 		error = audio_initbufs(sc);
2822 		if (error) goto err;
2823 		if (sc->sc_pr.blksize != oldpblksize ||
2824 		    sc->sc_rr.blksize != oldrblksize)
2825 			audio_calcwater(sc);
2826 		if ((sc->sc_mode & AUMODE_PLAY) &&
2827 		    pbus && !sc->sc_pbus && !sc->sc_pr.pause)
2828 			error = audiostartp(sc);
2829 		if (!error &&
2830 		    (sc->sc_mode & AUMODE_RECORD) &&
2831 		    rbus && !sc->sc_rbus && !sc->sc_rr.pause)
2832 			error = audiostartr(sc);
2833 	err:
2834 		splx(s);
2835 		if (error)
2836 			return error;
2837 	}
2838 
2839 	/* Change water marks after initializing the buffers. */
2840 	if (ai->hiwat != ~0) {
2841 		blks = ai->hiwat;
2842 		if (blks > sc->sc_pr.maxblks)
2843 			blks = sc->sc_pr.maxblks;
2844 		if (blks < 2)
2845 			blks = 2;
2846 		sc->sc_pr.usedhigh = blks * sc->sc_pr.blksize;
2847 	}
2848 	if (ai->lowat != ~0) {
2849 		blks = ai->lowat;
2850 		if (blks > sc->sc_pr.maxblks - 1)
2851 			blks = sc->sc_pr.maxblks - 1;
2852 		sc->sc_pr.usedlow = blks * sc->sc_pr.blksize;
2853 	}
2854 	if (ai->hiwat != ~0 || ai->lowat != ~0) {
2855 		if (sc->sc_pr.usedlow > sc->sc_pr.usedhigh - sc->sc_pr.blksize)
2856 			sc->sc_pr.usedlow = sc->sc_pr.usedhigh - sc->sc_pr.blksize;
2857 	}
2858 
2859 	if (p->pause != (u_char)~0) {
2860 		sc->sc_pr.pause = p->pause;
2861 		if (!p->pause && !sc->sc_pbus && (sc->sc_mode & AUMODE_PLAY)) {
2862 			s = splaudio();
2863 			error = audiostartp(sc);
2864 			splx(s);
2865 			if (error)
2866 				return error;
2867 		}
2868 	}
2869 	if (r->pause != (u_char)~0) {
2870 		sc->sc_rr.pause = r->pause;
2871 		if (!r->pause && !sc->sc_rbus && (sc->sc_mode & AUMODE_RECORD)) {
2872 			s = splaudio();
2873 			error = audiostartr(sc);
2874 			splx(s);
2875 			if (error)
2876 				return error;
2877 		}
2878 	}
2879 
2880 	return (0);
2881 }
2882 
2883 int
2884 audiogetinfo(struct audio_softc *sc, struct audio_info *ai)
2885 {
2886 	struct audio_prinfo *r = &ai->record, *p = &ai->play;
2887 	struct audio_hw_if *hw = sc->hw_if;
2888 
2889 	if (hw == 0)		/* HW has not attached */
2890 		return(ENXIO);
2891 
2892 	p->sample_rate = sc->sc_pparams.sample_rate;
2893 	r->sample_rate = sc->sc_rparams.sample_rate;
2894 	p->channels = sc->sc_pparams.channels;
2895 	r->channels = sc->sc_rparams.channels;
2896 	p->precision = sc->sc_pparams.precision;
2897 	r->precision = sc->sc_rparams.precision;
2898 	p->encoding = sc->sc_pparams.encoding;
2899 	r->encoding = sc->sc_rparams.encoding;
2900 
2901 	r->port = au_get_port(sc, &sc->sc_inports);
2902 	p->port = au_get_port(sc, &sc->sc_outports);
2903 
2904 	r->avail_ports = sc->sc_inports.allports;
2905 	p->avail_ports = sc->sc_outports.allports;
2906 
2907 	au_get_gain(sc, &sc->sc_inports,  &r->gain, &r->balance);
2908 	au_get_gain(sc, &sc->sc_outports, &p->gain, &p->balance);
2909 
2910 	if (sc->sc_monitor_port != -1) {
2911 		mixer_ctrl_t ct;
2912 
2913 		ct.dev = sc->sc_monitor_port;
2914 		ct.type = AUDIO_MIXER_VALUE;
2915 		ct.un.value.num_channels = 1;
2916 		if (sc->hw_if->get_port(sc->hw_hdl, &ct))
2917 			ai->monitor_gain = 0;
2918 		else
2919 			ai->monitor_gain =
2920 				ct.un.value.level[AUDIO_MIXER_LEVEL_MONO];
2921 	} else
2922 		ai->monitor_gain = 0;
2923 
2924 	au_get_mute(sc, &sc->sc_outports, &ai->output_muted);
2925 
2926 	p->seek = sc->sc_pr.used / sc->sc_pparams.factor;
2927 	r->seek = sc->sc_rr.used / sc->sc_rparams.factor;
2928 
2929 	p->samples = sc->sc_pr.stamp - sc->sc_pr.drops;
2930 	r->samples = sc->sc_rr.stamp - sc->sc_rr.drops;
2931 
2932 	p->eof = sc->sc_eof;
2933 	r->eof = 0;
2934 
2935 	p->pause = sc->sc_pr.pause;
2936 	r->pause = sc->sc_rr.pause;
2937 
2938 	p->error = sc->sc_pr.drops != 0;
2939 	r->error = sc->sc_rr.drops != 0;
2940 
2941 	p->waiting = r->waiting = 0;		/* open never hangs */
2942 
2943 	p->open = (sc->sc_open & AUOPEN_WRITE) != 0;
2944 	r->open = (sc->sc_open & AUOPEN_READ) != 0;
2945 
2946 	p->active = sc->sc_pbus;
2947 	r->active = sc->sc_rbus;
2948 
2949 	p->buffer_size = sc->sc_pr.bufsize / sc->sc_pparams.factor;
2950 	r->buffer_size = sc->sc_rr.bufsize / sc->sc_rparams.factor;
2951 
2952 	r->block_size = sc->sc_rr.blksize / sc->sc_rparams.factor;
2953 	p->block_size = sc->sc_pr.blksize / sc->sc_pparams.factor;
2954 	if (p->block_size != 0) {
2955 		ai->hiwat = sc->sc_pr.usedhigh / sc->sc_pr.blksize;
2956 		ai->lowat = sc->sc_pr.usedlow / sc->sc_pr.blksize;
2957 	} else {
2958 		ai->hiwat = ai->lowat = 0;
2959 	}
2960 	ai->blocksize = p->block_size;	/* for compatibility, remove this */
2961 	ai->mode = sc->sc_mode;
2962 
2963 	return (0);
2964 }
2965 
2966 int
2967 audiogetbufinfo(struct audio_softc *sc, struct audio_bufinfo *info, int mode)
2968 {
2969 	struct audio_ringbuffer *buf;
2970 	int factor;
2971 
2972 	factor = 1;
2973 	if (mode == AUMODE_PLAY) {
2974 		buf = &sc->sc_pr;
2975 		factor = sc->sc_pparams.factor;
2976 	} else {
2977 		buf = &sc->sc_rr;
2978 		factor = sc->sc_rparams.factor;
2979 	}
2980 
2981 	info->seek = buf->used / factor;
2982 	info->blksize = buf->blksize / factor;
2983 	if (buf->blksize != 0) {
2984 		info->hiwat = buf->usedhigh / buf->blksize;
2985 		info->lowat = buf->usedlow / buf->blksize;
2986 	} else {
2987 		info->hiwat = 0;
2988 		info->lowat = 0;
2989 	}
2990 
2991 	return (0);
2992 }
2993 
2994 
2995 /*
2996  * Mixer driver
2997  */
2998 int
2999 mixer_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
3000     struct proc *p)
3001 {
3002 	DPRINTF(("mixer_open: dev=0x%x flags=0x%x sc=%p\n", dev, flags, sc));
3003 
3004 	return (0);
3005 }
3006 
3007 /*
3008  * Remove a process from those to be signalled on mixer activity.
3009  */
3010 static void
3011 mixer_remove(struct audio_softc *sc, struct proc *p)
3012 {
3013 	struct mixer_asyncs **pm, *m;
3014 
3015 	for(pm = &sc->sc_async_mixer; *pm; pm = &(*pm)->next) {
3016 		if ((*pm)->proc == p) {
3017 			m = *pm;
3018 			*pm = m->next;
3019 			free(m, M_DEVBUF);
3020 			return;
3021 		}
3022 	}
3023 }
3024 
3025 /*
3026  * Signal all processes waiting for the mixer.
3027  */
3028 static void
3029 mixer_signal(struct audio_softc *sc)
3030 {
3031 	struct mixer_asyncs *m;
3032 
3033 	for(m = sc->sc_async_mixer; m; m = m->next)
3034 		psignal(m->proc, SIGIO);
3035 }
3036 
3037 /*
3038  * Close a mixer device
3039  */
3040 /* ARGSUSED */
3041 int
3042 mixer_close(dev_t dev, int flags, int ifmt, struct proc *p)
3043 {
3044 	int unit = AUDIOUNIT(dev);
3045 	struct audio_softc *sc = audio_cd.cd_devs[unit];
3046 
3047 	DPRINTF(("mixer_close: unit %d\n", AUDIOUNIT(dev)));
3048 
3049 	mixer_remove(sc, p);
3050 
3051 	return (0);
3052 }
3053 
3054 int
3055 mixer_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
3056 {
3057 	int unit = AUDIOUNIT(dev);
3058 	struct audio_softc *sc = audio_cd.cd_devs[unit];
3059 	struct audio_hw_if *hw = sc->hw_if;
3060 	int error = EINVAL;
3061 
3062 	DPRINTF(("mixer_ioctl(%d,'%c',%d)\n",
3063 		 IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff));
3064 
3065 	switch (cmd) {
3066 	case FIOASYNC:
3067 		mixer_remove(sc, p); /* remove old entry */
3068 		if (*(int *)addr) {
3069 			struct mixer_asyncs *ma;
3070 			ma = malloc(sizeof (struct mixer_asyncs),
3071 			    M_DEVBUF, M_WAITOK);
3072 			ma->next = sc->sc_async_mixer;
3073 			ma->proc = p;
3074 			sc->sc_async_mixer = ma;
3075 		}
3076 		error = 0;
3077 		break;
3078 
3079 	case AUDIO_GETDEV:
3080 		DPRINTF(("AUDIO_GETDEV\n"));
3081 		error = hw->getdev(sc->hw_hdl, (audio_device_t *)addr);
3082 		break;
3083 
3084 	case AUDIO_MIXER_DEVINFO:
3085 		DPRINTF(("AUDIO_MIXER_DEVINFO\n"));
3086 		((mixer_devinfo_t *)addr)->un.v.delta = 0; /* default */
3087 		error = hw->query_devinfo(sc->hw_hdl, (mixer_devinfo_t *)addr);
3088 		break;
3089 
3090 	case AUDIO_MIXER_READ:
3091 		DPRINTF(("AUDIO_MIXER_READ\n"));
3092 		error = hw->get_port(sc->hw_hdl, (mixer_ctrl_t *)addr);
3093 		break;
3094 
3095 	case AUDIO_MIXER_WRITE:
3096 		if (!(flag & FWRITE))
3097 			return (EACCES);
3098 		DPRINTF(("AUDIO_MIXER_WRITE\n"));
3099 		error = hw->set_port(sc->hw_hdl, (mixer_ctrl_t *)addr);
3100 		if (!error && hw->commit_settings)
3101 			error = hw->commit_settings(sc->hw_hdl);
3102 		if (!error)
3103 			mixer_signal(sc);
3104 		break;
3105 
3106 	default:
3107 		error = ENOTTY;
3108 		break;
3109 	}
3110 	DPRINTF(("mixer_ioctl(%d,'%c',%d) result %d\n",
3111 		 IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff, error));
3112 	return (error);
3113 }
3114 #endif
3115 
3116 int
3117 audiokqfilter(dev_t dev, struct knote *kn)
3118 {
3119 	int unit = AUDIOUNIT(dev);
3120 	struct audio_softc *sc = audio_cd.cd_devs[unit];
3121 	struct klist *klist;
3122 	int s;
3123 
3124 	switch (kn->kn_filter) {
3125 	case EVFILT_READ:
3126 		klist = &sc->sc_rsel.si_note;
3127 		kn->kn_fop = &audioread_filtops;
3128 		break;
3129 	case EVFILT_WRITE:
3130 		klist = &sc->sc_wsel.si_note;
3131 		kn->kn_fop = &audiowrite_filtops;
3132 		break;
3133 	default:
3134 		return (1);
3135 	}
3136 	kn->kn_hook = (void *)sc;
3137 
3138 	s = splaudio();
3139 	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
3140 	splx(s);
3141 
3142 	return (0);
3143 }
3144 
3145 void
3146 filt_audiordetach(struct knote *kn)
3147 {
3148 	struct audio_softc *sc = (struct audio_softc *)kn->kn_hook;
3149 	int s = splaudio();
3150 
3151 	SLIST_REMOVE(&sc->sc_rsel.si_note, kn, knote, kn_selnext);
3152 	splx(s);
3153 }
3154 
3155 int
3156 filt_audioread(struct knote *kn, long hint)
3157 {
3158 	struct audio_softc *sc = (struct audio_softc *)kn->kn_hook;
3159 
3160 	return AUDIO_FILTREAD(sc);
3161 }
3162 
3163 void
3164 filt_audiowdetach(struct knote *kn)
3165 {
3166 	struct audio_softc *sc = (struct audio_softc *)kn->kn_hook;
3167 	int s = splaudio();
3168 
3169 	SLIST_REMOVE(&sc->sc_wsel.si_note, kn, knote, kn_selnext);
3170 	splx(s);
3171 }
3172 
3173 int
3174 filt_audiowrite(struct knote *kn, long hint)
3175 {
3176 	struct audio_softc *sc = (struct audio_softc *)kn->kn_hook;
3177 
3178 	return AUDIO_FILTWRITE(sc);
3179 }
3180 
3181 #if NAUDIO > 0 && NWSKBD > 0
3182 int
3183 wskbd_set_mixervolume(long dir)
3184 {
3185 	struct audio_softc *sc;
3186 	mixer_devinfo_t mi;
3187 	int error;
3188 	u_int gain;
3189 	u_char balance, mute;
3190 
3191 	if (audio_cd.cd_ndevs == 0 || (sc = audio_cd.cd_devs[0]) == NULL) {
3192 		DPRINTF(("wskbd_set_mixervolume: audio_cd\n"));
3193 		return (ENXIO);
3194 	}
3195 
3196 	if (sc->sc_outports.master == -1) {
3197 		DPRINTF(("wskbd_set_mixervolume: master == -1\n"));
3198 		return (ENXIO);
3199 	}
3200 
3201 	if (dir == 0) {
3202 		/* Mute */
3203 
3204 		error = au_get_mute(sc, &sc->sc_outports, &mute);
3205 		if (error != 0) {
3206 			DPRINTF(("wskbd_set_mixervolume:"
3207 			    " au_get_mute: %d\n", error));
3208 			return (error);
3209 		}
3210 
3211 		mute = !mute;
3212 
3213 		error = au_set_mute(sc, &sc->sc_outports, mute);
3214 		if (error != 0) {
3215 			DPRINTF(("wskbd_set_mixervolume:"
3216 			    " au_set_mute: %d\n", error));
3217 			return (error);
3218 		}
3219 	} else {
3220 		/* Raise or lower volume */
3221 
3222 		mi.index = sc->sc_outports.master;
3223 		error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
3224 		if (error != 0) {
3225 			DPRINTF(("wskbd_set_mixervolume:"
3226 			    " query_devinfo: %d\n", error));
3227 			return (error);
3228 		}
3229 
3230 		au_get_gain(sc, &sc->sc_outports, &gain, &balance);
3231 
3232 		if (dir > 0)
3233 			gain += mi.un.v.delta;
3234 		else
3235 			gain -= mi.un.v.delta;
3236 
3237 		error = au_set_gain(sc, &sc->sc_outports, gain, balance);
3238 		if (error != 0) {
3239 			DPRINTF(("wskbd_set_mixervolume:"
3240 			    " au_set_gain: %d\n", error));
3241 			return (error);
3242 		}
3243 	}
3244 
3245 	return (0);
3246 }
3247 #endif /* NAUDIO > 0 && NWSKBD > 0 */
3248