Sun Mar 28 19:55:37 2021 UTC ()
audio only has one interface attribute, so no need to be explcit about it.
audio also doesn't have locators, so don't pass any to config_search().


(thorpej)
diff -r1.91.2.3 -r1.91.2.4 src/sys/dev/audio/audio.c

cvs diff -r1.91.2.3 -r1.91.2.4 src/sys/dev/audio/audio.c (switch to unified diff)

--- src/sys/dev/audio/audio.c 2021/03/21 21:09:09 1.91.2.3
+++ src/sys/dev/audio/audio.c 2021/03/28 19:55:37 1.91.2.4
@@ -1,2419 +1,2417 @@ @@ -1,2419 +1,2417 @@
1/* $NetBSD: audio.c,v 1.91.2.3 2021/03/21 21:09:09 thorpej Exp $ */ 1/* $NetBSD: audio.c,v 1.91.2.4 2021/03/28 19:55:37 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1991-1993 Regents of the University of California. 33 * Copyright (c) 1991-1993 Regents of the University of California.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software 44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement: 45 * must display the following acknowledgement:
46 * This product includes software developed by the Computer Systems 46 * This product includes software developed by the Computer Systems
47 * Engineering Group at Lawrence Berkeley Laboratory. 47 * Engineering Group at Lawrence Berkeley Laboratory.
48 * 4. Neither the name of the University nor of the Laboratory may be used 48 * 4. Neither the name of the University nor of the Laboratory may be used
49 * to endorse or promote products derived from this software without 49 * to endorse or promote products derived from this software without
50 * specific prior written permission. 50 * specific prior written permission.
51 * 51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE. 62 * SUCH DAMAGE.
63 */ 63 */
64 64
65/* 65/*
66 * Locking: there are three locks per device. 66 * Locking: there are three locks per device.
67 * 67 *
68 * - sc_lock, provided by the underlying driver. This is an adaptive lock, 68 * - sc_lock, provided by the underlying driver. This is an adaptive lock,
69 * returned in the second parameter to hw_if->get_locks(). It is known 69 * returned in the second parameter to hw_if->get_locks(). It is known
70 * as the "thread lock". 70 * as the "thread lock".
71 * 71 *
72 * It serializes access to state in all places except the 72 * It serializes access to state in all places except the
73 * driver's interrupt service routine. This lock is taken from process 73 * driver's interrupt service routine. This lock is taken from process
74 * context (example: access to /dev/audio). It is also taken from soft 74 * context (example: access to /dev/audio). It is also taken from soft
75 * interrupt handlers in this module, primarily to serialize delivery of 75 * interrupt handlers in this module, primarily to serialize delivery of
76 * wakeups. This lock may be used/provided by modules external to the 76 * wakeups. This lock may be used/provided by modules external to the
77 * audio subsystem, so take care not to introduce a lock order problem. 77 * audio subsystem, so take care not to introduce a lock order problem.
78 * LONG TERM SLEEPS MUST NOT OCCUR WITH THIS LOCK HELD. 78 * LONG TERM SLEEPS MUST NOT OCCUR WITH THIS LOCK HELD.
79 * 79 *
80 * - sc_intr_lock, provided by the underlying driver. This may be either a 80 * - sc_intr_lock, provided by the underlying driver. This may be either a
81 * spinlock (at IPL_SCHED or IPL_VM) or an adaptive lock (IPL_NONE or 81 * spinlock (at IPL_SCHED or IPL_VM) or an adaptive lock (IPL_NONE or
82 * IPL_SOFT*), returned in the first parameter to hw_if->get_locks(). It 82 * IPL_SOFT*), returned in the first parameter to hw_if->get_locks(). It
83 * is known as the "interrupt lock". 83 * is known as the "interrupt lock".
84 * 84 *
85 * It provides atomic access to the device's hardware state, and to audio 85 * It provides atomic access to the device's hardware state, and to audio
86 * channel data that may be accessed by the hardware driver's ISR. 86 * channel data that may be accessed by the hardware driver's ISR.
87 * In all places outside the ISR, sc_lock must be held before taking 87 * In all places outside the ISR, sc_lock must be held before taking
88 * sc_intr_lock. This is to ensure that groups of hardware operations are 88 * sc_intr_lock. This is to ensure that groups of hardware operations are
89 * made atomically. SLEEPS CANNOT OCCUR WITH THIS LOCK HELD. 89 * made atomically. SLEEPS CANNOT OCCUR WITH THIS LOCK HELD.
90 * 90 *
91 * - sc_exlock, private to this module. This is a variable protected by 91 * - sc_exlock, private to this module. This is a variable protected by
92 * sc_lock. It is known as the "critical section". 92 * sc_lock. It is known as the "critical section".
93 * Some operations release sc_lock in order to allocate memory, to wait 93 * Some operations release sc_lock in order to allocate memory, to wait
94 * for in-flight I/O to complete, to copy to/from user context, etc. 94 * for in-flight I/O to complete, to copy to/from user context, etc.
95 * sc_exlock provides a critical section even under the circumstance. 95 * sc_exlock provides a critical section even under the circumstance.
96 * "+" in following list indicates the interfaces which necessary to be 96 * "+" in following list indicates the interfaces which necessary to be
97 * protected by sc_exlock. 97 * protected by sc_exlock.
98 * 98 *
99 * List of hardware interface methods, and which locks are held when each 99 * List of hardware interface methods, and which locks are held when each
100 * is called by this module: 100 * is called by this module:
101 * 101 *
102 * METHOD INTR THREAD NOTES 102 * METHOD INTR THREAD NOTES
103 * ----------------------- ------- ------- ------------------------- 103 * ----------------------- ------- ------- -------------------------
104 * open x x + 104 * open x x +
105 * close x x + 105 * close x x +
106 * query_format - x 106 * query_format - x
107 * set_format - x 107 * set_format - x
108 * round_blocksize - x 108 * round_blocksize - x
109 * commit_settings - x 109 * commit_settings - x
110 * init_output x x 110 * init_output x x
111 * init_input x x 111 * init_input x x
112 * start_output x x + 112 * start_output x x +
113 * start_input x x + 113 * start_input x x +
114 * halt_output x x + 114 * halt_output x x +
115 * halt_input x x + 115 * halt_input x x +
116 * speaker_ctl x x 116 * speaker_ctl x x
117 * getdev - x 117 * getdev - x
118 * set_port - x + 118 * set_port - x +
119 * get_port - x + 119 * get_port - x +
120 * query_devinfo - x 120 * query_devinfo - x
121 * allocm - - + 121 * allocm - - +
122 * freem - - + 122 * freem - - +
123 * round_buffersize - x 123 * round_buffersize - x
124 * get_props - - Called at attach time 124 * get_props - - Called at attach time
125 * trigger_output x x + 125 * trigger_output x x +
126 * trigger_input x x + 126 * trigger_input x x +
127 * dev_ioctl - x 127 * dev_ioctl - x
128 * get_locks - - Called at attach time 128 * get_locks - - Called at attach time
129 * 129 *
130 * In addition, there is an additional lock. 130 * In addition, there is an additional lock.
131 * 131 *
132 * - track->lock. This is an atomic variable and is similar to the 132 * - track->lock. This is an atomic variable and is similar to the
133 * "interrupt lock". This is one for each track. If any thread context 133 * "interrupt lock". This is one for each track. If any thread context
134 * (and software interrupt context) and hardware interrupt context who 134 * (and software interrupt context) and hardware interrupt context who
135 * want to access some variables on this track, they must acquire this 135 * want to access some variables on this track, they must acquire this
136 * lock before. It protects track's consistency between hardware 136 * lock before. It protects track's consistency between hardware
137 * interrupt context and others. 137 * interrupt context and others.
138 */ 138 */
139 139
140#include <sys/cdefs.h> 140#include <sys/cdefs.h>
141__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.91.2.3 2021/03/21 21:09:09 thorpej Exp $"); 141__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.91.2.4 2021/03/28 19:55:37 thorpej Exp $");
142 142
143#ifdef _KERNEL_OPT 143#ifdef _KERNEL_OPT
144#include "audio.h" 144#include "audio.h"
145#include "midi.h" 145#include "midi.h"
146#endif 146#endif
147 147
148#if NAUDIO > 0 148#if NAUDIO > 0
149 149
150#include <sys/types.h> 150#include <sys/types.h>
151#include <sys/param.h> 151#include <sys/param.h>
152#include <sys/atomic.h> 152#include <sys/atomic.h>
153#include <sys/audioio.h> 153#include <sys/audioio.h>
154#include <sys/conf.h> 154#include <sys/conf.h>
155#include <sys/cpu.h> 155#include <sys/cpu.h>
156#include <sys/device.h> 156#include <sys/device.h>
157#include <sys/fcntl.h> 157#include <sys/fcntl.h>
158#include <sys/file.h> 158#include <sys/file.h>
159#include <sys/filedesc.h> 159#include <sys/filedesc.h>
160#include <sys/intr.h> 160#include <sys/intr.h>
161#include <sys/ioctl.h> 161#include <sys/ioctl.h>
162#include <sys/kauth.h> 162#include <sys/kauth.h>
163#include <sys/kernel.h> 163#include <sys/kernel.h>
164#include <sys/kmem.h> 164#include <sys/kmem.h>
165#include <sys/malloc.h> 165#include <sys/malloc.h>
166#include <sys/mman.h> 166#include <sys/mman.h>
167#include <sys/module.h> 167#include <sys/module.h>
168#include <sys/poll.h> 168#include <sys/poll.h>
169#include <sys/proc.h> 169#include <sys/proc.h>
170#include <sys/queue.h> 170#include <sys/queue.h>
171#include <sys/select.h> 171#include <sys/select.h>
172#include <sys/signalvar.h> 172#include <sys/signalvar.h>
173#include <sys/stat.h> 173#include <sys/stat.h>
174#include <sys/sysctl.h> 174#include <sys/sysctl.h>
175#include <sys/systm.h> 175#include <sys/systm.h>
176#include <sys/syslog.h> 176#include <sys/syslog.h>
177#include <sys/vnode.h> 177#include <sys/vnode.h>
178 178
179#include <dev/audio/audio_if.h> 179#include <dev/audio/audio_if.h>
180#include <dev/audio/audiovar.h> 180#include <dev/audio/audiovar.h>
181#include <dev/audio/audiodef.h> 181#include <dev/audio/audiodef.h>
182#include <dev/audio/linear.h> 182#include <dev/audio/linear.h>
183#include <dev/audio/mulaw.h> 183#include <dev/audio/mulaw.h>
184 184
185#include <machine/endian.h> 185#include <machine/endian.h>
186 186
187#include <uvm/uvm_extern.h> 187#include <uvm/uvm_extern.h>
188 188
189#include "ioconf.h" 189#include "ioconf.h"
190 190
191/* 191/*
192 * 0: No debug logs 192 * 0: No debug logs
193 * 1: action changes like open/close/set_format... 193 * 1: action changes like open/close/set_format...
194 * 2: + normal operations like read/write/ioctl... 194 * 2: + normal operations like read/write/ioctl...
195 * 3: + TRACEs except interrupt 195 * 3: + TRACEs except interrupt
196 * 4: + TRACEs including interrupt 196 * 4: + TRACEs including interrupt
197 */ 197 */
198//#define AUDIO_DEBUG 1 198//#define AUDIO_DEBUG 1
199 199
200#if defined(AUDIO_DEBUG) 200#if defined(AUDIO_DEBUG)
201 201
202int audiodebug = AUDIO_DEBUG; 202int audiodebug = AUDIO_DEBUG;
203static void audio_vtrace(struct audio_softc *sc, const char *, const char *, 203static void audio_vtrace(struct audio_softc *sc, const char *, const char *,
204 const char *, va_list); 204 const char *, va_list);
205static void audio_trace(struct audio_softc *sc, const char *, const char *, ...) 205static void audio_trace(struct audio_softc *sc, const char *, const char *, ...)
206 __printflike(3, 4); 206 __printflike(3, 4);
207static void audio_tracet(const char *, audio_track_t *, const char *, ...) 207static void audio_tracet(const char *, audio_track_t *, const char *, ...)
208 __printflike(3, 4); 208 __printflike(3, 4);
209static void audio_tracef(const char *, audio_file_t *, const char *, ...) 209static void audio_tracef(const char *, audio_file_t *, const char *, ...)
210 __printflike(3, 4); 210 __printflike(3, 4);
211 211
212/* XXX sloppy memory logger */ 212/* XXX sloppy memory logger */
213static void audio_mlog_init(void); 213static void audio_mlog_init(void);
214static void audio_mlog_free(void); 214static void audio_mlog_free(void);
215static void audio_mlog_softintr(void *); 215static void audio_mlog_softintr(void *);
216extern void audio_mlog_flush(void); 216extern void audio_mlog_flush(void);
217extern void audio_mlog_printf(const char *, ...); 217extern void audio_mlog_printf(const char *, ...);
218 218
219static int mlog_refs; /* reference counter */ 219static int mlog_refs; /* reference counter */
220static char *mlog_buf[2]; /* double buffer */ 220static char *mlog_buf[2]; /* double buffer */
221static int mlog_buflen; /* buffer length */ 221static int mlog_buflen; /* buffer length */
222static int mlog_used; /* used length */ 222static int mlog_used; /* used length */
223static int mlog_full; /* number of dropped lines by buffer full */ 223static int mlog_full; /* number of dropped lines by buffer full */
224static int mlog_drop; /* number of dropped lines by busy */ 224static int mlog_drop; /* number of dropped lines by busy */
225static volatile uint32_t mlog_inuse; /* in-use */ 225static volatile uint32_t mlog_inuse; /* in-use */
226static int mlog_wpage; /* active page */ 226static int mlog_wpage; /* active page */
227static void *mlog_sih; /* softint handle */ 227static void *mlog_sih; /* softint handle */
228 228
229static void 229static void
230audio_mlog_init(void) 230audio_mlog_init(void)
231{ 231{
232 mlog_refs++; 232 mlog_refs++;
233 if (mlog_refs > 1) 233 if (mlog_refs > 1)
234 return; 234 return;
235 mlog_buflen = 4096; 235 mlog_buflen = 4096;
236 mlog_buf[0] = kmem_zalloc(mlog_buflen, KM_SLEEP); 236 mlog_buf[0] = kmem_zalloc(mlog_buflen, KM_SLEEP);
237 mlog_buf[1] = kmem_zalloc(mlog_buflen, KM_SLEEP); 237 mlog_buf[1] = kmem_zalloc(mlog_buflen, KM_SLEEP);
238 mlog_used = 0; 238 mlog_used = 0;
239 mlog_full = 0; 239 mlog_full = 0;
240 mlog_drop = 0; 240 mlog_drop = 0;
241 mlog_inuse = 0; 241 mlog_inuse = 0;
242 mlog_wpage = 0; 242 mlog_wpage = 0;
243 mlog_sih = softint_establish(SOFTINT_SERIAL, audio_mlog_softintr, NULL); 243 mlog_sih = softint_establish(SOFTINT_SERIAL, audio_mlog_softintr, NULL);
244 if (mlog_sih == NULL) 244 if (mlog_sih == NULL)
245 printf("%s: softint_establish failed\n", __func__); 245 printf("%s: softint_establish failed\n", __func__);
246} 246}
247 247
248static void 248static void
249audio_mlog_free(void) 249audio_mlog_free(void)
250{ 250{
251 mlog_refs--; 251 mlog_refs--;
252 if (mlog_refs > 0) 252 if (mlog_refs > 0)
253 return; 253 return;
254 254
255 audio_mlog_flush(); 255 audio_mlog_flush();
256 if (mlog_sih) 256 if (mlog_sih)
257 softint_disestablish(mlog_sih); 257 softint_disestablish(mlog_sih);
258 kmem_free(mlog_buf[0], mlog_buflen); 258 kmem_free(mlog_buf[0], mlog_buflen);
259 kmem_free(mlog_buf[1], mlog_buflen); 259 kmem_free(mlog_buf[1], mlog_buflen);
260} 260}
261 261
262/* 262/*
263 * Flush memory buffer. 263 * Flush memory buffer.
264 * It must not be called from hardware interrupt context. 264 * It must not be called from hardware interrupt context.
265 */ 265 */
266void 266void
267audio_mlog_flush(void) 267audio_mlog_flush(void)
268{ 268{
269 if (mlog_refs == 0) 269 if (mlog_refs == 0)
270 return; 270 return;
271 271
272 /* Nothing to do if already in use ? */ 272 /* Nothing to do if already in use ? */
273 if (atomic_swap_32(&mlog_inuse, 1) == 1) 273 if (atomic_swap_32(&mlog_inuse, 1) == 1)
274 return; 274 return;
275 275
276 int rpage = mlog_wpage; 276 int rpage = mlog_wpage;
277 mlog_wpage ^= 1; 277 mlog_wpage ^= 1;
278 mlog_buf[mlog_wpage][0] = '\0'; 278 mlog_buf[mlog_wpage][0] = '\0';
279 mlog_used = 0; 279 mlog_used = 0;
280 280
281 atomic_swap_32(&mlog_inuse, 0); 281 atomic_swap_32(&mlog_inuse, 0);
282 282
283 if (mlog_buf[rpage][0] != '\0') { 283 if (mlog_buf[rpage][0] != '\0') {
284 printf("%s", mlog_buf[rpage]); 284 printf("%s", mlog_buf[rpage]);
285 if (mlog_drop > 0) 285 if (mlog_drop > 0)
286 printf("mlog_drop %d\n", mlog_drop); 286 printf("mlog_drop %d\n", mlog_drop);
287 if (mlog_full > 0) 287 if (mlog_full > 0)
288 printf("mlog_full %d\n", mlog_full); 288 printf("mlog_full %d\n", mlog_full);
289 } 289 }
290 mlog_full = 0; 290 mlog_full = 0;
291 mlog_drop = 0; 291 mlog_drop = 0;
292} 292}
293 293
294static void 294static void
295audio_mlog_softintr(void *cookie) 295audio_mlog_softintr(void *cookie)
296{ 296{
297 audio_mlog_flush(); 297 audio_mlog_flush();
298} 298}
299 299
300void 300void
301audio_mlog_printf(const char *fmt, ...) 301audio_mlog_printf(const char *fmt, ...)
302{ 302{
303 int len; 303 int len;
304 va_list ap; 304 va_list ap;
305 305
306 if (atomic_swap_32(&mlog_inuse, 1) == 1) { 306 if (atomic_swap_32(&mlog_inuse, 1) == 1) {
307 /* already inuse */ 307 /* already inuse */
308 mlog_drop++; 308 mlog_drop++;
309 return; 309 return;
310 } 310 }
311 311
312 va_start(ap, fmt); 312 va_start(ap, fmt);
313 len = vsnprintf( 313 len = vsnprintf(
314 mlog_buf[mlog_wpage] + mlog_used, 314 mlog_buf[mlog_wpage] + mlog_used,
315 mlog_buflen - mlog_used, 315 mlog_buflen - mlog_used,
316 fmt, ap); 316 fmt, ap);
317 va_end(ap); 317 va_end(ap);
318 318
319 mlog_used += len; 319 mlog_used += len;
320 if (mlog_buflen - mlog_used <= 1) { 320 if (mlog_buflen - mlog_used <= 1) {
321 mlog_full++; 321 mlog_full++;
322 } 322 }
323 323
324 atomic_swap_32(&mlog_inuse, 0); 324 atomic_swap_32(&mlog_inuse, 0);
325 325
326 if (mlog_sih) 326 if (mlog_sih)
327 softint_schedule(mlog_sih); 327 softint_schedule(mlog_sih);
328} 328}
329 329
330/* trace functions */ 330/* trace functions */
331static void 331static void
332audio_vtrace(struct audio_softc *sc, const char *funcname, const char *header, 332audio_vtrace(struct audio_softc *sc, const char *funcname, const char *header,
333 const char *fmt, va_list ap) 333 const char *fmt, va_list ap)
334{ 334{
335 char buf[256]; 335 char buf[256];
336 int n; 336 int n;
337 337
338 n = 0; 338 n = 0;
339 buf[0] = '\0'; 339 buf[0] = '\0';
340 n += snprintf(buf + n, sizeof(buf) - n, "%s@%d %s", 340 n += snprintf(buf + n, sizeof(buf) - n, "%s@%d %s",
341 funcname, device_unit(sc->sc_dev), header); 341 funcname, device_unit(sc->sc_dev), header);
342 n += vsnprintf(buf + n, sizeof(buf) - n, fmt, ap); 342 n += vsnprintf(buf + n, sizeof(buf) - n, fmt, ap);
343 343
344 if (cpu_intr_p()) { 344 if (cpu_intr_p()) {
345 audio_mlog_printf("%s\n", buf); 345 audio_mlog_printf("%s\n", buf);
346 } else { 346 } else {
347 audio_mlog_flush(); 347 audio_mlog_flush();
348 printf("%s\n", buf); 348 printf("%s\n", buf);
349 } 349 }
350} 350}
351 351
352static void 352static void
353audio_trace(struct audio_softc *sc, const char *funcname, const char *fmt, ...) 353audio_trace(struct audio_softc *sc, const char *funcname, const char *fmt, ...)
354{ 354{
355 va_list ap; 355 va_list ap;
356 356
357 va_start(ap, fmt); 357 va_start(ap, fmt);
358 audio_vtrace(sc, funcname, "", fmt, ap); 358 audio_vtrace(sc, funcname, "", fmt, ap);
359 va_end(ap); 359 va_end(ap);
360} 360}
361 361
362static void 362static void
363audio_tracet(const char *funcname, audio_track_t *track, const char *fmt, ...) 363audio_tracet(const char *funcname, audio_track_t *track, const char *fmt, ...)
364{ 364{
365 char hdr[16]; 365 char hdr[16];
366 va_list ap; 366 va_list ap;
367 367
368 snprintf(hdr, sizeof(hdr), "#%d ", track->id); 368 snprintf(hdr, sizeof(hdr), "#%d ", track->id);
369 va_start(ap, fmt); 369 va_start(ap, fmt);
370 audio_vtrace(track->mixer->sc, funcname, hdr, fmt, ap); 370 audio_vtrace(track->mixer->sc, funcname, hdr, fmt, ap);
371 va_end(ap); 371 va_end(ap);
372} 372}
373 373
374static void 374static void
375audio_tracef(const char *funcname, audio_file_t *file, const char *fmt, ...) 375audio_tracef(const char *funcname, audio_file_t *file, const char *fmt, ...)
376{ 376{
377 char hdr[32]; 377 char hdr[32];
378 char phdr[16], rhdr[16]; 378 char phdr[16], rhdr[16];
379 va_list ap; 379 va_list ap;
380 380
381 phdr[0] = '\0'; 381 phdr[0] = '\0';
382 rhdr[0] = '\0'; 382 rhdr[0] = '\0';
383 if (file->ptrack) 383 if (file->ptrack)
384 snprintf(phdr, sizeof(phdr), "#%d", file->ptrack->id); 384 snprintf(phdr, sizeof(phdr), "#%d", file->ptrack->id);
385 if (file->rtrack) 385 if (file->rtrack)
386 snprintf(rhdr, sizeof(rhdr), "#%d", file->rtrack->id); 386 snprintf(rhdr, sizeof(rhdr), "#%d", file->rtrack->id);
387 snprintf(hdr, sizeof(hdr), "{%s,%s} ", phdr, rhdr); 387 snprintf(hdr, sizeof(hdr), "{%s,%s} ", phdr, rhdr);
388 388
389 va_start(ap, fmt); 389 va_start(ap, fmt);
390 audio_vtrace(file->sc, funcname, hdr, fmt, ap); 390 audio_vtrace(file->sc, funcname, hdr, fmt, ap);
391 va_end(ap); 391 va_end(ap);
392} 392}
393 393
394#define DPRINTF(n, fmt...) do { \ 394#define DPRINTF(n, fmt...) do { \
395 if (audiodebug >= (n)) { \ 395 if (audiodebug >= (n)) { \
396 audio_mlog_flush(); \ 396 audio_mlog_flush(); \
397 printf(fmt); \ 397 printf(fmt); \
398 } \ 398 } \
399} while (0) 399} while (0)
400#define TRACE(n, fmt...) do { \ 400#define TRACE(n, fmt...) do { \
401 if (audiodebug >= (n)) audio_trace(sc, __func__, fmt); \ 401 if (audiodebug >= (n)) audio_trace(sc, __func__, fmt); \
402} while (0) 402} while (0)
403#define TRACET(n, t, fmt...) do { \ 403#define TRACET(n, t, fmt...) do { \
404 if (audiodebug >= (n)) audio_tracet(__func__, t, fmt); \ 404 if (audiodebug >= (n)) audio_tracet(__func__, t, fmt); \
405} while (0) 405} while (0)
406#define TRACEF(n, f, fmt...) do { \ 406#define TRACEF(n, f, fmt...) do { \
407 if (audiodebug >= (n)) audio_tracef(__func__, f, fmt); \ 407 if (audiodebug >= (n)) audio_tracef(__func__, f, fmt); \
408} while (0) 408} while (0)
409 409
410struct audio_track_debugbuf { 410struct audio_track_debugbuf {
411 char usrbuf[32]; 411 char usrbuf[32];
412 char codec[32]; 412 char codec[32];
413 char chvol[32]; 413 char chvol[32];
414 char chmix[32]; 414 char chmix[32];
415 char freq[32]; 415 char freq[32];
416 char outbuf[32]; 416 char outbuf[32];
417}; 417};
418 418
419static void 419static void
420audio_track_bufstat(audio_track_t *track, struct audio_track_debugbuf *buf) 420audio_track_bufstat(audio_track_t *track, struct audio_track_debugbuf *buf)
421{ 421{
422 422
423 memset(buf, 0, sizeof(*buf)); 423 memset(buf, 0, sizeof(*buf));
424 424
425 snprintf(buf->outbuf, sizeof(buf->outbuf), " out=%d/%d/%d", 425 snprintf(buf->outbuf, sizeof(buf->outbuf), " out=%d/%d/%d",
426 track->outbuf.head, track->outbuf.used, track->outbuf.capacity); 426 track->outbuf.head, track->outbuf.used, track->outbuf.capacity);
427 if (track->freq.filter) 427 if (track->freq.filter)
428 snprintf(buf->freq, sizeof(buf->freq), " f=%d/%d/%d", 428 snprintf(buf->freq, sizeof(buf->freq), " f=%d/%d/%d",
429 track->freq.srcbuf.head, 429 track->freq.srcbuf.head,
430 track->freq.srcbuf.used, 430 track->freq.srcbuf.used,
431 track->freq.srcbuf.capacity); 431 track->freq.srcbuf.capacity);
432 if (track->chmix.filter) 432 if (track->chmix.filter)
433 snprintf(buf->chmix, sizeof(buf->chmix), " m=%d", 433 snprintf(buf->chmix, sizeof(buf->chmix), " m=%d",
434 track->chmix.srcbuf.used); 434 track->chmix.srcbuf.used);
435 if (track->chvol.filter) 435 if (track->chvol.filter)
436 snprintf(buf->chvol, sizeof(buf->chvol), " v=%d", 436 snprintf(buf->chvol, sizeof(buf->chvol), " v=%d",
437 track->chvol.srcbuf.used); 437 track->chvol.srcbuf.used);
438 if (track->codec.filter) 438 if (track->codec.filter)
439 snprintf(buf->codec, sizeof(buf->codec), " e=%d", 439 snprintf(buf->codec, sizeof(buf->codec), " e=%d",
440 track->codec.srcbuf.used); 440 track->codec.srcbuf.used);
441 snprintf(buf->usrbuf, sizeof(buf->usrbuf), " usr=%d/%d/H%d", 441 snprintf(buf->usrbuf, sizeof(buf->usrbuf), " usr=%d/%d/H%d",
442 track->usrbuf.head, track->usrbuf.used, track->usrbuf_usedhigh); 442 track->usrbuf.head, track->usrbuf.used, track->usrbuf_usedhigh);
443} 443}
444#else 444#else
445#define DPRINTF(n, fmt...) do { } while (0) 445#define DPRINTF(n, fmt...) do { } while (0)
446#define TRACE(n, fmt, ...) do { } while (0) 446#define TRACE(n, fmt, ...) do { } while (0)
447#define TRACET(n, t, fmt, ...) do { } while (0) 447#define TRACET(n, t, fmt, ...) do { } while (0)
448#define TRACEF(n, f, fmt, ...) do { } while (0) 448#define TRACEF(n, f, fmt, ...) do { } while (0)
449#endif 449#endif
450 450
451#define SPECIFIED(x) ((x) != ~0) 451#define SPECIFIED(x) ((x) != ~0)
452#define SPECIFIED_CH(x) ((x) != (u_char)~0) 452#define SPECIFIED_CH(x) ((x) != (u_char)~0)
453 453
454/* 454/*
455 * Default hardware blocksize in msec. 455 * Default hardware blocksize in msec.
456 * 456 *
457 * We use 10 msec for most modern platforms. This period is good enough to 457 * We use 10 msec for most modern platforms. This period is good enough to
458 * play audio and video synchronizely. 458 * play audio and video synchronizely.
459 * In contrast, for very old platforms, this is usually too short and too 459 * In contrast, for very old platforms, this is usually too short and too
460 * severe. Also such platforms usually can not play video confortably, so 460 * severe. Also such platforms usually can not play video confortably, so
461 * it's not so important to make the blocksize shorter. If the platform 461 * it's not so important to make the blocksize shorter. If the platform
462 * defines its own value as __AUDIO_BLK_MS in its <machine/param.h>, it 462 * defines its own value as __AUDIO_BLK_MS in its <machine/param.h>, it
463 * uses this instead. 463 * uses this instead.
464 * 464 *
465 * In either case, you can overwrite AUDIO_BLK_MS by your kernel 465 * In either case, you can overwrite AUDIO_BLK_MS by your kernel
466 * configuration file if you wish. 466 * configuration file if you wish.
467 */ 467 */
468#if !defined(AUDIO_BLK_MS) 468#if !defined(AUDIO_BLK_MS)
469# if defined(__AUDIO_BLK_MS) 469# if defined(__AUDIO_BLK_MS)
470# define AUDIO_BLK_MS __AUDIO_BLK_MS 470# define AUDIO_BLK_MS __AUDIO_BLK_MS
471# else 471# else
472# define AUDIO_BLK_MS (10) 472# define AUDIO_BLK_MS (10)
473# endif 473# endif
474#endif 474#endif
475 475
476/* Device timeout in msec */ 476/* Device timeout in msec */
477#define AUDIO_TIMEOUT (3000) 477#define AUDIO_TIMEOUT (3000)
478 478
479/* #define AUDIO_PM_IDLE */ 479/* #define AUDIO_PM_IDLE */
480#ifdef AUDIO_PM_IDLE 480#ifdef AUDIO_PM_IDLE
481int audio_idle_timeout = 30; 481int audio_idle_timeout = 30;
482#endif 482#endif
483 483
484/* Number of elements of async mixer's pid */ 484/* Number of elements of async mixer's pid */
485#define AM_CAPACITY (4) 485#define AM_CAPACITY (4)
486 486
487struct portname { 487struct portname {
488 const char *name; 488 const char *name;
489 int mask; 489 int mask;
490}; 490};
491 491
492static int audiomatch(device_t, cfdata_t, void *); 492static int audiomatch(device_t, cfdata_t, void *);
493static void audioattach(device_t, device_t, void *); 493static void audioattach(device_t, device_t, void *);
494static int audiodetach(device_t, int); 494static int audiodetach(device_t, int);
495static int audioactivate(device_t, enum devact); 495static int audioactivate(device_t, enum devact);
496static void audiochilddet(device_t, device_t); 496static void audiochilddet(device_t, device_t);
497static int audiorescan(device_t, const char *, const int *); 497static int audiorescan(device_t, const char *, const int *);
498 498
499static int audio_modcmd(modcmd_t, void *); 499static int audio_modcmd(modcmd_t, void *);
500 500
501#ifdef AUDIO_PM_IDLE 501#ifdef AUDIO_PM_IDLE
502static void audio_idle(void *); 502static void audio_idle(void *);
503static void audio_activity(device_t, devactive_t); 503static void audio_activity(device_t, devactive_t);
504#endif 504#endif
505 505
506static bool audio_suspend(device_t dv, const pmf_qual_t *); 506static bool audio_suspend(device_t dv, const pmf_qual_t *);
507static bool audio_resume(device_t dv, const pmf_qual_t *); 507static bool audio_resume(device_t dv, const pmf_qual_t *);
508static void audio_volume_down(device_t); 508static void audio_volume_down(device_t);
509static void audio_volume_up(device_t); 509static void audio_volume_up(device_t);
510static void audio_volume_toggle(device_t); 510static void audio_volume_toggle(device_t);
511 511
512static void audio_mixer_capture(struct audio_softc *); 512static void audio_mixer_capture(struct audio_softc *);
513static void audio_mixer_restore(struct audio_softc *); 513static void audio_mixer_restore(struct audio_softc *);
514 514
515static void audio_softintr_rd(void *); 515static void audio_softintr_rd(void *);
516static void audio_softintr_wr(void *); 516static void audio_softintr_wr(void *);
517 517
518static void audio_printf(struct audio_softc *, const char *, ...) 518static void audio_printf(struct audio_softc *, const char *, ...)
519 __printflike(2, 3); 519 __printflike(2, 3);
520static int audio_exlock_mutex_enter(struct audio_softc *); 520static int audio_exlock_mutex_enter(struct audio_softc *);
521static void audio_exlock_mutex_exit(struct audio_softc *); 521static void audio_exlock_mutex_exit(struct audio_softc *);
522static int audio_exlock_enter(struct audio_softc *); 522static int audio_exlock_enter(struct audio_softc *);
523static void audio_exlock_exit(struct audio_softc *); 523static void audio_exlock_exit(struct audio_softc *);
524static void audio_sc_acquire_foropen(struct audio_softc *, struct psref *); 524static void audio_sc_acquire_foropen(struct audio_softc *, struct psref *);
525static struct audio_softc *audio_sc_acquire_fromfile(audio_file_t *, 525static struct audio_softc *audio_sc_acquire_fromfile(audio_file_t *,
526 struct psref *); 526 struct psref *);
527static void audio_sc_release(struct audio_softc *, struct psref *); 527static void audio_sc_release(struct audio_softc *, struct psref *);
528static int audio_track_waitio(struct audio_softc *, audio_track_t *); 528static int audio_track_waitio(struct audio_softc *, audio_track_t *);
529 529
530static int audioclose(struct file *); 530static int audioclose(struct file *);
531static int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int); 531static int audioread(struct file *, off_t *, struct uio *, kauth_cred_t, int);
532static int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int); 532static int audiowrite(struct file *, off_t *, struct uio *, kauth_cred_t, int);
533static int audioioctl(struct file *, u_long, void *); 533static int audioioctl(struct file *, u_long, void *);
534static int audiopoll(struct file *, int); 534static int audiopoll(struct file *, int);
535static int audiokqfilter(struct file *, struct knote *); 535static int audiokqfilter(struct file *, struct knote *);
536static int audiommap(struct file *, off_t *, size_t, int, int *, int *, 536static int audiommap(struct file *, off_t *, size_t, int, int *, int *,
537 struct uvm_object **, int *); 537 struct uvm_object **, int *);
538static int audiostat(struct file *, struct stat *); 538static int audiostat(struct file *, struct stat *);
539 539
540static void filt_audiowrite_detach(struct knote *); 540static void filt_audiowrite_detach(struct knote *);
541static int filt_audiowrite_event(struct knote *, long); 541static int filt_audiowrite_event(struct knote *, long);
542static void filt_audioread_detach(struct knote *); 542static void filt_audioread_detach(struct knote *);
543static int filt_audioread_event(struct knote *, long); 543static int filt_audioread_event(struct knote *, long);
544 544
545static int audio_open(dev_t, struct audio_softc *, int, int, struct lwp *, 545static int audio_open(dev_t, struct audio_softc *, int, int, struct lwp *,
546 audio_file_t **); 546 audio_file_t **);
547static int audio_close(struct audio_softc *, audio_file_t *); 547static int audio_close(struct audio_softc *, audio_file_t *);
548static int audio_unlink(struct audio_softc *, audio_file_t *); 548static int audio_unlink(struct audio_softc *, audio_file_t *);
549static int audio_read(struct audio_softc *, struct uio *, int, audio_file_t *); 549static int audio_read(struct audio_softc *, struct uio *, int, audio_file_t *);
550static int audio_write(struct audio_softc *, struct uio *, int, audio_file_t *); 550static int audio_write(struct audio_softc *, struct uio *, int, audio_file_t *);
551static void audio_file_clear(struct audio_softc *, audio_file_t *); 551static void audio_file_clear(struct audio_softc *, audio_file_t *);
552static int audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int, 552static int audio_ioctl(dev_t, struct audio_softc *, u_long, void *, int,
553 struct lwp *, audio_file_t *); 553 struct lwp *, audio_file_t *);
554static int audio_poll(struct audio_softc *, int, struct lwp *, audio_file_t *); 554static int audio_poll(struct audio_softc *, int, struct lwp *, audio_file_t *);
555static int audio_kqfilter(struct audio_softc *, audio_file_t *, struct knote *); 555static int audio_kqfilter(struct audio_softc *, audio_file_t *, struct knote *);
556static int audio_mmap(struct audio_softc *, off_t *, size_t, int, int *, int *, 556static int audio_mmap(struct audio_softc *, off_t *, size_t, int, int *, int *,
557 struct uvm_object **, int *, audio_file_t *); 557 struct uvm_object **, int *, audio_file_t *);
558 558
559static int audioctl_open(dev_t, struct audio_softc *, int, int, struct lwp *); 559static int audioctl_open(dev_t, struct audio_softc *, int, int, struct lwp *);
560 560
561static void audio_pintr(void *); 561static void audio_pintr(void *);
562static void audio_rintr(void *); 562static void audio_rintr(void *);
563 563
564static int audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *); 564static int audio_query_devinfo(struct audio_softc *, mixer_devinfo_t *);
565 565
566static __inline int audio_track_readablebytes(const audio_track_t *); 566static __inline int audio_track_readablebytes(const audio_track_t *);
567static int audio_file_setinfo(struct audio_softc *, audio_file_t *, 567static int audio_file_setinfo(struct audio_softc *, audio_file_t *,
568 const struct audio_info *); 568 const struct audio_info *);
569static int audio_track_setinfo_check(audio_track_t *, 569static int audio_track_setinfo_check(audio_track_t *,
570 audio_format2_t *, const struct audio_prinfo *); 570 audio_format2_t *, const struct audio_prinfo *);
571static void audio_track_setinfo_water(audio_track_t *, 571static void audio_track_setinfo_water(audio_track_t *,
572 const struct audio_info *); 572 const struct audio_info *);
573static int audio_hw_setinfo(struct audio_softc *, const struct audio_info *, 573static int audio_hw_setinfo(struct audio_softc *, const struct audio_info *,
574 struct audio_info *); 574 struct audio_info *);
575static int audio_hw_set_format(struct audio_softc *, int, 575static int audio_hw_set_format(struct audio_softc *, int,
576 const audio_format2_t *, const audio_format2_t *, 576 const audio_format2_t *, const audio_format2_t *,
577 audio_filter_reg_t *, audio_filter_reg_t *); 577 audio_filter_reg_t *, audio_filter_reg_t *);
578static int audiogetinfo(struct audio_softc *, struct audio_info *, int, 578static int audiogetinfo(struct audio_softc *, struct audio_info *, int,
579 audio_file_t *); 579 audio_file_t *);
580static bool audio_can_playback(struct audio_softc *); 580static bool audio_can_playback(struct audio_softc *);
581static bool audio_can_capture(struct audio_softc *); 581static bool audio_can_capture(struct audio_softc *);
582static int audio_check_params(audio_format2_t *); 582static int audio_check_params(audio_format2_t *);
583static int audio_mixers_init(struct audio_softc *sc, int, 583static int audio_mixers_init(struct audio_softc *sc, int,
584 const audio_format2_t *, const audio_format2_t *, 584 const audio_format2_t *, const audio_format2_t *,
585 const audio_filter_reg_t *, const audio_filter_reg_t *); 585 const audio_filter_reg_t *, const audio_filter_reg_t *);
586static int audio_select_freq(const struct audio_format *); 586static int audio_select_freq(const struct audio_format *);
587static int audio_hw_probe(struct audio_softc *, audio_format2_t *, int); 587static int audio_hw_probe(struct audio_softc *, audio_format2_t *, int);
588static int audio_hw_validate_format(struct audio_softc *, int, 588static int audio_hw_validate_format(struct audio_softc *, int,
589 const audio_format2_t *); 589 const audio_format2_t *);
590static int audio_mixers_set_format(struct audio_softc *, 590static int audio_mixers_set_format(struct audio_softc *,
591 const struct audio_info *); 591 const struct audio_info *);
592static void audio_mixers_get_format(struct audio_softc *, struct audio_info *); 592static void audio_mixers_get_format(struct audio_softc *, struct audio_info *);
593static int audio_sysctl_blk_ms(SYSCTLFN_PROTO); 593static int audio_sysctl_blk_ms(SYSCTLFN_PROTO);
594static int audio_sysctl_multiuser(SYSCTLFN_PROTO); 594static int audio_sysctl_multiuser(SYSCTLFN_PROTO);
595#if defined(AUDIO_DEBUG) 595#if defined(AUDIO_DEBUG)
596static int audio_sysctl_debug(SYSCTLFN_PROTO); 596static int audio_sysctl_debug(SYSCTLFN_PROTO);
597static void audio_format2_tostr(char *, size_t, const audio_format2_t *); 597static void audio_format2_tostr(char *, size_t, const audio_format2_t *);
598static void audio_print_format2(const char *, const audio_format2_t *) __unused; 598static void audio_print_format2(const char *, const audio_format2_t *) __unused;
599#endif 599#endif
600 600
601static void *audio_realloc(void *, size_t); 601static void *audio_realloc(void *, size_t);
602static int audio_realloc_usrbuf(audio_track_t *, int); 602static int audio_realloc_usrbuf(audio_track_t *, int);
603static void audio_free_usrbuf(audio_track_t *); 603static void audio_free_usrbuf(audio_track_t *);
604 604
605static audio_track_t *audio_track_create(struct audio_softc *, 605static audio_track_t *audio_track_create(struct audio_softc *,
606 audio_trackmixer_t *); 606 audio_trackmixer_t *);
607static void audio_track_destroy(audio_track_t *); 607static void audio_track_destroy(audio_track_t *);
608static audio_filter_t audio_track_get_codec(audio_track_t *, 608static audio_filter_t audio_track_get_codec(audio_track_t *,
609 const audio_format2_t *, const audio_format2_t *); 609 const audio_format2_t *, const audio_format2_t *);
610static int audio_track_set_format(audio_track_t *, audio_format2_t *); 610static int audio_track_set_format(audio_track_t *, audio_format2_t *);
611static void audio_track_play(audio_track_t *); 611static void audio_track_play(audio_track_t *);
612static int audio_track_drain(struct audio_softc *, audio_track_t *); 612static int audio_track_drain(struct audio_softc *, audio_track_t *);
613static void audio_track_record(audio_track_t *); 613static void audio_track_record(audio_track_t *);
614static void audio_track_clear(struct audio_softc *, audio_track_t *); 614static void audio_track_clear(struct audio_softc *, audio_track_t *);
615 615
616static int audio_mixer_init(struct audio_softc *, int, 616static int audio_mixer_init(struct audio_softc *, int,
617 const audio_format2_t *, const audio_filter_reg_t *); 617 const audio_format2_t *, const audio_filter_reg_t *);
618static void audio_mixer_destroy(struct audio_softc *, audio_trackmixer_t *); 618static void audio_mixer_destroy(struct audio_softc *, audio_trackmixer_t *);
619static void audio_pmixer_start(struct audio_softc *, bool); 619static void audio_pmixer_start(struct audio_softc *, bool);
620static void audio_pmixer_process(struct audio_softc *); 620static void audio_pmixer_process(struct audio_softc *);
621static void audio_pmixer_agc(audio_trackmixer_t *, int); 621static void audio_pmixer_agc(audio_trackmixer_t *, int);
622static int audio_pmixer_mix_track(audio_trackmixer_t *, audio_track_t *, int); 622static int audio_pmixer_mix_track(audio_trackmixer_t *, audio_track_t *, int);
623static void audio_pmixer_output(struct audio_softc *); 623static void audio_pmixer_output(struct audio_softc *);
624static int audio_pmixer_halt(struct audio_softc *); 624static int audio_pmixer_halt(struct audio_softc *);
625static void audio_rmixer_start(struct audio_softc *); 625static void audio_rmixer_start(struct audio_softc *);
626static void audio_rmixer_process(struct audio_softc *); 626static void audio_rmixer_process(struct audio_softc *);
627static void audio_rmixer_input(struct audio_softc *); 627static void audio_rmixer_input(struct audio_softc *);
628static int audio_rmixer_halt(struct audio_softc *); 628static int audio_rmixer_halt(struct audio_softc *);
629 629
630static void mixer_init(struct audio_softc *); 630static void mixer_init(struct audio_softc *);
631static int mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *); 631static int mixer_open(dev_t, struct audio_softc *, int, int, struct lwp *);
632static int mixer_close(struct audio_softc *, audio_file_t *); 632static int mixer_close(struct audio_softc *, audio_file_t *);
633static int mixer_ioctl(struct audio_softc *, u_long, void *, int, struct lwp *); 633static int mixer_ioctl(struct audio_softc *, u_long, void *, int, struct lwp *);
634static void mixer_async_add(struct audio_softc *, pid_t); 634static void mixer_async_add(struct audio_softc *, pid_t);
635static void mixer_async_remove(struct audio_softc *, pid_t); 635static void mixer_async_remove(struct audio_softc *, pid_t);
636static void mixer_signal(struct audio_softc *); 636static void mixer_signal(struct audio_softc *);
637 637
638static int au_portof(struct audio_softc *, char *, int); 638static int au_portof(struct audio_softc *, char *, int);
639 639
640static void au_setup_ports(struct audio_softc *, struct au_mixer_ports *, 640static void au_setup_ports(struct audio_softc *, struct au_mixer_ports *,
641 mixer_devinfo_t *, const struct portname *); 641 mixer_devinfo_t *, const struct portname *);
642static int au_set_lr_value(struct audio_softc *, mixer_ctrl_t *, int, int); 642static int au_set_lr_value(struct audio_softc *, mixer_ctrl_t *, int, int);
643static int au_get_lr_value(struct audio_softc *, mixer_ctrl_t *, int *, int *); 643static int au_get_lr_value(struct audio_softc *, mixer_ctrl_t *, int *, int *);
644static int au_set_gain(struct audio_softc *, struct au_mixer_ports *, int, int); 644static int au_set_gain(struct audio_softc *, struct au_mixer_ports *, int, int);
645static void au_get_gain(struct audio_softc *, struct au_mixer_ports *, 645static void au_get_gain(struct audio_softc *, struct au_mixer_ports *,
646 u_int *, u_char *); 646 u_int *, u_char *);
647static int au_set_port(struct audio_softc *, struct au_mixer_ports *, u_int); 647static int au_set_port(struct audio_softc *, struct au_mixer_ports *, u_int);
648static int au_get_port(struct audio_softc *, struct au_mixer_ports *); 648static int au_get_port(struct audio_softc *, struct au_mixer_ports *);
649static int au_set_monitor_gain(struct audio_softc *, int); 649static int au_set_monitor_gain(struct audio_softc *, int);
650static int au_get_monitor_gain(struct audio_softc *); 650static int au_get_monitor_gain(struct audio_softc *);
651static int audio_get_port(struct audio_softc *, mixer_ctrl_t *); 651static int audio_get_port(struct audio_softc *, mixer_ctrl_t *);
652static int audio_set_port(struct audio_softc *, mixer_ctrl_t *); 652static int audio_set_port(struct audio_softc *, mixer_ctrl_t *);
653 653
654static __inline struct audio_params 654static __inline struct audio_params
655format2_to_params(const audio_format2_t *f2) 655format2_to_params(const audio_format2_t *f2)
656{ 656{
657 audio_params_t p; 657 audio_params_t p;
658 658
659 /* validbits/precision <-> precision/stride */ 659 /* validbits/precision <-> precision/stride */
660 p.sample_rate = f2->sample_rate; 660 p.sample_rate = f2->sample_rate;
661 p.channels = f2->channels; 661 p.channels = f2->channels;
662 p.encoding = f2->encoding; 662 p.encoding = f2->encoding;
663 p.validbits = f2->precision; 663 p.validbits = f2->precision;
664 p.precision = f2->stride; 664 p.precision = f2->stride;
665 return p; 665 return p;
666} 666}
667 667
668static __inline audio_format2_t 668static __inline audio_format2_t
669params_to_format2(const struct audio_params *p) 669params_to_format2(const struct audio_params *p)
670{ 670{
671 audio_format2_t f2; 671 audio_format2_t f2;
672 672
673 /* precision/stride <-> validbits/precision */ 673 /* precision/stride <-> validbits/precision */
674 f2.sample_rate = p->sample_rate; 674 f2.sample_rate = p->sample_rate;
675 f2.channels = p->channels; 675 f2.channels = p->channels;
676 f2.encoding = p->encoding; 676 f2.encoding = p->encoding;
677 f2.precision = p->validbits; 677 f2.precision = p->validbits;
678 f2.stride = p->precision; 678 f2.stride = p->precision;
679 return f2; 679 return f2;
680} 680}
681 681
682/* Return true if this track is a playback track. */ 682/* Return true if this track is a playback track. */
683static __inline bool 683static __inline bool
684audio_track_is_playback(const audio_track_t *track) 684audio_track_is_playback(const audio_track_t *track)
685{ 685{
686 686
687 return ((track->mode & AUMODE_PLAY) != 0); 687 return ((track->mode & AUMODE_PLAY) != 0);
688} 688}
689 689
690/* Return true if this track is a recording track. */ 690/* Return true if this track is a recording track. */
691static __inline bool 691static __inline bool
692audio_track_is_record(const audio_track_t *track) 692audio_track_is_record(const audio_track_t *track)
693{ 693{
694 694
695 return ((track->mode & AUMODE_RECORD) != 0); 695 return ((track->mode & AUMODE_RECORD) != 0);
696} 696}
697 697
698#if 0 /* XXX Not used yet */ 698#if 0 /* XXX Not used yet */
699/* 699/*
700 * Convert 0..255 volume used in userland to internal presentation 0..256. 700 * Convert 0..255 volume used in userland to internal presentation 0..256.
701 */ 701 */
702static __inline u_int 702static __inline u_int
703audio_volume_to_inner(u_int v) 703audio_volume_to_inner(u_int v)
704{ 704{
705 705
706 return v < 127 ? v : v + 1; 706 return v < 127 ? v : v + 1;
707} 707}
708 708
709/* 709/*
710 * Convert 0..256 internal presentation to 0..255 volume used in userland. 710 * Convert 0..256 internal presentation to 0..255 volume used in userland.
711 */ 711 */
712static __inline u_int 712static __inline u_int
713audio_volume_to_outer(u_int v) 713audio_volume_to_outer(u_int v)
714{ 714{
715 715
716 return v < 127 ? v : v - 1; 716 return v < 127 ? v : v - 1;
717} 717}
718#endif /* 0 */ 718#endif /* 0 */
719 719
720static dev_type_open(audioopen); 720static dev_type_open(audioopen);
721/* XXXMRG use more dev_type_xxx */ 721/* XXXMRG use more dev_type_xxx */
722 722
723const struct cdevsw audio_cdevsw = { 723const struct cdevsw audio_cdevsw = {
724 .d_open = audioopen, 724 .d_open = audioopen,
725 .d_close = noclose, 725 .d_close = noclose,
726 .d_read = noread, 726 .d_read = noread,
727 .d_write = nowrite, 727 .d_write = nowrite,
728 .d_ioctl = noioctl, 728 .d_ioctl = noioctl,
729 .d_stop = nostop, 729 .d_stop = nostop,
730 .d_tty = notty, 730 .d_tty = notty,
731 .d_poll = nopoll, 731 .d_poll = nopoll,
732 .d_mmap = nommap, 732 .d_mmap = nommap,
733 .d_kqfilter = nokqfilter, 733 .d_kqfilter = nokqfilter,
734 .d_discard = nodiscard, 734 .d_discard = nodiscard,
735 .d_flag = D_OTHER | D_MPSAFE 735 .d_flag = D_OTHER | D_MPSAFE
736}; 736};
737 737
738const struct fileops audio_fileops = { 738const struct fileops audio_fileops = {
739 .fo_name = "audio", 739 .fo_name = "audio",
740 .fo_read = audioread, 740 .fo_read = audioread,
741 .fo_write = audiowrite, 741 .fo_write = audiowrite,
742 .fo_ioctl = audioioctl, 742 .fo_ioctl = audioioctl,
743 .fo_fcntl = fnullop_fcntl, 743 .fo_fcntl = fnullop_fcntl,
744 .fo_stat = audiostat, 744 .fo_stat = audiostat,
745 .fo_poll = audiopoll, 745 .fo_poll = audiopoll,
746 .fo_close = audioclose, 746 .fo_close = audioclose,
747 .fo_mmap = audiommap, 747 .fo_mmap = audiommap,
748 .fo_kqfilter = audiokqfilter, 748 .fo_kqfilter = audiokqfilter,
749 .fo_restart = fnullop_restart 749 .fo_restart = fnullop_restart
750}; 750};
751 751
752/* The default audio mode: 8 kHz mono mu-law */ 752/* The default audio mode: 8 kHz mono mu-law */
753static const struct audio_params audio_default = { 753static const struct audio_params audio_default = {
754 .sample_rate = 8000, 754 .sample_rate = 8000,
755 .encoding = AUDIO_ENCODING_ULAW, 755 .encoding = AUDIO_ENCODING_ULAW,
756 .precision = 8, 756 .precision = 8,
757 .validbits = 8, 757 .validbits = 8,
758 .channels = 1, 758 .channels = 1,
759}; 759};
760 760
761static const char *encoding_names[] = { 761static const char *encoding_names[] = {
762 "none", 762 "none",
763 AudioEmulaw, 763 AudioEmulaw,
764 AudioEalaw, 764 AudioEalaw,
765 "pcm16", 765 "pcm16",
766 "pcm8", 766 "pcm8",
767 AudioEadpcm, 767 AudioEadpcm,
768 AudioEslinear_le, 768 AudioEslinear_le,
769 AudioEslinear_be, 769 AudioEslinear_be,
770 AudioEulinear_le, 770 AudioEulinear_le,
771 AudioEulinear_be, 771 AudioEulinear_be,
772 AudioEslinear, 772 AudioEslinear,
773 AudioEulinear, 773 AudioEulinear,
774 AudioEmpeg_l1_stream, 774 AudioEmpeg_l1_stream,
775 AudioEmpeg_l1_packets, 775 AudioEmpeg_l1_packets,
776 AudioEmpeg_l1_system, 776 AudioEmpeg_l1_system,
777 AudioEmpeg_l2_stream, 777 AudioEmpeg_l2_stream,
778 AudioEmpeg_l2_packets, 778 AudioEmpeg_l2_packets,
779 AudioEmpeg_l2_system, 779 AudioEmpeg_l2_system,
780 AudioEac3, 780 AudioEac3,
781}; 781};
782 782
783/* 783/*
784 * Returns encoding name corresponding to AUDIO_ENCODING_*. 784 * Returns encoding name corresponding to AUDIO_ENCODING_*.
785 * Note that it may return a local buffer because it is mainly for debugging. 785 * Note that it may return a local buffer because it is mainly for debugging.
786 */ 786 */
787const char * 787const char *
788audio_encoding_name(int encoding) 788audio_encoding_name(int encoding)
789{ 789{
790 static char buf[16]; 790 static char buf[16];
791 791
792 if (0 <= encoding && encoding < __arraycount(encoding_names)) { 792 if (0 <= encoding && encoding < __arraycount(encoding_names)) {
793 return encoding_names[encoding]; 793 return encoding_names[encoding];
794 } else { 794 } else {
795 snprintf(buf, sizeof(buf), "enc=%d", encoding); 795 snprintf(buf, sizeof(buf), "enc=%d", encoding);
796 return buf; 796 return buf;
797 } 797 }
798} 798}
799 799
800/* 800/*
801 * Supported encodings used by AUDIO_GETENC. 801 * Supported encodings used by AUDIO_GETENC.
802 * index and flags are set by code. 802 * index and flags are set by code.
803 * XXX is there any needs for SLINEAR_OE:>=16/ULINEAR_OE:>=16 ? 803 * XXX is there any needs for SLINEAR_OE:>=16/ULINEAR_OE:>=16 ?
804 */ 804 */
805static const audio_encoding_t audio_encodings[] = { 805static const audio_encoding_t audio_encodings[] = {
806 { 0, AudioEmulaw, AUDIO_ENCODING_ULAW, 8, 0 }, 806 { 0, AudioEmulaw, AUDIO_ENCODING_ULAW, 8, 0 },
807 { 0, AudioEalaw, AUDIO_ENCODING_ALAW, 8, 0 }, 807 { 0, AudioEalaw, AUDIO_ENCODING_ALAW, 8, 0 },
808 { 0, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 0 }, 808 { 0, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 0 },
809 { 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0 }, 809 { 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0 },
810 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0 }, 810 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0 },
811 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16, 0 }, 811 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16, 0 },
812 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16, 0 }, 812 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16, 0 },
813 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16, 0 }, 813 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16, 0 },
814#if defined(AUDIO_SUPPORT_LINEAR24) 814#if defined(AUDIO_SUPPORT_LINEAR24)
815 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 24, 0 }, 815 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 24, 0 },
816 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 24, 0 }, 816 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 24, 0 },
817 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 24, 0 }, 817 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 24, 0 },
818 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 24, 0 }, 818 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 24, 0 },
819#endif 819#endif
820 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 32, 0 }, 820 { 0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 32, 0 },
821 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 32, 0 }, 821 { 0, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 32, 0 },
822 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 32, 0 }, 822 { 0, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 32, 0 },
823 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 32, 0 }, 823 { 0, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 32, 0 },
824}; 824};
825 825
826static const struct portname itable[] = { 826static const struct portname itable[] = {
827 { AudioNmicrophone, AUDIO_MICROPHONE }, 827 { AudioNmicrophone, AUDIO_MICROPHONE },
828 { AudioNline, AUDIO_LINE_IN }, 828 { AudioNline, AUDIO_LINE_IN },
829 { AudioNcd, AUDIO_CD }, 829 { AudioNcd, AUDIO_CD },
830 { 0, 0 } 830 { 0, 0 }
831}; 831};
832static const struct portname otable[] = { 832static const struct portname otable[] = {
833 { AudioNspeaker, AUDIO_SPEAKER }, 833 { AudioNspeaker, AUDIO_SPEAKER },
834 { AudioNheadphone, AUDIO_HEADPHONE }, 834 { AudioNheadphone, AUDIO_HEADPHONE },
835 { AudioNline, AUDIO_LINE_OUT }, 835 { AudioNline, AUDIO_LINE_OUT },
836 { 0, 0 } 836 { 0, 0 }
837}; 837};
838 838
839static struct psref_class *audio_psref_class __read_mostly; 839static struct psref_class *audio_psref_class __read_mostly;
840 840
841CFATTACH_DECL3_NEW(audio, sizeof(struct audio_softc), 841CFATTACH_DECL3_NEW(audio, sizeof(struct audio_softc),
842 audiomatch, audioattach, audiodetach, audioactivate, audiorescan, 842 audiomatch, audioattach, audiodetach, audioactivate, audiorescan,
843 audiochilddet, DVF_DETACH_SHUTDOWN); 843 audiochilddet, DVF_DETACH_SHUTDOWN);
844 844
845static int 845static int
846audiomatch(device_t parent, cfdata_t match, void *aux) 846audiomatch(device_t parent, cfdata_t match, void *aux)
847{ 847{
848 struct audio_attach_args *sa; 848 struct audio_attach_args *sa;
849 849
850 sa = aux; 850 sa = aux;
851 DPRINTF(1, "%s: type=%d sa=%p hw=%p\n", 851 DPRINTF(1, "%s: type=%d sa=%p hw=%p\n",
852 __func__, sa->type, sa, sa->hwif); 852 __func__, sa->type, sa, sa->hwif);
853 return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0; 853 return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0;
854} 854}
855 855
856static void 856static void
857audioattach(device_t parent, device_t self, void *aux) 857audioattach(device_t parent, device_t self, void *aux)
858{ 858{
859 struct audio_softc *sc; 859 struct audio_softc *sc;
860 struct audio_attach_args *sa; 860 struct audio_attach_args *sa;
861 const struct audio_hw_if *hw_if; 861 const struct audio_hw_if *hw_if;
862 audio_format2_t phwfmt; 862 audio_format2_t phwfmt;
863 audio_format2_t rhwfmt; 863 audio_format2_t rhwfmt;
864 audio_filter_reg_t pfil; 864 audio_filter_reg_t pfil;
865 audio_filter_reg_t rfil; 865 audio_filter_reg_t rfil;
866 const struct sysctlnode *node; 866 const struct sysctlnode *node;
867 void *hdlp; 867 void *hdlp;
868 bool has_playback; 868 bool has_playback;
869 bool has_capture; 869 bool has_capture;
870 bool has_indep; 870 bool has_indep;
871 bool has_fulldup; 871 bool has_fulldup;
872 int mode; 872 int mode;
873 int error; 873 int error;
874 874
875 sc = device_private(self); 875 sc = device_private(self);
876 sc->sc_dev = self; 876 sc->sc_dev = self;
877 sa = (struct audio_attach_args *)aux; 877 sa = (struct audio_attach_args *)aux;
878 hw_if = sa->hwif; 878 hw_if = sa->hwif;
879 hdlp = sa->hdl; 879 hdlp = sa->hdl;
880 880
881 if (hw_if == NULL) { 881 if (hw_if == NULL) {
882 panic("audioattach: missing hw_if method"); 882 panic("audioattach: missing hw_if method");
883 } 883 }
884 if (hw_if->get_locks == NULL || hw_if->get_props == NULL) { 884 if (hw_if->get_locks == NULL || hw_if->get_props == NULL) {
885 aprint_error(": missing mandatory method\n"); 885 aprint_error(": missing mandatory method\n");
886 return; 886 return;
887 } 887 }
888 888
889 hw_if->get_locks(hdlp, &sc->sc_intr_lock, &sc->sc_lock); 889 hw_if->get_locks(hdlp, &sc->sc_intr_lock, &sc->sc_lock);
890 sc->sc_props = hw_if->get_props(hdlp); 890 sc->sc_props = hw_if->get_props(hdlp);
891 891
892 has_playback = (sc->sc_props & AUDIO_PROP_PLAYBACK); 892 has_playback = (sc->sc_props & AUDIO_PROP_PLAYBACK);
893 has_capture = (sc->sc_props & AUDIO_PROP_CAPTURE); 893 has_capture = (sc->sc_props & AUDIO_PROP_CAPTURE);
894 has_indep = (sc->sc_props & AUDIO_PROP_INDEPENDENT); 894 has_indep = (sc->sc_props & AUDIO_PROP_INDEPENDENT);
895 has_fulldup = (sc->sc_props & AUDIO_PROP_FULLDUPLEX); 895 has_fulldup = (sc->sc_props & AUDIO_PROP_FULLDUPLEX);
896 896
897#ifdef DIAGNOSTIC 897#ifdef DIAGNOSTIC
898 if (hw_if->query_format == NULL || 898 if (hw_if->query_format == NULL ||
899 hw_if->set_format == NULL || 899 hw_if->set_format == NULL ||
900 hw_if->getdev == NULL || 900 hw_if->getdev == NULL ||
901 hw_if->set_port == NULL || 901 hw_if->set_port == NULL ||
902 hw_if->get_port == NULL || 902 hw_if->get_port == NULL ||
903 hw_if->query_devinfo == NULL) { 903 hw_if->query_devinfo == NULL) {
904 aprint_error(": missing mandatory method\n"); 904 aprint_error(": missing mandatory method\n");
905 return; 905 return;
906 } 906 }
907 if (has_playback) { 907 if (has_playback) {
908 if ((hw_if->start_output == NULL && 908 if ((hw_if->start_output == NULL &&
909 hw_if->trigger_output == NULL) || 909 hw_if->trigger_output == NULL) ||
910 hw_if->halt_output == NULL) { 910 hw_if->halt_output == NULL) {
911 aprint_error(": missing playback method\n"); 911 aprint_error(": missing playback method\n");
912 } 912 }
913 } 913 }
914 if (has_capture) { 914 if (has_capture) {
915 if ((hw_if->start_input == NULL && 915 if ((hw_if->start_input == NULL &&
916 hw_if->trigger_input == NULL) || 916 hw_if->trigger_input == NULL) ||
917 hw_if->halt_input == NULL) { 917 hw_if->halt_input == NULL) {
918 aprint_error(": missing capture method\n"); 918 aprint_error(": missing capture method\n");
919 } 919 }
920 } 920 }
921#endif 921#endif
922 922
923 sc->hw_if = hw_if; 923 sc->hw_if = hw_if;
924 sc->hw_hdl = hdlp; 924 sc->hw_hdl = hdlp;
925 sc->hw_dev = parent; 925 sc->hw_dev = parent;
926 926
927 sc->sc_exlock = 1; 927 sc->sc_exlock = 1;
928 sc->sc_blk_ms = AUDIO_BLK_MS; 928 sc->sc_blk_ms = AUDIO_BLK_MS;
929 SLIST_INIT(&sc->sc_files); 929 SLIST_INIT(&sc->sc_files);
930 cv_init(&sc->sc_exlockcv, "audiolk"); 930 cv_init(&sc->sc_exlockcv, "audiolk");
931 sc->sc_am_capacity = 0; 931 sc->sc_am_capacity = 0;
932 sc->sc_am_used = 0; 932 sc->sc_am_used = 0;
933 sc->sc_am = NULL; 933 sc->sc_am = NULL;
934 934
935 /* MMAP is now supported by upper layer. */ 935 /* MMAP is now supported by upper layer. */
936 sc->sc_props |= AUDIO_PROP_MMAP; 936 sc->sc_props |= AUDIO_PROP_MMAP;
937 937
938 KASSERT(has_playback || has_capture); 938 KASSERT(has_playback || has_capture);
939 /* Unidirectional device must have neither FULLDUP nor INDEPENDENT. */ 939 /* Unidirectional device must have neither FULLDUP nor INDEPENDENT. */
940 if (!has_playback || !has_capture) { 940 if (!has_playback || !has_capture) {
941 KASSERT(!has_indep); 941 KASSERT(!has_indep);
942 KASSERT(!has_fulldup); 942 KASSERT(!has_fulldup);
943 } 943 }
944 944
945 mode = 0; 945 mode = 0;
946 if (has_playback) { 946 if (has_playback) {
947 aprint_normal(": playback"); 947 aprint_normal(": playback");
948 mode |= AUMODE_PLAY; 948 mode |= AUMODE_PLAY;
949 } 949 }
950 if (has_capture) { 950 if (has_capture) {
951 aprint_normal("%c capture", has_playback ? ',' : ':'); 951 aprint_normal("%c capture", has_playback ? ',' : ':');
952 mode |= AUMODE_RECORD; 952 mode |= AUMODE_RECORD;
953 } 953 }
954 if (has_playback && has_capture) { 954 if (has_playback && has_capture) {
955 if (has_fulldup) 955 if (has_fulldup)
956 aprint_normal(", full duplex"); 956 aprint_normal(", full duplex");
957 else 957 else
958 aprint_normal(", half duplex"); 958 aprint_normal(", half duplex");
959 959
960 if (has_indep) 960 if (has_indep)
961 aprint_normal(", independent"); 961 aprint_normal(", independent");
962 } 962 }
963 963
964 aprint_naive("\n"); 964 aprint_naive("\n");
965 aprint_normal("\n"); 965 aprint_normal("\n");
966 966
967 /* probe hw params */ 967 /* probe hw params */
968 memset(&phwfmt, 0, sizeof(phwfmt)); 968 memset(&phwfmt, 0, sizeof(phwfmt));
969 memset(&rhwfmt, 0, sizeof(rhwfmt)); 969 memset(&rhwfmt, 0, sizeof(rhwfmt));
970 memset(&pfil, 0, sizeof(pfil)); 970 memset(&pfil, 0, sizeof(pfil));
971 memset(&rfil, 0, sizeof(rfil)); 971 memset(&rfil, 0, sizeof(rfil));
972 if (has_indep) { 972 if (has_indep) {
973 int perror, rerror; 973 int perror, rerror;
974 974
975 /* On independent devices, probe separately. */ 975 /* On independent devices, probe separately. */
976 perror = audio_hw_probe(sc, &phwfmt, AUMODE_PLAY); 976 perror = audio_hw_probe(sc, &phwfmt, AUMODE_PLAY);
977 rerror = audio_hw_probe(sc, &rhwfmt, AUMODE_RECORD); 977 rerror = audio_hw_probe(sc, &rhwfmt, AUMODE_RECORD);
978 if (perror && rerror) { 978 if (perror && rerror) {
979 aprint_error_dev(self, 979 aprint_error_dev(self,
980 "audio_hw_probe failed: perror=%d, rerror=%d\n", 980 "audio_hw_probe failed: perror=%d, rerror=%d\n",
981 perror, rerror); 981 perror, rerror);
982 goto bad; 982 goto bad;
983 } 983 }
984 if (perror) { 984 if (perror) {
985 mode &= ~AUMODE_PLAY; 985 mode &= ~AUMODE_PLAY;
986 aprint_error_dev(self, "audio_hw_probe failed: " 986 aprint_error_dev(self, "audio_hw_probe failed: "
987 "errno=%d, playback disabled\n", perror); 987 "errno=%d, playback disabled\n", perror);
988 } 988 }
989 if (rerror) { 989 if (rerror) {
990 mode &= ~AUMODE_RECORD; 990 mode &= ~AUMODE_RECORD;
991 aprint_error_dev(self, "audio_hw_probe failed: " 991 aprint_error_dev(self, "audio_hw_probe failed: "
992 "errno=%d, capture disabled\n", rerror); 992 "errno=%d, capture disabled\n", rerror);
993 } 993 }
994 } else { 994 } else {
995 /* 995 /*
996 * On non independent devices or uni-directional devices, 996 * On non independent devices or uni-directional devices,
997 * probe once (simultaneously). 997 * probe once (simultaneously).
998 */ 998 */
999 audio_format2_t *fmt = has_playback ? &phwfmt : &rhwfmt; 999 audio_format2_t *fmt = has_playback ? &phwfmt : &rhwfmt;
1000 error = audio_hw_probe(sc, fmt, mode); 1000 error = audio_hw_probe(sc, fmt, mode);
1001 if (error) { 1001 if (error) {
1002 aprint_error_dev(self, 1002 aprint_error_dev(self,
1003 "audio_hw_probe failed: errno=%d\n", error); 1003 "audio_hw_probe failed: errno=%d\n", error);
1004 goto bad; 1004 goto bad;
1005 } 1005 }
1006 if (has_playback && has_capture) 1006 if (has_playback && has_capture)
1007 rhwfmt = phwfmt; 1007 rhwfmt = phwfmt;
1008 } 1008 }
1009 1009
1010 /* Init hardware. */ 1010 /* Init hardware. */
1011 /* hw_probe() also validates [pr]hwfmt. */ 1011 /* hw_probe() also validates [pr]hwfmt. */
1012 error = audio_hw_set_format(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil); 1012 error = audio_hw_set_format(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
1013 if (error) { 1013 if (error) {
1014 aprint_error_dev(self, 1014 aprint_error_dev(self,
1015 "audio_hw_set_format failed: errno=%d\n", error); 1015 "audio_hw_set_format failed: errno=%d\n", error);
1016 goto bad; 1016 goto bad;
1017 } 1017 }
1018 1018
1019 /* 1019 /*
1020 * Init track mixers. If at least one direction is available on 1020 * Init track mixers. If at least one direction is available on
1021 * attach time, we assume a success. 1021 * attach time, we assume a success.
1022 */ 1022 */
1023 error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil); 1023 error = audio_mixers_init(sc, mode, &phwfmt, &rhwfmt, &pfil, &rfil);
1024 if (sc->sc_pmixer == NULL && sc->sc_rmixer == NULL) { 1024 if (sc->sc_pmixer == NULL && sc->sc_rmixer == NULL) {
1025 aprint_error_dev(self, 1025 aprint_error_dev(self,
1026 "audio_mixers_init failed: errno=%d\n", error); 1026 "audio_mixers_init failed: errno=%d\n", error);
1027 goto bad; 1027 goto bad;
1028 } 1028 }
1029 1029
1030 sc->sc_psz = pserialize_create(); 1030 sc->sc_psz = pserialize_create();
1031 psref_target_init(&sc->sc_psref, audio_psref_class); 1031 psref_target_init(&sc->sc_psref, audio_psref_class);
1032 1032
1033 selinit(&sc->sc_wsel); 1033 selinit(&sc->sc_wsel);
1034 selinit(&sc->sc_rsel); 1034 selinit(&sc->sc_rsel);
1035 1035
1036 /* Initial parameter of /dev/sound */ 1036 /* Initial parameter of /dev/sound */
1037 sc->sc_sound_pparams = params_to_format2(&audio_default); 1037 sc->sc_sound_pparams = params_to_format2(&audio_default);
1038 sc->sc_sound_rparams = params_to_format2(&audio_default); 1038 sc->sc_sound_rparams = params_to_format2(&audio_default);
1039 sc->sc_sound_ppause = false; 1039 sc->sc_sound_ppause = false;
1040 sc->sc_sound_rpause = false; 1040 sc->sc_sound_rpause = false;
1041 1041
1042 /* XXX TODO: consider about sc_ai */ 1042 /* XXX TODO: consider about sc_ai */
1043 1043
1044 mixer_init(sc); 1044 mixer_init(sc);
1045 TRACE(2, "inputs ports=0x%x, input master=%d, " 1045 TRACE(2, "inputs ports=0x%x, input master=%d, "
1046 "output ports=0x%x, output master=%d", 1046 "output ports=0x%x, output master=%d",
1047 sc->sc_inports.allports, sc->sc_inports.master, 1047 sc->sc_inports.allports, sc->sc_inports.master,
1048 sc->sc_outports.allports, sc->sc_outports.master); 1048 sc->sc_outports.allports, sc->sc_outports.master);
1049 1049
1050 sysctl_createv(&sc->sc_log, 0, NULL, &node, 1050 sysctl_createv(&sc->sc_log, 0, NULL, &node,
1051 0, 1051 0,
1052 CTLTYPE_NODE, device_xname(sc->sc_dev), 1052 CTLTYPE_NODE, device_xname(sc->sc_dev),
1053 SYSCTL_DESCR("audio test"), 1053 SYSCTL_DESCR("audio test"),
1054 NULL, 0, 1054 NULL, 0,
1055 NULL, 0, 1055 NULL, 0,
1056 CTL_HW, 1056 CTL_HW,
1057 CTL_CREATE, CTL_EOL); 1057 CTL_CREATE, CTL_EOL);
1058 1058
1059 if (node != NULL) { 1059 if (node != NULL) {
1060 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 1060 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
1061 CTLFLAG_READWRITE, 1061 CTLFLAG_READWRITE,
1062 CTLTYPE_INT, "blk_ms", 1062 CTLTYPE_INT, "blk_ms",
1063 SYSCTL_DESCR("blocksize in msec"), 1063 SYSCTL_DESCR("blocksize in msec"),
1064 audio_sysctl_blk_ms, 0, (void *)sc, 0, 1064 audio_sysctl_blk_ms, 0, (void *)sc, 0,
1065 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 1065 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
1066 1066
1067 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 1067 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
1068 CTLFLAG_READWRITE, 1068 CTLFLAG_READWRITE,
1069 CTLTYPE_BOOL, "multiuser", 1069 CTLTYPE_BOOL, "multiuser",
1070 SYSCTL_DESCR("allow multiple user access"), 1070 SYSCTL_DESCR("allow multiple user access"),
1071 audio_sysctl_multiuser, 0, (void *)sc, 0, 1071 audio_sysctl_multiuser, 0, (void *)sc, 0,
1072 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 1072 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
1073 1073
1074#if defined(AUDIO_DEBUG) 1074#if defined(AUDIO_DEBUG)
1075 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 1075 sysctl_createv(&sc->sc_log, 0, NULL, NULL,
1076 CTLFLAG_READWRITE, 1076 CTLFLAG_READWRITE,
1077 CTLTYPE_INT, "debug", 1077 CTLTYPE_INT, "debug",
1078 SYSCTL_DESCR("debug level (0..4)"), 1078 SYSCTL_DESCR("debug level (0..4)"),
1079 audio_sysctl_debug, 0, (void *)sc, 0, 1079 audio_sysctl_debug, 0, (void *)sc, 0,
1080 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 1080 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
1081#endif 1081#endif
1082 } 1082 }
1083 1083
1084#ifdef AUDIO_PM_IDLE 1084#ifdef AUDIO_PM_IDLE
1085 callout_init(&sc->sc_idle_counter, 0); 1085 callout_init(&sc->sc_idle_counter, 0);
1086 callout_setfunc(&sc->sc_idle_counter, audio_idle, self); 1086 callout_setfunc(&sc->sc_idle_counter, audio_idle, self);
1087#endif 1087#endif
1088 1088
1089 if (!pmf_device_register(self, audio_suspend, audio_resume)) 1089 if (!pmf_device_register(self, audio_suspend, audio_resume))
1090 aprint_error_dev(self, "couldn't establish power handler\n"); 1090 aprint_error_dev(self, "couldn't establish power handler\n");
1091#ifdef AUDIO_PM_IDLE 1091#ifdef AUDIO_PM_IDLE
1092 if (!device_active_register(self, audio_activity)) 1092 if (!device_active_register(self, audio_activity))
1093 aprint_error_dev(self, "couldn't register activity handler\n"); 1093 aprint_error_dev(self, "couldn't register activity handler\n");
1094#endif 1094#endif
1095 1095
1096 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN, 1096 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN,
1097 audio_volume_down, true)) 1097 audio_volume_down, true))
1098 aprint_error_dev(self, "couldn't add volume down handler\n"); 1098 aprint_error_dev(self, "couldn't add volume down handler\n");
1099 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP, 1099 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP,
1100 audio_volume_up, true)) 1100 audio_volume_up, true))
1101 aprint_error_dev(self, "couldn't add volume up handler\n"); 1101 aprint_error_dev(self, "couldn't add volume up handler\n");
1102 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE, 1102 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE,
1103 audio_volume_toggle, true)) 1103 audio_volume_toggle, true))
1104 aprint_error_dev(self, "couldn't add volume toggle handler\n"); 1104 aprint_error_dev(self, "couldn't add volume toggle handler\n");
1105 1105
1106#ifdef AUDIO_PM_IDLE 1106#ifdef AUDIO_PM_IDLE
1107 callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz); 1107 callout_schedule(&sc->sc_idle_counter, audio_idle_timeout * hz);
1108#endif 1108#endif
1109 1109
1110#if defined(AUDIO_DEBUG) 1110#if defined(AUDIO_DEBUG)
1111 audio_mlog_init(); 1111 audio_mlog_init();
1112#endif 1112#endif
1113 1113
1114 audiorescan(self, "audio", NULL); 1114 audiorescan(self, NULL, NULL);
1115 sc->sc_exlock = 0; 1115 sc->sc_exlock = 0;
1116 return; 1116 return;
1117 1117
1118bad: 1118bad:
1119 /* Clearing hw_if means that device is attached but disabled. */ 1119 /* Clearing hw_if means that device is attached but disabled. */
1120 sc->hw_if = NULL; 1120 sc->hw_if = NULL;
1121 sc->sc_exlock = 0; 1121 sc->sc_exlock = 0;
1122 aprint_error_dev(sc->sc_dev, "disabled\n"); 1122 aprint_error_dev(sc->sc_dev, "disabled\n");
1123 return; 1123 return;
1124} 1124}
1125 1125
1126/* 1126/*
1127 * Initialize hardware mixer. 1127 * Initialize hardware mixer.
1128 * This function is called from audioattach(). 1128 * This function is called from audioattach().
1129 */ 1129 */
1130static void 1130static void
1131mixer_init(struct audio_softc *sc) 1131mixer_init(struct audio_softc *sc)
1132{ 1132{
1133 mixer_devinfo_t mi; 1133 mixer_devinfo_t mi;
1134 int iclass, mclass, oclass, rclass; 1134 int iclass, mclass, oclass, rclass;
1135 int record_master_found, record_source_found; 1135 int record_master_found, record_source_found;
1136 1136
1137 iclass = mclass = oclass = rclass = -1; 1137 iclass = mclass = oclass = rclass = -1;
1138 sc->sc_inports.index = -1; 1138 sc->sc_inports.index = -1;
1139 sc->sc_inports.master = -1; 1139 sc->sc_inports.master = -1;
1140 sc->sc_inports.nports = 0; 1140 sc->sc_inports.nports = 0;
1141 sc->sc_inports.isenum = false; 1141 sc->sc_inports.isenum = false;
1142 sc->sc_inports.allports = 0; 1142 sc->sc_inports.allports = 0;
1143 sc->sc_inports.isdual = false; 1143 sc->sc_inports.isdual = false;
1144 sc->sc_inports.mixerout = -1; 1144 sc->sc_inports.mixerout = -1;
1145 sc->sc_inports.cur_port = -1; 1145 sc->sc_inports.cur_port = -1;
1146 sc->sc_outports.index = -1; 1146 sc->sc_outports.index = -1;
1147 sc->sc_outports.master = -1; 1147 sc->sc_outports.master = -1;
1148 sc->sc_outports.nports = 0; 1148 sc->sc_outports.nports = 0;
1149 sc->sc_outports.isenum = false; 1149 sc->sc_outports.isenum = false;
1150 sc->sc_outports.allports = 0; 1150 sc->sc_outports.allports = 0;
1151 sc->sc_outports.isdual = false; 1151 sc->sc_outports.isdual = false;
1152 sc->sc_outports.mixerout = -1; 1152 sc->sc_outports.mixerout = -1;
1153 sc->sc_outports.cur_port = -1; 1153 sc->sc_outports.cur_port = -1;
1154 sc->sc_monitor_port = -1; 1154 sc->sc_monitor_port = -1;
1155 /* 1155 /*
1156 * Read through the underlying driver's list, picking out the class 1156 * Read through the underlying driver's list, picking out the class
1157 * names from the mixer descriptions. We'll need them to decode the 1157 * names from the mixer descriptions. We'll need them to decode the
1158 * mixer descriptions on the next pass through the loop. 1158 * mixer descriptions on the next pass through the loop.
1159 */ 1159 */
1160 mutex_enter(sc->sc_lock); 1160 mutex_enter(sc->sc_lock);
1161 for(mi.index = 0; ; mi.index++) { 1161 for(mi.index = 0; ; mi.index++) {
1162 if (audio_query_devinfo(sc, &mi) != 0) 1162 if (audio_query_devinfo(sc, &mi) != 0)
1163 break; 1163 break;
1164 /* 1164 /*
1165 * The type of AUDIO_MIXER_CLASS merely introduces a class. 1165 * The type of AUDIO_MIXER_CLASS merely introduces a class.
1166 * All the other types describe an actual mixer. 1166 * All the other types describe an actual mixer.
1167 */ 1167 */
1168 if (mi.type == AUDIO_MIXER_CLASS) { 1168 if (mi.type == AUDIO_MIXER_CLASS) {
1169 if (strcmp(mi.label.name, AudioCinputs) == 0) 1169 if (strcmp(mi.label.name, AudioCinputs) == 0)
1170 iclass = mi.mixer_class; 1170 iclass = mi.mixer_class;
1171 if (strcmp(mi.label.name, AudioCmonitor) == 0) 1171 if (strcmp(mi.label.name, AudioCmonitor) == 0)
1172 mclass = mi.mixer_class; 1172 mclass = mi.mixer_class;
1173 if (strcmp(mi.label.name, AudioCoutputs) == 0) 1173 if (strcmp(mi.label.name, AudioCoutputs) == 0)
1174 oclass = mi.mixer_class; 1174 oclass = mi.mixer_class;
1175 if (strcmp(mi.label.name, AudioCrecord) == 0) 1175 if (strcmp(mi.label.name, AudioCrecord) == 0)
1176 rclass = mi.mixer_class; 1176 rclass = mi.mixer_class;
1177 } 1177 }
1178 } 1178 }
1179 mutex_exit(sc->sc_lock); 1179 mutex_exit(sc->sc_lock);
1180 1180
1181 /* Allocate save area. Ensure non-zero allocation. */ 1181 /* Allocate save area. Ensure non-zero allocation. */
1182 sc->sc_nmixer_states = mi.index; 1182 sc->sc_nmixer_states = mi.index;
1183 sc->sc_mixer_state = kmem_zalloc(sizeof(mixer_ctrl_t) * 1183 sc->sc_mixer_state = kmem_zalloc(sizeof(mixer_ctrl_t) *
1184 (sc->sc_nmixer_states + 1), KM_SLEEP); 1184 (sc->sc_nmixer_states + 1), KM_SLEEP);
1185 1185
1186 /* 1186 /*
1187 * This is where we assign each control in the "audio" model, to the 1187 * This is where we assign each control in the "audio" model, to the
1188 * underlying "mixer" control. We walk through the whole list once, 1188 * underlying "mixer" control. We walk through the whole list once,
1189 * assigning likely candidates as we come across them. 1189 * assigning likely candidates as we come across them.
1190 */ 1190 */
1191 record_master_found = 0; 1191 record_master_found = 0;
1192 record_source_found = 0; 1192 record_source_found = 0;
1193 mutex_enter(sc->sc_lock); 1193 mutex_enter(sc->sc_lock);
1194 for(mi.index = 0; ; mi.index++) { 1194 for(mi.index = 0; ; mi.index++) {
1195 if (audio_query_devinfo(sc, &mi) != 0) 1195 if (audio_query_devinfo(sc, &mi) != 0)
1196 break; 1196 break;
1197 KASSERT(mi.index < sc->sc_nmixer_states); 1197 KASSERT(mi.index < sc->sc_nmixer_states);
1198 if (mi.type == AUDIO_MIXER_CLASS) 1198 if (mi.type == AUDIO_MIXER_CLASS)
1199 continue; 1199 continue;
1200 if (mi.mixer_class == iclass) { 1200 if (mi.mixer_class == iclass) {
1201 /* 1201 /*
1202 * AudioCinputs is only a fallback, when we don't 1202 * AudioCinputs is only a fallback, when we don't
1203 * find what we're looking for in AudioCrecord, so 1203 * find what we're looking for in AudioCrecord, so
1204 * check the flags before accepting one of these. 1204 * check the flags before accepting one of these.
1205 */ 1205 */
1206 if (strcmp(mi.label.name, AudioNmaster) == 0 1206 if (strcmp(mi.label.name, AudioNmaster) == 0
1207 && record_master_found == 0) 1207 && record_master_found == 0)
1208 sc->sc_inports.master = mi.index; 1208 sc->sc_inports.master = mi.index;
1209 if (strcmp(mi.label.name, AudioNsource) == 0 1209 if (strcmp(mi.label.name, AudioNsource) == 0
1210 && record_source_found == 0) { 1210 && record_source_found == 0) {
1211 if (mi.type == AUDIO_MIXER_ENUM) { 1211 if (mi.type == AUDIO_MIXER_ENUM) {
1212 int i; 1212 int i;
1213 for(i = 0; i < mi.un.e.num_mem; i++) 1213 for(i = 0; i < mi.un.e.num_mem; i++)
1214 if (strcmp(mi.un.e.member[i].label.name, 1214 if (strcmp(mi.un.e.member[i].label.name,
1215 AudioNmixerout) == 0) 1215 AudioNmixerout) == 0)
1216 sc->sc_inports.mixerout = 1216 sc->sc_inports.mixerout =
1217 mi.un.e.member[i].ord; 1217 mi.un.e.member[i].ord;
1218 } 1218 }
1219 au_setup_ports(sc, &sc->sc_inports, &mi, 1219 au_setup_ports(sc, &sc->sc_inports, &mi,
1220 itable); 1220 itable);
1221 } 1221 }
1222 if (strcmp(mi.label.name, AudioNdac) == 0 && 1222 if (strcmp(mi.label.name, AudioNdac) == 0 &&
1223 sc->sc_outports.master == -1) 1223 sc->sc_outports.master == -1)
1224 sc->sc_outports.master = mi.index; 1224 sc->sc_outports.master = mi.index;
1225 } else if (mi.mixer_class == mclass) { 1225 } else if (mi.mixer_class == mclass) {
1226 if (strcmp(mi.label.name, AudioNmonitor) == 0) 1226 if (strcmp(mi.label.name, AudioNmonitor) == 0)
1227 sc->sc_monitor_port = mi.index; 1227 sc->sc_monitor_port = mi.index;
1228 } else if (mi.mixer_class == oclass) { 1228 } else if (mi.mixer_class == oclass) {
1229 if (strcmp(mi.label.name, AudioNmaster) == 0) 1229 if (strcmp(mi.label.name, AudioNmaster) == 0)
1230 sc->sc_outports.master = mi.index; 1230 sc->sc_outports.master = mi.index;
1231 if (strcmp(mi.label.name, AudioNselect) == 0) 1231 if (strcmp(mi.label.name, AudioNselect) == 0)
1232 au_setup_ports(sc, &sc->sc_outports, &mi, 1232 au_setup_ports(sc, &sc->sc_outports, &mi,
1233 otable); 1233 otable);
1234 } else if (mi.mixer_class == rclass) { 1234 } else if (mi.mixer_class == rclass) {
1235 /* 1235 /*
1236 * These are the preferred mixers for the audio record 1236 * These are the preferred mixers for the audio record
1237 * controls, so set the flags here, but don't check. 1237 * controls, so set the flags here, but don't check.
1238 */ 1238 */
1239 if (strcmp(mi.label.name, AudioNmaster) == 0) { 1239 if (strcmp(mi.label.name, AudioNmaster) == 0) {
1240 sc->sc_inports.master = mi.index; 1240 sc->sc_inports.master = mi.index;
1241 record_master_found = 1; 1241 record_master_found = 1;
1242 } 1242 }
1243#if 1 /* Deprecated. Use AudioNmaster. */ 1243#if 1 /* Deprecated. Use AudioNmaster. */
1244 if (strcmp(mi.label.name, AudioNrecord) == 0) { 1244 if (strcmp(mi.label.name, AudioNrecord) == 0) {
1245 sc->sc_inports.master = mi.index; 1245 sc->sc_inports.master = mi.index;
1246 record_master_found = 1; 1246 record_master_found = 1;
1247 } 1247 }
1248 if (strcmp(mi.label.name, AudioNvolume) == 0) { 1248 if (strcmp(mi.label.name, AudioNvolume) == 0) {
1249 sc->sc_inports.master = mi.index; 1249 sc->sc_inports.master = mi.index;
1250 record_master_found = 1; 1250 record_master_found = 1;
1251 } 1251 }
1252#endif 1252#endif
1253 if (strcmp(mi.label.name, AudioNsource) == 0) { 1253 if (strcmp(mi.label.name, AudioNsource) == 0) {
1254 if (mi.type == AUDIO_MIXER_ENUM) { 1254 if (mi.type == AUDIO_MIXER_ENUM) {
1255 int i; 1255 int i;
1256 for(i = 0; i < mi.un.e.num_mem; i++) 1256 for(i = 0; i < mi.un.e.num_mem; i++)
1257 if (strcmp(mi.un.e.member[i].label.name, 1257 if (strcmp(mi.un.e.member[i].label.name,
1258 AudioNmixerout) == 0) 1258 AudioNmixerout) == 0)
1259 sc->sc_inports.mixerout = 1259 sc->sc_inports.mixerout =
1260 mi.un.e.member[i].ord; 1260 mi.un.e.member[i].ord;
1261 } 1261 }
1262 au_setup_ports(sc, &sc->sc_inports, &mi, 1262 au_setup_ports(sc, &sc->sc_inports, &mi,
1263 itable); 1263 itable);
1264 record_source_found = 1; 1264 record_source_found = 1;
1265 } 1265 }
1266 } 1266 }
1267 } 1267 }
1268 mutex_exit(sc->sc_lock); 1268 mutex_exit(sc->sc_lock);
1269} 1269}
1270 1270
1271static int 1271static int
1272audioactivate(device_t self, enum devact act) 1272audioactivate(device_t self, enum devact act)
1273{ 1273{
1274 struct audio_softc *sc = device_private(self); 1274 struct audio_softc *sc = device_private(self);
1275 1275
1276 switch (act) { 1276 switch (act) {
1277 case DVACT_DEACTIVATE: 1277 case DVACT_DEACTIVATE:
1278 mutex_enter(sc->sc_lock); 1278 mutex_enter(sc->sc_lock);
1279 sc->sc_dying = true; 1279 sc->sc_dying = true;
1280 cv_broadcast(&sc->sc_exlockcv); 1280 cv_broadcast(&sc->sc_exlockcv);
1281 mutex_exit(sc->sc_lock); 1281 mutex_exit(sc->sc_lock);
1282 return 0; 1282 return 0;
1283 default: 1283 default:
1284 return EOPNOTSUPP; 1284 return EOPNOTSUPP;
1285 } 1285 }
1286} 1286}
1287 1287
1288static int 1288static int
1289audiodetach(device_t self, int flags) 1289audiodetach(device_t self, int flags)
1290{ 1290{
1291 struct audio_softc *sc; 1291 struct audio_softc *sc;
1292 struct audio_file *file; 1292 struct audio_file *file;
1293 int error; 1293 int error;
1294 1294
1295 sc = device_private(self); 1295 sc = device_private(self);
1296 TRACE(2, "flags=%d", flags); 1296 TRACE(2, "flags=%d", flags);
1297 1297
1298 /* device is not initialized */ 1298 /* device is not initialized */
1299 if (sc->hw_if == NULL) 1299 if (sc->hw_if == NULL)
1300 return 0; 1300 return 0;
1301 1301
1302 /* Start draining existing accessors of the device. */ 1302 /* Start draining existing accessors of the device. */
1303 error = config_detach_children(self, flags); 1303 error = config_detach_children(self, flags);
1304 if (error) 1304 if (error)
1305 return error; 1305 return error;
1306 1306
1307 /* 1307 /*
1308 * This waits currently running sysctls to finish if exists. 1308 * This waits currently running sysctls to finish if exists.
1309 * After this, no more new sysctls will come. 1309 * After this, no more new sysctls will come.
1310 */ 1310 */
1311 sysctl_teardown(&sc->sc_log); 1311 sysctl_teardown(&sc->sc_log);
1312 1312
1313 mutex_enter(sc->sc_lock); 1313 mutex_enter(sc->sc_lock);
1314 sc->sc_dying = true; 1314 sc->sc_dying = true;
1315 cv_broadcast(&sc->sc_exlockcv); 1315 cv_broadcast(&sc->sc_exlockcv);
1316 if (sc->sc_pmixer) 1316 if (sc->sc_pmixer)
1317 cv_broadcast(&sc->sc_pmixer->outcv); 1317 cv_broadcast(&sc->sc_pmixer->outcv);
1318 if (sc->sc_rmixer) 1318 if (sc->sc_rmixer)
1319 cv_broadcast(&sc->sc_rmixer->outcv); 1319 cv_broadcast(&sc->sc_rmixer->outcv);
1320 1320
1321 /* Prevent new users */ 1321 /* Prevent new users */
1322 SLIST_FOREACH(file, &sc->sc_files, entry) { 1322 SLIST_FOREACH(file, &sc->sc_files, entry) {
1323 atomic_store_relaxed(&file->dying, true); 1323 atomic_store_relaxed(&file->dying, true);
1324 } 1324 }
1325 1325
1326 /* 1326 /*
1327 * Wait for existing users to drain. 1327 * Wait for existing users to drain.
1328 * - pserialize_perform waits for all pserialize_read sections on 1328 * - pserialize_perform waits for all pserialize_read sections on
1329 * all CPUs; after this, no more new psref_acquire can happen. 1329 * all CPUs; after this, no more new psref_acquire can happen.
1330 * - psref_target_destroy waits for all extant acquired psrefs to 1330 * - psref_target_destroy waits for all extant acquired psrefs to
1331 * be psref_released. 1331 * be psref_released.
1332 */ 1332 */
1333 pserialize_perform(sc->sc_psz); 1333 pserialize_perform(sc->sc_psz);
1334 mutex_exit(sc->sc_lock); 1334 mutex_exit(sc->sc_lock);
1335 psref_target_destroy(&sc->sc_psref, audio_psref_class); 1335 psref_target_destroy(&sc->sc_psref, audio_psref_class);
1336 1336
1337 /* 1337 /*
1338 * We are now guaranteed that there are no calls to audio fileops 1338 * We are now guaranteed that there are no calls to audio fileops
1339 * that hold sc, and any new calls with files that were for sc will 1339 * that hold sc, and any new calls with files that were for sc will
1340 * fail. Thus, we now have exclusive access to the softc. 1340 * fail. Thus, we now have exclusive access to the softc.
1341 */ 1341 */
1342 sc->sc_exlock = 1; 1342 sc->sc_exlock = 1;
1343 1343
1344 /* 1344 /*
1345 * Clean up all open instances. 1345 * Clean up all open instances.
1346 * Here, we no longer need any locks to traverse sc_files. 1346 * Here, we no longer need any locks to traverse sc_files.
1347 */ 1347 */
1348 while ((file = SLIST_FIRST(&sc->sc_files)) != NULL) { 1348 while ((file = SLIST_FIRST(&sc->sc_files)) != NULL) {
1349 audio_unlink(sc, file); 1349 audio_unlink(sc, file);
1350 } 1350 }
1351 1351
1352 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_DOWN, 1352 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_DOWN,
1353 audio_volume_down, true); 1353 audio_volume_down, true);
1354 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_UP, 1354 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_UP,
1355 audio_volume_up, true); 1355 audio_volume_up, true);
1356 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_TOGGLE, 1356 pmf_event_deregister(self, PMFE_AUDIO_VOLUME_TOGGLE,
1357 audio_volume_toggle, true); 1357 audio_volume_toggle, true);
1358 1358
1359#ifdef AUDIO_PM_IDLE 1359#ifdef AUDIO_PM_IDLE
1360 callout_halt(&sc->sc_idle_counter, sc->sc_lock); 1360 callout_halt(&sc->sc_idle_counter, sc->sc_lock);
1361 1361
1362 device_active_deregister(self, audio_activity); 1362 device_active_deregister(self, audio_activity);
1363#endif 1363#endif
1364 1364
1365 pmf_device_deregister(self); 1365 pmf_device_deregister(self);
1366 1366
1367 /* Free resources */ 1367 /* Free resources */
1368 if (sc->sc_pmixer) { 1368 if (sc->sc_pmixer) {
1369 audio_mixer_destroy(sc, sc->sc_pmixer); 1369 audio_mixer_destroy(sc, sc->sc_pmixer);
1370 kmem_free(sc->sc_pmixer, sizeof(*sc->sc_pmixer)); 1370 kmem_free(sc->sc_pmixer, sizeof(*sc->sc_pmixer));
1371 } 1371 }
1372 if (sc->sc_rmixer) { 1372 if (sc->sc_rmixer) {
1373 audio_mixer_destroy(sc, sc->sc_rmixer); 1373 audio_mixer_destroy(sc, sc->sc_rmixer);
1374 kmem_free(sc->sc_rmixer, sizeof(*sc->sc_rmixer)); 1374 kmem_free(sc->sc_rmixer, sizeof(*sc->sc_rmixer));
1375 } 1375 }
1376 if (sc->sc_am) 1376 if (sc->sc_am)
1377 kern_free(sc->sc_am); 1377 kern_free(sc->sc_am);
1378 1378
1379 seldestroy(&sc->sc_wsel); 1379 seldestroy(&sc->sc_wsel);
1380 seldestroy(&sc->sc_rsel); 1380 seldestroy(&sc->sc_rsel);
1381 1381
1382#ifdef AUDIO_PM_IDLE 1382#ifdef AUDIO_PM_IDLE
1383 callout_destroy(&sc->sc_idle_counter); 1383 callout_destroy(&sc->sc_idle_counter);
1384#endif 1384#endif
1385 1385
1386 cv_destroy(&sc->sc_exlockcv); 1386 cv_destroy(&sc->sc_exlockcv);
1387 1387
1388#if defined(AUDIO_DEBUG) 1388#if defined(AUDIO_DEBUG)
1389 audio_mlog_free(); 1389 audio_mlog_free();
1390#endif 1390#endif
1391 1391
1392 return 0; 1392 return 0;
1393} 1393}
1394 1394
1395static void 1395static void
1396audiochilddet(device_t self, device_t child) 1396audiochilddet(device_t self, device_t child)
1397{ 1397{
1398 1398
1399 /* we hold no child references, so do nothing */ 1399 /* we hold no child references, so do nothing */
1400} 1400}
1401 1401
1402static int 1402static int
1403audiosearch(device_t parent, cfdata_t cf, const int *locs, void *aux) 1403audiosearch(device_t parent, cfdata_t cf, const int *locs, void *aux)
1404{ 1404{
1405 1405
1406 if (config_match(parent, cf, aux)) 1406 if (config_match(parent, cf, aux))
1407 config_attach_loc(parent, cf, locs, aux, NULL); 1407 config_attach_loc(parent, cf, locs, aux, NULL);
1408 1408
1409 return 0; 1409 return 0;
1410} 1410}
1411 1411
1412static int 1412static int
1413audiorescan(device_t self, const char *ifattr, const int *locators) 1413audiorescan(device_t self, const char *ifattr, const int *locators)
1414{ 1414{
1415 struct audio_softc *sc = device_private(self); 1415 struct audio_softc *sc = device_private(self);
1416 1416
1417 config_search(sc->sc_dev, NULL, 1417 config_search(sc->sc_dev, NULL,
1418 CFARG_SUBMATCH, audiosearch, 1418 CFARG_SUBMATCH, audiosearch,
1419 CFARG_IATTR, ifattr, 
1420 CFARG_LOCATORS, locators, 
1421 CFARG_EOL); 1419 CFARG_EOL);
1422 1420
1423 return 0; 1421 return 0;
1424} 1422}
1425 1423
1426/* 1424/*
1427 * Called from hardware driver. This is where the MI audio driver gets 1425 * Called from hardware driver. This is where the MI audio driver gets
1428 * probed/attached to the hardware driver. 1426 * probed/attached to the hardware driver.
1429 */ 1427 */
1430device_t 1428device_t
1431audio_attach_mi(const struct audio_hw_if *ahwp, void *hdlp, device_t dev) 1429audio_attach_mi(const struct audio_hw_if *ahwp, void *hdlp, device_t dev)
1432{ 1430{
1433 struct audio_attach_args arg; 1431 struct audio_attach_args arg;
1434 1432
1435#ifdef DIAGNOSTIC 1433#ifdef DIAGNOSTIC
1436 if (ahwp == NULL) { 1434 if (ahwp == NULL) {
1437 aprint_error("audio_attach_mi: NULL\n"); 1435 aprint_error("audio_attach_mi: NULL\n");
1438 return 0; 1436 return 0;
1439 } 1437 }
1440#endif 1438#endif
1441 arg.type = AUDIODEV_TYPE_AUDIO; 1439 arg.type = AUDIODEV_TYPE_AUDIO;
1442 arg.hwif = ahwp; 1440 arg.hwif = ahwp;
1443 arg.hdl = hdlp; 1441 arg.hdl = hdlp;
1444 return config_found(dev, &arg, audioprint, CFARG_EOL); 1442 return config_found(dev, &arg, audioprint, CFARG_EOL);
1445} 1443}
1446 1444
1447/* 1445/*
1448 * audio_printf() outputs fmt... with the audio device name and MD device 1446 * audio_printf() outputs fmt... with the audio device name and MD device
1449 * name prefixed. If the message is considered to be related to the MD 1447 * name prefixed. If the message is considered to be related to the MD
1450 * driver, use this one instead of device_printf(). 1448 * driver, use this one instead of device_printf().
1451 */ 1449 */
1452static void 1450static void
1453audio_printf(struct audio_softc *sc, const char *fmt, ...) 1451audio_printf(struct audio_softc *sc, const char *fmt, ...)
1454{ 1452{
1455 va_list ap; 1453 va_list ap;
1456 1454
1457 printf("%s(%s): ", device_xname(sc->sc_dev), device_xname(sc->hw_dev)); 1455 printf("%s(%s): ", device_xname(sc->sc_dev), device_xname(sc->hw_dev));
1458 va_start(ap, fmt); 1456 va_start(ap, fmt);
1459 vprintf(fmt, ap); 1457 vprintf(fmt, ap);
1460 va_end(ap); 1458 va_end(ap);
1461} 1459}
1462 1460
1463/* 1461/*
1464 * Enter critical section and also keep sc_lock. 1462 * Enter critical section and also keep sc_lock.
1465 * If successful, returns 0 with sc_lock held. Otherwise returns errno. 1463 * If successful, returns 0 with sc_lock held. Otherwise returns errno.
1466 * Must be called without sc_lock held. 1464 * Must be called without sc_lock held.
1467 */ 1465 */
1468static int 1466static int
1469audio_exlock_mutex_enter(struct audio_softc *sc) 1467audio_exlock_mutex_enter(struct audio_softc *sc)
1470{ 1468{
1471 int error; 1469 int error;
1472 1470
1473 mutex_enter(sc->sc_lock); 1471 mutex_enter(sc->sc_lock);
1474 if (sc->sc_dying) { 1472 if (sc->sc_dying) {
1475 mutex_exit(sc->sc_lock); 1473 mutex_exit(sc->sc_lock);
1476 return EIO; 1474 return EIO;
1477 } 1475 }
1478 1476
1479 while (__predict_false(sc->sc_exlock != 0)) { 1477 while (__predict_false(sc->sc_exlock != 0)) {
1480 error = cv_wait_sig(&sc->sc_exlockcv, sc->sc_lock); 1478 error = cv_wait_sig(&sc->sc_exlockcv, sc->sc_lock);
1481 if (sc->sc_dying) 1479 if (sc->sc_dying)
1482 error = EIO; 1480 error = EIO;
1483 if (error) { 1481 if (error) {
1484 mutex_exit(sc->sc_lock); 1482 mutex_exit(sc->sc_lock);
1485 return error; 1483 return error;
1486 } 1484 }
1487 } 1485 }
1488 1486
1489 /* Acquire */ 1487 /* Acquire */
1490 sc->sc_exlock = 1; 1488 sc->sc_exlock = 1;
1491 return 0; 1489 return 0;
1492} 1490}
1493 1491
1494/* 1492/*
1495 * Exit critical section and exit sc_lock. 1493 * Exit critical section and exit sc_lock.
1496 * Must be called with sc_lock held. 1494 * Must be called with sc_lock held.
1497 */ 1495 */
1498static void 1496static void
1499audio_exlock_mutex_exit(struct audio_softc *sc) 1497audio_exlock_mutex_exit(struct audio_softc *sc)
1500{ 1498{
1501 1499
1502 KASSERT(mutex_owned(sc->sc_lock)); 1500 KASSERT(mutex_owned(sc->sc_lock));
1503 1501
1504 sc->sc_exlock = 0; 1502 sc->sc_exlock = 0;
1505 cv_broadcast(&sc->sc_exlockcv); 1503 cv_broadcast(&sc->sc_exlockcv);
1506 mutex_exit(sc->sc_lock); 1504 mutex_exit(sc->sc_lock);
1507} 1505}
1508 1506
1509/* 1507/*
1510 * Enter critical section. 1508 * Enter critical section.
1511 * If successful, it returns 0. Otherwise returns errno. 1509 * If successful, it returns 0. Otherwise returns errno.
1512 * Must be called without sc_lock held. 1510 * Must be called without sc_lock held.
1513 * This function returns without sc_lock held. 1511 * This function returns without sc_lock held.
1514 */ 1512 */
1515static int 1513static int
1516audio_exlock_enter(struct audio_softc *sc) 1514audio_exlock_enter(struct audio_softc *sc)
1517{ 1515{
1518 int error; 1516 int error;
1519 1517
1520 error = audio_exlock_mutex_enter(sc); 1518 error = audio_exlock_mutex_enter(sc);
1521 if (error) 1519 if (error)
1522 return error; 1520 return error;
1523 mutex_exit(sc->sc_lock); 1521 mutex_exit(sc->sc_lock);
1524 return 0; 1522 return 0;
1525} 1523}
1526 1524
1527/* 1525/*
1528 * Exit critical section. 1526 * Exit critical section.
1529 * Must be called without sc_lock held. 1527 * Must be called without sc_lock held.
1530 */ 1528 */
1531static void 1529static void
1532audio_exlock_exit(struct audio_softc *sc) 1530audio_exlock_exit(struct audio_softc *sc)
1533{ 1531{
1534 1532
1535 mutex_enter(sc->sc_lock); 1533 mutex_enter(sc->sc_lock);
1536 audio_exlock_mutex_exit(sc); 1534 audio_exlock_mutex_exit(sc);
1537} 1535}
1538 1536
1539/* 1537/*
1540 * Increment reference counter for this sc. 1538 * Increment reference counter for this sc.
1541 * This is intended to be used for open. 1539 * This is intended to be used for open.
1542 */ 1540 */
1543void 1541void
1544audio_sc_acquire_foropen(struct audio_softc *sc, struct psref *refp) 1542audio_sc_acquire_foropen(struct audio_softc *sc, struct psref *refp)
1545{ 1543{
1546 int s; 1544 int s;
1547 1545
1548 /* Block audiodetach while we acquire a reference */ 1546 /* Block audiodetach while we acquire a reference */
1549 s = pserialize_read_enter(); 1547 s = pserialize_read_enter();
1550 1548
1551 /* 1549 /*
1552 * We don't examine sc_dying here. However, all open methods 1550 * We don't examine sc_dying here. However, all open methods
1553 * call audio_exlock_enter() right after this, so we can examine 1551 * call audio_exlock_enter() right after this, so we can examine
1554 * sc_dying in it. 1552 * sc_dying in it.
1555 */ 1553 */
1556 1554
1557 /* Acquire a reference */ 1555 /* Acquire a reference */
1558 psref_acquire(refp, &sc->sc_psref, audio_psref_class); 1556 psref_acquire(refp, &sc->sc_psref, audio_psref_class);
1559 1557
1560 /* Now sc won't go away until we drop the reference count */ 1558 /* Now sc won't go away until we drop the reference count */
1561 pserialize_read_exit(s); 1559 pserialize_read_exit(s);
1562} 1560}
1563 1561
1564/* 1562/*
1565 * Get sc from file, and increment reference counter for this sc. 1563 * Get sc from file, and increment reference counter for this sc.
1566 * This is intended to be used for methods other than open. 1564 * This is intended to be used for methods other than open.
1567 * If successful, returns sc. Otherwise returns NULL. 1565 * If successful, returns sc. Otherwise returns NULL.
1568 */ 1566 */
1569struct audio_softc * 1567struct audio_softc *
1570audio_sc_acquire_fromfile(audio_file_t *file, struct psref *refp) 1568audio_sc_acquire_fromfile(audio_file_t *file, struct psref *refp)
1571{ 1569{
1572 int s; 1570 int s;
1573 bool dying; 1571 bool dying;
1574 1572
1575 /* Block audiodetach while we acquire a reference */ 1573 /* Block audiodetach while we acquire a reference */
1576 s = pserialize_read_enter(); 1574 s = pserialize_read_enter();
1577 1575
1578 /* If close or audiodetach already ran, tough -- no more audio */ 1576 /* If close or audiodetach already ran, tough -- no more audio */
1579 dying = atomic_load_relaxed(&file->dying); 1577 dying = atomic_load_relaxed(&file->dying);
1580 if (dying) { 1578 if (dying) {
1581 pserialize_read_exit(s); 1579 pserialize_read_exit(s);
1582 return NULL; 1580 return NULL;
1583 } 1581 }
1584 1582
1585 /* Acquire a reference */ 1583 /* Acquire a reference */
1586 psref_acquire(refp, &file->sc->sc_psref, audio_psref_class); 1584 psref_acquire(refp, &file->sc->sc_psref, audio_psref_class);
1587 1585
1588 /* Now sc won't go away until we drop the reference count */ 1586 /* Now sc won't go away until we drop the reference count */
1589 pserialize_read_exit(s); 1587 pserialize_read_exit(s);
1590 1588
1591 return file->sc; 1589 return file->sc;
1592} 1590}
1593 1591
1594/* 1592/*
1595 * Decrement reference counter for this sc. 1593 * Decrement reference counter for this sc.
1596 */ 1594 */
1597void 1595void
1598audio_sc_release(struct audio_softc *sc, struct psref *refp) 1596audio_sc_release(struct audio_softc *sc, struct psref *refp)
1599{ 1597{
1600 1598
1601 psref_release(refp, &sc->sc_psref, audio_psref_class); 1599 psref_release(refp, &sc->sc_psref, audio_psref_class);
1602} 1600}
1603 1601
1604/* 1602/*
1605 * Wait for I/O to complete, releasing sc_lock. 1603 * Wait for I/O to complete, releasing sc_lock.
1606 * Must be called with sc_lock held. 1604 * Must be called with sc_lock held.
1607 */ 1605 */
1608static int 1606static int
1609audio_track_waitio(struct audio_softc *sc, audio_track_t *track) 1607audio_track_waitio(struct audio_softc *sc, audio_track_t *track)
1610{ 1608{
1611 int error; 1609 int error;
1612 1610
1613 KASSERT(track); 1611 KASSERT(track);
1614 KASSERT(mutex_owned(sc->sc_lock)); 1612 KASSERT(mutex_owned(sc->sc_lock));
1615 1613
1616 /* Wait for pending I/O to complete. */ 1614 /* Wait for pending I/O to complete. */
1617 error = cv_timedwait_sig(&track->mixer->outcv, sc->sc_lock, 1615 error = cv_timedwait_sig(&track->mixer->outcv, sc->sc_lock,
1618 mstohz(AUDIO_TIMEOUT)); 1616 mstohz(AUDIO_TIMEOUT));
1619 if (sc->sc_suspending) { 1617 if (sc->sc_suspending) {
1620 /* If it's about to suspend, ignore timeout error. */ 1618 /* If it's about to suspend, ignore timeout error. */
1621 if (error == EWOULDBLOCK) { 1619 if (error == EWOULDBLOCK) {
1622 TRACET(2, track, "timeout (suspending)"); 1620 TRACET(2, track, "timeout (suspending)");
1623 return 0; 1621 return 0;
1624 } 1622 }
1625 } 1623 }
1626 if (sc->sc_dying) { 1624 if (sc->sc_dying) {
1627 error = EIO; 1625 error = EIO;
1628 } 1626 }
1629 if (error) { 1627 if (error) {
1630 TRACET(2, track, "cv_timedwait_sig failed %d", error); 1628 TRACET(2, track, "cv_timedwait_sig failed %d", error);
1631 if (error == EWOULDBLOCK) 1629 if (error == EWOULDBLOCK)
1632 audio_printf(sc, "device timeout\n"); 1630 audio_printf(sc, "device timeout\n");
1633 } else { 1631 } else {
1634 TRACET(3, track, "wakeup"); 1632 TRACET(3, track, "wakeup");
1635 } 1633 }
1636 return error; 1634 return error;
1637} 1635}
1638 1636
1639/* 1637/*
1640 * Try to acquire track lock. 1638 * Try to acquire track lock.
1641 * It doesn't block if the track lock is already aquired. 1639 * It doesn't block if the track lock is already aquired.
1642 * Returns true if the track lock was acquired, or false if the track 1640 * Returns true if the track lock was acquired, or false if the track
1643 * lock was already acquired. 1641 * lock was already acquired.
1644 */ 1642 */
1645static __inline bool 1643static __inline bool
1646audio_track_lock_tryenter(audio_track_t *track) 1644audio_track_lock_tryenter(audio_track_t *track)
1647{ 1645{
1648 return (atomic_cas_uint(&track->lock, 0, 1) == 0); 1646 return (atomic_cas_uint(&track->lock, 0, 1) == 0);
1649} 1647}
1650 1648
1651/* 1649/*
1652 * Acquire track lock. 1650 * Acquire track lock.
1653 */ 1651 */
1654static __inline void 1652static __inline void
1655audio_track_lock_enter(audio_track_t *track) 1653audio_track_lock_enter(audio_track_t *track)
1656{ 1654{
1657 /* Don't sleep here. */ 1655 /* Don't sleep here. */
1658 while (audio_track_lock_tryenter(track) == false) 1656 while (audio_track_lock_tryenter(track) == false)
1659 ; 1657 ;
1660} 1658}
1661 1659
1662/* 1660/*
1663 * Release track lock. 1661 * Release track lock.
1664 */ 1662 */
1665static __inline void 1663static __inline void
1666audio_track_lock_exit(audio_track_t *track) 1664audio_track_lock_exit(audio_track_t *track)
1667{ 1665{
1668 atomic_swap_uint(&track->lock, 0); 1666 atomic_swap_uint(&track->lock, 0);
1669} 1667}
1670 1668
1671 1669
1672static int 1670static int
1673audioopen(dev_t dev, int flags, int ifmt, struct lwp *l) 1671audioopen(dev_t dev, int flags, int ifmt, struct lwp *l)
1674{ 1672{
1675 struct audio_softc *sc; 1673 struct audio_softc *sc;
1676 struct psref sc_ref; 1674 struct psref sc_ref;
1677 int bound; 1675 int bound;
1678 int error; 1676 int error;
1679 1677
1680 /* Find the device */ 1678 /* Find the device */
1681 sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev)); 1679 sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev));
1682 if (sc == NULL || sc->hw_if == NULL) 1680 if (sc == NULL || sc->hw_if == NULL)
1683 return ENXIO; 1681 return ENXIO;
1684 1682
1685 bound = curlwp_bind(); 1683 bound = curlwp_bind();
1686 audio_sc_acquire_foropen(sc, &sc_ref); 1684 audio_sc_acquire_foropen(sc, &sc_ref);
1687 1685
1688 error = audio_exlock_enter(sc); 1686 error = audio_exlock_enter(sc);
1689 if (error) 1687 if (error)
1690 goto done; 1688 goto done;
1691 1689
1692 device_active(sc->sc_dev, DVA_SYSTEM); 1690 device_active(sc->sc_dev, DVA_SYSTEM);
1693 switch (AUDIODEV(dev)) { 1691 switch (AUDIODEV(dev)) {
1694 case SOUND_DEVICE: 1692 case SOUND_DEVICE:
1695 case AUDIO_DEVICE: 1693 case AUDIO_DEVICE:
1696 error = audio_open(dev, sc, flags, ifmt, l, NULL); 1694 error = audio_open(dev, sc, flags, ifmt, l, NULL);
1697 break; 1695 break;
1698 case AUDIOCTL_DEVICE: 1696 case AUDIOCTL_DEVICE:
1699 error = audioctl_open(dev, sc, flags, ifmt, l); 1697 error = audioctl_open(dev, sc, flags, ifmt, l);
1700 break; 1698 break;
1701 case MIXER_DEVICE: 1699 case MIXER_DEVICE:
1702 error = mixer_open(dev, sc, flags, ifmt, l); 1700 error = mixer_open(dev, sc, flags, ifmt, l);
1703 break; 1701 break;
1704 default: 1702 default:
1705 error = ENXIO; 1703 error = ENXIO;
1706 break; 1704 break;
1707 } 1705 }
1708 audio_exlock_exit(sc); 1706 audio_exlock_exit(sc);
1709 1707
1710done: 1708done:
1711 audio_sc_release(sc, &sc_ref); 1709 audio_sc_release(sc, &sc_ref);
1712 curlwp_bindx(bound); 1710 curlwp_bindx(bound);
1713 return error; 1711 return error;
1714} 1712}
1715 1713
1716static int 1714static int
1717audioclose(struct file *fp) 1715audioclose(struct file *fp)
1718{ 1716{
1719 struct audio_softc *sc; 1717 struct audio_softc *sc;
1720 struct psref sc_ref; 1718 struct psref sc_ref;
1721 audio_file_t *file; 1719 audio_file_t *file;
1722 int bound; 1720 int bound;
1723 int error; 1721 int error;
1724 dev_t dev; 1722 dev_t dev;
1725 1723
1726 KASSERT(fp->f_audioctx); 1724 KASSERT(fp->f_audioctx);
1727 file = fp->f_audioctx; 1725 file = fp->f_audioctx;
1728 dev = file->dev; 1726 dev = file->dev;
1729 error = 0; 1727 error = 0;
1730 1728
1731 /* 1729 /*
1732 * audioclose() must 1730 * audioclose() must
1733 * - unplug track from the trackmixer (and unplug anything from softc), 1731 * - unplug track from the trackmixer (and unplug anything from softc),
1734 * if sc exists. 1732 * if sc exists.
1735 * - free all memory objects, regardless of sc. 1733 * - free all memory objects, regardless of sc.
1736 */ 1734 */
1737 1735
1738 bound = curlwp_bind(); 1736 bound = curlwp_bind();
1739 sc = audio_sc_acquire_fromfile(file, &sc_ref); 1737 sc = audio_sc_acquire_fromfile(file, &sc_ref);
1740 if (sc) { 1738 if (sc) {
1741 switch (AUDIODEV(dev)) { 1739 switch (AUDIODEV(dev)) {
1742 case SOUND_DEVICE: 1740 case SOUND_DEVICE:
1743 case AUDIO_DEVICE: 1741 case AUDIO_DEVICE:
1744 error = audio_close(sc, file); 1742 error = audio_close(sc, file);
1745 break; 1743 break;
1746 case AUDIOCTL_DEVICE: 1744 case AUDIOCTL_DEVICE:
1747 error = 0; 1745 error = 0;
1748 break; 1746 break;
1749 case MIXER_DEVICE: 1747 case MIXER_DEVICE:
1750 error = mixer_close(sc, file); 1748 error = mixer_close(sc, file);
1751 break; 1749 break;
1752 default: 1750 default:
1753 error = ENXIO; 1751 error = ENXIO;
1754 break; 1752 break;
1755 } 1753 }
1756 1754
1757 audio_sc_release(sc, &sc_ref); 1755 audio_sc_release(sc, &sc_ref);
1758 } 1756 }
1759 curlwp_bindx(bound); 1757 curlwp_bindx(bound);
1760 1758
1761 /* Free memory objects anyway */ 1759 /* Free memory objects anyway */
1762 TRACEF(2, file, "free memory"); 1760 TRACEF(2, file, "free memory");
1763 if (file->ptrack) 1761 if (file->ptrack)
1764 audio_track_destroy(file->ptrack); 1762 audio_track_destroy(file->ptrack);
1765 if (file->rtrack) 1763 if (file->rtrack)
1766 audio_track_destroy(file->rtrack); 1764 audio_track_destroy(file->rtrack);
1767 kmem_free(file, sizeof(*file)); 1765 kmem_free(file, sizeof(*file));
1768 fp->f_audioctx = NULL; 1766 fp->f_audioctx = NULL;
1769 1767
1770 return error; 1768 return error;
1771} 1769}
1772 1770
1773static int 1771static int
1774audioread(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, 1772audioread(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
1775 int ioflag) 1773 int ioflag)
1776{ 1774{
1777 struct audio_softc *sc; 1775 struct audio_softc *sc;
1778 struct psref sc_ref; 1776 struct psref sc_ref;
1779 audio_file_t *file; 1777 audio_file_t *file;
1780 int bound; 1778 int bound;
1781 int error; 1779 int error;
1782 dev_t dev; 1780 dev_t dev;
1783 1781
1784 KASSERT(fp->f_audioctx); 1782 KASSERT(fp->f_audioctx);
1785 file = fp->f_audioctx; 1783 file = fp->f_audioctx;
1786 dev = file->dev; 1784 dev = file->dev;
1787 1785
1788 bound = curlwp_bind(); 1786 bound = curlwp_bind();
1789 sc = audio_sc_acquire_fromfile(file, &sc_ref); 1787 sc = audio_sc_acquire_fromfile(file, &sc_ref);
1790 if (sc == NULL) { 1788 if (sc == NULL) {
1791 error = EIO; 1789 error = EIO;
1792 goto done; 1790 goto done;
1793 } 1791 }
1794 1792
1795 if (fp->f_flag & O_NONBLOCK) 1793 if (fp->f_flag & O_NONBLOCK)
1796 ioflag |= IO_NDELAY; 1794 ioflag |= IO_NDELAY;
1797 1795
1798 switch (AUDIODEV(dev)) { 1796 switch (AUDIODEV(dev)) {
1799 case SOUND_DEVICE: 1797 case SOUND_DEVICE:
1800 case AUDIO_DEVICE: 1798 case AUDIO_DEVICE:
1801 error = audio_read(sc, uio, ioflag, file); 1799 error = audio_read(sc, uio, ioflag, file);
1802 break; 1800 break;
1803 case AUDIOCTL_DEVICE: 1801 case AUDIOCTL_DEVICE:
1804 case MIXER_DEVICE: 1802 case MIXER_DEVICE:
1805 error = ENODEV; 1803 error = ENODEV;
1806 break; 1804 break;
1807 default: 1805 default:
1808 error = ENXIO; 1806 error = ENXIO;
1809 break; 1807 break;
1810 } 1808 }
1811 1809
1812 audio_sc_release(sc, &sc_ref); 1810 audio_sc_release(sc, &sc_ref);
1813done: 1811done:
1814 curlwp_bindx(bound); 1812 curlwp_bindx(bound);
1815 return error; 1813 return error;
1816} 1814}
1817 1815
1818static int 1816static int
1819audiowrite(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, 1817audiowrite(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
1820 int ioflag) 1818 int ioflag)
1821{ 1819{
1822 struct audio_softc *sc; 1820 struct audio_softc *sc;
1823 struct psref sc_ref; 1821 struct psref sc_ref;
1824 audio_file_t *file; 1822 audio_file_t *file;
1825 int bound; 1823 int bound;
1826 int error; 1824 int error;
1827 dev_t dev; 1825 dev_t dev;
1828 1826
1829 KASSERT(fp->f_audioctx); 1827 KASSERT(fp->f_audioctx);
1830 file = fp->f_audioctx; 1828 file = fp->f_audioctx;
1831 dev = file->dev; 1829 dev = file->dev;
1832 1830
1833 bound = curlwp_bind(); 1831 bound = curlwp_bind();
1834 sc = audio_sc_acquire_fromfile(file, &sc_ref); 1832 sc = audio_sc_acquire_fromfile(file, &sc_ref);
1835 if (sc == NULL) { 1833 if (sc == NULL) {
1836 error = EIO; 1834 error = EIO;
1837 goto done; 1835 goto done;
1838 } 1836 }
1839 1837
1840 if (fp->f_flag & O_NONBLOCK) 1838 if (fp->f_flag & O_NONBLOCK)
1841 ioflag |= IO_NDELAY; 1839 ioflag |= IO_NDELAY;
1842 1840
1843 switch (AUDIODEV(dev)) { 1841 switch (AUDIODEV(dev)) {
1844 case SOUND_DEVICE: 1842 case SOUND_DEVICE:
1845 case AUDIO_DEVICE: 1843 case AUDIO_DEVICE:
1846 error = audio_write(sc, uio, ioflag, file); 1844 error = audio_write(sc, uio, ioflag, file);
1847 break; 1845 break;
1848 case AUDIOCTL_DEVICE: 1846 case AUDIOCTL_DEVICE:
1849 case MIXER_DEVICE: 1847 case MIXER_DEVICE:
1850 error = ENODEV; 1848 error = ENODEV;
1851 break; 1849 break;
1852 default: 1850 default:
1853 error = ENXIO; 1851 error = ENXIO;
1854 break; 1852 break;
1855 } 1853 }
1856 1854
1857 audio_sc_release(sc, &sc_ref); 1855 audio_sc_release(sc, &sc_ref);
1858done: 1856done:
1859 curlwp_bindx(bound); 1857 curlwp_bindx(bound);
1860 return error; 1858 return error;
1861} 1859}
1862 1860
1863static int 1861static int
1864audioioctl(struct file *fp, u_long cmd, void *addr) 1862audioioctl(struct file *fp, u_long cmd, void *addr)
1865{ 1863{
1866 struct audio_softc *sc; 1864 struct audio_softc *sc;
1867 struct psref sc_ref; 1865 struct psref sc_ref;
1868 audio_file_t *file; 1866 audio_file_t *file;
1869 struct lwp *l = curlwp; 1867 struct lwp *l = curlwp;
1870 int bound; 1868 int bound;
1871 int error; 1869 int error;
1872 dev_t dev; 1870 dev_t dev;
1873 1871
1874 KASSERT(fp->f_audioctx); 1872 KASSERT(fp->f_audioctx);
1875 file = fp->f_audioctx; 1873 file = fp->f_audioctx;
1876 dev = file->dev; 1874 dev = file->dev;
1877 1875
1878 bound = curlwp_bind(); 1876 bound = curlwp_bind();
1879 sc = audio_sc_acquire_fromfile(file, &sc_ref); 1877 sc = audio_sc_acquire_fromfile(file, &sc_ref);
1880 if (sc == NULL) { 1878 if (sc == NULL) {
1881 error = EIO; 1879 error = EIO;
1882 goto done; 1880 goto done;
1883 } 1881 }
1884 1882
1885 switch (AUDIODEV(dev)) { 1883 switch (AUDIODEV(dev)) {
1886 case SOUND_DEVICE: 1884 case SOUND_DEVICE:
1887 case AUDIO_DEVICE: 1885 case AUDIO_DEVICE:
1888 case AUDIOCTL_DEVICE: 1886 case AUDIOCTL_DEVICE:
1889 mutex_enter(sc->sc_lock); 1887 mutex_enter(sc->sc_lock);
1890 device_active(sc->sc_dev, DVA_SYSTEM); 1888 device_active(sc->sc_dev, DVA_SYSTEM);
1891 mutex_exit(sc->sc_lock); 1889 mutex_exit(sc->sc_lock);
1892 if (IOCGROUP(cmd) == IOCGROUP(AUDIO_MIXER_READ)) 1890 if (IOCGROUP(cmd) == IOCGROUP(AUDIO_MIXER_READ))
1893 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l); 1891 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l);
1894 else 1892 else
1895 error = audio_ioctl(dev, sc, cmd, addr, fp->f_flag, l, 1893 error = audio_ioctl(dev, sc, cmd, addr, fp->f_flag, l,
1896 file); 1894 file);
1897 break; 1895 break;
1898 case MIXER_DEVICE: 1896 case MIXER_DEVICE:
1899 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l); 1897 error = mixer_ioctl(sc, cmd, addr, fp->f_flag, l);
1900 break; 1898 break;
1901 default: 1899 default:
1902 error = ENXIO; 1900 error = ENXIO;
1903 break; 1901 break;
1904 } 1902 }
1905 1903
1906 audio_sc_release(sc, &sc_ref); 1904 audio_sc_release(sc, &sc_ref);
1907done: 1905done:
1908 curlwp_bindx(bound); 1906 curlwp_bindx(bound);
1909 return error; 1907 return error;
1910} 1908}
1911 1909
1912static int 1910static int
1913audiostat(struct file *fp, struct stat *st) 1911audiostat(struct file *fp, struct stat *st)
1914{ 1912{
1915 struct audio_softc *sc; 1913 struct audio_softc *sc;
1916 struct psref sc_ref; 1914 struct psref sc_ref;
1917 audio_file_t *file; 1915 audio_file_t *file;
1918 int bound; 1916 int bound;
1919 int error; 1917 int error;
1920 1918
1921 KASSERT(fp->f_audioctx); 1919 KASSERT(fp->f_audioctx);
1922 file = fp->f_audioctx; 1920 file = fp->f_audioctx;
1923 1921
1924 bound = curlwp_bind(); 1922 bound = curlwp_bind();
1925 sc = audio_sc_acquire_fromfile(file, &sc_ref); 1923 sc = audio_sc_acquire_fromfile(file, &sc_ref);
1926 if (sc == NULL) { 1924 if (sc == NULL) {
1927 error = EIO; 1925 error = EIO;
1928 goto done; 1926 goto done;
1929 } 1927 }
1930 1928
1931 error = 0; 1929 error = 0;
1932 memset(st, 0, sizeof(*st)); 1930 memset(st, 0, sizeof(*st));
1933 1931
1934 st->st_dev = file->dev; 1932 st->st_dev = file->dev;
1935 st->st_uid = kauth_cred_geteuid(fp->f_cred); 1933 st->st_uid = kauth_cred_geteuid(fp->f_cred);
1936 st->st_gid = kauth_cred_getegid(fp->f_cred); 1934 st->st_gid = kauth_cred_getegid(fp->f_cred);
1937 st->st_mode = S_IFCHR; 1935 st->st_mode = S_IFCHR;
1938 1936
1939 audio_sc_release(sc, &sc_ref); 1937 audio_sc_release(sc, &sc_ref);
1940done: 1938done:
1941 curlwp_bindx(bound); 1939 curlwp_bindx(bound);
1942 return error; 1940 return error;
1943} 1941}
1944 1942
1945static int 1943static int
1946audiopoll(struct file *fp, int events) 1944audiopoll(struct file *fp, int events)
1947{ 1945{
1948 struct audio_softc *sc; 1946 struct audio_softc *sc;
1949 struct psref sc_ref; 1947 struct psref sc_ref;
1950 audio_file_t *file; 1948 audio_file_t *file;
1951 struct lwp *l = curlwp; 1949 struct lwp *l = curlwp;
1952 int bound; 1950 int bound;
1953 int revents; 1951 int revents;
1954 dev_t dev; 1952 dev_t dev;
1955 1953
1956 KASSERT(fp->f_audioctx); 1954 KASSERT(fp->f_audioctx);
1957 file = fp->f_audioctx; 1955 file = fp->f_audioctx;
1958 dev = file->dev; 1956 dev = file->dev;
1959 1957
1960 bound = curlwp_bind(); 1958 bound = curlwp_bind();
1961 sc = audio_sc_acquire_fromfile(file, &sc_ref); 1959 sc = audio_sc_acquire_fromfile(file, &sc_ref);
1962 if (sc == NULL) { 1960 if (sc == NULL) {
1963 revents = POLLERR; 1961 revents = POLLERR;
1964 goto done; 1962 goto done;
1965 } 1963 }
1966 1964
1967 switch (AUDIODEV(dev)) { 1965 switch (AUDIODEV(dev)) {
1968 case SOUND_DEVICE: 1966 case SOUND_DEVICE:
1969 case AUDIO_DEVICE: 1967 case AUDIO_DEVICE:
1970 revents = audio_poll(sc, events, l, file); 1968 revents = audio_poll(sc, events, l, file);
1971 break; 1969 break;
1972 case AUDIOCTL_DEVICE: 1970 case AUDIOCTL_DEVICE:
1973 case MIXER_DEVICE: 1971 case MIXER_DEVICE:
1974 revents = 0; 1972 revents = 0;
1975 break; 1973 break;
1976 default: 1974 default:
1977 revents = POLLERR; 1975 revents = POLLERR;
1978 break; 1976 break;
1979 } 1977 }
1980 1978
1981 audio_sc_release(sc, &sc_ref); 1979 audio_sc_release(sc, &sc_ref);
1982done: 1980done:
1983 curlwp_bindx(bound); 1981 curlwp_bindx(bound);
1984 return revents; 1982 return revents;
1985} 1983}
1986 1984
1987static int 1985static int
1988audiokqfilter(struct file *fp, struct knote *kn) 1986audiokqfilter(struct file *fp, struct knote *kn)
1989{ 1987{
1990 struct audio_softc *sc; 1988 struct audio_softc *sc;
1991 struct psref sc_ref; 1989 struct psref sc_ref;
1992 audio_file_t *file; 1990 audio_file_t *file;
1993 dev_t dev; 1991 dev_t dev;
1994 int bound; 1992 int bound;
1995 int error; 1993 int error;
1996 1994
1997 KASSERT(fp->f_audioctx); 1995 KASSERT(fp->f_audioctx);
1998 file = fp->f_audioctx; 1996 file = fp->f_audioctx;
1999 dev = file->dev; 1997 dev = file->dev;
2000 1998
2001 bound = curlwp_bind(); 1999 bound = curlwp_bind();
2002 sc = audio_sc_acquire_fromfile(file, &sc_ref); 2000 sc = audio_sc_acquire_fromfile(file, &sc_ref);
2003 if (sc == NULL) { 2001 if (sc == NULL) {
2004 error = EIO; 2002 error = EIO;
2005 goto done; 2003 goto done;
2006 } 2004 }
2007 2005
2008 switch (AUDIODEV(dev)) { 2006 switch (AUDIODEV(dev)) {
2009 case SOUND_DEVICE: 2007 case SOUND_DEVICE:
2010 case AUDIO_DEVICE: 2008 case AUDIO_DEVICE:
2011 error = audio_kqfilter(sc, file, kn); 2009 error = audio_kqfilter(sc, file, kn);
2012 break; 2010 break;
2013 case AUDIOCTL_DEVICE: 2011 case AUDIOCTL_DEVICE:
2014 case MIXER_DEVICE: 2012 case MIXER_DEVICE:
2015 error = ENODEV; 2013 error = ENODEV;
2016 break; 2014 break;
2017 default: 2015 default:
2018 error = ENXIO; 2016 error = ENXIO;
2019 break; 2017 break;
2020 } 2018 }
2021 2019
2022 audio_sc_release(sc, &sc_ref); 2020 audio_sc_release(sc, &sc_ref);
2023done: 2021done:
2024 curlwp_bindx(bound); 2022 curlwp_bindx(bound);
2025 return error; 2023 return error;
2026} 2024}
2027 2025
2028static int 2026static int
2029audiommap(struct file *fp, off_t *offp, size_t len, int prot, int *flagsp, 2027audiommap(struct file *fp, off_t *offp, size_t len, int prot, int *flagsp,
2030 int *advicep, struct uvm_object **uobjp, int *maxprotp) 2028 int *advicep, struct uvm_object **uobjp, int *maxprotp)
2031{ 2029{
2032 struct audio_softc *sc; 2030 struct audio_softc *sc;
2033 struct psref sc_ref; 2031 struct psref sc_ref;
2034 audio_file_t *file; 2032 audio_file_t *file;
2035 dev_t dev; 2033 dev_t dev;
2036 int bound; 2034 int bound;
2037 int error; 2035 int error;
2038 2036
2039 KASSERT(fp->f_audioctx); 2037 KASSERT(fp->f_audioctx);
2040 file = fp->f_audioctx; 2038 file = fp->f_audioctx;
2041 dev = file->dev; 2039 dev = file->dev;
2042 2040
2043 bound = curlwp_bind(); 2041 bound = curlwp_bind();
2044 sc = audio_sc_acquire_fromfile(file, &sc_ref); 2042 sc = audio_sc_acquire_fromfile(file, &sc_ref);
2045 if (sc == NULL) { 2043 if (sc == NULL) {
2046 error = EIO; 2044 error = EIO;
2047 goto done; 2045 goto done;
2048 } 2046 }
2049 2047
2050 mutex_enter(sc->sc_lock); 2048 mutex_enter(sc->sc_lock);
2051 device_active(sc->sc_dev, DVA_SYSTEM); /* XXXJDM */ 2049 device_active(sc->sc_dev, DVA_SYSTEM); /* XXXJDM */
2052 mutex_exit(sc->sc_lock); 2050 mutex_exit(sc->sc_lock);
2053 2051
2054 switch (AUDIODEV(dev)) { 2052 switch (AUDIODEV(dev)) {
2055 case SOUND_DEVICE: 2053 case SOUND_DEVICE:
2056 case AUDIO_DEVICE: 2054 case AUDIO_DEVICE:
2057 error = audio_mmap(sc, offp, len, prot, flagsp, advicep, 2055 error = audio_mmap(sc, offp, len, prot, flagsp, advicep,
2058 uobjp, maxprotp, file); 2056 uobjp, maxprotp, file);
2059 break; 2057 break;
2060 case AUDIOCTL_DEVICE: 2058 case AUDIOCTL_DEVICE:
2061 case MIXER_DEVICE: 2059 case MIXER_DEVICE:
2062 default: 2060 default:
2063 error = ENOTSUP; 2061 error = ENOTSUP;
2064 break; 2062 break;
2065 } 2063 }
2066 2064
2067 audio_sc_release(sc, &sc_ref); 2065 audio_sc_release(sc, &sc_ref);
2068done: 2066done:
2069 curlwp_bindx(bound); 2067 curlwp_bindx(bound);
2070 return error; 2068 return error;
2071} 2069}
2072 2070
2073 2071
2074/* Exported interfaces for audiobell. */ 2072/* Exported interfaces for audiobell. */
2075 2073
2076/* 2074/*
2077 * Open for audiobell. 2075 * Open for audiobell.
2078 * It stores allocated file to *filep. 2076 * It stores allocated file to *filep.
2079 * If successful returns 0, otherwise errno. 2077 * If successful returns 0, otherwise errno.
2080 */ 2078 */
2081int 2079int
2082audiobellopen(dev_t dev, audio_file_t **filep) 2080audiobellopen(dev_t dev, audio_file_t **filep)
2083{ 2081{
2084 struct audio_softc *sc; 2082 struct audio_softc *sc;
2085 struct psref sc_ref; 2083 struct psref sc_ref;
2086 int bound; 2084 int bound;
2087 int error; 2085 int error;
2088 2086
2089 /* Find the device */ 2087 /* Find the device */
2090 sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev)); 2088 sc = device_lookup_private(&audio_cd, AUDIOUNIT(dev));
2091 if (sc == NULL || sc->hw_if == NULL) 2089 if (sc == NULL || sc->hw_if == NULL)
2092 return ENXIO; 2090 return ENXIO;
2093 2091
2094 bound = curlwp_bind(); 2092 bound = curlwp_bind();
2095 audio_sc_acquire_foropen(sc, &sc_ref); 2093 audio_sc_acquire_foropen(sc, &sc_ref);
2096 2094
2097 error = audio_exlock_enter(sc); 2095 error = audio_exlock_enter(sc);
2098 if (error) 2096 if (error)
2099 goto done; 2097 goto done;
2100 2098
2101 device_active(sc->sc_dev, DVA_SYSTEM); 2099 device_active(sc->sc_dev, DVA_SYSTEM);
2102 error = audio_open(dev, sc, FWRITE, 0, curlwp, filep); 2100 error = audio_open(dev, sc, FWRITE, 0, curlwp, filep);
2103 2101
2104 audio_exlock_exit(sc); 2102 audio_exlock_exit(sc);
2105done: 2103done:
2106 audio_sc_release(sc, &sc_ref); 2104 audio_sc_release(sc, &sc_ref);
2107 curlwp_bindx(bound); 2105 curlwp_bindx(bound);
2108 return error; 2106 return error;
2109} 2107}
2110 2108
2111/* Close for audiobell */ 2109/* Close for audiobell */
2112int 2110int
2113audiobellclose(audio_file_t *file) 2111audiobellclose(audio_file_t *file)
2114{ 2112{
2115 struct audio_softc *sc; 2113 struct audio_softc *sc;
2116 struct psref sc_ref; 2114 struct psref sc_ref;
2117 int bound; 2115 int bound;
2118 int error; 2116 int error;
2119 2117
2120 error = 0; 2118 error = 0;
2121 /* 2119 /*
2122 * audiobellclose() must 2120 * audiobellclose() must
2123 * - unplug track from the trackmixer if sc exist. 2121 * - unplug track from the trackmixer if sc exist.
2124 * - free all memory objects, regardless of sc. 2122 * - free all memory objects, regardless of sc.
2125 */ 2123 */
2126 bound = curlwp_bind(); 2124 bound = curlwp_bind();
2127 sc = audio_sc_acquire_fromfile(file, &sc_ref); 2125 sc = audio_sc_acquire_fromfile(file, &sc_ref);
2128 if (sc) { 2126 if (sc) {
2129 error = audio_close(sc, file); 2127 error = audio_close(sc, file);
2130 audio_sc_release(sc, &sc_ref); 2128 audio_sc_release(sc, &sc_ref);
2131 } 2129 }
2132 curlwp_bindx(bound); 2130 curlwp_bindx(bound);
2133 2131
2134 /* Free memory objects anyway */ 2132 /* Free memory objects anyway */
2135 KASSERT(file->ptrack); 2133 KASSERT(file->ptrack);
2136 audio_track_destroy(file->ptrack); 2134 audio_track_destroy(file->ptrack);
2137 KASSERT(file->rtrack == NULL); 2135 KASSERT(file->rtrack == NULL);
2138 kmem_free(file, sizeof(*file)); 2136 kmem_free(file, sizeof(*file));
2139 return error; 2137 return error;
2140} 2138}
2141 2139
2142/* Set sample rate for audiobell */ 2140/* Set sample rate for audiobell */
2143int 2141int
2144audiobellsetrate(audio_file_t *file, u_int sample_rate) 2142audiobellsetrate(audio_file_t *file, u_int sample_rate)
2145{ 2143{
2146 struct audio_softc *sc; 2144 struct audio_softc *sc;
2147 struct psref sc_ref; 2145 struct psref sc_ref;
2148 struct audio_info ai; 2146 struct audio_info ai;
2149 int bound; 2147 int bound;
2150 int error; 2148 int error;
2151 2149
2152 bound = curlwp_bind(); 2150 bound = curlwp_bind();
2153 sc = audio_sc_acquire_fromfile(file, &sc_ref); 2151 sc = audio_sc_acquire_fromfile(file, &sc_ref);
2154 if (sc == NULL) { 2152 if (sc == NULL) {
2155 error = EIO; 2153 error = EIO;
2156 goto done1; 2154 goto done1;
2157 } 2155 }
2158 2156
2159 AUDIO_INITINFO(&ai); 2157 AUDIO_INITINFO(&ai);
2160 ai.play.sample_rate = sample_rate; 2158 ai.play.sample_rate = sample_rate;
2161 2159
2162 error = audio_exlock_enter(sc); 2160 error = audio_exlock_enter(sc);
2163 if (error) 2161 if (error)
2164 goto done2; 2162 goto done2;
2165 error = audio_file_setinfo(sc, file, &ai); 2163 error = audio_file_setinfo(sc, file, &ai);
2166 audio_exlock_exit(sc); 2164 audio_exlock_exit(sc);
2167 2165
2168done2: 2166done2:
2169 audio_sc_release(sc, &sc_ref); 2167 audio_sc_release(sc, &sc_ref);
2170done1: 2168done1:
2171 curlwp_bindx(bound); 2169 curlwp_bindx(bound);
2172 return error; 2170 return error;
2173} 2171}
2174 2172
2175/* Playback for audiobell */ 2173/* Playback for audiobell */
2176int 2174int
2177audiobellwrite(audio_file_t *file, struct uio *uio) 2175audiobellwrite(audio_file_t *file, struct uio *uio)
2178{ 2176{
2179 struct audio_softc *sc; 2177 struct audio_softc *sc;
2180 struct psref sc_ref; 2178 struct psref sc_ref;
2181 int bound; 2179 int bound;
2182 int error; 2180 int error;
2183 2181
2184 bound = curlwp_bind(); 2182 bound = curlwp_bind();
2185 sc = audio_sc_acquire_fromfile(file, &sc_ref); 2183 sc = audio_sc_acquire_fromfile(file, &sc_ref);
2186 if (sc == NULL) { 2184 if (sc == NULL) {
2187 error = EIO; 2185 error = EIO;
2188 goto done; 2186 goto done;
2189 } 2187 }
2190 2188
2191 error = audio_write(sc, uio, 0, file); 2189 error = audio_write(sc, uio, 0, file);
2192 2190
2193 audio_sc_release(sc, &sc_ref); 2191 audio_sc_release(sc, &sc_ref);
2194done: 2192done:
2195 curlwp_bindx(bound); 2193 curlwp_bindx(bound);
2196 return error; 2194 return error;
2197} 2195}
2198 2196
2199 2197
2200/* 2198/*
2201 * Audio driver 2199 * Audio driver
2202 */ 2200 */
2203 2201
2204/* 2202/*
2205 * Must be called with sc_exlock held and without sc_lock held. 2203 * Must be called with sc_exlock held and without sc_lock held.
2206 */ 2204 */
2207int 2205int
2208audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt, 2206audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt,
2209 struct lwp *l, audio_file_t **bellfile) 2207 struct lwp *l, audio_file_t **bellfile)
2210{ 2208{
2211 struct audio_info ai; 2209 struct audio_info ai;
2212 struct file *fp; 2210 struct file *fp;
2213 audio_file_t *af; 2211 audio_file_t *af;
2214 audio_ring_t *hwbuf; 2212 audio_ring_t *hwbuf;
2215 bool fullduplex; 2213 bool fullduplex;
2216 bool cred_held; 2214 bool cred_held;
2217 bool hw_opened; 2215 bool hw_opened;
2218 bool rmixer_started; 2216 bool rmixer_started;
2219 bool inserted; 2217 bool inserted;
2220 int fd; 2218 int fd;
2221 int error; 2219 int error;
2222 2220
2223 KASSERT(sc->sc_exlock); 2221 KASSERT(sc->sc_exlock);
2224 2222
2225 TRACE(1, "%sdev=%s flags=0x%x po=%d ro=%d", 2223 TRACE(1, "%sdev=%s flags=0x%x po=%d ro=%d",
2226 (audiodebug >= 3) ? "start " : "", 2224 (audiodebug >= 3) ? "start " : "",
2227 ISDEVSOUND(dev) ? "sound" : "audio", 2225 ISDEVSOUND(dev) ? "sound" : "audio",
2228 flags, sc->sc_popens, sc->sc_ropens); 2226 flags, sc->sc_popens, sc->sc_ropens);
2229 2227
2230 fp = NULL; 2228 fp = NULL;
2231 cred_held = false; 2229 cred_held = false;
2232 hw_opened = false; 2230 hw_opened = false;
2233 rmixer_started = false; 2231 rmixer_started = false;
2234 inserted = false; 2232 inserted = false;
2235 2233
2236 af = kmem_zalloc(sizeof(audio_file_t), KM_SLEEP); 2234 af = kmem_zalloc(sizeof(audio_file_t), KM_SLEEP);
2237 af->sc = sc; 2235 af->sc = sc;
2238 af->dev = dev; 2236 af->dev = dev;
2239 if ((flags & FWRITE) != 0 && audio_can_playback(sc)) 2237 if ((flags & FWRITE) != 0 && audio_can_playback(sc))
2240 af->mode |= AUMODE_PLAY | AUMODE_PLAY_ALL; 2238 af->mode |= AUMODE_PLAY | AUMODE_PLAY_ALL;
2241 if ((flags & FREAD) != 0 && audio_can_capture(sc)) 2239 if ((flags & FREAD) != 0 && audio_can_capture(sc))
2242 af->mode |= AUMODE_RECORD; 2240 af->mode |= AUMODE_RECORD;
2243 if (af->mode == 0) { 2241 if (af->mode == 0) {
2244 error = ENXIO; 2242 error = ENXIO;
2245 goto bad; 2243 goto bad;
2246 } 2244 }
2247 2245
2248 fullduplex = (sc->sc_props & AUDIO_PROP_FULLDUPLEX); 2246 fullduplex = (sc->sc_props & AUDIO_PROP_FULLDUPLEX);
2249 2247
2250 /* 2248 /*
2251 * On half duplex hardware, 2249 * On half duplex hardware,
2252 * 1. if mode is (PLAY | REC), let mode PLAY. 2250 * 1. if mode is (PLAY | REC), let mode PLAY.
2253 * 2. if mode is PLAY, let mode PLAY if no rec tracks, otherwise error. 2251 * 2. if mode is PLAY, let mode PLAY if no rec tracks, otherwise error.
2254 * 3. if mode is REC, let mode REC if no play tracks, otherwise error. 2252 * 3. if mode is REC, let mode REC if no play tracks, otherwise error.
2255 */ 2253 */
2256 if (fullduplex == false) { 2254 if (fullduplex == false) {
2257 if ((af->mode & AUMODE_PLAY)) { 2255 if ((af->mode & AUMODE_PLAY)) {
2258 if (sc->sc_ropens != 0) { 2256 if (sc->sc_ropens != 0) {
2259 TRACE(1, "record track already exists"); 2257 TRACE(1, "record track already exists");
2260 error = ENODEV; 2258 error = ENODEV;
2261 goto bad; 2259 goto bad;
2262 } 2260 }
2263 /* Play takes precedence */ 2261 /* Play takes precedence */
2264 af->mode &= ~AUMODE_RECORD; 2262 af->mode &= ~AUMODE_RECORD;
2265 } 2263 }
2266 if ((af->mode & AUMODE_RECORD)) { 2264 if ((af->mode & AUMODE_RECORD)) {
2267 if (sc->sc_popens != 0) { 2265 if (sc->sc_popens != 0) {
2268 TRACE(1, "play track already exists"); 2266 TRACE(1, "play track already exists");
2269 error = ENODEV; 2267 error = ENODEV;
2270 goto bad; 2268 goto bad;
2271 } 2269 }
2272 } 2270 }
2273 } 2271 }
2274 2272
2275 /* Create tracks */ 2273 /* Create tracks */
2276 if ((af->mode & AUMODE_PLAY)) 2274 if ((af->mode & AUMODE_PLAY))
2277 af->ptrack = audio_track_create(sc, sc->sc_pmixer); 2275 af->ptrack = audio_track_create(sc, sc->sc_pmixer);
2278 if ((af->mode & AUMODE_RECORD)) 2276 if ((af->mode & AUMODE_RECORD))
2279 af->rtrack = audio_track_create(sc, sc->sc_rmixer); 2277 af->rtrack = audio_track_create(sc, sc->sc_rmixer);
2280 2278
2281 /* Set parameters */ 2279 /* Set parameters */
2282 AUDIO_INITINFO(&ai); 2280 AUDIO_INITINFO(&ai);
2283 if (bellfile) { 2281 if (bellfile) {
2284 /* If audiobell, only sample_rate will be set later. */ 2282 /* If audiobell, only sample_rate will be set later. */
2285 ai.play.sample_rate = audio_default.sample_rate; 2283 ai.play.sample_rate = audio_default.sample_rate;
2286 ai.play.encoding = AUDIO_ENCODING_SLINEAR_NE; 2284 ai.play.encoding = AUDIO_ENCODING_SLINEAR_NE;
2287 ai.play.channels = 1; 2285 ai.play.channels = 1;
2288 ai.play.precision = 16; 2286 ai.play.precision = 16;
2289 ai.play.pause = 0; 2287 ai.play.pause = 0;
2290 } else if (ISDEVAUDIO(dev)) { 2288 } else if (ISDEVAUDIO(dev)) {
2291 /* If /dev/audio, initialize everytime. */ 2289 /* If /dev/audio, initialize everytime. */
2292 ai.play.sample_rate = audio_default.sample_rate; 2290 ai.play.sample_rate = audio_default.sample_rate;
2293 ai.play.encoding = audio_default.encoding; 2291 ai.play.encoding = audio_default.encoding;
2294 ai.play.channels = audio_default.channels; 2292 ai.play.channels = audio_default.channels;
2295 ai.play.precision = audio_default.precision; 2293 ai.play.precision = audio_default.precision;
2296 ai.play.pause = 0; 2294 ai.play.pause = 0;
2297 ai.record.sample_rate = audio_default.sample_rate; 2295 ai.record.sample_rate = audio_default.sample_rate;
2298 ai.record.encoding = audio_default.encoding; 2296 ai.record.encoding = audio_default.encoding;
2299 ai.record.channels = audio_default.channels; 2297 ai.record.channels = audio_default.channels;
2300 ai.record.precision = audio_default.precision; 2298 ai.record.precision = audio_default.precision;
2301 ai.record.pause = 0; 2299 ai.record.pause = 0;
2302 } else { 2300 } else {
2303 /* If /dev/sound, take over the previous parameters. */ 2301 /* If /dev/sound, take over the previous parameters. */
2304 ai.play.sample_rate = sc->sc_sound_pparams.sample_rate; 2302 ai.play.sample_rate = sc->sc_sound_pparams.sample_rate;
2305 ai.play.encoding = sc->sc_sound_pparams.encoding; 2303 ai.play.encoding = sc->sc_sound_pparams.encoding;
2306 ai.play.channels = sc->sc_sound_pparams.channels; 2304 ai.play.channels = sc->sc_sound_pparams.channels;
2307 ai.play.precision = sc->sc_sound_pparams.precision; 2305 ai.play.precision = sc->sc_sound_pparams.precision;
2308 ai.play.pause = sc->sc_sound_ppause; 2306 ai.play.pause = sc->sc_sound_ppause;
2309 ai.record.sample_rate = sc->sc_sound_rparams.sample_rate; 2307 ai.record.sample_rate = sc->sc_sound_rparams.sample_rate;
2310 ai.record.encoding = sc->sc_sound_rparams.encoding; 2308 ai.record.encoding = sc->sc_sound_rparams.encoding;
2311 ai.record.channels = sc->sc_sound_rparams.channels; 2309 ai.record.channels = sc->sc_sound_rparams.channels;
2312 ai.record.precision = sc->sc_sound_rparams.precision; 2310 ai.record.precision = sc->sc_sound_rparams.precision;
2313 ai.record.pause = sc->sc_sound_rpause; 2311 ai.record.pause = sc->sc_sound_rpause;
2314 } 2312 }
2315 error = audio_file_setinfo(sc, af, &ai); 2313 error = audio_file_setinfo(sc, af, &ai);
2316 if (error) 2314 if (error)
2317 goto bad; 2315 goto bad;
2318 2316
2319 if (sc->sc_popens + sc->sc_ropens == 0) { 2317 if (sc->sc_popens + sc->sc_ropens == 0) {
2320 /* First open */ 2318 /* First open */
2321 2319
2322 sc->sc_cred = kauth_cred_get(); 2320 sc->sc_cred = kauth_cred_get();
2323 kauth_cred_hold(sc->sc_cred); 2321 kauth_cred_hold(sc->sc_cred);
2324 cred_held = true; 2322 cred_held = true;
2325 2323
2326 if (sc->hw_if->open) { 2324 if (sc->hw_if->open) {
2327 int hwflags; 2325 int hwflags;
2328 2326
2329 /* 2327 /*
2330 * Call hw_if->open() only at first open of 2328 * Call hw_if->open() only at first open of
2331 * combination of playback and recording. 2329 * combination of playback and recording.
2332 * On full duplex hardware, the flags passed to 2330 * On full duplex hardware, the flags passed to
2333 * hw_if->open() is always (FREAD | FWRITE) 2331 * hw_if->open() is always (FREAD | FWRITE)
2334 * regardless of this open()'s flags. 2332 * regardless of this open()'s flags.
2335 * see also dev/isa/aria.c 2333 * see also dev/isa/aria.c
2336 * On half duplex hardware, the flags passed to 2334 * On half duplex hardware, the flags passed to
2337 * hw_if->open() is either FREAD or FWRITE. 2335 * hw_if->open() is either FREAD or FWRITE.
2338 * see also arch/evbarm/mini2440/audio_mini2440.c 2336 * see also arch/evbarm/mini2440/audio_mini2440.c
2339 */ 2337 */
2340 if (fullduplex) { 2338 if (fullduplex) {
2341 hwflags = FREAD | FWRITE; 2339 hwflags = FREAD | FWRITE;
2342 } else { 2340 } else {
2343 /* Construct hwflags from af->mode. */ 2341 /* Construct hwflags from af->mode. */
2344 hwflags = 0; 2342 hwflags = 0;
2345 if ((af->mode & AUMODE_PLAY) != 0) 2343 if ((af->mode & AUMODE_PLAY) != 0)
2346 hwflags |= FWRITE; 2344 hwflags |= FWRITE;
2347 if ((af->mode & AUMODE_RECORD) != 0) 2345 if ((af->mode & AUMODE_RECORD) != 0)
2348 hwflags |= FREAD; 2346 hwflags |= FREAD;
2349 } 2347 }
2350 2348
2351 mutex_enter(sc->sc_lock); 2349 mutex_enter(sc->sc_lock);
2352 mutex_enter(sc->sc_intr_lock); 2350 mutex_enter(sc->sc_intr_lock);
2353 error = sc->hw_if->open(sc->hw_hdl, hwflags); 2351 error = sc->hw_if->open(sc->hw_hdl, hwflags);
2354 mutex_exit(sc->sc_intr_lock); 2352 mutex_exit(sc->sc_intr_lock);
2355 mutex_exit(sc->sc_lock); 2353 mutex_exit(sc->sc_lock);
2356 if (error) 2354 if (error)
2357 goto bad; 2355 goto bad;
2358 } 2356 }
2359 /* 2357 /*
2360 * Regardless of whether we called hw_if->open (whether 2358 * Regardless of whether we called hw_if->open (whether
2361 * hw_if->open exists) or not, we move to the Opened phase 2359 * hw_if->open exists) or not, we move to the Opened phase
2362 * here. Therefore from this point, we have to call 2360 * here. Therefore from this point, we have to call
2363 * hw_if->close (if exists) whenever abort. 2361 * hw_if->close (if exists) whenever abort.
2364 * Note that both of hw_if->{open,close} are optional. 2362 * Note that both of hw_if->{open,close} are optional.
2365 */ 2363 */
2366 hw_opened = true; 2364 hw_opened = true;
2367 2365
2368 /* 2366 /*
2369 * Set speaker mode when a half duplex. 2367 * Set speaker mode when a half duplex.
2370 * XXX I'm not sure this is correct. 2368 * XXX I'm not sure this is correct.
2371 */ 2369 */
2372 if (1/*XXX*/) { 2370 if (1/*XXX*/) {
2373 if (sc->hw_if->speaker_ctl) { 2371 if (sc->hw_if->speaker_ctl) {
2374 int on; 2372 int on;
2375 if (af->ptrack) { 2373 if (af->ptrack) {
2376 on = 1; 2374 on = 1;
2377 } else { 2375 } else {
2378 on = 0; 2376 on = 0;
2379 } 2377 }
2380 mutex_enter(sc->sc_lock); 2378 mutex_enter(sc->sc_lock);
2381 mutex_enter(sc->sc_intr_lock); 2379 mutex_enter(sc->sc_intr_lock);
2382 error = sc->hw_if->speaker_ctl(sc->hw_hdl, on); 2380 error = sc->hw_if->speaker_ctl(sc->hw_hdl, on);
2383 mutex_exit(sc->sc_intr_lock); 2381 mutex_exit(sc->sc_intr_lock);
2384 mutex_exit(sc->sc_lock); 2382 mutex_exit(sc->sc_lock);
2385 if (error) 2383 if (error)
2386 goto bad; 2384 goto bad;
2387 } 2385 }
2388 } 2386 }
2389 } else if (sc->sc_multiuser == false) { 2387 } else if (sc->sc_multiuser == false) {
2390 uid_t euid = kauth_cred_geteuid(kauth_cred_get()); 2388 uid_t euid = kauth_cred_geteuid(kauth_cred_get());
2391 if (euid != 0 && euid != kauth_cred_geteuid(sc->sc_cred)) { 2389 if (euid != 0 && euid != kauth_cred_geteuid(sc->sc_cred)) {
2392 error = EPERM; 2390 error = EPERM;
2393 goto bad; 2391 goto bad;
2394 } 2392 }
2395 } 2393 }
2396 2394
2397 /* Call init_output if this is the first playback open. */ 2395 /* Call init_output if this is the first playback open. */
2398 if (af->ptrack && sc->sc_popens == 0) { 2396 if (af->ptrack && sc->sc_popens == 0) {
2399 if (sc->hw_if->init_output) { 2397 if (sc->hw_if->init_output) {
2400 hwbuf = &sc->sc_pmixer->hwbuf; 2398 hwbuf = &sc->sc_pmixer->hwbuf;
2401 mutex_enter(sc->sc_lock); 2399 mutex_enter(sc->sc_lock);
2402 mutex_enter(sc->sc_intr_lock); 2400 mutex_enter(sc->sc_intr_lock);
2403 error = sc->hw_if->init_output(sc->hw_hdl, 2401 error = sc->hw_if->init_output(sc->hw_hdl,
2404 hwbuf->mem, 2402 hwbuf->mem,
2405 hwbuf->capacity * 2403 hwbuf->capacity *
2406 hwbuf->fmt.channels * hwbuf->fmt.stride / NBBY); 2404 hwbuf->fmt.channels * hwbuf->fmt.stride / NBBY);
2407 mutex_exit(sc->sc_intr_lock); 2405 mutex_exit(sc->sc_intr_lock);
2408 mutex_exit(sc->sc_lock); 2406 mutex_exit(sc->sc_lock);
2409 if (error) 2407 if (error)
2410 goto bad; 2408 goto bad;
2411 } 2409 }
2412 } 2410 }
2413 /* 2411 /*
2414 * Call init_input and start rmixer, if this is the first recording 2412 * Call init_input and start rmixer, if this is the first recording
2415 * open. See pause consideration notes. 2413 * open. See pause consideration notes.
2416 */ 2414 */
2417 if (af->rtrack && sc->sc_ropens == 0) { 2415 if (af->rtrack && sc->sc_ropens == 0) {
2418 if (sc->hw_if->init_input) { 2416 if (sc->hw_if->init_input) {
2419 hwbuf = &sc->sc_rmixer->hwbuf; 2417 hwbuf = &sc->sc_rmixer->hwbuf;