Tue Aug 15 05:11:25 2017 UTC ()
Clean up audio_allocbufs().
As a result of sc_audiochan cleanup, it is easy to access sc_hwvc.


(isaki)
diff -r1.395 -r1.396 src/sys/dev/audio.c

cvs diff -r1.395 -r1.396 src/sys/dev/Attic/audio.c (switch to unified diff)

--- src/sys/dev/Attic/audio.c 2017/08/15 05:05:32 1.395
+++ src/sys/dev/Attic/audio.c 2017/08/15 05:11:25 1.396
@@ -1,2112 +1,2115 @@ @@ -1,2112 +1,2115 @@
1/* $NetBSD: audio.c,v 1.395 2017/08/15 05:05:32 isaki Exp $ */ 1/* $NetBSD: audio.c,v 1.396 2017/08/15 05:11:25 isaki Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au> 4 * Copyright (c) 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Copyright (c) 2008 The NetBSD Foundation, Inc. 7 * Copyright (c) 2008 The NetBSD Foundation, Inc.
8 * All rights reserved. 8 * All rights reserved.
9 * 9 *
10 * This code is derived from software contributed to The NetBSD Foundation 10 * This code is derived from software contributed to The NetBSD Foundation
11 * by Andrew Doran. 11 * by Andrew Doran.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions 14 * modification, are permitted provided that the following conditions
15 * are met: 15 * are met:
16 * 1. Redistributions of source code must retain the above copyright 16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer. 17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright 18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the 19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution. 20 * documentation and/or other materials provided with the distribution.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE. 32 * POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * Copyright (c) 1991-1993 Regents of the University of California. 36 * Copyright (c) 1991-1993 Regents of the University of California.
37 * All rights reserved. 37 * All rights reserved.
38 * 38 *
39 * Redistribution and use in source and binary forms, with or without 39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions 40 * modification, are permitted provided that the following conditions
41 * are met: 41 * are met:
42 * 1. Redistributions of source code must retain the above copyright 42 * 1. Redistributions of source code must retain the above copyright
43 * notice, this list of conditions and the following disclaimer. 43 * notice, this list of conditions and the following disclaimer.
44 * 2. Redistributions in binary form must reproduce the above copyright 44 * 2. Redistributions in binary form must reproduce the above copyright
45 * notice, this list of conditions and the following disclaimer in the 45 * notice, this list of conditions and the following disclaimer in the
46 * documentation and/or other materials provided with the distribution. 46 * documentation and/or other materials provided with the distribution.
47 * 3. All advertising materials mentioning features or use of this software 47 * 3. All advertising materials mentioning features or use of this software
48 * must display the following acknowledgement: 48 * must display the following acknowledgement:
49 * This product includes software developed by the Computer Systems 49 * This product includes software developed by the Computer Systems
50 * Engineering Group at Lawrence Berkeley Laboratory. 50 * Engineering Group at Lawrence Berkeley Laboratory.
51 * 4. Neither the name of the University nor of the Laboratory may be used 51 * 4. Neither the name of the University nor of the Laboratory may be used
52 * to endorse or promote products derived from this software without 52 * to endorse or promote products derived from this software without
53 * specific prior written permission. 53 * specific prior written permission.
54 * 54 *
55 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 55 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 58 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * SUCH DAMAGE. 65 * SUCH DAMAGE.
66 */ 66 */
67 67
68/* 68/*
69 * This is a (partially) SunOS-compatible /dev/audio driver for NetBSD. 69 * This is a (partially) SunOS-compatible /dev/audio driver for NetBSD.
70 * 70 *
71 * This code tries to do something half-way sensible with 71 * This code tries to do something half-way sensible with
72 * half-duplex hardware, such as with the SoundBlaster hardware. With 72 * half-duplex hardware, such as with the SoundBlaster hardware. With
73 * half-duplex hardware allowing O_RDWR access doesn't really make 73 * half-duplex hardware allowing O_RDWR access doesn't really make
74 * sense. However, closing and opening the device to "turn around the 74 * sense. However, closing and opening the device to "turn around the
75 * line" is relatively expensive and costs a card reset (which can 75 * line" is relatively expensive and costs a card reset (which can
76 * take some time, at least for the SoundBlaster hardware). Instead 76 * take some time, at least for the SoundBlaster hardware). Instead
77 * we allow O_RDWR access, and provide an ioctl to set the "mode", 77 * we allow O_RDWR access, and provide an ioctl to set the "mode",
78 * i.e. playing or recording. 78 * i.e. playing or recording.
79 * 79 *
80 * If you write to a half-duplex device in record mode, the data is 80 * If you write to a half-duplex device in record mode, the data is
81 * tossed. If you read from the device in play mode, you get silence 81 * tossed. If you read from the device in play mode, you get silence
82 * filled buffers at the rate at which samples are naturally 82 * filled buffers at the rate at which samples are naturally
83 * generated. 83 * generated.
84 * 84 *
85 * If you try to set both play and record mode on a half-duplex 85 * If you try to set both play and record mode on a half-duplex
86 * device, playing takes precedence. 86 * device, playing takes precedence.
87 */ 87 */
88 88
89/* 89/*
90 * Locking: there are two locks. 90 * Locking: there are two locks.
91 * 91 *
92 * - sc_lock, provided by the underlying driver. This is an adaptive lock, 92 * - sc_lock, provided by the underlying driver. This is an adaptive lock,
93 * returned in the second parameter to hw_if->get_locks(). It is known 93 * returned in the second parameter to hw_if->get_locks(). It is known
94 * as the "thread lock". 94 * as the "thread lock".
95 * 95 *
96 * It serializes access to state in all places except the  96 * It serializes access to state in all places except the
97 * driver's interrupt service routine. This lock is taken from process 97 * driver's interrupt service routine. This lock is taken from process
98 * context (example: access to /dev/audio). It is also taken from soft 98 * context (example: access to /dev/audio). It is also taken from soft
99 * interrupt handlers in this module, primarily to serialize delivery of 99 * interrupt handlers in this module, primarily to serialize delivery of
100 * wakeups. This lock may be used/provided by modules external to the 100 * wakeups. This lock may be used/provided by modules external to the
101 * audio subsystem, so take care not to introduce a lock order problem.  101 * audio subsystem, so take care not to introduce a lock order problem.
102 * LONG TERM SLEEPS MUST NOT OCCUR WITH THIS LOCK HELD. 102 * LONG TERM SLEEPS MUST NOT OCCUR WITH THIS LOCK HELD.
103 * 103 *
104 * - sc_intr_lock, provided by the underlying driver. This may be either a 104 * - sc_intr_lock, provided by the underlying driver. This may be either a
105 * spinlock (at IPL_SCHED or IPL_VM) or an adaptive lock (IPL_NONE or 105 * spinlock (at IPL_SCHED or IPL_VM) or an adaptive lock (IPL_NONE or
106 * IPL_SOFT*), returned in the first parameter to hw_if->get_locks(). It 106 * IPL_SOFT*), returned in the first parameter to hw_if->get_locks(). It
107 * is known as the "interrupt lock". 107 * is known as the "interrupt lock".
108 * 108 *
109 * It provides atomic access to the device's hardware state, and to audio 109 * It provides atomic access to the device's hardware state, and to audio
110 * channel data that may be accessed by the hardware driver's ISR. 110 * channel data that may be accessed by the hardware driver's ISR.
111 * In all places outside the ISR, sc_lock must be held before taking 111 * In all places outside the ISR, sc_lock must be held before taking
112 * sc_intr_lock. This is to ensure that groups of hardware operations are 112 * sc_intr_lock. This is to ensure that groups of hardware operations are
113 * made atomically. SLEEPS CANNOT OCCUR WITH THIS LOCK HELD. 113 * made atomically. SLEEPS CANNOT OCCUR WITH THIS LOCK HELD.
114 * 114 *
115 * List of hardware interface methods, and which locks are held when each 115 * List of hardware interface methods, and which locks are held when each
116 * is called by this module: 116 * is called by this module:
117 * 117 *
118 * METHOD INTR THREAD NOTES 118 * METHOD INTR THREAD NOTES
119 * ----------------------- ------- ------- ------------------------- 119 * ----------------------- ------- ------- -------------------------
120 * open x x 120 * open x x
121 * close x x 121 * close x x
122 * drain x x 122 * drain x x
123 * query_encoding - x 123 * query_encoding - x
124 * set_params - x 124 * set_params - x
125 * round_blocksize - x 125 * round_blocksize - x
126 * commit_settings - x 126 * commit_settings - x
127 * init_output x x 127 * init_output x x
128 * init_input x x 128 * init_input x x
129 * start_output x x 129 * start_output x x
130 * start_input x x 130 * start_input x x
131 * halt_output x x 131 * halt_output x x
132 * halt_input x x 132 * halt_input x x
133 * speaker_ctl x x 133 * speaker_ctl x x
134 * getdev - x 134 * getdev - x
135 * setfd - x 135 * setfd - x
136 * set_port - x 136 * set_port - x
137 * get_port - x 137 * get_port - x
138 * query_devinfo - x 138 * query_devinfo - x
139 * allocm - - Called at attach time 139 * allocm - - Called at attach time
140 * freem - - Called at attach time 140 * freem - - Called at attach time
141 * round_buffersize - x 141 * round_buffersize - x
142 * mappage - - Mem. unchanged after attach 142 * mappage - - Mem. unchanged after attach
143 * get_props - x 143 * get_props - x
144 * trigger_output x x 144 * trigger_output x x
145 * trigger_input x x 145 * trigger_input x x
146 * dev_ioctl - x 146 * dev_ioctl - x
147 * get_locks - - Called at attach time 147 * get_locks - - Called at attach time
148 */ 148 */
149 149
150#include <sys/cdefs.h> 150#include <sys/cdefs.h>
151__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.395 2017/08/15 05:05:32 isaki Exp $"); 151__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.396 2017/08/15 05:11:25 isaki Exp $");
152 152
153#ifdef _KERNEL_OPT 153#ifdef _KERNEL_OPT
154#include "audio.h" 154#include "audio.h"
155#include "midi.h" 155#include "midi.h"
156#endif 156#endif
157 157
158#if NAUDIO > 0 158#if NAUDIO > 0
159 159
160#include <sys/types.h> 160#include <sys/types.h>
161#include <sys/param.h> 161#include <sys/param.h>
162#include <sys/ioctl.h> 162#include <sys/ioctl.h>
163#include <sys/fcntl.h> 163#include <sys/fcntl.h>
164#include <sys/file.h> 164#include <sys/file.h>
165#include <sys/filedesc.h> 165#include <sys/filedesc.h>
166#include <sys/vnode.h> 166#include <sys/vnode.h>
167#include <sys/select.h> 167#include <sys/select.h>
168#include <sys/poll.h> 168#include <sys/poll.h>
169#include <sys/kauth.h> 169#include <sys/kauth.h>
170#include <sys/kmem.h> 170#include <sys/kmem.h>
171#include <sys/malloc.h> 171#include <sys/malloc.h>
172#include <sys/module.h> 172#include <sys/module.h>
173#include <sys/proc.h> 173#include <sys/proc.h>
174#include <sys/queue.h> 174#include <sys/queue.h>
175#include <sys/stat.h> 175#include <sys/stat.h>
176#include <sys/systm.h> 176#include <sys/systm.h>
177#include <sys/sysctl.h> 177#include <sys/sysctl.h>
178#include <sys/syslog.h> 178#include <sys/syslog.h>
179#include <sys/kernel.h> 179#include <sys/kernel.h>
180#include <sys/signalvar.h> 180#include <sys/signalvar.h>
181#include <sys/conf.h> 181#include <sys/conf.h>
182#include <sys/audioio.h> 182#include <sys/audioio.h>
183#include <sys/device.h> 183#include <sys/device.h>
184#include <sys/intr.h> 184#include <sys/intr.h>
185#include <sys/kthread.h> 185#include <sys/kthread.h>
186#include <sys/cpu.h> 186#include <sys/cpu.h>
187#include <sys/mman.h> 187#include <sys/mman.h>
188 188
189#include <dev/audio_if.h> 189#include <dev/audio_if.h>
190#include <dev/audiovar.h> 190#include <dev/audiovar.h>
191#include <dev/auconv.h> 191#include <dev/auconv.h>
192#include <dev/auvolconv.h> 192#include <dev/auvolconv.h>
193 193
194#include <machine/endian.h> 194#include <machine/endian.h>
195 195
196#include <uvm/uvm.h> 196#include <uvm/uvm.h>
197 197
198/* #define AUDIO_DEBUG 1 */ 198/* #define AUDIO_DEBUG 1 */
199#ifdef AUDIO_DEBUG 199#ifdef AUDIO_DEBUG
200#define DPRINTF(x) if (audiodebug) printf x 200#define DPRINTF(x) if (audiodebug) printf x
201#define DPRINTFN(n,x) if (audiodebug>(n)) printf x 201#define DPRINTFN(n,x) if (audiodebug>(n)) printf x
202int audiodebug = AUDIO_DEBUG; 202int audiodebug = AUDIO_DEBUG;
203#else 203#else
204#define DPRINTF(x) 204#define DPRINTF(x)
205#define DPRINTFN(n,x) 205#define DPRINTFN(n,x)
206#endif 206#endif
207 207
208#define ROUNDSIZE(x) (x) &= -16 /* round to nice boundary */ 208#define ROUNDSIZE(x) (x) &= -16 /* round to nice boundary */
209#define SPECIFIED(x) ((int)(x) != ~0) 209#define SPECIFIED(x) ((int)(x) != ~0)
210#define SPECIFIED_CH(x) ((x) != (u_char)~0) 210#define SPECIFIED_CH(x) ((x) != (u_char)~0)
211 211
212/* #define AUDIO_PM_IDLE */ 212/* #define AUDIO_PM_IDLE */
213#ifdef AUDIO_PM_IDLE 213#ifdef AUDIO_PM_IDLE
214int audio_idle_timeout = 30; 214int audio_idle_timeout = 30;
215#endif 215#endif
216 216
217#define HW_LOCK(x) do { \ 217#define HW_LOCK(x) do { \
218 if ((x) == sc->sc_hwvc) \ 218 if ((x) == sc->sc_hwvc) \
219 mutex_enter(sc->sc_intr_lock); \ 219 mutex_enter(sc->sc_intr_lock); \
220} while (0) 220} while (0)
221 221
222#define HW_UNLOCK(x) do { \ 222#define HW_UNLOCK(x) do { \
223 if ((x) == sc->sc_hwvc) \ 223 if ((x) == sc->sc_hwvc) \
224 mutex_exit(sc->sc_intr_lock); \ 224 mutex_exit(sc->sc_intr_lock); \
225} while (0) 225} while (0)
226 226
227int audio_blk_ms = AUDIO_BLK_MS; 227int audio_blk_ms = AUDIO_BLK_MS;
228 228
229int audiosetinfo(struct audio_softc *, struct audio_info *, bool, 229int audiosetinfo(struct audio_softc *, struct audio_info *, bool,
230 struct virtual_channel *); 230 struct virtual_channel *);
231int audiogetinfo(struct audio_softc *, struct audio_info *, int, 231int audiogetinfo(struct audio_softc *, struct audio_info *, int,
232 struct virtual_channel *); 232 struct virtual_channel *);
233 233
234int audio_open(dev_t, struct audio_softc *, int, int, struct lwp *, 234int audio_open(dev_t, struct audio_softc *, int, int, struct lwp *,
235 struct file **); 235 struct file **);
236int audio_close(struct audio_softc *, int, struct audio_chan *); 236int audio_close(struct audio_softc *, int, struct audio_chan *);
237int audio_read(struct audio_softc *, struct uio *, int, 237int audio_read(struct audio_softc *, struct uio *, int,
238 struct virtual_channel *); 238 struct virtual_channel *);
239int audio_write(struct audio_softc *, struct uio *, int, 239int audio_write(struct audio_softc *, struct uio *, int,
240 struct virtual_channel *); 240 struct virtual_channel *);
241int audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int, 241int audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int,
242 struct lwp *, struct audio_chan *); 242 struct lwp *, struct audio_chan *);
243int audio_poll(struct audio_softc *, int, struct lwp *, 243int audio_poll(struct audio_softc *, int, struct lwp *,
244 struct virtual_channel *); 244 struct virtual_channel *);
245int audio_kqfilter(struct audio_chan *, struct knote *); 245int audio_kqfilter(struct audio_chan *, struct knote *);
246int audio_mmap(struct audio_softc *, off_t *, size_t, int, int *, int *, 246int audio_mmap(struct audio_softc *, off_t *, size_t, int, int *, int *,
247 struct uvm_object **, int *, struct virtual_channel *); 247 struct uvm_object **, int *, struct virtual_channel *);
248static int audio_fop_mmap(struct file *, off_t *, size_t, int, int *, int *, 248static int audio_fop_mmap(struct file *, off_t *, size_t, int, int *, int *,
249 struct uvm_object **, int *); 249 struct uvm_object **, int *);
250 250
251int mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *, 251int mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *,
252 struct file **); 252 struct file **);
253int mixer_close(struct audio_softc *, int, struct audio_chan *); 253int mixer_close(struct audio_softc *, int, struct audio_chan *);
254int mixer_ioctl(struct audio_softc *, u_long, void *, int, struct lwp *); 254int mixer_ioctl(struct audio_softc *, u_long, void *, int, struct lwp *);
255static void mixer_remove(struct audio_softc *); 255static void mixer_remove(struct audio_softc *);
256static void mixer_signal(struct audio_softc *); 256static void mixer_signal(struct audio_softc *);
257static void grow_mixer_states(struct audio_softc *, int); 257static void grow_mixer_states(struct audio_softc *, int);
258static void shrink_mixer_states(struct audio_softc *, int); 258static void shrink_mixer_states(struct audio_softc *, int);
259 259
260void audio_init_record(struct audio_softc *, struct virtual_channel *); 260void audio_init_record(struct audio_softc *, struct virtual_channel *);
261void audio_init_play(struct audio_softc *, struct virtual_channel *); 261void audio_init_play(struct audio_softc *, struct virtual_channel *);
262int audiostartr(struct audio_softc *, struct virtual_channel *); 262int audiostartr(struct audio_softc *, struct virtual_channel *);
263int audiostartp(struct audio_softc *, struct virtual_channel *); 263int audiostartp(struct audio_softc *, struct virtual_channel *);
264void audio_rint(void *); 264void audio_rint(void *);
265void audio_pint(void *); 265void audio_pint(void *);
266void audio_mix(void *); 266void audio_mix(void *);
267void audio_upmix(void *); 267void audio_upmix(void *);
268void audio_play_thread(void *); 268void audio_play_thread(void *);
269void audio_rec_thread(void *); 269void audio_rec_thread(void *);
270void recswvol_func(struct audio_softc *, struct audio_ringbuffer *, 270void recswvol_func(struct audio_softc *, struct audio_ringbuffer *,
271 size_t, struct virtual_channel *); 271 size_t, struct virtual_channel *);
272void mix_func(struct audio_softc *, struct audio_ringbuffer *, 272void mix_func(struct audio_softc *, struct audio_ringbuffer *,
273 struct virtual_channel *); 273 struct virtual_channel *);
274int mix_write(void *); 274int mix_write(void *);
275int mix_read(void *); 275int mix_read(void *);
276int audio_check_params(struct audio_params *); 276int audio_check_params(struct audio_params *);
277 277
278void audio_calc_blksize(struct audio_softc *, int, struct virtual_channel *); 278void audio_calc_blksize(struct audio_softc *, int, struct virtual_channel *);
279void audio_fill_silence(const struct audio_params *, uint8_t *, int); 279void audio_fill_silence(const struct audio_params *, uint8_t *, int);
280int audio_silence_copyout(struct audio_softc *, int, struct uio *); 280int audio_silence_copyout(struct audio_softc *, int, struct uio *);
281 281
282static int audio_allocbufs(struct audio_softc *, struct virtual_channel *); 282static int audio_allocbufs(struct audio_softc *);
283void audio_init_ringbuffer(struct audio_softc *, 283void audio_init_ringbuffer(struct audio_softc *,
284 struct audio_ringbuffer *, int); 284 struct audio_ringbuffer *, int);
285int audio_initbufs(struct audio_softc *, struct virtual_channel *); 285int audio_initbufs(struct audio_softc *, struct virtual_channel *);
286void audio_calcwater(struct audio_softc *, struct virtual_channel *); 286void audio_calcwater(struct audio_softc *, struct virtual_channel *);
287int audio_drain(struct audio_softc *, struct virtual_channel *); 287int audio_drain(struct audio_softc *, struct virtual_channel *);
288void audio_clear(struct audio_softc *, struct virtual_channel *); 288void audio_clear(struct audio_softc *, struct virtual_channel *);
289void audio_clear_intr_unlocked(struct audio_softc *sc, 289void audio_clear_intr_unlocked(struct audio_softc *sc,
290 struct virtual_channel *); 290 struct virtual_channel *);
291static inline void 291static inline void
292 audio_pint_silence(struct audio_softc *, struct audio_ringbuffer *, 292 audio_pint_silence(struct audio_softc *, struct audio_ringbuffer *,
293 uint8_t *, int, struct virtual_channel *); 293 uint8_t *, int, struct virtual_channel *);
294int audio_alloc_ring(struct audio_softc *, struct audio_ringbuffer *, int, 294int audio_alloc_ring(struct audio_softc *, struct audio_ringbuffer *, int,
295 size_t); 295 size_t);
296void audio_free_ring(struct audio_softc *, struct audio_ringbuffer *); 296void audio_free_ring(struct audio_softc *, struct audio_ringbuffer *);
297static int audio_setup_pfilters(struct audio_softc *, const audio_params_t *, 297static int audio_setup_pfilters(struct audio_softc *, const audio_params_t *,
298 stream_filter_list_t *, struct virtual_channel *); 298 stream_filter_list_t *, struct virtual_channel *);
299static int audio_setup_rfilters(struct audio_softc *, const audio_params_t *, 299static int audio_setup_rfilters(struct audio_softc *, const audio_params_t *,
300 stream_filter_list_t *, struct virtual_channel *); 300 stream_filter_list_t *, struct virtual_channel *);
301static void audio_destroy_pfilters(struct virtual_channel *); 301static void audio_destroy_pfilters(struct virtual_channel *);
302static void audio_destroy_rfilters(struct virtual_channel *); 302static void audio_destroy_rfilters(struct virtual_channel *);
303static void audio_stream_dtor(audio_stream_t *); 303static void audio_stream_dtor(audio_stream_t *);
304static int audio_stream_ctor(audio_stream_t *, const audio_params_t *, int); 304static int audio_stream_ctor(audio_stream_t *, const audio_params_t *, int);
305static void stream_filter_list_append(stream_filter_list_t *, 305static void stream_filter_list_append(stream_filter_list_t *,
306 stream_filter_factory_t, const audio_params_t *); 306 stream_filter_factory_t, const audio_params_t *);
307static void stream_filter_list_prepend(stream_filter_list_t *, 307static void stream_filter_list_prepend(stream_filter_list_t *,
308 stream_filter_factory_t, const audio_params_t *); 308 stream_filter_factory_t, const audio_params_t *);
309static void stream_filter_list_set(stream_filter_list_t *, int, 309static void stream_filter_list_set(stream_filter_list_t *, int,
310 stream_filter_factory_t, const audio_params_t *); 310 stream_filter_factory_t, const audio_params_t *);
311int audio_set_defaults(struct audio_softc *, u_int, 311int audio_set_defaults(struct audio_softc *, u_int,
312 struct virtual_channel *); 312 struct virtual_channel *);
313static int audio_sysctl_frequency(SYSCTLFN_PROTO); 313static int audio_sysctl_frequency(SYSCTLFN_PROTO);
314static int audio_sysctl_precision(SYSCTLFN_PROTO); 314static int audio_sysctl_precision(SYSCTLFN_PROTO);
315static int audio_sysctl_channels(SYSCTLFN_PROTO); 315static int audio_sysctl_channels(SYSCTLFN_PROTO);
316 316
317static int audiomatch(device_t, cfdata_t, void *); 317static int audiomatch(device_t, cfdata_t, void *);
318static void audioattach(device_t, device_t, void *); 318static void audioattach(device_t, device_t, void *);
319static int audiodetach(device_t, int); 319static int audiodetach(device_t, int);
320static int audioactivate(device_t, enum devact); 320static int audioactivate(device_t, enum devact);
321static void audiochilddet(device_t, device_t); 321static void audiochilddet(device_t, device_t);
322static int audiorescan(device_t, const char *, const int *); 322static int audiorescan(device_t, const char *, const int *);
323 323
324static int audio_modcmd(modcmd_t, void *); 324static int audio_modcmd(modcmd_t, void *);
325 325
326#ifdef AUDIO_PM_IDLE 326#ifdef AUDIO_PM_IDLE
327static void audio_idle(void *); 327static void audio_idle(void *);
328static void audio_activity(device_t, devactive_t); 328static void audio_activity(device_t, devactive_t);
329#endif 329#endif
330 330
331static bool audio_suspend(device_t dv, const pmf_qual_t *); 331static bool audio_suspend(device_t dv, const pmf_qual_t *);
332static bool audio_resume(device_t dv, const pmf_qual_t *); 332static bool audio_resume(device_t dv, const pmf_qual_t *);
333static void audio_volume_down(device_t); 333static void audio_volume_down(device_t);
334static void audio_volume_up(device_t); 334static void audio_volume_up(device_t);
335static void audio_volume_toggle(device_t); 335static void audio_volume_toggle(device_t);
336 336
337static void audio_mixer_capture(struct audio_softc *); 337static void audio_mixer_capture(struct audio_softc *);
338static void audio_mixer_restore(struct audio_softc *); 338static void audio_mixer_restore(struct audio_softc *);
339 339
340static int audio_get_props(struct audio_softc *); 340static int audio_get_props(struct audio_softc *);
341static bool audio_can_playback(struct audio_softc *); 341static bool audio_can_playback(struct audio_softc *);
342static bool audio_can_capture(struct audio_softc *); 342static bool audio_can_capture(struct audio_softc *);
343 343
344static void audio_softintr_rd(void *); 344static void audio_softintr_rd(void *);
345static void audio_softintr_wr(void *); 345static void audio_softintr_wr(void *);
346 346
347static int audio_enter(dev_t, krw_t, struct audio_softc **); 347static int audio_enter(dev_t, krw_t, struct audio_softc **);
348static void audio_exit(struct audio_softc *); 348static void audio_exit(struct audio_softc *);
349static int audio_waitio(struct audio_softc *, kcondvar_t *, 349static int audio_waitio(struct audio_softc *, kcondvar_t *,
350 struct virtual_channel *); 350 struct virtual_channel *);
351 351
352static int audioclose(struct file *); 352static int audioclose(struct file *);
353static int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int); 353static int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int);
354static int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int); 354static int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int);
355static int audioioctl(struct file *, u_long, void *); 355static int audioioctl(struct file *, u_long, void *);
356static int audiopoll(struct file *, int); 356static int audiopoll(struct file *, int);
357static int audiokqfilter(struct file *, struct knote *); 357static int audiokqfilter(struct file *, struct knote *);
358static int audiostat(struct file *, struct stat *); 358static int audiostat(struct file *, struct stat *);
359 359
360struct portname { 360struct portname {
361 const char *name; 361 const char *name;
362 int mask; 362 int mask;
363}; 363};
364static const struct portname itable[] = { 364static const struct portname itable[] = {
365 { AudioNmicrophone, AUDIO_MICROPHONE }, 365 { AudioNmicrophone, AUDIO_MICROPHONE },
366 { AudioNline, AUDIO_LINE_IN }, 366 { AudioNline, AUDIO_LINE_IN },
367 { AudioNcd, AUDIO_CD }, 367 { AudioNcd, AUDIO_CD },
368 { 0, 0 } 368 { 0, 0 }
369}; 369};
370static const struct portname otable[] = { 370static const struct portname otable[] = {
371 { AudioNspeaker, AUDIO_SPEAKER }, 371 { AudioNspeaker, AUDIO_SPEAKER },
372 { AudioNheadphone, AUDIO_HEADPHONE }, 372 { AudioNheadphone, AUDIO_HEADPHONE },
373 { AudioNline, AUDIO_LINE_OUT }, 373 { AudioNline, AUDIO_LINE_OUT },
374 { 0, 0 } 374 { 0, 0 }
375}; 375};
376void au_setup_ports(struct audio_softc *, struct au_mixer_ports *, 376void au_setup_ports(struct audio_softc *, struct au_mixer_ports *,
377 mixer_devinfo_t *, const struct portname *); 377 mixer_devinfo_t *, const struct portname *);
378int au_set_gain(struct audio_softc *, struct au_mixer_ports *, 378int au_set_gain(struct audio_softc *, struct au_mixer_ports *,
379 int, int); 379 int, int);
380void au_get_gain(struct audio_softc *, struct au_mixer_ports *, 380void au_get_gain(struct audio_softc *, struct au_mixer_ports *,
381 u_int *, u_char *); 381 u_int *, u_char *);
382int au_set_port(struct audio_softc *, struct au_mixer_ports *, 382int au_set_port(struct audio_softc *, struct au_mixer_ports *,
383 u_int); 383 u_int);
384int au_get_port(struct audio_softc *, struct au_mixer_ports *); 384int au_get_port(struct audio_softc *, struct au_mixer_ports *);
385static int 385static int
386 audio_get_port(struct audio_softc *, mixer_ctrl_t *); 386 audio_get_port(struct audio_softc *, mixer_ctrl_t *);
387static int 387static int
388 audio_set_port(struct audio_softc *, mixer_ctrl_t *); 388 audio_set_port(struct audio_softc *, mixer_ctrl_t *);
389static int 389static int
390 audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *); 390 audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *);
391static int audio_set_params (struct audio_softc *, int, int, 391static int audio_set_params (struct audio_softc *, int, int,
392 audio_params_t *, audio_params_t *, 392 audio_params_t *, audio_params_t *,
393 stream_filter_list_t *, stream_filter_list_t *, 393 stream_filter_list_t *, stream_filter_list_t *,
394 const struct virtual_channel *); 394 const struct virtual_channel *);
395static int 395static int
396audio_query_encoding(struct audio_softc *, struct audio_encoding *); 396audio_query_encoding(struct audio_softc *, struct audio_encoding *);
397static int audio_set_vchan_defaults(struct audio_softc *, u_int); 397static int audio_set_vchan_defaults(struct audio_softc *, u_int);
398static int vchan_autoconfig(struct audio_softc *); 398static int vchan_autoconfig(struct audio_softc *);
399int au_get_lr_value(struct audio_softc *, mixer_ctrl_t *, int *, int *); 399int au_get_lr_value(struct audio_softc *, mixer_ctrl_t *, int *, int *);
400int au_set_lr_value(struct audio_softc *, mixer_ctrl_t *, int, int); 400int au_set_lr_value(struct audio_softc *, mixer_ctrl_t *, int, int);
401int au_portof(struct audio_softc *, char *, int); 401int au_portof(struct audio_softc *, char *, int);
402 402
403typedef struct uio_fetcher { 403typedef struct uio_fetcher {
404 stream_fetcher_t base; 404 stream_fetcher_t base;
405 struct uio *uio; 405 struct uio *uio;
406 int usedhigh; 406 int usedhigh;
407 int last_used; 407 int last_used;
408} uio_fetcher_t; 408} uio_fetcher_t;
409 409
410static void uio_fetcher_ctor(uio_fetcher_t *, struct uio *, int); 410static void uio_fetcher_ctor(uio_fetcher_t *, struct uio *, int);
411static int uio_fetcher_fetch_to(struct audio_softc *, stream_fetcher_t *, 411static int uio_fetcher_fetch_to(struct audio_softc *, stream_fetcher_t *,
412 audio_stream_t *, int); 412 audio_stream_t *, int);
413static int null_fetcher_fetch_to(struct audio_softc *, stream_fetcher_t *, 413static int null_fetcher_fetch_to(struct audio_softc *, stream_fetcher_t *,
414 audio_stream_t *, int); 414 audio_stream_t *, int);
415 415
416static dev_type_open(audioopen); 416static dev_type_open(audioopen);
417/* XXXMRG use more dev_type_xxx */ 417/* XXXMRG use more dev_type_xxx */
418 418
419const struct cdevsw audio_cdevsw = { 419const struct cdevsw audio_cdevsw = {
420 .d_open = audioopen, 420 .d_open = audioopen,
421 .d_close = noclose, 421 .d_close = noclose,
422 .d_read = noread, 422 .d_read = noread,
423 .d_write = nowrite, 423 .d_write = nowrite,
424 .d_ioctl = noioctl, 424 .d_ioctl = noioctl,
425 .d_stop = nostop, 425 .d_stop = nostop,
426 .d_tty = notty, 426 .d_tty = notty,
427 .d_poll = nopoll, 427 .d_poll = nopoll,
428 .d_mmap = nommap, 428 .d_mmap = nommap,
429 .d_kqfilter = nokqfilter, 429 .d_kqfilter = nokqfilter,
430 .d_discard = nodiscard, 430 .d_discard = nodiscard,
431 .d_flag = D_OTHER | D_MPSAFE 431 .d_flag = D_OTHER | D_MPSAFE
432}; 432};
433 433
434const struct fileops audio_fileops = { 434const struct fileops audio_fileops = {
435 .fo_read = audioread, 435 .fo_read = audioread,
436 .fo_write = audiowrite, 436 .fo_write = audiowrite,
437 .fo_ioctl = audioioctl, 437 .fo_ioctl = audioioctl,
438 .fo_fcntl = fnullop_fcntl, 438 .fo_fcntl = fnullop_fcntl,
439 .fo_stat = audiostat, 439 .fo_stat = audiostat,
440 .fo_poll = audiopoll, 440 .fo_poll = audiopoll,
441 .fo_close = audioclose, 441 .fo_close = audioclose,
442 .fo_mmap = audio_fop_mmap, 442 .fo_mmap = audio_fop_mmap,
443 .fo_kqfilter = audiokqfilter, 443 .fo_kqfilter = audiokqfilter,
444 .fo_restart = fnullop_restart 444 .fo_restart = fnullop_restart
445}; 445};
446 446
447/* The default audio mode: 8 kHz mono mu-law */ 447/* The default audio mode: 8 kHz mono mu-law */
448const struct audio_params audio_default = { 448const struct audio_params audio_default = {
449 .sample_rate = 8000, 449 .sample_rate = 8000,
450 .encoding = AUDIO_ENCODING_ULAW, 450 .encoding = AUDIO_ENCODING_ULAW,
451 .precision = 8, 451 .precision = 8,
452 .validbits = 8, 452 .validbits = 8,
453 .channels = 1, 453 .channels = 1,
454}; 454};
455 455
456int auto_config_precision[] = { 16, 8, 32 }; 456int auto_config_precision[] = { 16, 8, 32 };
457int auto_config_channels[] = { 2, AUDIO_MAX_CHANNELS, 10, 8, 6, 4, 1 }; 457int auto_config_channels[] = { 2, AUDIO_MAX_CHANNELS, 10, 8, 6, 4, 1 };
458int auto_config_freq[] = { 48000, 44100, 96000, 192000, 32000, 458int auto_config_freq[] = { 48000, 44100, 96000, 192000, 32000,
459 22050, 16000, 11025, 8000, 4000 }; 459 22050, 16000, 11025, 8000, 4000 };
460 460
461CFATTACH_DECL3_NEW(audio, sizeof(struct audio_softc), 461CFATTACH_DECL3_NEW(audio, sizeof(struct audio_softc),
462 audiomatch, audioattach, audiodetach, audioactivate, audiorescan, 462 audiomatch, audioattach, audiodetach, audioactivate, audiorescan,
463 audiochilddet, DVF_DETACH_SHUTDOWN); 463 audiochilddet, DVF_DETACH_SHUTDOWN);
464 464
465extern struct cfdriver audio_cd; 465extern struct cfdriver audio_cd;
466 466
467static int 467static int
468audiomatch(device_t parent, cfdata_t match, void *aux) 468audiomatch(device_t parent, cfdata_t match, void *aux)
469{ 469{
470 struct audio_attach_args *sa; 470 struct audio_attach_args *sa;
471 471
472 sa = aux; 472 sa = aux;
473 DPRINTF(("%s: type=%d sa=%p hw=%p\n", 473 DPRINTF(("%s: type=%d sa=%p hw=%p\n",
474 __func__, sa->type, sa, sa->hwif)); 474 __func__, sa->type, sa, sa->hwif));
475 return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0; 475 return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0;
476} 476}
477 477
478static void 478static void
479audioattach(device_t parent, device_t self, void *aux) 479audioattach(device_t parent, device_t self, void *aux)
480{ 480{
481 struct audio_softc *sc; 481 struct audio_softc *sc;
482 struct audio_attach_args *sa; 482 struct audio_attach_args *sa;
483 struct virtual_channel *vc; 483 struct virtual_channel *vc;
484 const struct audio_hw_if *hwp; 484 const struct audio_hw_if *hwp;
485 const struct sysctlnode *node; 485 const struct sysctlnode *node;
486 void *hdlp; 486 void *hdlp;
487 int error; 487 int error;
488 mixer_devinfo_t mi; 488 mixer_devinfo_t mi;
489 int iclass, mclass, oclass, rclass, props; 489 int iclass, mclass, oclass, rclass, props;
490 int record_master_found, record_source_found; 490 int record_master_found, record_source_found;
491 491
492 sc = device_private(self); 492 sc = device_private(self);
493 sc->dev = self; 493 sc->dev = self;
494 sa = aux; 494 sa = aux;
495 hwp = sa->hwif; 495 hwp = sa->hwif;
496 hdlp = sa->hdl; 496 hdlp = sa->hdl;
497 sc->sc_opens = 0; 497 sc->sc_opens = 0;
498 sc->sc_recopens = 0; 498 sc->sc_recopens = 0;
499 sc->sc_aivalid = false; 499 sc->sc_aivalid = false;
500 sc->sc_ready = true; 500 sc->sc_ready = true;
501 501
502 sc->sc_format[0].mode = AUMODE_PLAY | AUMODE_RECORD; 502 sc->sc_format[0].mode = AUMODE_PLAY | AUMODE_RECORD;
503 sc->sc_format[0].encoding = 503 sc->sc_format[0].encoding =
504#if BYTE_ORDER == LITTLE_ENDIAN 504#if BYTE_ORDER == LITTLE_ENDIAN
505 AUDIO_ENCODING_SLINEAR_LE; 505 AUDIO_ENCODING_SLINEAR_LE;
506#else 506#else
507 AUDIO_ENCODING_SLINEAR_BE; 507 AUDIO_ENCODING_SLINEAR_BE;
508#endif 508#endif
509 sc->sc_format[0].precision = 16; 509 sc->sc_format[0].precision = 16;
510 sc->sc_format[0].validbits = 16; 510 sc->sc_format[0].validbits = 16;
511 sc->sc_format[0].channels = 2; 511 sc->sc_format[0].channels = 2;
512 sc->sc_format[0].channel_mask = AUFMT_STEREO; 512 sc->sc_format[0].channel_mask = AUFMT_STEREO;
513 sc->sc_format[0].frequency_type = 1; 513 sc->sc_format[0].frequency_type = 1;
514 sc->sc_format[0].frequency[0] = 44100; 514 sc->sc_format[0].frequency[0] = 44100;
515 515
516 sc->sc_trigger_started = false; 516 sc->sc_trigger_started = false;
517 sc->sc_rec_started = false; 517 sc->sc_rec_started = false;
518 sc->sc_dying = false; 518 sc->sc_dying = false;
519 SIMPLEQ_INIT(&sc->sc_audiochan); 519 SIMPLEQ_INIT(&sc->sc_audiochan);
520 520
521 vc = kmem_zalloc(sizeof(struct virtual_channel), KM_SLEEP); 521 vc = kmem_zalloc(sizeof(struct virtual_channel), KM_SLEEP);
522 sc->sc_hwvc = vc; 522 sc->sc_hwvc = vc;
523 vc->sc_open = 0; 523 vc->sc_open = 0;
524 vc->sc_mode = 0; 524 vc->sc_mode = 0;
525 vc->sc_npfilters = 0; 525 vc->sc_npfilters = 0;
526 vc->sc_nrfilters = 0; 526 vc->sc_nrfilters = 0;
527 memset(vc->sc_pfilters, 0, sizeof(vc->sc_pfilters)); 527 memset(vc->sc_pfilters, 0, sizeof(vc->sc_pfilters));
528 memset(vc->sc_rfilters, 0, sizeof(vc->sc_rfilters)); 528 memset(vc->sc_rfilters, 0, sizeof(vc->sc_rfilters));
529 vc->sc_lastinfovalid = false; 529 vc->sc_lastinfovalid = false;
530 vc->sc_swvol = 255; 530 vc->sc_swvol = 255;
531 vc->sc_recswvol = 255; 531 vc->sc_recswvol = 255;
532 532
533 if (auconv_create_encodings(sc->sc_format, VAUDIO_NFORMATS, 533 if (auconv_create_encodings(sc->sc_format, VAUDIO_NFORMATS,
534 &sc->sc_encodings) != 0) { 534 &sc->sc_encodings) != 0) {
535 aprint_error_dev(self, "couldn't create encodings\n"); 535 aprint_error_dev(self, "couldn't create encodings\n");
536 return; 536 return;
537 } 537 }
538 538
539 cv_init(&sc->sc_rchan, "audiord"); 539 cv_init(&sc->sc_rchan, "audiord");
540 cv_init(&sc->sc_wchan, "audiowr"); 540 cv_init(&sc->sc_wchan, "audiowr");
541 cv_init(&sc->sc_lchan, "audiolk"); 541 cv_init(&sc->sc_lchan, "audiolk");
542 cv_init(&sc->sc_condvar,"play"); 542 cv_init(&sc->sc_condvar,"play");
543 cv_init(&sc->sc_rcondvar,"record"); 543 cv_init(&sc->sc_rcondvar,"record");
544 544
545 if (hwp == NULL || hwp->get_locks == NULL) { 545 if (hwp == NULL || hwp->get_locks == NULL) {
546 aprint_error(": missing method\n"); 546 aprint_error(": missing method\n");
547 panic("audioattach"); 547 panic("audioattach");
548 } 548 }
549 549
550 hwp->get_locks(hdlp, &sc->sc_intr_lock, &sc->sc_lock); 550 hwp->get_locks(hdlp, &sc->sc_intr_lock, &sc->sc_lock);
551 551
552#ifdef DIAGNOSTIC 552#ifdef DIAGNOSTIC
553 if (hwp->query_encoding == NULL || 553 if (hwp->query_encoding == NULL ||
554 hwp->set_params == NULL || 554 hwp->set_params == NULL ||
555 (hwp->start_output == NULL && hwp->trigger_output == NULL) || 555 (hwp->start_output == NULL && hwp->trigger_output == NULL) ||
556 (hwp->start_input == NULL && hwp->trigger_input == NULL) || 556 (hwp->start_input == NULL && hwp->trigger_input == NULL) ||
557 hwp->halt_output == NULL || 557 hwp->halt_output == NULL ||
558 hwp->halt_input == NULL || 558 hwp->halt_input == NULL ||
559 hwp->getdev == NULL || 559 hwp->getdev == NULL ||
560 hwp->set_port == NULL || 560 hwp->set_port == NULL ||
561 hwp->get_port == NULL || 561 hwp->get_port == NULL ||
562 hwp->query_devinfo == NULL || 562 hwp->query_devinfo == NULL ||
563 hwp->get_props == NULL) { 563 hwp->get_props == NULL) {
564 aprint_error(": missing method\n"); 564 aprint_error(": missing method\n");
565 return; 565 return;
566 } 566 }
567#endif 567#endif
568 568
569 sc->hw_if = hwp; 569 sc->hw_if = hwp;
570 sc->hw_hdl = hdlp; 570 sc->hw_hdl = hdlp;
571 sc->sc_dev = parent; 571 sc->sc_dev = parent;
572 572
573 mutex_enter(sc->sc_lock); 573 mutex_enter(sc->sc_lock);
574 props = audio_get_props(sc); 574 props = audio_get_props(sc);
575 mutex_exit(sc->sc_lock); 575 mutex_exit(sc->sc_lock);
576 576
577 if (props & AUDIO_PROP_FULLDUPLEX) 577 if (props & AUDIO_PROP_FULLDUPLEX)
578 aprint_normal(": full duplex"); 578 aprint_normal(": full duplex");
579 else 579 else
580 aprint_normal(": half duplex"); 580 aprint_normal(": half duplex");
581 581
582 if (props & AUDIO_PROP_PLAYBACK) 582 if (props & AUDIO_PROP_PLAYBACK)
583 aprint_normal(", playback"); 583 aprint_normal(", playback");
584 if (props & AUDIO_PROP_CAPTURE) 584 if (props & AUDIO_PROP_CAPTURE)
585 aprint_normal(", capture"); 585 aprint_normal(", capture");
586 if (props & AUDIO_PROP_MMAP) 586 if (props & AUDIO_PROP_MMAP)
587 aprint_normal(", mmap"); 587 aprint_normal(", mmap");
588 if (props & AUDIO_PROP_INDEPENDENT) 588 if (props & AUDIO_PROP_INDEPENDENT)
589 aprint_normal(", independent"); 589 aprint_normal(", independent");
590 590
591 aprint_naive("\n"); 591 aprint_naive("\n");
592 aprint_normal("\n"); 592 aprint_normal("\n");
593 593
594 mutex_enter(sc->sc_lock); 594 mutex_enter(sc->sc_lock);
595 if (audio_allocbufs(sc, vc) != 0) { 595 if (audio_allocbufs(sc) != 0) {
596 aprint_error_dev(sc->sc_dev, 596 aprint_error_dev(sc->sc_dev,
597 "could not allocate ring buffer\n"); 597 "could not allocate ring buffer\n");
598 mutex_exit(sc->sc_lock); 598 mutex_exit(sc->sc_lock);
599 return; 599 return;
600 } 600 }
601 mutex_exit(sc->sc_lock); 601 mutex_exit(sc->sc_lock);
602 602
603 sc->sc_lastgain = 128; 603 sc->sc_lastgain = 128;
604 sc->sc_multiuser = false; 604 sc->sc_multiuser = false;
605 605
606 error = vchan_autoconfig(sc); 606 error = vchan_autoconfig(sc);
607 if (error != 0) { 607 if (error != 0) {
608 aprint_error_dev(sc->sc_dev, "%s: audio_set_vchan_defaults() " 608 aprint_error_dev(sc->sc_dev, "%s: audio_set_vchan_defaults() "
609 "failed\n", __func__); 609 "failed\n", __func__);
610 } 610 }
611 611
612 sc->sc_sih_rd = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE, 612 sc->sc_sih_rd = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE,
613 audio_softintr_rd, sc); 613 audio_softintr_rd, sc);
614 sc->sc_sih_wr = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE, 614 sc->sc_sih_wr = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE,
615 audio_softintr_wr, sc); 615 audio_softintr_wr, sc);
616 616
617 iclass = mclass = oclass = rclass = -1; 617 iclass = mclass = oclass = rclass = -1;
618 sc->sc_inports.index = -1; 618 sc->sc_inports.index = -1;
619 sc->sc_inports.master = -1; 619 sc->sc_inports.master = -1;
620 sc->sc_inports.nports = 0; 620 sc->sc_inports.nports = 0;
621 sc->sc_inports.isenum = false; 621 sc->sc_inports.isenum = false;
622 sc->sc_inports.allports = 0; 622 sc->sc_inports.allports = 0;
623 sc->sc_inports.isdual = false; 623 sc->sc_inports.isdual = false;
624 sc->sc_inports.mixerout = -1; 624 sc->sc_inports.mixerout = -1;
625 sc->sc_inports.cur_port = -1; 625 sc->sc_inports.cur_port = -1;
626 sc->sc_outports.index = -1; 626 sc->sc_outports.index = -1;
627 sc->sc_outports.master = -1; 627 sc->sc_outports.master = -1;
628 sc->sc_outports.nports = 0; 628 sc->sc_outports.nports = 0;
629 sc->sc_outports.isenum = false; 629 sc->sc_outports.isenum = false;
630 sc->sc_outports.allports = 0; 630 sc->sc_outports.allports = 0;
631 sc->sc_outports.isdual = false; 631 sc->sc_outports.isdual = false;
632 sc->sc_outports.mixerout = -1; 632 sc->sc_outports.mixerout = -1;
633 sc->sc_outports.cur_port = -1; 633 sc->sc_outports.cur_port = -1;
634 sc->sc_monitor_port = -1; 634 sc->sc_monitor_port = -1;
635 /* 635 /*
636 * Read through the underlying driver's list, picking out the class 636 * Read through the underlying driver's list, picking out the class
637 * names from the mixer descriptions. We'll need them to decode the 637 * names from the mixer descriptions. We'll need them to decode the
638 * mixer descriptions on the next pass through the loop. 638 * mixer descriptions on the next pass through the loop.
639 */ 639 */
640 mutex_enter(sc->sc_lock); 640 mutex_enter(sc->sc_lock);
641 for(mi.index = 0; ; mi.index++) { 641 for(mi.index = 0; ; mi.index++) {
642 if (audio_query_devinfo(sc, &mi) != 0) 642 if (audio_query_devinfo(sc, &mi) != 0)
643 break; 643 break;
644 /* 644 /*
645 * The type of AUDIO_MIXER_CLASS merely introduces a class. 645 * The type of AUDIO_MIXER_CLASS merely introduces a class.
646 * All the other types describe an actual mixer. 646 * All the other types describe an actual mixer.
647 */ 647 */
648 if (mi.type == AUDIO_MIXER_CLASS) { 648 if (mi.type == AUDIO_MIXER_CLASS) {
649 if (strcmp(mi.label.name, AudioCinputs) == 0) 649 if (strcmp(mi.label.name, AudioCinputs) == 0)
650 iclass = mi.mixer_class; 650 iclass = mi.mixer_class;
651 if (strcmp(mi.label.name, AudioCmonitor) == 0) 651 if (strcmp(mi.label.name, AudioCmonitor) == 0)
652 mclass = mi.mixer_class; 652 mclass = mi.mixer_class;
653 if (strcmp(mi.label.name, AudioCoutputs) == 0) 653 if (strcmp(mi.label.name, AudioCoutputs) == 0)
654 oclass = mi.mixer_class; 654 oclass = mi.mixer_class;
655 if (strcmp(mi.label.name, AudioCrecord) == 0) 655 if (strcmp(mi.label.name, AudioCrecord) == 0)
656 rclass = mi.mixer_class; 656 rclass = mi.mixer_class;
657 } 657 }
658 } 658 }
659 mutex_exit(sc->sc_lock); 659 mutex_exit(sc->sc_lock);
660 660
661 /* Allocate save area. Ensure non-zero allocation. */ 661 /* Allocate save area. Ensure non-zero allocation. */
662 sc->sc_static_nmixer_states = mi.index; 662 sc->sc_static_nmixer_states = mi.index;
663 sc->sc_static_nmixer_states++; 663 sc->sc_static_nmixer_states++;
664 sc->sc_nmixer_states = sc->sc_static_nmixer_states; 664 sc->sc_nmixer_states = sc->sc_static_nmixer_states;
665 sc->sc_mixer_state = kmem_zalloc(sizeof(mixer_ctrl_t) * 665 sc->sc_mixer_state = kmem_zalloc(sizeof(mixer_ctrl_t) *
666 (sc->sc_nmixer_states + 1), KM_SLEEP); 666 (sc->sc_nmixer_states + 1), KM_SLEEP);
667 667
668 /* 668 /*
669 * This is where we assign each control in the "audio" model, to the 669 * This is where we assign each control in the "audio" model, to the
670 * underlying "mixer" control. We walk through the whole list once, 670 * underlying "mixer" control. We walk through the whole list once,
671 * assigning likely candidates as we come across them. 671 * assigning likely candidates as we come across them.
672 */ 672 */
673 record_master_found = 0; 673 record_master_found = 0;
674 record_source_found = 0; 674 record_source_found = 0;
675 mutex_enter(sc->sc_lock); 675 mutex_enter(sc->sc_lock);
676 for(mi.index = 0; ; mi.index++) { 676 for(mi.index = 0; ; mi.index++) {
677 if (audio_query_devinfo(sc, &mi) != 0) 677 if (audio_query_devinfo(sc, &mi) != 0)
678 break; 678 break;
679 KASSERT(mi.index < sc->sc_nmixer_states); 679 KASSERT(mi.index < sc->sc_nmixer_states);
680 if (mi.type == AUDIO_MIXER_CLASS) 680 if (mi.type == AUDIO_MIXER_CLASS)
681 continue; 681 continue;
682 if (mi.mixer_class == iclass) { 682 if (mi.mixer_class == iclass) {
683 /* 683 /*
684 * AudioCinputs is only a fallback, when we don't 684 * AudioCinputs is only a fallback, when we don't
685 * find what we're looking for in AudioCrecord, so 685 * find what we're looking for in AudioCrecord, so
686 * check the flags before accepting one of these. 686 * check the flags before accepting one of these.
687 */ 687 */
688 if (strcmp(mi.label.name, AudioNmaster) == 0 688 if (strcmp(mi.label.name, AudioNmaster) == 0
689 && record_master_found == 0) 689 && record_master_found == 0)
690 sc->sc_inports.master = mi.index; 690 sc->sc_inports.master = mi.index;
691 if (strcmp(mi.label.name, AudioNsource) == 0 691 if (strcmp(mi.label.name, AudioNsource) == 0
692 && record_source_found == 0) { 692 && record_source_found == 0) {
693 if (mi.type == AUDIO_MIXER_ENUM) { 693 if (mi.type == AUDIO_MIXER_ENUM) {
694 int i; 694 int i;
695 for(i = 0; i < mi.un.e.num_mem; i++) 695 for(i = 0; i < mi.un.e.num_mem; i++)
696 if (strcmp(mi.un.e.member[i].label.name, 696 if (strcmp(mi.un.e.member[i].label.name,
697 AudioNmixerout) == 0) 697 AudioNmixerout) == 0)
698 sc->sc_inports.mixerout = 698 sc->sc_inports.mixerout =
699 mi.un.e.member[i].ord; 699 mi.un.e.member[i].ord;
700 } 700 }
701 au_setup_ports(sc, &sc->sc_inports, &mi, 701 au_setup_ports(sc, &sc->sc_inports, &mi,
702 itable); 702 itable);
703 } 703 }
704 if (strcmp(mi.label.name, AudioNdac) == 0 && 704 if (strcmp(mi.label.name, AudioNdac) == 0 &&
705 sc->sc_outports.master == -1) 705 sc->sc_outports.master == -1)
706 sc->sc_outports.master = mi.index; 706 sc->sc_outports.master = mi.index;
707 } else if (mi.mixer_class == mclass) { 707 } else if (mi.mixer_class == mclass) {
708 if (strcmp(mi.label.name, AudioNmonitor) == 0) 708 if (strcmp(mi.label.name, AudioNmonitor) == 0)
709 sc->sc_monitor_port = mi.index; 709 sc->sc_monitor_port = mi.index;
710 } else if (mi.mixer_class == oclass) { 710 } else if (mi.mixer_class == oclass) {
711 if (strcmp(mi.label.name, AudioNmaster) == 0) 711 if (strcmp(mi.label.name, AudioNmaster) == 0)
712 sc->sc_outports.master = mi.index; 712 sc->sc_outports.master = mi.index;
713 if (strcmp(mi.label.name, AudioNselect) == 0) 713 if (strcmp(mi.label.name, AudioNselect) == 0)
714 au_setup_ports(sc, &sc->sc_outports, &mi, 714 au_setup_ports(sc, &sc->sc_outports, &mi,
715 otable); 715 otable);
716 } else if (mi.mixer_class == rclass) { 716 } else if (mi.mixer_class == rclass) {
717 /* 717 /*
718 * These are the preferred mixers for the audio record 718 * These are the preferred mixers for the audio record
719 * controls, so set the flags here, but don't check. 719 * controls, so set the flags here, but don't check.
720 */ 720 */
721 if (strcmp(mi.label.name, AudioNmaster) == 0) { 721 if (strcmp(mi.label.name, AudioNmaster) == 0) {
722 sc->sc_inports.master = mi.index; 722 sc->sc_inports.master = mi.index;
723 record_master_found = 1; 723 record_master_found = 1;
724 } 724 }
725#if 1 /* Deprecated. Use AudioNmaster. */ 725#if 1 /* Deprecated. Use AudioNmaster. */
726 if (strcmp(mi.label.name, AudioNrecord) == 0) { 726 if (strcmp(mi.label.name, AudioNrecord) == 0) {
727 sc->sc_inports.master = mi.index; 727 sc->sc_inports.master = mi.index;
728 record_master_found = 1; 728 record_master_found = 1;
729 } 729 }
730 if (strcmp(mi.label.name, AudioNvolume) == 0) { 730 if (strcmp(mi.label.name, AudioNvolume) == 0) {
731 sc->sc_inports.master = mi.index; 731 sc->sc_inports.master = mi.index;
732 record_master_found = 1; 732 record_master_found = 1;
733 } 733 }
734#endif 734#endif
735 if (strcmp(mi.label.name, AudioNsource) == 0) { 735 if (strcmp(mi.label.name, AudioNsource) == 0) {
736 if (mi.type == AUDIO_MIXER_ENUM) { 736 if (mi.type == AUDIO_MIXER_ENUM) {
737 int i; 737 int i;
738 for(i = 0; i < mi.un.e.num_mem; i++) 738 for(i = 0; i < mi.un.e.num_mem; i++)
739 if (strcmp(mi.un.e.member[i].label.name, 739 if (strcmp(mi.un.e.member[i].label.name,
740 AudioNmixerout) == 0) 740 AudioNmixerout) == 0)
741 sc->sc_inports.mixerout = 741 sc->sc_inports.mixerout =
742 mi.un.e.member[i].ord; 742 mi.un.e.member[i].ord;
743 } 743 }
744 au_setup_ports(sc, &sc->sc_inports, &mi, 744 au_setup_ports(sc, &sc->sc_inports, &mi,
745 itable); 745 itable);
746 record_source_found = 1; 746 record_source_found = 1;
747 } 747 }
748 } 748 }
749 } 749 }
750 mutex_exit(sc->sc_lock); 750 mutex_exit(sc->sc_lock);
751 DPRINTF(("audio_attach: inputs ports=0x%x, input master=%d, " 751 DPRINTF(("audio_attach: inputs ports=0x%x, input master=%d, "
752 "output ports=0x%x, output master=%d\n", 752 "output ports=0x%x, output master=%d\n",
753 sc->sc_inports.allports, sc->sc_inports.master, 753 sc->sc_inports.allports, sc->sc_inports.master,
754 sc->sc_outports.allports, sc->sc_outports.master)); 754 sc->sc_outports.allports, sc->sc_outports.master));
755 755
756 /* sysctl set-up for alternate configs */ 756 /* sysctl set-up for alternate configs */
757 sysctl_createv(&sc->sc_log, 0, NULL, &node, 757 sysctl_createv(&sc->sc_log, 0, NULL, &node,
758 0, 758 0,
759 CTLTYPE_NODE, device_xname(sc->sc_dev), 759 CTLTYPE_NODE, device_xname(sc->sc_dev),
760 SYSCTL_DESCR("audio format information"), 760 SYSCTL_DESCR("audio format information"),
761 NULL, 0, 761 NULL, 0,
762 NULL, 0, 762 NULL, 0,
763 CTL_HW, 763 CTL_HW,
764 CTL_CREATE, CTL_EOL); 764 CTL_CREATE, CTL_EOL);
765 765
766 if (node != NULL) { 766 if (node != NULL) {
767 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 767 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
768 CTLFLAG_READWRITE, 768 CTLFLAG_READWRITE,
769 CTLTYPE_INT, "frequency", 769 CTLTYPE_INT, "frequency",
770 SYSCTL_DESCR("intermediate frequency"), 770 SYSCTL_DESCR("intermediate frequency"),
771 audio_sysctl_frequency, 0, 771 audio_sysctl_frequency, 0,
772 (void *)sc, 0, 772 (void *)sc, 0,
773 CTL_HW, node->sysctl_num, 773 CTL_HW, node->sysctl_num,
774 CTL_CREATE, CTL_EOL); 774 CTL_CREATE, CTL_EOL);
775 775
776 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 776 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
777 CTLFLAG_READWRITE, 777 CTLFLAG_READWRITE,
778 CTLTYPE_INT, "precision", 778 CTLTYPE_INT, "precision",
779 SYSCTL_DESCR("intermediate precision"), 779 SYSCTL_DESCR("intermediate precision"),
780 audio_sysctl_precision, 0, 780 audio_sysctl_precision, 0,
781 (void *)sc, 0, 781 (void *)sc, 0,
782 CTL_HW, node->sysctl_num, 782 CTL_HW, node->sysctl_num,
783 CTL_CREATE, CTL_EOL); 783 CTL_CREATE, CTL_EOL);
784 784
785 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 785 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
786 CTLFLAG_READWRITE, 786 CTLFLAG_READWRITE,
787 CTLTYPE_INT, "channels", 787 CTLTYPE_INT, "channels",
788 SYSCTL_DESCR("intermediate channels"), 788 SYSCTL_DESCR("intermediate channels"),
789 audio_sysctl_channels, 0, 789 audio_sysctl_channels, 0,
790 (void *)sc, 0, 790 (void *)sc, 0,
791 CTL_HW, node->sysctl_num, 791 CTL_HW, node->sysctl_num,
792 CTL_CREATE, CTL_EOL); 792 CTL_CREATE, CTL_EOL);
793 793
794 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 794 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
795 CTLFLAG_READWRITE, 795 CTLFLAG_READWRITE,
796 CTLTYPE_BOOL, "multiuser", 796 CTLTYPE_BOOL, "multiuser",
797 SYSCTL_DESCR("allow multiple user acess"), 797 SYSCTL_DESCR("allow multiple user acess"),
798 NULL, 0, 798 NULL, 0,
799 &sc->sc_multiuser, 0, 799 &sc->sc_multiuser, 0,
800 CTL_HW, node->sysctl_num, 800 CTL_HW, node->sysctl_num,
801 CTL_CREATE, CTL_EOL); 801 CTL_CREATE, CTL_EOL);
802 } 802 }
803 803
804 selinit(&sc->sc_rsel); 804 selinit(&sc->sc_rsel);
805 selinit(&sc->sc_wsel); 805 selinit(&sc->sc_wsel);
806 806
807#ifdef AUDIO_PM_IDLE 807#ifdef AUDIO_PM_IDLE
808 callout_init(&sc->sc_idle_counter, 0); 808 callout_init(&sc->sc_idle_counter, 0);
809 callout_setfunc(&sc->sc_idle_counter, audio_idle, self); 809 callout_setfunc(&sc->sc_idle_counter, audio_idle, self);
810#endif 810#endif
811 811
812 if (!pmf_device_register(self, audio_suspend, audio_resume)) 812 if (!pmf_device_register(self, audio_suspend, audio_resume))
813 aprint_error_dev(self, "couldn't establish power handler\n"); 813 aprint_error_dev(self, "couldn't establish power handler\n");
814#ifdef AUDIO_PM_IDLE 814#ifdef AUDIO_PM_IDLE
815 if (!device_active_register(self, audio_activity)) 815 if (!device_active_register(self, audio_activity))
816 aprint_error_dev(self, "couldn't register activity handler\n"); 816 aprint_error_dev(self, "couldn't register activity handler\n");
817#endif 817#endif
818 818
819 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN, 819 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN,
820 audio_volume_down, true)) 820 audio_volume_down, true))
821 aprint_error_dev(self, "couldn't add volume down handler\n"); 821 aprint_error_dev(self, "couldn't add volume down handler\n");
822 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP, 822 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP,
823 audio_volume_up, true)) 823 audio_volume_up, true))
824 aprint_error_dev(self, "couldn't add volume up handler\n"); 824 aprint_error_dev(self, "couldn't add volume up handler\n");
825 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE, 825 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE,
826 audio_volume_toggle, true)) 826 audio_volume_toggle, true))
827 aprint_error_dev(self, "couldn't add volume toggle handler\n"); 827 aprint_error_dev(self, "couldn't add volume toggle handler\n");
828 828
829#ifdef AUDIO_PM_IDLE 829#ifdef AUDIO_PM_IDLE
830 callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz); 830 callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz);
831#endif 831#endif
832 kthread_create(PRI_SOFTSERIAL, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL, 832 kthread_create(PRI_SOFTSERIAL, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL,
833 audio_rec_thread, sc, &sc->sc_recthread, "audiorec"); 833 audio_rec_thread, sc, &sc->sc_recthread, "audiorec");
834 kthread_create(PRI_SOFTSERIAL, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL, 834 kthread_create(PRI_SOFTSERIAL, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL,
835 audio_play_thread, sc, &sc->sc_playthread, "audiomix"); 835 audio_play_thread, sc, &sc->sc_playthread, "audiomix");
836 audiorescan(self, "audio", NULL); 836 audiorescan(self, "audio", NULL);
837} 837}
838 838
839static int 839static int
840audioactivate(device_t self, enum devact act) 840audioactivate(device_t self, enum devact act)
841{ 841{
842 struct audio_softc *sc = device_private(self); 842 struct audio_softc *sc = device_private(self);
843 843
844 switch (act) { 844 switch (act) {
845 case DVACT_DEACTIVATE: 845 case DVACT_DEACTIVATE:
846 mutex_enter(sc->sc_lock); 846 mutex_enter(sc->sc_lock);
847 sc->sc_dying = true; 847 sc->sc_dying = true;
848 mutex_enter(sc->sc_intr_lock); 848 mutex_enter(sc->sc_intr_lock);
849 cv_broadcast(&sc->sc_condvar); 849 cv_broadcast(&sc->sc_condvar);
850 cv_broadcast(&sc->sc_rcondvar); 850 cv_broadcast(&sc->sc_rcondvar);
851 cv_broadcast(&sc->sc_wchan); 851 cv_broadcast(&sc->sc_wchan);
852 cv_broadcast(&sc->sc_rchan); 852 cv_broadcast(&sc->sc_rchan);
853 cv_broadcast(&sc->sc_lchan); 853 cv_broadcast(&sc->sc_lchan);
854 mutex_exit(sc->sc_intr_lock); 854 mutex_exit(sc->sc_intr_lock);
855 mutex_exit(sc->sc_lock); 855 mutex_exit(sc->sc_lock);
856 return 0; 856 return 0;
857 default: 857 default:
858 return EOPNOTSUPP; 858 return EOPNOTSUPP;
859 } 859 }
860} 860}
861 861
862static int 862static int
863audiodetach(device_t self, int flags) 863audiodetach(device_t self, int flags)
864{ 864{
865 struct audio_softc *sc; 865 struct audio_softc *sc;
866 struct audio_chan *chan; 866 struct audio_chan *chan;
867 int maj, mn, rc; 867 int maj, mn, rc;
868 868
869 sc = device_private(self); 869 sc = device_private(self);
870 DPRINTF(("audio_detach: sc=%p flags=%d\n", sc, flags)); 870 DPRINTF(("audio_detach: sc=%p flags=%d\n", sc, flags));
871 871
872 /* Start draining existing accessors of the device. */ 872 /* Start draining existing accessors of the device. */
873 if ((rc = config_detach_children(self, flags)) != 0) 873 if ((rc = config_detach_children(self, flags)) != 0)
874 return rc; 874 return rc;
875 mutex_enter(sc->sc_lock); 875 mutex_enter(sc->sc_lock);
876 sc->sc_dying = true; 876 sc->sc_dying = true;
877 cv_broadcast(&sc->sc_wchan); 877 cv_broadcast(&sc->sc_wchan);
878 cv_broadcast(&sc->sc_rchan); 878 cv_broadcast(&sc->sc_rchan);
879 mutex_enter(sc->sc_intr_lock); 879 mutex_enter(sc->sc_intr_lock);
880 cv_broadcast(&sc->sc_condvar); 880 cv_broadcast(&sc->sc_condvar);
881 cv_broadcast(&sc->sc_rcondvar); 881 cv_broadcast(&sc->sc_rcondvar);
882 mutex_exit(sc->sc_intr_lock); 882 mutex_exit(sc->sc_intr_lock);
883 mutex_exit(sc->sc_lock); 883 mutex_exit(sc->sc_lock);
884 kthread_join(sc->sc_playthread); 884 kthread_join(sc->sc_playthread);
885 kthread_join(sc->sc_recthread); 885 kthread_join(sc->sc_recthread);
886 mutex_enter(sc->sc_lock); 886 mutex_enter(sc->sc_lock);
887 cv_destroy(&sc->sc_condvar); 887 cv_destroy(&sc->sc_condvar);
888 cv_destroy(&sc->sc_rcondvar); 888 cv_destroy(&sc->sc_rcondvar);
889 mutex_exit(sc->sc_lock); 889 mutex_exit(sc->sc_lock);
890 890
891 /* delete sysctl nodes */ 891 /* delete sysctl nodes */
892 sysctl_teardown(&sc->sc_log); 892 sysctl_teardown(&sc->sc_log);
893 893
894 /* locate the major number */ 894 /* locate the major number */
895 maj = cdevsw_lookup_major(&audio_cdevsw); 895 maj = cdevsw_lookup_major(&audio_cdevsw);
896 896
897 /* 897 /*
898 * Nuke the vnodes for any open instances (calls close). 898 * Nuke the vnodes for any open instances (calls close).
899 * Will wait until any activity on the device nodes has ceased. 899 * Will wait until any activity on the device nodes has ceased.
900 * 900 *
901 * XXXAD NOT YET. 901 * XXXAD NOT YET.
902 * 902 *
903 * XXXAD NEED TO PREVENT NEW REFERENCES THROUGH AUDIO_ENTER(). 903 * XXXAD NEED TO PREVENT NEW REFERENCES THROUGH AUDIO_ENTER().
904 */ 904 */
905 mn = device_unit(self); 905 mn = device_unit(self);
906 vdevgone(maj, mn | SOUND_DEVICE, mn | SOUND_DEVICE, VCHR); 906 vdevgone(maj, mn | SOUND_DEVICE, mn | SOUND_DEVICE, VCHR);
907 vdevgone(maj, mn | AUDIO_DEVICE, mn | AUDIO_DEVICE, VCHR); 907 vdevgone(maj, mn | AUDIO_DEVICE, mn | AUDIO_DEVICE, VCHR);
908 vdevgone(maj, mn | AUDIOCTL_DEVICE, mn | AUDIOCTL_DEVICE, VCHR); 908 vdevgone(maj, mn | AUDIOCTL_DEVICE, mn | AUDIOCTL_DEVICE, VCHR);
909 vdevgone(maj, mn | MIXER_DEVICE, mn | MIXER_DEVICE, VCHR); 909 vdevgone(maj, mn | MIXER_DEVICE, mn | MIXER_DEVICE, VCHR);
910 910
911 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_DOWN, 911 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_DOWN,
912 audio_volume_down, true); 912 audio_volume_down, true);
913 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_UP, 913 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_UP,
914 audio_volume_up, true); 914 audio_volume_up, true);
915 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_TOGGLE, 915 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_TOGGLE,
916 audio_volume_toggle, true); 916 audio_volume_toggle, true);
917 917
918#ifdef AUDIO_PM_IDLE 918#ifdef AUDIO_PM_IDLE
919 callout_halt(&sc->sc_idle_counter, sc->sc_lock); 919 callout_halt(&sc->sc_idle_counter, sc->sc_lock);
920 920
921 device_active_deregister(self, audio_activity); 921 device_active_deregister(self, audio_activity);
922#endif 922#endif
923 923
924 pmf_device_deregister(self); 924 pmf_device_deregister(self);
925 925
926 /* free resources */ 926 /* free resources */
927 SIMPLEQ_FOREACH(chan, &sc->sc_audiochan, entries) { 927 SIMPLEQ_FOREACH(chan, &sc->sc_audiochan, entries) {
928 audio_free_ring(sc, &chan->vc->sc_mpr); 928 audio_free_ring(sc, &chan->vc->sc_mpr);
929 audio_free_ring(sc, &chan->vc->sc_mrr); 929 audio_free_ring(sc, &chan->vc->sc_mrr);
930 } 930 }
931 audio_free_ring(sc, &sc->sc_hwvc->sc_mpr); 931 audio_free_ring(sc, &sc->sc_hwvc->sc_mpr);
932 audio_free_ring(sc, &sc->sc_hwvc->sc_mrr); 932 audio_free_ring(sc, &sc->sc_hwvc->sc_mrr);
933 audio_free_ring(sc, &sc->sc_pr); 933 audio_free_ring(sc, &sc->sc_pr);
934 audio_free_ring(sc, &sc->sc_rr); 934 audio_free_ring(sc, &sc->sc_rr);
935 SIMPLEQ_FOREACH(chan, &sc->sc_audiochan, entries) { 935 SIMPLEQ_FOREACH(chan, &sc->sc_audiochan, entries) {
936 audio_destroy_pfilters(chan->vc); 936 audio_destroy_pfilters(chan->vc);
937 audio_destroy_rfilters(chan->vc); 937 audio_destroy_rfilters(chan->vc);
938 } 938 }
939 audio_destroy_pfilters(sc->sc_hwvc); 939 audio_destroy_pfilters(sc->sc_hwvc);
940 audio_destroy_rfilters(sc->sc_hwvc); 940 audio_destroy_rfilters(sc->sc_hwvc);
941 941
942 auconv_delete_encodings(sc->sc_encodings); 942 auconv_delete_encodings(sc->sc_encodings);
943 943
944 if (sc->sc_sih_rd) { 944 if (sc->sc_sih_rd) {
945 softint_disestablish(sc->sc_sih_rd); 945 softint_disestablish(sc->sc_sih_rd);
946 sc->sc_sih_rd = NULL; 946 sc->sc_sih_rd = NULL;
947 } 947 }
948 if (sc->sc_sih_wr) { 948 if (sc->sc_sih_wr) {
949 softint_disestablish(sc->sc_sih_wr); 949 softint_disestablish(sc->sc_sih_wr);
950 sc->sc_sih_wr = NULL; 950 sc->sc_sih_wr = NULL;
951 } 951 }
952 952
953 kmem_free(sc->sc_hwvc, sizeof(struct virtual_channel)); 953 kmem_free(sc->sc_hwvc, sizeof(struct virtual_channel));
954 kmem_free(sc->sc_mixer_state, sizeof(mixer_ctrl_t) * 954 kmem_free(sc->sc_mixer_state, sizeof(mixer_ctrl_t) *
955 (sc->sc_nmixer_states + 1)); 955 (sc->sc_nmixer_states + 1));
956 956
957#ifdef AUDIO_PM_IDLE 957#ifdef AUDIO_PM_IDLE
958 callout_destroy(&sc->sc_idle_counter); 958 callout_destroy(&sc->sc_idle_counter);
959#endif 959#endif
960 seldestroy(&sc->sc_rsel); 960 seldestroy(&sc->sc_rsel);
961 seldestroy(&sc->sc_wsel); 961 seldestroy(&sc->sc_wsel);
962 962
963 cv_destroy(&sc->sc_rchan); 963 cv_destroy(&sc->sc_rchan);
964 cv_destroy(&sc->sc_wchan); 964 cv_destroy(&sc->sc_wchan);
965 cv_destroy(&sc->sc_lchan); 965 cv_destroy(&sc->sc_lchan);
966 966
967 return 0; 967 return 0;
968} 968}
969 969
970static void 970static void
971audiochilddet(device_t self, device_t child) 971audiochilddet(device_t self, device_t child)
972{ 972{
973 973
974 /* we hold no child references, so do nothing */ 974 /* we hold no child references, so do nothing */
975} 975}
976 976
977static int 977static int
978audiosearch(device_t parent, cfdata_t cf, const int *locs, void *aux) 978audiosearch(device_t parent, cfdata_t cf, const int *locs, void *aux)
979{ 979{
980 980
981 if (config_match(parent, cf, aux)) 981 if (config_match(parent, cf, aux))
982 config_attach_loc(parent, cf, locs, aux, NULL); 982 config_attach_loc(parent, cf, locs, aux, NULL);
983 983
984 return 0; 984 return 0;
985} 985}
986 986
987static int 987static int
988audiorescan(device_t self, const char *ifattr, const int *flags) 988audiorescan(device_t self, const char *ifattr, const int *flags)
989{ 989{
990 struct audio_softc *sc = device_private(self); 990 struct audio_softc *sc = device_private(self);
991 991
992 if (!ifattr_match(ifattr, "audio")) 992 if (!ifattr_match(ifattr, "audio"))
993 return 0; 993 return 0;
994 994
995 config_search_loc(audiosearch, sc->dev, "audio", NULL, NULL); 995 config_search_loc(audiosearch, sc->dev, "audio", NULL, NULL);
996 996
997 return 0; 997 return 0;
998} 998}
999 999
1000 1000
1001int 1001int
1002au_portof(struct audio_softc *sc, char *name, int class) 1002au_portof(struct audio_softc *sc, char *name, int class)
1003{ 1003{
1004 mixer_devinfo_t mi; 1004 mixer_devinfo_t mi;
1005 1005
1006 for (mi.index = 0; audio_query_devinfo(sc, &mi) == 0; mi.index++) { 1006 for (mi.index = 0; audio_query_devinfo(sc, &mi) == 0; mi.index++) {
1007 if (mi.mixer_class == class && strcmp(mi.label.name, name) == 0) 1007 if (mi.mixer_class == class && strcmp(mi.label.name, name) == 0)
1008 return mi.index; 1008 return mi.index;
1009 } 1009 }
1010 return -1; 1010 return -1;
1011} 1011}
1012 1012
1013void 1013void
1014au_setup_ports(struct audio_softc *sc, struct au_mixer_ports *ports, 1014au_setup_ports(struct audio_softc *sc, struct au_mixer_ports *ports,
1015 mixer_devinfo_t *mi, const struct portname *tbl) 1015 mixer_devinfo_t *mi, const struct portname *tbl)
1016{ 1016{
1017 int i, j; 1017 int i, j;
1018 1018
1019 ports->index = mi->index; 1019 ports->index = mi->index;
1020 if (mi->type == AUDIO_MIXER_ENUM) { 1020 if (mi->type == AUDIO_MIXER_ENUM) {
1021 ports->isenum = true; 1021 ports->isenum = true;
1022 for(i = 0; tbl[i].name; i++) 1022 for(i = 0; tbl[i].name; i++)
1023 for(j = 0; j < mi->un.e.num_mem; j++) 1023 for(j = 0; j < mi->un.e.num_mem; j++)
1024 if (strcmp(mi->un.e.member[j].label.name, 1024 if (strcmp(mi->un.e.member[j].label.name,
1025 tbl[i].name) == 0) { 1025 tbl[i].name) == 0) {
1026 ports->allports |= tbl[i].mask; 1026 ports->allports |= tbl[i].mask;
1027 ports->aumask[ports->nports] = tbl[i].mask; 1027 ports->aumask[ports->nports] = tbl[i].mask;
1028 ports->misel[ports->nports] = 1028 ports->misel[ports->nports] =
1029 mi->un.e.member[j].ord; 1029 mi->un.e.member[j].ord;
1030 ports->miport[ports->nports] = 1030 ports->miport[ports->nports] =
1031 au_portof(sc, mi->un.e.member[j].label.name, 1031 au_portof(sc, mi->un.e.member[j].label.name,
1032 mi->mixer_class); 1032 mi->mixer_class);
1033 if (ports->mixerout != -1 && 1033 if (ports->mixerout != -1 &&
1034 ports->miport[ports->nports] != -1) 1034 ports->miport[ports->nports] != -1)
1035 ports->isdual = true; 1035 ports->isdual = true;
1036 ++ports->nports; 1036 ++ports->nports;
1037 } 1037 }
1038 } else if (mi->type == AUDIO_MIXER_SET) { 1038 } else if (mi->type == AUDIO_MIXER_SET) {
1039 for(i = 0; tbl[i].name; i++) 1039 for(i = 0; tbl[i].name; i++)
1040 for(j = 0; j < mi->un.s.num_mem; j++) 1040 for(j = 0; j < mi->un.s.num_mem; j++)
1041 if (strcmp(mi->un.s.member[j].label.name, 1041 if (strcmp(mi->un.s.member[j].label.name,
1042 tbl[i].name) == 0) { 1042 tbl[i].name) == 0) {
1043 ports->allports |= tbl[i].mask; 1043 ports->allports |= tbl[i].mask;
1044 ports->aumask[ports->nports] = tbl[i].mask; 1044 ports->aumask[ports->nports] = tbl[i].mask;
1045 ports->misel[ports->nports] = 1045 ports->misel[ports->nports] =
1046 mi->un.s.member[j].mask; 1046 mi->un.s.member[j].mask;
1047 ports->miport[ports->nports] = 1047 ports->miport[ports->nports] =
1048 au_portof(sc, mi->un.s.member[j].label.name, 1048 au_portof(sc, mi->un.s.member[j].label.name,
1049 mi->mixer_class); 1049 mi->mixer_class);
1050 ++ports->nports; 1050 ++ports->nports;
1051 } 1051 }
1052 } 1052 }
1053} 1053}
1054 1054
1055/* 1055/*
1056 * Called from hardware driver. This is where the MI audio driver gets 1056 * Called from hardware driver. This is where the MI audio driver gets
1057 * probed/attached to the hardware driver. 1057 * probed/attached to the hardware driver.
1058 */ 1058 */
1059device_t 1059device_t
1060audio_attach_mi(const struct audio_hw_if *ahwp, void *hdlp, device_t dev) 1060audio_attach_mi(const struct audio_hw_if *ahwp, void *hdlp, device_t dev)
1061{ 1061{
1062 struct audio_attach_args arg; 1062 struct audio_attach_args arg;
1063 1063
1064#ifdef DIAGNOSTIC 1064#ifdef DIAGNOSTIC
1065 if (ahwp == NULL) { 1065 if (ahwp == NULL) {
1066 aprint_error("audio_attach_mi: NULL\n"); 1066 aprint_error("audio_attach_mi: NULL\n");
1067 return 0; 1067 return 0;
1068 } 1068 }
1069#endif 1069#endif
1070 arg.type = AUDIODEV_TYPE_AUDIO; 1070 arg.type = AUDIODEV_TYPE_AUDIO;
1071 arg.hwif = ahwp; 1071 arg.hwif = ahwp;
1072 arg.hdl = hdlp; 1072 arg.hdl = hdlp;
1073 return config_found(dev, &arg, audioprint); 1073 return config_found(dev, &arg, audioprint);
1074} 1074}
1075 1075
1076#ifdef AUDIO_DEBUG 1076#ifdef AUDIO_DEBUG
1077void audio_printsc(struct audio_softc *); 1077void audio_printsc(struct audio_softc *);
1078void audio_print_params(const char *, struct audio_params *); 1078void audio_print_params(const char *, struct audio_params *);
1079 1079
1080void 1080void
1081audio_printsc(struct audio_softc *sc) 1081audio_printsc(struct audio_softc *sc)
1082{ 1082{
1083 struct virtual_channel *vc; 1083 struct virtual_channel *vc;
1084 1084
1085 vc = sc->sc_hwvc; 1085 vc = sc->sc_hwvc;
1086 1086
1087 printf("hwhandle %p hw_if %p ", sc->hw_hdl, sc->hw_if); 1087 printf("hwhandle %p hw_if %p ", sc->hw_hdl, sc->hw_if);
1088 printf("open 0x%x mode 0x%x\n", vc->sc_open, vc->sc_mode); 1088 printf("open 0x%x mode 0x%x\n", vc->sc_open, vc->sc_mode);
1089 printf("rchan 0x%x wchan 0x%x ", cv_has_waiters(&sc->sc_rchan), 1089 printf("rchan 0x%x wchan 0x%x ", cv_has_waiters(&sc->sc_rchan),
1090 cv_has_waiters(&sc->sc_wchan)); 1090 cv_has_waiters(&sc->sc_wchan));
1091 printf("rring used 0x%x pring used=%d\n", 1091 printf("rring used 0x%x pring used=%d\n",
1092 audio_stream_get_used(&vc->sc_mrr.s), 1092 audio_stream_get_used(&vc->sc_mrr.s),
1093 audio_stream_get_used(&vc->sc_mpr.s)); 1093 audio_stream_get_used(&vc->sc_mpr.s));
1094 printf("rbus 0x%x pbus 0x%x ", vc->sc_rbus, vc->sc_pbus); 1094 printf("rbus 0x%x pbus 0x%x ", vc->sc_rbus, vc->sc_pbus);
1095 printf("blksize %d", vc->sc_mpr.blksize); 1095 printf("blksize %d", vc->sc_mpr.blksize);
1096 printf("hiwat %d lowat %d\n", vc->sc_mpr.usedhigh, 1096 printf("hiwat %d lowat %d\n", vc->sc_mpr.usedhigh,
1097 vc->sc_mpr.usedlow); 1097 vc->sc_mpr.usedlow);
1098} 1098}
1099 1099
1100void 1100void
1101audio_print_params(const char *s, struct audio_params *p) 1101audio_print_params(const char *s, struct audio_params *p)
1102{ 1102{
1103 printf("%s enc=%u %uch %u/%ubit %uHz\n", s, p->encoding, p->channels, 1103 printf("%s enc=%u %uch %u/%ubit %uHz\n", s, p->encoding, p->channels,
1104 p->validbits, p->precision, p->sample_rate); 1104 p->validbits, p->precision, p->sample_rate);
1105} 1105}
1106#endif 1106#endif
1107 1107
1108/* Allocate all ring buffers. called from audioattach() */ 1108/* Allocate all ring buffers. called from audioattach() */
1109static int 1109static int
1110audio_allocbufs(struct audio_softc *sc, struct virtual_channel *vc) 1110audio_allocbufs(struct audio_softc *sc)
1111{ 1111{
 1112 struct virtual_channel *vc;
1112 int error; 1113 int error;
1113 1114
 1115 vc = sc->sc_hwvc;
 1116
1114 sc->sc_pr.s.start = NULL; 1117 sc->sc_pr.s.start = NULL;
1115 vc->sc_mpr.s.start = NULL; 1118 vc->sc_mpr.s.start = NULL;
1116 sc->sc_rr.s.start = NULL; 1119 sc->sc_rr.s.start = NULL;
1117 vc->sc_mrr.s.start = NULL; 1120 vc->sc_mrr.s.start = NULL;
1118 1121
1119 if (audio_can_playback(sc)) { 1122 if (audio_can_playback(sc)) {
1120 error = audio_alloc_ring(sc, &sc->sc_pr, 1123 error = audio_alloc_ring(sc, &sc->sc_pr,
1121 AUMODE_PLAY, AU_RING_SIZE); 1124 AUMODE_PLAY, AU_RING_SIZE);
1122 if (error) 1125 if (error)
1123 goto bad_play1; 1126 goto bad_play1;
1124 1127
1125 error = audio_alloc_ring(sc, &vc->sc_mpr, 1128 error = audio_alloc_ring(sc, &vc->sc_mpr,
1126 AUMODE_PLAY, AU_RING_SIZE); 1129 AUMODE_PLAY, AU_RING_SIZE);
1127 if (error) 1130 if (error)
1128 goto bad_play2; 1131 goto bad_play2;
1129 } 1132 }
1130 if (audio_can_capture(sc)) { 1133 if (audio_can_capture(sc)) {
1131 error = audio_alloc_ring(sc, &sc->sc_rr, 1134 error = audio_alloc_ring(sc, &sc->sc_rr,
1132 AUMODE_RECORD, AU_RING_SIZE); 1135 AUMODE_RECORD, AU_RING_SIZE);
1133 if (error) 1136 if (error)
1134 goto bad_rec1; 1137 goto bad_rec1;
1135 1138
1136 error = audio_alloc_ring(sc, &vc->sc_mrr, 1139 error = audio_alloc_ring(sc, &vc->sc_mrr,
1137 AUMODE_RECORD, AU_RING_SIZE); 1140 AUMODE_RECORD, AU_RING_SIZE);
1138 if (error) 1141 if (error)
1139 goto bad_rec2; 1142 goto bad_rec2;
1140 } 1143 }
1141 return 0; 1144 return 0;
1142 1145
1143bad_rec2: 1146bad_rec2:
1144 if (sc->sc_rr.s.start != NULL) 1147 if (sc->sc_rr.s.start != NULL)
1145 audio_free_ring(sc, &sc->sc_rr); 1148 audio_free_ring(sc, &sc->sc_rr);
1146bad_rec1: 1149bad_rec1:
1147 if (vc->sc_mpr.s.start != NULL) 1150 if (vc->sc_mpr.s.start != NULL)
1148 audio_free_ring(sc, &vc->sc_mpr); 1151 audio_free_ring(sc, &vc->sc_mpr);
1149bad_play2: 1152bad_play2:
1150 if (sc->sc_pr.s.start != NULL) 1153 if (sc->sc_pr.s.start != NULL)
1151 audio_free_ring(sc, &sc->sc_pr); 1154 audio_free_ring(sc, &sc->sc_pr);
1152bad_play1: 1155bad_play1:
1153 return error; 1156 return error;
1154} 1157}
1155 1158
1156int 1159int
1157audio_alloc_ring(struct audio_softc *sc, struct audio_ringbuffer *r, 1160audio_alloc_ring(struct audio_softc *sc, struct audio_ringbuffer *r,
1158 int direction, size_t bufsize) 1161 int direction, size_t bufsize)
1159{ 1162{
1160 const struct audio_hw_if *hw; 1163 const struct audio_hw_if *hw;
1161 struct virtual_channel *vc; 1164 struct virtual_channel *vc;
1162 void *hdl; 1165 void *hdl;
1163 vaddr_t vstart; 1166 vaddr_t vstart;
1164 vsize_t vsize; 1167 vsize_t vsize;
1165 int error; 1168 int error;
1166 1169
1167 vc = sc->sc_hwvc; 1170 vc = sc->sc_hwvc;
1168 hw = sc->hw_if; 1171 hw = sc->hw_if;
1169 hdl = sc->hw_hdl; 1172 hdl = sc->hw_hdl;
1170 /* 1173 /*
1171 * Alloc DMA play and record buffers 1174 * Alloc DMA play and record buffers
1172 */ 1175 */
1173 if (bufsize < AUMINBUF) 1176 if (bufsize < AUMINBUF)
1174 bufsize = AUMINBUF; 1177 bufsize = AUMINBUF;
1175 ROUNDSIZE(bufsize); 1178 ROUNDSIZE(bufsize);
1176 if (hw->round_buffersize) 1179 if (hw->round_buffersize)
1177 bufsize = hw->round_buffersize(hdl, direction, bufsize); 1180 bufsize = hw->round_buffersize(hdl, direction, bufsize);
1178 1181
1179 if (hw->allocm && (r == &vc->sc_mpr || r == &vc->sc_mrr)) { 1182 if (hw->allocm && (r == &vc->sc_mpr || r == &vc->sc_mrr)) {
1180 /* Hardware ringbuffer. No dedicated uvm object.*/ 1183 /* Hardware ringbuffer. No dedicated uvm object.*/
1181 r->uobj = NULL; 1184 r->uobj = NULL;
1182 r->s.start = hw->allocm(hdl, direction, bufsize); 1185 r->s.start = hw->allocm(hdl, direction, bufsize);
1183 if (r->s.start == NULL) 1186 if (r->s.start == NULL)
1184 return ENOMEM; 1187 return ENOMEM;
1185 } else { 1188 } else {
1186 /* Software ringbuffer. */ 1189 /* Software ringbuffer. */
1187 vstart = 0; 1190 vstart = 0;
1188 1191
1189 /* Get a nonzero multiple of PAGE_SIZE. */ 1192 /* Get a nonzero multiple of PAGE_SIZE. */
1190 vsize = roundup2(MAX(bufsize, PAGE_SIZE), PAGE_SIZE); 1193 vsize = roundup2(MAX(bufsize, PAGE_SIZE), PAGE_SIZE);
1191 1194
1192 /* Create a uvm anonymous object. */ 1195 /* Create a uvm anonymous object. */
1193 r->uobj = uao_create(vsize, 0); 1196 r->uobj = uao_create(vsize, 0);
1194 1197
1195 /* Map it into the kernel virtual address space. */ 1198 /* Map it into the kernel virtual address space. */
1196 error = uvm_map(kernel_map, &vstart, vsize, r->uobj, 0, 0, 1199 error = uvm_map(kernel_map, &vstart, vsize, r->uobj, 0, 0,
1197 UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, UVM_INH_NONE, 1200 UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW, UVM_INH_NONE,
1198 UVM_ADV_RANDOM, 0)); 1201 UVM_ADV_RANDOM, 0));
1199 if (error) { 1202 if (error) {
1200 uao_detach(r->uobj); /* release reference */ 1203 uao_detach(r->uobj); /* release reference */
1201 r->uobj = NULL; /* paranoia */ 1204 r->uobj = NULL; /* paranoia */
1202 return error; 1205 return error;
1203 } 1206 }
1204 1207
1205 error = uvm_map_pageable(kernel_map, vstart, vstart + vsize, 1208 error = uvm_map_pageable(kernel_map, vstart, vstart + vsize,
1206 false, 0); 1209 false, 0);
1207 if (error) { 1210 if (error) {
1208 uvm_unmap(kernel_map, vstart, vstart + vsize); 1211 uvm_unmap(kernel_map, vstart, vstart + vsize);
1209 uao_detach(r->uobj); 1212 uao_detach(r->uobj);
1210 r->uobj = NULL; /* paranoia */ 1213 r->uobj = NULL; /* paranoia */
1211 return error; 1214 return error;
1212 } 1215 }
1213 r->s.start = (void *)vstart; 1216 r->s.start = (void *)vstart;
1214 } 1217 }
1215 1218
1216 r->s.bufsize = bufsize; 1219 r->s.bufsize = bufsize;
1217 1220
1218 return 0; 1221 return 0;
1219} 1222}
1220 1223
1221void 1224void
1222audio_free_ring(struct audio_softc *sc, struct audio_ringbuffer *r) 1225audio_free_ring(struct audio_softc *sc, struct audio_ringbuffer *r)
1223{ 1226{
1224 struct virtual_channel *vc; 1227 struct virtual_channel *vc;
1225 vaddr_t vstart; 1228 vaddr_t vstart;
1226 vsize_t vsize; 1229 vsize_t vsize;
1227 1230
1228 if (r->s.start == NULL) 1231 if (r->s.start == NULL)
1229 return; 1232 return;
1230 1233
1231 vc = sc->sc_hwvc; 1234 vc = sc->sc_hwvc;
1232 1235
1233 if (sc->hw_if->freem && (r == &vc->sc_mpr || r == &vc->sc_mrr)) { 1236 if (sc->hw_if->freem && (r == &vc->sc_mpr || r == &vc->sc_mrr)) {
1234 /* Hardware ringbuffer. */ 1237 /* Hardware ringbuffer. */
1235 KASSERT(r->uobj == NULL); 1238 KASSERT(r->uobj == NULL);
1236 sc->hw_if->freem(sc->hw_hdl, r->s.start, r->s.bufsize); 1239 sc->hw_if->freem(sc->hw_hdl, r->s.start, r->s.bufsize);
1237 } else { 1240 } else {
1238 /* Software ringbuffer. */ 1241 /* Software ringbuffer. */
1239 vstart = (vaddr_t)r->s.start; 1242 vstart = (vaddr_t)r->s.start;
1240 vsize = roundup2(MAX(r->s.bufsize, PAGE_SIZE), PAGE_SIZE); 1243 vsize = roundup2(MAX(r->s.bufsize, PAGE_SIZE), PAGE_SIZE);
1241 1244
1242 /* 1245 /*
1243 * Unmap the kernel mapping. uvm_unmap releases the 1246 * Unmap the kernel mapping. uvm_unmap releases the
1244 * reference to the uvm object, and this should be the 1247 * reference to the uvm object, and this should be the
1245 * last virtual mapping of the uvm object, so no need 1248 * last virtual mapping of the uvm object, so no need
1246 * to explicitly release (`detach') the object. 1249 * to explicitly release (`detach') the object.
1247 */ 1250 */
1248 uvm_unmap(kernel_map, vstart, vstart + vsize); 1251 uvm_unmap(kernel_map, vstart, vstart + vsize);
1249 1252
1250 r->uobj = NULL; /* paranoia */ 1253 r->uobj = NULL; /* paranoia */
1251 } 1254 }
1252 1255
1253 r->s.start = NULL; 1256 r->s.start = NULL;
1254} 1257}
1255 1258
1256static int 1259static int
1257audio_setup_pfilters(struct audio_softc *sc, const audio_params_t *pp, 1260audio_setup_pfilters(struct audio_softc *sc, const audio_params_t *pp,
1258 stream_filter_list_t *pfilters, struct virtual_channel *vc) 1261 stream_filter_list_t *pfilters, struct virtual_channel *vc)
1259{ 1262{
1260 stream_filter_t *pf[AUDIO_MAX_FILTERS], *of[AUDIO_MAX_FILTERS]; 1263 stream_filter_t *pf[AUDIO_MAX_FILTERS], *of[AUDIO_MAX_FILTERS];
1261 audio_stream_t ps[AUDIO_MAX_FILTERS], os[AUDIO_MAX_FILTERS]; 1264 audio_stream_t ps[AUDIO_MAX_FILTERS], os[AUDIO_MAX_FILTERS];
1262 const audio_params_t *from_param; 1265 const audio_params_t *from_param;
1263 audio_params_t *to_param; 1266 audio_params_t *to_param;
1264 int i, n, onfilters; 1267 int i, n, onfilters;
1265 1268
1266 KASSERT(mutex_owned(sc->sc_lock)); 1269 KASSERT(mutex_owned(sc->sc_lock));
1267 1270
1268 /* Construct new filters. */ 1271 /* Construct new filters. */
1269 memset(pf, 0, sizeof(pf)); 1272 memset(pf, 0, sizeof(pf));
1270 memset(ps, 0, sizeof(ps)); 1273 memset(ps, 0, sizeof(ps));
1271 from_param = pp; 1274 from_param = pp;
1272 for (i = 0; i < pfilters->req_size; i++) { 1275 for (i = 0; i < pfilters->req_size; i++) {
1273 n = pfilters->req_size - i - 1; 1276 n = pfilters->req_size - i - 1;
1274 to_param = &pfilters->filters[n].param; 1277 to_param = &pfilters->filters[n].param;
1275 audio_check_params(to_param); 1278 audio_check_params(to_param);
1276 pf[i] = pfilters->filters[n].factory(sc, from_param, to_param); 1279 pf[i] = pfilters->filters[n].factory(sc, from_param, to_param);
1277 if (pf[i] == NULL) 1280 if (pf[i] == NULL)
1278 break; 1281 break;
1279 if (audio_stream_ctor(&ps[i], from_param, AU_RING_SIZE)) 1282 if (audio_stream_ctor(&ps[i], from_param, AU_RING_SIZE))
1280 break; 1283 break;
1281 if (i > 0) 1284 if (i > 0)
1282 pf[i]->set_fetcher(pf[i], &pf[i - 1]->base); 1285 pf[i]->set_fetcher(pf[i], &pf[i - 1]->base);
1283 from_param = to_param; 1286 from_param = to_param;
1284 } 1287 }
1285 if (i < pfilters->req_size) { /* failure */ 1288 if (i < pfilters->req_size) { /* failure */
1286 DPRINTF(("%s: pfilters failure\n", __func__)); 1289 DPRINTF(("%s: pfilters failure\n", __func__));
1287 for (; i >= 0; i--) { 1290 for (; i >= 0; i--) {
1288 if (pf[i] != NULL) 1291 if (pf[i] != NULL)
1289 pf[i]->dtor(pf[i]); 1292 pf[i]->dtor(pf[i]);
1290 audio_stream_dtor(&ps[i]); 1293 audio_stream_dtor(&ps[i]);
1291 } 1294 }
1292 return EINVAL; 1295 return EINVAL;
1293 } 1296 }
1294 1297
1295 /* Swap in new filters. */ 1298 /* Swap in new filters. */
1296 HW_LOCK(vc); 1299 HW_LOCK(vc);
1297 memcpy(of, vc->sc_pfilters, sizeof(of)); 1300 memcpy(of, vc->sc_pfilters, sizeof(of));
1298 memcpy(os, vc->sc_pstreams, sizeof(os)); 1301 memcpy(os, vc->sc_pstreams, sizeof(os));
1299 onfilters = vc->sc_npfilters; 1302 onfilters = vc->sc_npfilters;
1300 memcpy(vc->sc_pfilters, pf, sizeof(pf)); 1303 memcpy(vc->sc_pfilters, pf, sizeof(pf));
1301 memcpy(vc->sc_pstreams, ps, sizeof(ps)); 1304 memcpy(vc->sc_pstreams, ps, sizeof(ps));
1302 vc->sc_npfilters = pfilters->req_size; 1305 vc->sc_npfilters = pfilters->req_size;
1303 for (i = 0; i < pfilters->req_size; i++) 1306 for (i = 0; i < pfilters->req_size; i++)
1304 pf[i]->set_inputbuffer(pf[i], &vc->sc_pstreams[i]); 1307 pf[i]->set_inputbuffer(pf[i], &vc->sc_pstreams[i]);
1305 1308
1306 /* hardware format and the buffer near to userland */ 1309 /* hardware format and the buffer near to userland */
1307 if (pfilters->req_size <= 0) { 1310 if (pfilters->req_size <= 0) {
1308 vc->sc_mpr.s.param = *pp; 1311 vc->sc_mpr.s.param = *pp;
1309 vc->sc_pustream = &vc->sc_mpr.s; 1312 vc->sc_pustream = &vc->sc_mpr.s;
1310 } else { 1313 } else {
1311 vc->sc_mpr.s.param = pfilters->filters[0].param; 1314 vc->sc_mpr.s.param = pfilters->filters[0].param;
1312 vc->sc_pustream = &vc->sc_pstreams[0]; 1315 vc->sc_pustream = &vc->sc_pstreams[0];
1313 } 1316 }
1314 HW_UNLOCK(vc); 1317 HW_UNLOCK(vc);
1315 1318
1316 /* Destroy old filters. */ 1319 /* Destroy old filters. */
1317 for (i = 0; i < onfilters; i++) { 1320 for (i = 0; i < onfilters; i++) {
1318 of[i]->dtor(of[i]); 1321 of[i]->dtor(of[i]);
1319 audio_stream_dtor(&os[i]); 1322 audio_stream_dtor(&os[i]);
1320 } 1323 }
1321 1324
1322#ifdef AUDIO_DEBUG 1325#ifdef AUDIO_DEBUG
1323 if (audiodebug) { 1326 if (audiodebug) {
1324 printf("%s: HW-buffer=%p pustream=%p\n", 1327 printf("%s: HW-buffer=%p pustream=%p\n",
1325 __func__, &vc->sc_mpr.s, vc->sc_pustream); 1328 __func__, &vc->sc_mpr.s, vc->sc_pustream);
1326 for (i = 0; i < pfilters->req_size; i++) { 1329 for (i = 0; i < pfilters->req_size; i++) {
1327 char num[100]; 1330 char num[100];
1328 snprintf(num, 100, "[%d]", i); 1331 snprintf(num, 100, "[%d]", i);
1329 audio_print_params(num, &vc->sc_pstreams[i].param); 1332 audio_print_params(num, &vc->sc_pstreams[i].param);
1330 } 1333 }
1331 audio_print_params("[HW]", &vc->sc_mpr.s.param); 1334 audio_print_params("[HW]", &vc->sc_mpr.s.param);
1332 } 1335 }
1333#endif /* AUDIO_DEBUG */ 1336#endif /* AUDIO_DEBUG */
1334 1337
1335 return 0; 1338 return 0;
1336} 1339}
1337 1340
1338static int 1341static int
1339audio_setup_rfilters(struct audio_softc *sc, const audio_params_t *rp, 1342audio_setup_rfilters(struct audio_softc *sc, const audio_params_t *rp,
1340 stream_filter_list_t *rfilters, struct virtual_channel *vc) 1343 stream_filter_list_t *rfilters, struct virtual_channel *vc)
1341{ 1344{
1342 stream_filter_t *rf[AUDIO_MAX_FILTERS], *of[AUDIO_MAX_FILTERS]; 1345 stream_filter_t *rf[AUDIO_MAX_FILTERS], *of[AUDIO_MAX_FILTERS];
1343 audio_stream_t rs[AUDIO_MAX_FILTERS], os[AUDIO_MAX_FILTERS]; 1346 audio_stream_t rs[AUDIO_MAX_FILTERS], os[AUDIO_MAX_FILTERS];
1344 const audio_params_t *to_param; 1347 const audio_params_t *to_param;
1345 audio_params_t *from_param; 1348 audio_params_t *from_param;
1346 int i, onfilters; 1349 int i, onfilters;
1347 1350
1348 KASSERT(mutex_owned(sc->sc_lock)); 1351 KASSERT(mutex_owned(sc->sc_lock));
1349 1352
1350 /* Construct new filters. */ 1353 /* Construct new filters. */
1351 memset(rf, 0, sizeof(rf)); 1354 memset(rf, 0, sizeof(rf));
1352 memset(rs, 0, sizeof(rs)); 1355 memset(rs, 0, sizeof(rs));
1353 for (i = 0; i < rfilters->req_size; i++) { 1356 for (i = 0; i < rfilters->req_size; i++) {
1354 from_param = &rfilters->filters[i].param; 1357 from_param = &rfilters->filters[i].param;
1355 audio_check_params(from_param); 1358 audio_check_params(from_param);
1356 to_param = i + 1 < rfilters->req_size 1359 to_param = i + 1 < rfilters->req_size
1357 ? &rfilters->filters[i + 1].param : rp; 1360 ? &rfilters->filters[i + 1].param : rp;
1358 rf[i] = rfilters->filters[i].factory(sc, from_param, to_param); 1361 rf[i] = rfilters->filters[i].factory(sc, from_param, to_param);
1359 if (rf[i] == NULL) 1362 if (rf[i] == NULL)
1360 break; 1363 break;
1361 if (audio_stream_ctor(&rs[i], to_param, AU_RING_SIZE)) 1364 if (audio_stream_ctor(&rs[i], to_param, AU_RING_SIZE))
1362 break; 1365 break;
1363 if (i > 0) { 1366 if (i > 0) {
1364 rf[i]->set_fetcher(rf[i], &rf[i - 1]->base); 1367 rf[i]->set_fetcher(rf[i], &rf[i - 1]->base);
1365 } else { 1368 } else {
1366 /* rf[0] has no previous fetcher because 1369 /* rf[0] has no previous fetcher because
1367 * the audio hardware fills data to the 1370 * the audio hardware fills data to the
1368 * input buffer. */ 1371 * input buffer. */
1369 rf[0]->set_inputbuffer(rf[0], &vc->sc_mrr.s); 1372 rf[0]->set_inputbuffer(rf[0], &vc->sc_mrr.s);
1370 } 1373 }
1371 } 1374 }
1372 if (i < rfilters->req_size) { /* failure */ 1375 if (i < rfilters->req_size) { /* failure */
1373 DPRINTF(("%s: rfilters failure\n", __func__)); 1376 DPRINTF(("%s: rfilters failure\n", __func__));
1374 for (; i >= 0; i--) { 1377 for (; i >= 0; i--) {
1375 if (rf[i] != NULL) 1378 if (rf[i] != NULL)
1376 rf[i]->dtor(rf[i]); 1379 rf[i]->dtor(rf[i]);
1377 audio_stream_dtor(&rs[i]); 1380 audio_stream_dtor(&rs[i]);
1378 } 1381 }
1379 return EINVAL; 1382 return EINVAL;
1380 } 1383 }
1381 1384
1382 /* Swap in new filters. */ 1385 /* Swap in new filters. */
1383 HW_LOCK(vc); 1386 HW_LOCK(vc);
1384 memcpy(of, vc->sc_rfilters, sizeof(of)); 1387 memcpy(of, vc->sc_rfilters, sizeof(of));
1385 memcpy(os, vc->sc_rstreams, sizeof(os)); 1388 memcpy(os, vc->sc_rstreams, sizeof(os));
1386 onfilters = vc->sc_nrfilters; 1389 onfilters = vc->sc_nrfilters;
1387 memcpy(vc->sc_rfilters, rf, sizeof(rf)); 1390 memcpy(vc->sc_rfilters, rf, sizeof(rf));
1388 memcpy(vc->sc_rstreams, rs, sizeof(rs)); 1391 memcpy(vc->sc_rstreams, rs, sizeof(rs));
1389 vc->sc_nrfilters = rfilters->req_size; 1392 vc->sc_nrfilters = rfilters->req_size;
1390 for (i = 1; i < rfilters->req_size; i++) 1393 for (i = 1; i < rfilters->req_size; i++)
1391 rf[i]->set_inputbuffer(rf[i], &vc->sc_rstreams[i - 1]); 1394 rf[i]->set_inputbuffer(rf[i], &vc->sc_rstreams[i - 1]);
1392 1395
1393 /* hardware format and the buffer near to userland */ 1396 /* hardware format and the buffer near to userland */
1394 if (rfilters->req_size <= 0) { 1397 if (rfilters->req_size <= 0) {
1395 vc->sc_mrr.s.param = *rp; 1398 vc->sc_mrr.s.param = *rp;
1396 vc->sc_rustream = &vc->sc_mrr.s; 1399 vc->sc_rustream = &vc->sc_mrr.s;
1397 } else { 1400 } else {
1398 vc->sc_mrr.s.param = rfilters->filters[0].param; 1401 vc->sc_mrr.s.param = rfilters->filters[0].param;
1399 vc->sc_rustream = &vc->sc_rstreams[rfilters->req_size - 1]; 1402 vc->sc_rustream = &vc->sc_rstreams[rfilters->req_size - 1];
1400 } 1403 }
1401 HW_UNLOCK(vc); 1404 HW_UNLOCK(vc);
1402 1405
1403#ifdef AUDIO_DEBUG 1406#ifdef AUDIO_DEBUG
1404 if (audiodebug) { 1407 if (audiodebug) {
1405 printf("%s: HW-buffer=%p rustream=%p\n", 1408 printf("%s: HW-buffer=%p rustream=%p\n",
1406 __func__, &vc->sc_mrr.s, vc->sc_rustream); 1409 __func__, &vc->sc_mrr.s, vc->sc_rustream);
1407 audio_print_params("[HW]", &vc->sc_mrr.s.param); 1410 audio_print_params("[HW]", &vc->sc_mrr.s.param);
1408 for (i = 0; i < rfilters->req_size; i++) { 1411 for (i = 0; i < rfilters->req_size; i++) {
1409 char num[100]; 1412 char num[100];
1410 snprintf(num, 100, "[%d]", i); 1413 snprintf(num, 100, "[%d]", i);
1411 audio_print_params(num, &vc->sc_rstreams[i].param); 1414 audio_print_params(num, &vc->sc_rstreams[i].param);
1412 } 1415 }
1413 } 1416 }
1414#endif /* AUDIO_DEBUG */ 1417#endif /* AUDIO_DEBUG */
1415 1418
1416 /* Destroy old filters. */ 1419 /* Destroy old filters. */
1417 for (i = 0; i < onfilters; i++) { 1420 for (i = 0; i < onfilters; i++) {
1418 of[i]->dtor(of[i]); 1421 of[i]->dtor(of[i]);
1419 audio_stream_dtor(&os[i]); 1422 audio_stream_dtor(&os[i]);
1420 } 1423 }
1421 1424
1422 return 0; 1425 return 0;
1423} 1426}
1424 1427
1425static void 1428static void
1426audio_destroy_pfilters(struct virtual_channel *vc) 1429audio_destroy_pfilters(struct virtual_channel *vc)
1427{ 1430{
1428 int i; 1431 int i;
1429 1432
1430 for (i = 0; i < vc->sc_npfilters; i++) { 1433 for (i = 0; i < vc->sc_npfilters; i++) {
1431 vc->sc_pfilters[i]->dtor(vc->sc_pfilters[i]); 1434 vc->sc_pfilters[i]->dtor(vc->sc_pfilters[i]);
1432 vc->sc_pfilters[i] = NULL; 1435 vc->sc_pfilters[i] = NULL;
1433 audio_stream_dtor(&vc->sc_pstreams[i]); 1436 audio_stream_dtor(&vc->sc_pstreams[i]);
1434 } 1437 }
1435 vc->sc_npfilters = 0; 1438 vc->sc_npfilters = 0;
1436} 1439}
1437 1440
1438static void 1441static void
1439audio_destroy_rfilters(struct virtual_channel *vc) 1442audio_destroy_rfilters(struct virtual_channel *vc)
1440{ 1443{
1441 int i; 1444 int i;
1442 1445
1443 for (i = 0; i < vc->sc_nrfilters; i++) { 1446 for (i = 0; i < vc->sc_nrfilters; i++) {
1444 vc->sc_rfilters[i]->dtor(vc->sc_rfilters[i]); 1447 vc->sc_rfilters[i]->dtor(vc->sc_rfilters[i]);
1445 vc->sc_rfilters[i] = NULL; 1448 vc->sc_rfilters[i] = NULL;
1446 audio_stream_dtor(&vc->sc_pstreams[i]); 1449 audio_stream_dtor(&vc->sc_pstreams[i]);
1447 } 1450 }
1448 vc->sc_nrfilters = 0; 1451 vc->sc_nrfilters = 0;
1449} 1452}
1450 1453
1451static void 1454static void
1452audio_stream_dtor(audio_stream_t *stream) 1455audio_stream_dtor(audio_stream_t *stream)
1453{ 1456{
1454 1457
1455 if (stream->start != NULL) 1458 if (stream->start != NULL)
1456 kmem_free(stream->start, stream->bufsize); 1459 kmem_free(stream->start, stream->bufsize);
1457 memset(stream, 0, sizeof(audio_stream_t)); 1460 memset(stream, 0, sizeof(audio_stream_t));
1458} 1461}
1459 1462
1460static int 1463static int
1461audio_stream_ctor(audio_stream_t *stream, const audio_params_t *param, int size) 1464audio_stream_ctor(audio_stream_t *stream, const audio_params_t *param, int size)
1462{ 1465{
1463 int frame_size; 1466 int frame_size;
1464 1467
1465 size = min(size, AU_RING_SIZE); 1468 size = min(size, AU_RING_SIZE);
1466 stream->bufsize = size; 1469 stream->bufsize = size;
1467 stream->start = kmem_zalloc(size, KM_SLEEP); 1470 stream->start = kmem_zalloc(size, KM_SLEEP);
1468 frame_size = (param->precision + 7) / 8 * param->channels; 1471 frame_size = (param->precision + 7) / 8 * param->channels;
1469 size = (size / frame_size) * frame_size; 1472 size = (size / frame_size) * frame_size;
1470 stream->end = stream->start + size; 1473 stream->end = stream->start + size;
1471 stream->inp = stream->start; 1474 stream->inp = stream->start;
1472 stream->outp = stream->start; 1475 stream->outp = stream->start;
1473 stream->used = 0; 1476 stream->used = 0;
1474 stream->param = *param; 1477 stream->param = *param;
1475 stream->loop = false; 1478 stream->loop = false;
1476 return 0; 1479 return 0;
1477} 1480}
1478 1481
1479static void 1482static void
1480stream_filter_list_append(stream_filter_list_t *list, 1483stream_filter_list_append(stream_filter_list_t *list,
1481 stream_filter_factory_t factory, 1484 stream_filter_factory_t factory,
1482 const audio_params_t *param) 1485 const audio_params_t *param)
1483{ 1486{
1484 1487
1485 if (list->req_size >= AUDIO_MAX_FILTERS) { 1488 if (list->req_size >= AUDIO_MAX_FILTERS) {
1486 printf("%s: increase AUDIO_MAX_FILTERS in sys/dev/audio_if.h\n", 1489 printf("%s: increase AUDIO_MAX_FILTERS in sys/dev/audio_if.h\n",
1487 __func__); 1490 __func__);
1488 return; 1491 return;
1489 } 1492 }
1490 list->filters[list->req_size].factory = factory; 1493 list->filters[list->req_size].factory = factory;
1491 list->filters[list->req_size].param = *param; 1494 list->filters[list->req_size].param = *param;
1492 list->req_size++; 1495 list->req_size++;
1493} 1496}
1494 1497
1495static void 1498static void
1496stream_filter_list_set(stream_filter_list_t *list, int i, 1499stream_filter_list_set(stream_filter_list_t *list, int i,
1497 stream_filter_factory_t factory, 1500 stream_filter_factory_t factory,
1498 const audio_params_t *param) 1501 const audio_params_t *param)
1499{ 1502{
1500 1503
1501 if (i < 0 || i >= AUDIO_MAX_FILTERS) { 1504 if (i < 0 || i >= AUDIO_MAX_FILTERS) {
1502 printf("%s: invalid index: %d\n", __func__, i); 1505 printf("%s: invalid index: %d\n", __func__, i);
1503 return; 1506 return;
1504 } 1507 }
1505 1508
1506 list->filters[i].factory = factory; 1509 list->filters[i].factory = factory;
1507 list->filters[i].param = *param; 1510 list->filters[i].param = *param;
1508 if (list->req_size <= i) 1511 if (list->req_size <= i)
1509 list->req_size = i + 1; 1512 list->req_size = i + 1;
1510} 1513}
1511 1514
1512static void 1515static void
1513stream_filter_list_prepend(stream_filter_list_t *list, 1516stream_filter_list_prepend(stream_filter_list_t *list,
1514 stream_filter_factory_t factory, 1517 stream_filter_factory_t factory,
1515 const audio_params_t *param) 1518 const audio_params_t *param)
1516{ 1519{
1517 1520
1518 if (list->req_size >= AUDIO_MAX_FILTERS) { 1521 if (list->req_size >= AUDIO_MAX_FILTERS) {
1519 printf("%s: increase AUDIO_MAX_FILTERS in sys/dev/audio_if.h\n", 1522 printf("%s: increase AUDIO_MAX_FILTERS in sys/dev/audio_if.h\n",
1520 __func__); 1523 __func__);
1521 return; 1524 return;
1522 } 1525 }
1523 memmove(&list->filters[1], &list->filters[0], 1526 memmove(&list->filters[1], &list->filters[0],
1524 sizeof(struct stream_filter_req) * list->req_size); 1527 sizeof(struct stream_filter_req) * list->req_size);
1525 list->filters[0].factory = factory; 1528 list->filters[0].factory = factory;
1526 list->filters[0].param = *param; 1529 list->filters[0].param = *param;
1527 list->req_size++; 1530 list->req_size++;
1528} 1531}
1529 1532
1530/* 1533/*
1531 * Look up audio device and acquire locks for device access. 1534 * Look up audio device and acquire locks for device access.
1532 */ 1535 */
1533static int 1536static int
1534audio_enter(dev_t dev, krw_t rw, struct audio_softc **scp) 1537audio_enter(dev_t dev, krw_t rw, struct audio_softc **scp)
1535{ 1538{
1536 1539
1537 struct audio_softc *sc; 1540 struct audio_softc *sc;
1538 1541
1539 /* First, find the device and take sc_lock. */ 1542 /* First, find the device and take sc_lock. */
1540 sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev)); 1543 sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev));
1541 if (sc == NULL || sc->hw_if == NULL) 1544 if (sc == NULL || sc->hw_if == NULL)
1542 return ENXIO; 1545 return ENXIO;
1543 mutex_enter(sc->sc_lock); 1546 mutex_enter(sc->sc_lock);
1544 if (sc->sc_dying) { 1547 if (sc->sc_dying) {
1545 mutex_exit(sc->sc_lock); 1548 mutex_exit(sc->sc_lock);
1546 return EIO; 1549 return EIO;
1547 } 1550 }
1548 1551
1549 *scp = sc; 1552 *scp = sc;
1550 return 0; 1553 return 0;
1551} 1554}
1552 1555
1553/* 1556/*
1554 * Release reference to device acquired with audio_enter(). 1557 * Release reference to device acquired with audio_enter().
1555 */ 1558 */
1556static void 1559static void
1557audio_exit(struct audio_softc *sc) 1560audio_exit(struct audio_softc *sc)
1558{ 1561{
1559 cv_broadcast(&sc->sc_lchan); 1562 cv_broadcast(&sc->sc_lchan);
1560 mutex_exit(sc->sc_lock); 1563 mutex_exit(sc->sc_lock);
1561} 1564}
1562 1565
1563/* 1566/*
1564 * Wait for I/O to complete, releasing device lock. 1567 * Wait for I/O to complete, releasing device lock.
1565 */ 1568 */
1566static int 1569static int
1567audio_waitio(struct audio_softc *sc, kcondvar_t *chan, struct virtual_channel *vc) 1570audio_waitio(struct audio_softc *sc, kcondvar_t *chan, struct virtual_channel *vc)
1568{ 1571{
1569 struct audio_chan *vchan; 1572 struct audio_chan *vchan;
1570 bool found = false; 1573 bool found = false;
1571 int error; 1574 int error;
1572 1575
1573 KASSERT(mutex_owned(sc->sc_lock)); 1576 KASSERT(mutex_owned(sc->sc_lock));
1574 cv_broadcast(&sc->sc_lchan); 1577 cv_broadcast(&sc->sc_lchan);
1575 1578
1576 /* Wait for pending I/O to complete. */ 1579 /* Wait for pending I/O to complete. */
1577 error = cv_wait_sig(chan, sc->sc_lock); 1580 error = cv_wait_sig(chan, sc->sc_lock);
1578 1581
1579 found = false; 1582 found = false;
1580 SIMPLEQ_FOREACH(vchan, &sc->sc_audiochan, entries) { 1583 SIMPLEQ_FOREACH(vchan, &sc->sc_audiochan, entries) {
1581 if (vchan->vc == vc) { 1584 if (vchan->vc == vc) {
1582 found = true; 1585 found = true;
1583 break; 1586 break;
1584 } 1587 }
1585 } 1588 }
1586 if (found == false) 1589 if (found == false)
1587 error = EIO; 1590 error = EIO;
1588 1591
1589 return error; 1592 return error;
1590} 1593}
1591 1594
1592/* Exported interfaces for audiobell. */ 1595/* Exported interfaces for audiobell. */
1593int 1596int
1594audiobellopen(dev_t dev, int flags, int ifmt, struct lwp *l, 1597audiobellopen(dev_t dev, int flags, int ifmt, struct lwp *l,
1595 struct file **fp) 1598 struct file **fp)
1596{ 1599{
1597 struct audio_softc *sc; 1600 struct audio_softc *sc;
1598 int error; 1601 int error;
1599 1602
1600 if ((error = audio_enter(dev, RW_WRITER, &sc)) != 0) 1603 if ((error = audio_enter(dev, RW_WRITER, &sc)) != 0)
1601 return error; 1604 return error;
1602 device_active(sc->dev, DVA_SYSTEM); 1605 device_active(sc->dev, DVA_SYSTEM);
1603 switch (AUDIODEV(dev)) { 1606 switch (AUDIODEV(dev)) {
1604 case AUDIO_DEVICE: 1607 case AUDIO_DEVICE:
1605 error = audio_open(dev, sc, flags, ifmt, l, fp); 1608 error = audio_open(dev, sc, flags, ifmt, l, fp);
1606 break; 1609 break;
1607 default: 1610 default:
1608 error = EINVAL; 1611 error = EINVAL;
1609 break; 1612 break;
1610 } 1613 }
1611 audio_exit(sc); 1614 audio_exit(sc);
1612 1615
1613 return error; 1616 return error;
1614} 1617}
1615 1618
1616int 1619int
1617audiobellclose(struct file *fp) 1620audiobellclose(struct file *fp)
1618{ 1621{
1619 1622
1620 return audioclose(fp); 1623 return audioclose(fp);
1621} 1624}
1622 1625
1623int 1626int
1624audiobellwrite(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, 1627audiobellwrite(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
1625 int ioflag) 1628 int ioflag)
1626{ 1629{
1627 1630
1628 return audiowrite(fp, offp, uio, cred, ioflag); 1631 return audiowrite(fp, offp, uio, cred, ioflag);
1629} 1632}
1630 1633
1631int 1634int
1632audiobellioctl(struct file *fp, u_long cmd, void *addr) 1635audiobellioctl(struct file *fp, u_long cmd, void *addr)
1633{ 1636{
1634 1637
1635 return audioioctl(fp, cmd, addr); 1638 return audioioctl(fp, cmd, addr);
1636} 1639}
1637 1640
1638static int 1641static int
1639audioopen(dev_t dev, int flags, int ifmt, struct lwp *l) 1642audioopen(dev_t dev, int flags, int ifmt, struct lwp *l)
1640{ 1643{
1641 struct audio_softc *sc; 1644 struct audio_softc *sc;
1642 struct file *fp; 1645 struct file *fp;
1643 int error; 1646 int error;
1644 1647
1645 if ((error = audio_enter(dev, RW_WRITER, &sc)) != 0) 1648 if ((error = audio_enter(dev, RW_WRITER, &sc)) != 0)
1646 return error; 1649 return error;
1647 device_active(sc->dev, DVA_SYSTEM); 1650 device_active(sc->dev, DVA_SYSTEM);
1648 switch (AUDIODEV(dev)) { 1651 switch (AUDIODEV(dev)) {
1649 case SOUND_DEVICE: 1652 case SOUND_DEVICE:
1650 case AUDIO_DEVICE: 1653 case AUDIO_DEVICE:
1651 case AUDIOCTL_DEVICE: 1654 case AUDIOCTL_DEVICE:
1652 error = audio_open(dev, sc, flags, ifmt, l, &fp); 1655 error = audio_open(dev, sc, flags, ifmt, l, &fp);
1653 break; 1656 break;
1654 case MIXER_DEVICE: 1657 case MIXER_DEVICE:
1655 error = mixer_open(dev, sc, flags, ifmt, l, &fp); 1658 error = mixer_open(dev, sc, flags, ifmt, l, &fp);
1656 break; 1659 break;
1657 default: 1660 default:
1658 error = ENXIO; 1661 error = ENXIO;
1659 break; 1662 break;
1660 } 1663 }
1661 audio_exit(sc); 1664 audio_exit(sc);
1662 1665
1663 return error; 1666 return error;
1664} 1667}
1665 1668
1666static int 1669static int
1667audioclose(struct file *fp) 1670audioclose(struct file *fp)
1668{ 1671{
1669 struct audio_softc *sc; 1672 struct audio_softc *sc;
1670 struct audio_chan *chan; 1673 struct audio_chan *chan;
1671 int error; 1674 int error;
1672 dev_t dev; 1675 dev_t dev;
1673 1676
1674 chan = fp->f_audioctx; 1677 chan = fp->f_audioctx;
1675 if (chan == NULL) /* XXX:NS Why is this needed. */ 1678 if (chan == NULL) /* XXX:NS Why is this needed. */
1676 return EIO; 1679 return EIO;
1677 1680
1678 dev = chan->dev; 1681 dev = chan->dev;
1679 1682
1680 if ((error = audio_enter(dev, RW_WRITER, &sc)) != 0) 1683 if ((error = audio_enter(dev, RW_WRITER, &sc)) != 0)
1681 return error; 1684 return error;
1682 1685
1683 device_active(sc->dev, DVA_SYSTEM); 1686 device_active(sc->dev, DVA_SYSTEM);
1684 switch (AUDIODEV(dev)) { 1687 switch (AUDIODEV(dev)) {
1685 case SOUND_DEVICE: 1688 case SOUND_DEVICE:
1686 case AUDIO_DEVICE: 1689 case AUDIO_DEVICE:
1687 case AUDIOCTL_DEVICE: 1690 case AUDIOCTL_DEVICE:
1688 error = audio_close(sc, fp->f_flag, chan); 1691 error = audio_close(sc, fp->f_flag, chan);
1689 break; 1692 break;
1690 case MIXER_DEVICE: 1693 case MIXER_DEVICE:
1691 error = mixer_close(sc, fp->f_flag, chan); 1694 error = mixer_close(sc, fp->f_flag, chan);
1692 break; 1695 break;
1693 default: 1696 default:
1694 error = ENXIO; 1697 error = ENXIO;
1695 break; 1698 break;
1696 } 1699 }
1697 if (error == 0) { 1700 if (error == 0) {
1698 kmem_free(fp->f_audioctx, sizeof(struct audio_chan)); 1701 kmem_free(fp->f_audioctx, sizeof(struct audio_chan));
1699 fp->f_audioctx = NULL; 1702 fp->f_audioctx = NULL;
1700 } 1703 }
1701 1704
1702 audio_exit(sc); 1705 audio_exit(sc);
1703 1706
1704 return error; 1707 return error;
1705} 1708}
1706 1709
1707static int 1710static int
1708audioread(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, 1711audioread(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
1709 int ioflag) 1712 int ioflag)
1710{ 1713{
1711 struct audio_softc *sc; 1714 struct audio_softc *sc;
1712 struct virtual_channel *vc; 1715 struct virtual_channel *vc;
1713 int error; 1716 int error;
1714 dev_t dev; 1717 dev_t dev;
1715 1718
1716 if (fp->f_audioctx == NULL) 1719 if (fp->f_audioctx == NULL)
1717 return EIO; 1720 return EIO;
1718 1721
1719 dev = fp->f_audioctx->dev; 1722 dev = fp->f_audioctx->dev;
1720 1723
1721 if ((error = audio_enter(dev, RW_READER, &sc)) != 0) 1724 if ((error = audio_enter(dev, RW_READER, &sc)) != 0)
1722 return error; 1725 return error;
1723 1726
1724 if (fp->f_flag & O_NONBLOCK) 1727 if (fp->f_flag & O_NONBLOCK)
1725 ioflag |= IO_NDELAY; 1728 ioflag |= IO_NDELAY;
1726 1729
1727 switch (AUDIODEV(dev)) { 1730 switch (AUDIODEV(dev)) {
1728 case SOUND_DEVICE: 1731 case SOUND_DEVICE:
1729 case AUDIO_DEVICE: 1732 case AUDIO_DEVICE:
1730 vc = fp->f_audioctx->vc; 1733 vc = fp->f_audioctx->vc;
1731 error = audio_read(sc, uio, ioflag, vc); 1734 error = audio_read(sc, uio, ioflag, vc);
1732 break; 1735 break;
1733 case AUDIOCTL_DEVICE: 1736 case AUDIOCTL_DEVICE:
1734 case MIXER_DEVICE: 1737 case MIXER_DEVICE:
1735 error = ENODEV; 1738 error = ENODEV;
1736 break; 1739 break;
1737 default: 1740 default:
1738 error = ENXIO; 1741 error = ENXIO;
1739 break; 1742 break;
1740 } 1743 }
1741 audio_exit(sc); 1744 audio_exit(sc);
1742 1745
1743 return error; 1746 return error;
1744} 1747}
1745 1748
1746static int 1749static int
1747audiowrite(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, 1750audiowrite(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
1748 int ioflag) 1751 int ioflag)
1749{ 1752{
1750 struct audio_softc *sc; 1753 struct audio_softc *sc;
1751 struct virtual_channel *vc; 1754 struct virtual_channel *vc;
1752 int error; 1755 int error;
1753 dev_t dev; 1756 dev_t dev;
1754 1757
1755 if (fp->f_audioctx == NULL) 1758 if (fp->f_audioctx == NULL)
1756 return EIO; 1759 return EIO;
1757 1760
1758 dev = fp->f_audioctx->dev; 1761 dev = fp->f_audioctx->dev;
1759 1762
1760 if ((error = audio_enter(dev, RW_READER, &sc)) != 0) 1763 if ((error = audio_enter(dev, RW_READER, &sc)) != 0)
1761 return error; 1764 return error;
1762 1765
1763 if (fp->f_flag & O_NONBLOCK) 1766 if (fp->f_flag & O_NONBLOCK)
1764 ioflag |= IO_NDELAY; 1767 ioflag |= IO_NDELAY;
1765 1768
1766 switch (AUDIODEV(dev)) { 1769 switch (AUDIODEV(dev)) {
1767 case SOUND_DEVICE: 1770 case SOUND_DEVICE:
1768 case AUDIO_DEVICE: 1771 case AUDIO_DEVICE:
1769 vc = fp->f_audioctx->vc; 1772 vc = fp->f_audioctx->vc;
1770 error = audio_write(sc, uio, ioflag, vc); 1773 error = audio_write(sc, uio, ioflag, vc);
1771 break; 1774 break;
1772 case AUDIOCTL_DEVICE: 1775 case AUDIOCTL_DEVICE:
1773 case MIXER_DEVICE: 1776 case MIXER_DEVICE:
1774 error = ENODEV; 1777 error = ENODEV;
1775 break; 1778 break;
1776 default: 1779 default:
1777 error = ENXIO; 1780 error = ENXIO;
1778 break; 1781 break;
1779 } 1782 }
1780 audio_exit(sc); 1783 audio_exit(sc);
1781 1784
1782 return error; 1785 return error;
1783} 1786}
1784 1787
1785static int 1788static int
1786audioioctl(struct file *fp, u_long cmd, void *addr) 1789audioioctl(struct file *fp, u_long cmd, void *addr)
1787{ 1790{
1788 struct audio_softc *sc; 1791 struct audio_softc *sc;
1789 struct audio_chan *chan; 1792 struct audio_chan *chan;
1790 struct lwp *l = curlwp; 1793 struct lwp *l = curlwp;
1791 int error; 1794 int error;
1792 krw_t rw; 1795 krw_t rw;
1793 dev_t dev; 1796 dev_t dev;
1794 1797
1795 if (fp->f_audioctx == NULL) 1798 if (fp->f_audioctx == NULL)
1796 return EIO; 1799 return EIO;
1797 1800
1798 chan = fp->f_audioctx; 1801 chan = fp->f_audioctx;
1799 dev = chan->dev; 1802 dev = chan->dev;
1800 1803
1801 /* Figure out which lock type we need. */ 1804 /* Figure out which lock type we need. */
1802 switch (cmd) { 1805 switch (cmd) {
1803 case AUDIO_FLUSH: 1806 case AUDIO_FLUSH:
1804 case AUDIO_SETINFO: 1807 case AUDIO_SETINFO:
1805 case AUDIO_DRAIN: 1808 case AUDIO_DRAIN:
1806 case AUDIO_SETFD: 1809 case AUDIO_SETFD:
1807 rw = RW_WRITER; 1810 rw = RW_WRITER;
1808 break; 1811 break;
1809 default: 1812 default:
1810 rw = RW_READER; 1813 rw = RW_READER;
1811 break; 1814 break;
1812 } 1815 }
1813 1816
1814 if ((error = audio_enter(dev, rw, &sc)) != 0) 1817 if ((error = audio_enter(dev, rw, &sc)) != 0)
1815 return error; 1818 return error;
1816 1819
1817 switch (AUDIODEV(dev)) { 1820 switch (AUDIODEV(dev)) {
1818 case SOUND_DEVICE: 1821 case SOUND_DEVICE:
1819 case AUDIO_DEVICE: 1822 case AUDIO_DEVICE:
1820 case AUDIOCTL_DEVICE: 1823 case AUDIOCTL_DEVICE:
1821 device_active(sc->dev, DVA_SYSTEM); 1824 device_active(sc->dev, DVA_SYSTEM);
1822 if (IOCGROUP(cmd) == IOCGROUP(AUDIO_MIXER_READ)) 1825 if (IOCGROUP(cmd) == IOCGROUP(AUDIO_MIXER_READ))
1823 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l); 1826 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l);
1824 else 1827 else
1825 error = audio_ioctl(dev, sc, cmd, addr, fp->f_flag, l, 1828 error = audio_ioctl(dev, sc, cmd, addr, fp->f_flag, l,
1826 chan); 1829 chan);
1827 break; 1830 break;
1828 case MIXER_DEVICE: 1831 case MIXER_DEVICE:
1829 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l); 1832 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l);
1830 break; 1833 break;
1831 default: 1834 default:
1832 error = ENXIO; 1835 error = ENXIO;
1833 break; 1836 break;
1834 } 1837 }
1835 audio_exit(sc); 1838 audio_exit(sc);
1836 1839
1837 return error; 1840 return error;
1838} 1841}
1839 1842
1840static int 1843static int
1841audiostat(struct file *fp, struct stat *st) 1844audiostat(struct file *fp, struct stat *st)
1842{ 1845{
1843 if (fp->f_audioctx == NULL) 1846 if (fp->f_audioctx == NULL)
1844 return EIO; 1847 return EIO;
1845 1848
1846 memset(st, 0, sizeof(*st)); 1849 memset(st, 0, sizeof(*st));
1847 1850
1848 st->st_dev = fp->f_audioctx->dev; 1851 st->st_dev = fp->f_audioctx->dev;
1849 1852
1850 st->st_uid = kauth_cred_geteuid(fp->f_cred); 1853 st->st_uid = kauth_cred_geteuid(fp->f_cred);
1851 st->st_gid = kauth_cred_getegid(fp->f_cred); 1854 st->st_gid = kauth_cred_getegid(fp->f_cred);
1852 st->st_mode = S_IFCHR; 1855 st->st_mode = S_IFCHR;
1853 return 0; 1856 return 0;
1854} 1857}
1855 1858
1856static int 1859static int
1857audiopoll(struct file *fp, int events) 1860audiopoll(struct file *fp, int events)
1858{ 1861{
1859 struct audio_softc *sc; 1862 struct audio_softc *sc;
1860 struct virtual_channel *vc; 1863 struct virtual_channel *vc;
1861 struct lwp *l = curlwp; 1864 struct lwp *l = curlwp;
1862 int revents; 1865 int revents;
1863 dev_t dev; 1866 dev_t dev;
1864 1867
1865 if (fp->f_audioctx == NULL) 1868 if (fp->f_audioctx == NULL)
1866 return EIO; 1869 return EIO;
1867 1870
1868 dev = fp->f_audioctx->dev; 1871 dev = fp->f_audioctx->dev;
1869 1872
1870 /* Don't bother with device level lock here. */ 1873 /* Don't bother with device level lock here. */
1871 sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev)); 1874 sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev));
1872 if (sc == NULL) 1875 if (sc == NULL)
1873 return ENXIO; 1876 return ENXIO;
1874 mutex_enter(sc->sc_lock); 1877 mutex_enter(sc->sc_lock);
1875 if (sc->sc_dying) { 1878 if (sc->sc_dying) {
1876 mutex_exit(sc->sc_lock); 1879 mutex_exit(sc->sc_lock);
1877 return EIO; 1880 return EIO;
1878 } 1881 }
1879 1882
1880 switch (AUDIODEV(dev)) { 1883 switch (AUDIODEV(dev)) {
1881 case SOUND_DEVICE: 1884 case SOUND_DEVICE:
1882 case AUDIO_DEVICE: 1885 case AUDIO_DEVICE:
1883 vc = fp->f_audioctx->vc; 1886 vc = fp->f_audioctx->vc;
1884 revents = audio_poll(sc, events, l, vc); 1887 revents = audio_poll(sc, events, l, vc);
1885 break; 1888 break;
1886 case AUDIOCTL_DEVICE: 1889 case AUDIOCTL_DEVICE:
1887 case MIXER_DEVICE: 1890 case MIXER_DEVICE:
1888 revents = 0; 1891 revents = 0;
1889 break; 1892 break;
1890 default: 1893 default:
1891 revents = POLLERR; 1894 revents = POLLERR;
1892 break; 1895 break;
1893 } 1896 }
1894 mutex_exit(sc->sc_lock); 1897 mutex_exit(sc->sc_lock);
1895 1898
1896 return revents; 1899 return revents;
1897} 1900}
1898 1901
1899static int 1902static int
1900audiokqfilter(struct file *fp, struct knote *kn) 1903audiokqfilter(struct file *fp, struct knote *kn)
1901{ 1904{
1902 struct audio_softc *sc; 1905 struct audio_softc *sc;
1903 int rv; 1906 int rv;
1904 struct audio_chan *chan; 1907 struct audio_chan *chan;
1905 dev_t dev; 1908 dev_t dev;
1906 1909
1907 chan = fp->f_audioctx; 1910 chan = fp->f_audioctx;
1908 dev = chan->dev; 1911 dev = chan->dev;
1909 1912
1910 /* Don't bother with device level lock here. */ 1913 /* Don't bother with device level lock here. */
1911 sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev)); 1914 sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev));
1912 if (sc == NULL) 1915 if (sc == NULL)
1913 return ENXIO; 1916 return ENXIO;
1914 mutex_enter(sc->sc_lock); 1917 mutex_enter(sc->sc_lock);
1915 if (sc->sc_dying) { 1918 if (sc->sc_dying) {
1916 mutex_exit(sc->sc_lock); 1919 mutex_exit(sc->sc_lock);
1917 return EIO; 1920 return EIO;
1918 } 1921 }
1919 switch (AUDIODEV(dev)) { 1922 switch (AUDIODEV(dev)) {
1920 case SOUND_DEVICE: 1923 case SOUND_DEVICE:
1921 case AUDIO_DEVICE: 1924 case AUDIO_DEVICE:
1922 rv = audio_kqfilter(chan, kn); 1925 rv = audio_kqfilter(chan, kn);
1923 break; 1926 break;
1924 case AUDIOCTL_DEVICE: 1927 case AUDIOCTL_DEVICE:
1925 case MIXER_DEVICE: 1928 case MIXER_DEVICE:
1926 rv = 1; 1929 rv = 1;
1927 break; 1930 break;
1928 default: 1931 default:
1929 rv = 1; 1932 rv = 1;
1930 } 1933 }
1931 mutex_exit(sc->sc_lock); 1934 mutex_exit(sc->sc_lock);
1932 1935
1933 return rv; 1936 return rv;
1934} 1937}
1935 1938
1936static int 1939static int
1937audio_fop_mmap(struct file *fp, off_t *offp, size_t len, int prot, int *flagsp, 1940audio_fop_mmap(struct file *fp, off_t *offp, size_t len, int prot, int *flagsp,
1938 int *advicep, struct uvm_object **uobjp, int *maxprotp) 1941 int *advicep, struct uvm_object **uobjp, int *maxprotp)
1939{ 1942{
1940 struct audio_softc *sc; 1943 struct audio_softc *sc;
1941 struct audio_chan *chan; 1944 struct audio_chan *chan;
1942 struct virtual_channel *vc; 1945 struct virtual_channel *vc;
1943 dev_t dev; 1946 dev_t dev;
1944 int error; 1947 int error;
1945 1948
1946 chan = fp->f_audioctx; 1949 chan = fp->f_audioctx;
1947 dev = chan->dev; 1950 dev = chan->dev;
1948 vc = chan->vc; 1951 vc = chan->vc;
1949 error = 0; 1952 error = 0;
1950 1953
1951 if ((error = audio_enter(dev, RW_READER, &sc)) != 0) 1954 if ((error = audio_enter(dev, RW_READER, &sc)) != 0)
1952 return 1; 1955 return 1;
1953 device_active(sc->dev, DVA_SYSTEM); /* XXXJDM */ 1956 device_active(sc->dev, DVA_SYSTEM); /* XXXJDM */
1954 1957
1955 switch (AUDIODEV(dev)) { 1958 switch (AUDIODEV(dev)) {
1956 case SOUND_DEVICE: 1959 case SOUND_DEVICE:
1957 case AUDIO_DEVICE: 1960 case AUDIO_DEVICE:
1958 error = audio_mmap(sc, offp, len, prot, flagsp, advicep, 1961 error = audio_mmap(sc, offp, len, prot, flagsp, advicep,
1959 uobjp, maxprotp, vc);  1962 uobjp, maxprotp, vc);
1960 break; 1963 break;
1961 case AUDIOCTL_DEVICE: 1964 case AUDIOCTL_DEVICE:
1962 case MIXER_DEVICE: 1965 case MIXER_DEVICE:
1963 default: 1966 default:
1964 error = ENOTSUP; 1967 error = ENOTSUP;
1965 break; 1968 break;
1966 } 1969 }
1967 audio_exit(sc); 1970 audio_exit(sc);
1968 1971
1969 return error; 1972 return error;
1970} 1973}
1971 1974
1972/* 1975/*
1973 * Audio driver 1976 * Audio driver
1974 */ 1977 */
1975void 1978void
1976audio_init_ringbuffer(struct audio_softc *sc, struct audio_ringbuffer *rp, 1979audio_init_ringbuffer(struct audio_softc *sc, struct audio_ringbuffer *rp,
1977 int mode) 1980 int mode)
1978{ 1981{
1979 int nblks; 1982 int nblks;
1980 int blksize; 1983 int blksize;
1981 1984
1982 blksize = rp->blksize; 1985 blksize = rp->blksize;
1983 if (blksize < AUMINBLK) 1986 if (blksize < AUMINBLK)
1984 blksize = AUMINBLK; 1987 blksize = AUMINBLK;
1985 if (blksize > (int)(rp->s.bufsize / AUMINNOBLK)) 1988 if (blksize > (int)(rp->s.bufsize / AUMINNOBLK))
1986 blksize = rp->s.bufsize / AUMINNOBLK; 1989 blksize = rp->s.bufsize / AUMINNOBLK;
1987 ROUNDSIZE(blksize); 1990 ROUNDSIZE(blksize);
1988 DPRINTF(("audio_init_ringbuffer: MI blksize=%d\n", blksize)); 1991 DPRINTF(("audio_init_ringbuffer: MI blksize=%d\n", blksize));
1989 if (sc->hw_if->round_blocksize) 1992 if (sc->hw_if->round_blocksize)
1990 blksize = sc->hw_if->round_blocksize(sc->hw_hdl, blksize, 1993 blksize = sc->hw_if->round_blocksize(sc->hw_hdl, blksize,
1991 mode, &rp->s.param); 1994 mode, &rp->s.param);
1992 if (blksize <= 0) 1995 if (blksize <= 0)
1993 panic("audio_init_ringbuffer: blksize=%d", blksize); 1996 panic("audio_init_ringbuffer: blksize=%d", blksize);
1994 nblks = rp->s.bufsize / blksize; 1997 nblks = rp->s.bufsize / blksize;
1995 1998
1996 DPRINTF(("audio_init_ringbuffer: final blksize=%d\n", blksize)); 1999 DPRINTF(("audio_init_ringbuffer: final blksize=%d\n", blksize));
1997 rp->blksize = blksize; 2000 rp->blksize = blksize;
1998 rp->maxblks = nblks; 2001 rp->maxblks = nblks;
1999 rp->s.end = rp->s.start + nblks * blksize; 2002 rp->s.end = rp->s.start + nblks * blksize;
2000 rp->s.outp = rp->s.inp = rp->s.start; 2003 rp->s.outp = rp->s.inp = rp->s.start;
2001 rp->s.used = 0; 2004 rp->s.used = 0;
2002 rp->stamp = 0; 2005 rp->stamp = 0;
2003 rp->stamp_last = 0; 2006 rp->stamp_last = 0;
2004 rp->fstamp = 0; 2007 rp->fstamp = 0;
2005 rp->drops = 0; 2008 rp->drops = 0;
2006 rp->copying = false; 2009 rp->copying = false;
2007 rp->needfill = false; 2010 rp->needfill = false;
2008 rp->mmapped = false; 2011 rp->mmapped = false;
2009 memset(rp->s.start, 0, blksize * 2); 2012 memset(rp->s.start, 0, blksize * 2);
2010} 2013}
2011 2014
2012int 2015int
2013audio_initbufs(struct audio_softc *sc, struct virtual_channel *vc) 2016audio_initbufs(struct audio_softc *sc, struct virtual_channel *vc)
2014{ 2017{
2015 const struct audio_hw_if *hw; 2018 const struct audio_hw_if *hw;
2016 int error; 2019 int error;
2017 2020
2018 if (vc == NULL) { 2021 if (vc == NULL) {
2019 vc = sc->sc_hwvc; 2022 vc = sc->sc_hwvc;
2020 sc->sc_pr.blksize = vc->sc_mrr.blksize; 2023 sc->sc_pr.blksize = vc->sc_mrr.blksize;
2021 sc->sc_rr.blksize = vc->sc_mrr.blksize; 2024 sc->sc_rr.blksize = vc->sc_mrr.blksize;
2022 } 2025 }
2023 2026
2024 DPRINTF(("audio_initbufs: mode=0x%x\n", vc->sc_mode)); 2027 DPRINTF(("audio_initbufs: mode=0x%x\n", vc->sc_mode));
2025 hw = sc->hw_if; 2028 hw = sc->hw_if;
2026 if (audio_can_capture(sc) && 2029 if (audio_can_capture(sc) &&
2027 ((vc->sc_open & AUOPEN_READ) || vc == sc->sc_hwvc)) { 2030 ((vc->sc_open & AUOPEN_READ) || vc == sc->sc_hwvc)) {
2028 audio_init_ringbuffer(sc, &vc->sc_mrr, 2031 audio_init_ringbuffer(sc, &vc->sc_mrr,
2029 AUMODE_RECORD); 2032 AUMODE_RECORD);
2030 if (sc->sc_opens == 0 && hw->init_input && 2033 if (sc->sc_opens == 0 && hw->init_input &&
2031 (vc->sc_mode & AUMODE_RECORD)) { 2034 (vc->sc_mode & AUMODE_RECORD)) {
2032 error = hw->init_input(sc->hw_hdl, vc->sc_mrr.s.start, 2035 error = hw->init_input(sc->hw_hdl, vc->sc_mrr.s.start,
2033 vc->sc_mrr.s.end - vc->sc_mrr.s.start); 2036 vc->sc_mrr.s.end - vc->sc_mrr.s.start);
2034 if (error) 2037 if (error)
2035 return error; 2038 return error;
2036 } 2039 }
2037 } 2040 }
2038 if (vc == sc->sc_hwvc) 2041 if (vc == sc->sc_hwvc)
2039 sc->sc_rr.blksize = vc->sc_mrr.blksize; 2042 sc->sc_rr.blksize = vc->sc_mrr.blksize;
2040 2043
2041 if (audio_can_playback(sc) && 2044 if (audio_can_playback(sc) &&
2042 ((vc->sc_open & AUOPEN_WRITE) || vc == sc->sc_hwvc)) { 2045 ((vc->sc_open & AUOPEN_WRITE) || vc == sc->sc_hwvc)) {
2043 audio_init_ringbuffer(sc, &vc->sc_mpr, 2046 audio_init_ringbuffer(sc, &vc->sc_mpr,
2044 AUMODE_PLAY); 2047 AUMODE_PLAY);
2045 vc->sc_sil_count = 0; 2048 vc->sc_sil_count = 0;
2046 if (sc->sc_opens == 0 && hw->init_output && 2049 if (sc->sc_opens == 0 && hw->init_output &&
2047 (vc->sc_mode & AUMODE_PLAY)) { 2050 (vc->sc_mode & AUMODE_PLAY)) {
2048 error = hw->init_output(sc->hw_hdl, vc->sc_mpr.s.start, 2051 error = hw->init_output(sc->hw_hdl, vc->sc_mpr.s.start,
2049 vc->sc_mpr.s.end - vc->sc_mpr.s.start); 2052 vc->sc_mpr.s.end - vc->sc_mpr.s.start);
2050 if (error) 2053 if (error)
2051 return error; 2054 return error;
2052 } 2055 }
2053 } 2056 }
2054 if (vc == sc->sc_hwvc) 2057 if (vc == sc->sc_hwvc)
2055 sc->sc_pr.blksize = vc->sc_mpr.blksize; 2058 sc->sc_pr.blksize = vc->sc_mpr.blksize;
2056 2059
2057#ifdef AUDIO_INTR_TIME 2060#ifdef AUDIO_INTR_TIME
2058 if (audio_can_playback(sc)) { 2061 if (audio_can_playback(sc)) {
2059 sc->sc_pnintr = 0; 2062 sc->sc_pnintr = 0;
2060 sc->sc_pblktime = (int64_t)vc->sc_mpr.blksize * 1000000 / 2063 sc->sc_pblktime = (int64_t)vc->sc_mpr.blksize * 1000000 /
2061 (vc->sc_pparams.channels * 2064 (vc->sc_pparams.channels *
2062 vc->sc_pparams.sample_rate * 2065 vc->sc_pparams.sample_rate *
2063 vc->sc_pparams.precision / NBBY); 2066 vc->sc_pparams.precision / NBBY);
2064 DPRINTF(("audio: play blktime = %" PRId64 " for %d\n", 2067 DPRINTF(("audio: play blktime = %" PRId64 " for %d\n",
2065 sc->sc_pblktime, vc->sc_mpr.blksize)); 2068 sc->sc_pblktime, vc->sc_mpr.blksize));
2066 } 2069 }
2067 if (audio_can_capture(sc)) { 2070 if (audio_can_capture(sc)) {
2068 sc->sc_rnintr = 0; 2071 sc->sc_rnintr = 0;
2069 sc->sc_rblktime = (int64_t)vc->sc_mrr.blksize * 1000000 / 2072 sc->sc_rblktime = (int64_t)vc->sc_mrr.blksize * 1000000 /
2070 (vc->sc_rparams.channels * 2073 (vc->sc_rparams.channels *
2071 vc->sc_rparams.sample_rate * 2074 vc->sc_rparams.sample_rate *
2072 vc->sc_rparams.precision / NBBY); 2075 vc->sc_rparams.precision / NBBY);
2073 DPRINTF(("audio: record blktime = %" PRId64 " for %d\n", 2076 DPRINTF(("audio: record blktime = %" PRId64 " for %d\n",
2074 sc->sc_rblktime, vc->sc_mrr.blksize)); 2077 sc->sc_rblktime, vc->sc_mrr.blksize));
2075 } 2078 }
2076#endif 2079#endif
2077 2080
2078 return 0; 2081 return 0;
2079} 2082}
2080 2083
2081void 2084void
2082audio_calcwater(struct audio_softc *sc, struct virtual_channel *vc) 2085audio_calcwater(struct audio_softc *sc, struct virtual_channel *vc)
2083{ 2086{
2084 /* set high at 100% */ 2087 /* set high at 100% */
2085 if (audio_can_playback(sc) && vc && vc->sc_pustream) { 2088 if (audio_can_playback(sc) && vc && vc->sc_pustream) {
2086 vc->sc_mpr.usedhigh = 2089 vc->sc_mpr.usedhigh =
2087 vc->sc_pustream->end - vc->sc_pustream->start; 2090 vc->sc_pustream->end - vc->sc_pustream->start;
2088 /* set low at 75% of usedhigh */ 2091 /* set low at 75% of usedhigh */
2089 vc->sc_mpr.usedlow = vc->sc_mpr.usedhigh * 3 / 4; 2092 vc->sc_mpr.usedlow = vc->sc_mpr.usedhigh * 3 / 4;
2090 if (vc->sc_mpr.usedlow == vc->sc_mpr.usedhigh) 2093 if (vc->sc_mpr.usedlow == vc->sc_mpr.usedhigh)
2091 vc->sc_mpr.usedlow -= vc->sc_mpr.blksize; 2094 vc->sc_mpr.usedlow -= vc->sc_mpr.blksize;
2092 } 2095 }
2093 2096
2094 if (audio_can_capture(sc) && vc && vc->sc_rustream) { 2097 if (audio_can_capture(sc) && vc && vc->sc_rustream) {
2095 vc->sc_mrr.usedhigh = 2098 vc->sc_mrr.usedhigh =
2096 vc->sc_rustream->end - vc->sc_rustream->start - 2099 vc->sc_rustream->end - vc->sc_rustream->start -
2097 vc->sc_mrr.blksize; 2100 vc->sc_mrr.blksize;
2098 vc->sc_mrr.usedlow = 0; 2101 vc->sc_mrr.usedlow = 0;
2099 DPRINTF(("%s: plow=%d phigh=%d rlow=%d rhigh=%d\n", __func__, 2102 DPRINTF(("%s: plow=%d phigh=%d rlow=%d rhigh=%d\n", __func__,
2100 vc->sc_mpr.usedlow, vc->sc_mpr.usedhigh, 2103 vc->sc_mpr.usedlow, vc->sc_mpr.usedhigh,
2101 vc->sc_mrr.usedlow, vc->sc_mrr.usedhigh)); 2104 vc->sc_mrr.usedlow, vc->sc_mrr.usedhigh));
2102 } 2105 }
2103} 2106}
2104 2107
2105int 2108int
2106audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt, 2109audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
2107 struct lwp *l, struct file **nfp) 2110 struct lwp *l, struct file **nfp)
2108{ 2111{
2109 struct file *fp; 2112 struct file *fp;
2110 int error, fd, n; 2113 int error, fd, n;
2111 u_int mode; 2114 u_int mode;
2112 const struct audio_hw_if *hw; 2115 const struct audio_hw_if *hw;