Sat Jun 10 06:05:48 2017 UTC ()
Pull up following revision(s) (requested by nat in ticket #20):
	sys/dev/pad/pad.c: revisions 1.33-1.35
	sys/dev/pad/padvar.h: revision 1.9
Express BYTESTOSLEEP as an 64 bit integer.
Use BYTESTOSLEEP in expresson of BYTES_PER_SEC.
--
sc_bytes_count needs to be set in pad_audio_open not pad_open.
--
Simplification of rate limiter.  It now works uni/multiprocessor.
--
pad blocksize 1024 -> 8192.  Helps when sleeping in rate limiter.


(snj)
diff -r1.32 -r1.32.2.1 src/sys/dev/pad/pad.c
diff -r1.8 -r1.8.2.1 src/sys/dev/pad/padvar.h

cvs diff -r1.32 -r1.32.2.1 src/sys/dev/pad/pad.c (switch to unified diff)

--- src/sys/dev/pad/pad.c 2017/06/01 09:44:30 1.32
+++ src/sys/dev/pad/pad.c 2017/06/10 06:05:47 1.32.2.1
@@ -1,823 +1,816 @@ @@ -1,823 +1,816 @@
1/* $NetBSD: pad.c,v 1.32 2017/06/01 09:44:30 pgoyette Exp $ */ 1/* $NetBSD: pad.c,v 1.32.2.1 2017/06/10 06:05:47 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.32 2017/06/01 09:44:30 pgoyette Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.32.2.1 2017/06/10 06:05:47 snj Exp $");
31 31
32#include <sys/types.h> 32#include <sys/types.h>
33#include <sys/param.h> 33#include <sys/param.h>
34#include <sys/conf.h> 34#include <sys/conf.h>
35#include <sys/buf.h> 35#include <sys/buf.h>
36#include <sys/kmem.h> 36#include <sys/kmem.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/device.h> 38#include <sys/device.h>
39#include <sys/proc.h> 39#include <sys/proc.h>
40#include <sys/condvar.h> 40#include <sys/condvar.h>
41#include <sys/select.h> 41#include <sys/select.h>
42#include <sys/audioio.h> 42#include <sys/audioio.h>
43#include <sys/vnode.h> 43#include <sys/vnode.h>
44#include <sys/module.h> 44#include <sys/module.h>
45#include <sys/atomic.h> 45#include <sys/atomic.h>
46#include <sys/time.h> 46#include <sys/time.h>
47 47
48#include <dev/audio_if.h> 48#include <dev/audio_if.h>
49#include <dev/audiovar.h> 49#include <dev/audiovar.h>
50#include <dev/auconv.h> 50#include <dev/auconv.h>
51#include <dev/auvolconv.h> 51#include <dev/auvolconv.h>
52 52
53#include <dev/pad/padvar.h> 53#include <dev/pad/padvar.h>
54 54
55#define PADUNIT(x) minor(x) 55#define PADUNIT(x) minor(x)
56 56
57extern struct cfdriver pad_cd; 57extern struct cfdriver pad_cd;
58 58
59typedef struct pad_block { 59typedef struct pad_block {
60 uint8_t *pb_ptr; 60 uint8_t *pb_ptr;
61 int pb_len; 61 int pb_len;
62} pad_block_t; 62} pad_block_t;
63 63
64enum { 64enum {
65 PAD_OUTPUT_CLASS, 65 PAD_OUTPUT_CLASS,
66 PAD_INPUT_CLASS, 66 PAD_INPUT_CLASS,
67 PAD_OUTPUT_MASTER_VOLUME, 67 PAD_OUTPUT_MASTER_VOLUME,
68 PAD_INPUT_DAC_VOLUME, 68 PAD_INPUT_DAC_VOLUME,
69 PAD_ENUM_LAST, 69 PAD_ENUM_LAST,
70}; 70};
71 71
72static int pad_match(device_t, cfdata_t, void *); 72static int pad_match(device_t, cfdata_t, void *);
73static void pad_attach(device_t, device_t, void *); 73static void pad_attach(device_t, device_t, void *);
74static int pad_detach(device_t, int); 74static int pad_detach(device_t, int);
75static void pad_childdet(device_t, device_t); 75static void pad_childdet(device_t, device_t);
76 76
77static int pad_audio_open(void *, int); 77static int pad_audio_open(void *, int);
78static int pad_query_encoding(void *, struct audio_encoding *); 78static int pad_query_encoding(void *, struct audio_encoding *);
79static int pad_set_params(void *, int, int, 79static int pad_set_params(void *, int, int,
80 audio_params_t *, audio_params_t *, 80 audio_params_t *, audio_params_t *,
81 stream_filter_list_t *, stream_filter_list_t *); 81 stream_filter_list_t *, stream_filter_list_t *);
82static int pad_start_output(void *, void *, int, 82static int pad_start_output(void *, void *, int,
83 void (*)(void *), void *); 83 void (*)(void *), void *);
84static int pad_start_input(void *, void *, int, 84static int pad_start_input(void *, void *, int,
85 void (*)(void *), void *); 85 void (*)(void *), void *);
86static int pad_halt_output(void *); 86static int pad_halt_output(void *);
87static int pad_halt_input(void *); 87static int pad_halt_input(void *);
88static int pad_getdev(void *, struct audio_device *); 88static int pad_getdev(void *, struct audio_device *);
89static int pad_set_port(void *, mixer_ctrl_t *); 89static int pad_set_port(void *, mixer_ctrl_t *);
90static int pad_get_port(void *, mixer_ctrl_t *); 90static int pad_get_port(void *, mixer_ctrl_t *);
91static int pad_query_devinfo(void *, mixer_devinfo_t *); 91static int pad_query_devinfo(void *, mixer_devinfo_t *);
92static int pad_get_props(void *); 92static int pad_get_props(void *);
93static int pad_round_blocksize(void *, int, int, const audio_params_t *); 93static int pad_round_blocksize(void *, int, int, const audio_params_t *);
94static void pad_get_locks(void *, kmutex_t **, kmutex_t **); 94static void pad_get_locks(void *, kmutex_t **, kmutex_t **);
95 95
96static stream_filter_t *pad_swvol_filter_le(struct audio_softc *, 96static stream_filter_t *pad_swvol_filter_le(struct audio_softc *,
97 const audio_params_t *, const audio_params_t *); 97 const audio_params_t *, const audio_params_t *);
98static stream_filter_t *pad_swvol_filter_be(struct audio_softc *, 98static stream_filter_t *pad_swvol_filter_be(struct audio_softc *,
99 const audio_params_t *, const audio_params_t *); 99 const audio_params_t *, const audio_params_t *);
100static void pad_swvol_dtor(stream_filter_t *); 100static void pad_swvol_dtor(stream_filter_t *);
101 101
102static bool pad_is_attached; /* Do we have an audio* child? */ 102static bool pad_is_attached; /* Do we have an audio* child? */
103 103
104static const struct audio_hw_if pad_hw_if = { 104static const struct audio_hw_if pad_hw_if = {
105 .open = pad_audio_open, 105 .open = pad_audio_open,
106 .query_encoding = pad_query_encoding, 106 .query_encoding = pad_query_encoding,
107 .set_params = pad_set_params, 107 .set_params = pad_set_params,
108 .start_output = pad_start_output, 108 .start_output = pad_start_output,
109 .start_input = pad_start_input, 109 .start_input = pad_start_input,
110 .halt_output = pad_halt_output, 110 .halt_output = pad_halt_output,
111 .halt_input = pad_halt_input, 111 .halt_input = pad_halt_input,
112 .getdev = pad_getdev, 112 .getdev = pad_getdev,
113 .set_port = pad_set_port, 113 .set_port = pad_set_port,
114 .get_port = pad_get_port, 114 .get_port = pad_get_port,
115 .query_devinfo = pad_query_devinfo, 115 .query_devinfo = pad_query_devinfo,
116 .get_props = pad_get_props, 116 .get_props = pad_get_props,
117 .round_blocksize = pad_round_blocksize, 117 .round_blocksize = pad_round_blocksize,
118 .get_locks = pad_get_locks, 118 .get_locks = pad_get_locks,
119}; 119};
120 120
121#define PAD_NFORMATS 1 121#define PAD_NFORMATS 1
122static const struct audio_format pad_formats[PAD_NFORMATS] = { 122static const struct audio_format pad_formats[PAD_NFORMATS] = {
123 { NULL, AUMODE_PLAY|AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16, 123 { NULL, AUMODE_PLAY|AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16,
124 2, AUFMT_STEREO, 1, { 44100 } }, 124 2, AUFMT_STEREO, 1, { 44100 } },
125}; 125};
126 126
127extern void padattach(int); 127extern void padattach(int);
128 128
129static int pad_add_block(pad_softc_t *, uint8_t *, int); 129static int pad_add_block(pad_softc_t *, uint8_t *, int);
130static int pad_get_block(pad_softc_t *, pad_block_t *, int); 130static int pad_get_block(pad_softc_t *, pad_block_t *, int);
131 131
132dev_type_open(pad_open); 132dev_type_open(pad_open);
133dev_type_close(pad_close); 133dev_type_close(pad_close);
134dev_type_read(pad_read); 134dev_type_read(pad_read);
135 135
136const struct cdevsw pad_cdevsw = { 136const struct cdevsw pad_cdevsw = {
137 .d_open = pad_open, 137 .d_open = pad_open,
138 .d_close = pad_close, 138 .d_close = pad_close,
139 .d_read = pad_read, 139 .d_read = pad_read,
140 .d_write = nowrite, 140 .d_write = nowrite,
141 .d_ioctl = noioctl, 141 .d_ioctl = noioctl,
142 .d_stop = nostop, 142 .d_stop = nostop,
143 .d_tty = notty, 143 .d_tty = notty,
144 .d_poll = nopoll, 144 .d_poll = nopoll,
145 .d_mmap = nommap, 145 .d_mmap = nommap,
146 .d_kqfilter = nokqfilter, 146 .d_kqfilter = nokqfilter,
147 .d_discard = nodiscard, 147 .d_discard = nodiscard,
148 .d_flag = D_OTHER | D_MPSAFE, 148 .d_flag = D_OTHER | D_MPSAFE,
149}; 149};
150 150
151CFATTACH_DECL2_NEW(pad, sizeof(pad_softc_t), pad_match, pad_attach, pad_detach, 151CFATTACH_DECL2_NEW(pad, sizeof(pad_softc_t), pad_match, pad_attach, pad_detach,
152 NULL, NULL, pad_childdet); 152 NULL, NULL, pad_childdet);
153 153
154void 154void
155padattach(int n) 155padattach(int n)
156{ 156{
157 int i, err; 157 int i, err;
158 cfdata_t cf; 158 cfdata_t cf;
159 159
160 aprint_debug("pad: requested %d units\n", n); 160 aprint_debug("pad: requested %d units\n", n);
161 161
162 err = config_cfattach_attach(pad_cd.cd_name, &pad_ca); 162 err = config_cfattach_attach(pad_cd.cd_name, &pad_ca);
163 if (err) { 163 if (err) {
164 aprint_error("%s: couldn't register cfattach: %d\n", 164 aprint_error("%s: couldn't register cfattach: %d\n",
165 pad_cd.cd_name, err); 165 pad_cd.cd_name, err);
166 config_cfdriver_detach(&pad_cd); 166 config_cfdriver_detach(&pad_cd);
167 return; 167 return;
168 } 168 }
169 169
170 for (i = 0; i < n; i++) { 170 for (i = 0; i < n; i++) {
171 cf = kmem_alloc(sizeof(struct cfdata), KM_SLEEP); 171 cf = kmem_alloc(sizeof(struct cfdata), KM_SLEEP);
172 cf->cf_name = pad_cd.cd_name; 172 cf->cf_name = pad_cd.cd_name;
173 cf->cf_atname = pad_cd.cd_name; 173 cf->cf_atname = pad_cd.cd_name;
174 cf->cf_unit = i; 174 cf->cf_unit = i;
175 cf->cf_fstate = FSTATE_STAR; 175 cf->cf_fstate = FSTATE_STAR;
176 176
177 (void)config_attach_pseudo(cf); 177 (void)config_attach_pseudo(cf);
178 } 178 }
179 179
180 return; 180 return;
181} 181}
182 182
183static int 183static int
184pad_add_block(pad_softc_t *sc, uint8_t *blk, int blksize) 184pad_add_block(pad_softc_t *sc, uint8_t *blk, int blksize)
185{ 185{
186 int l; 186 int l;
187 187
188 if (sc->sc_open == 0) 188 if (sc->sc_open == 0)
189 return EIO; 189 return EIO;
190 190
191 KASSERT(mutex_owned(&sc->sc_lock)); 191 KASSERT(mutex_owned(&sc->sc_lock));
192 192
193 if (sc->sc_buflen + blksize > PAD_BUFSIZE) 193 if (sc->sc_buflen + blksize > PAD_BUFSIZE)
194 return ENOBUFS; 194 return ENOBUFS;
195 195
196 if (sc->sc_wpos + blksize <= PAD_BUFSIZE) 196 if (sc->sc_wpos + blksize <= PAD_BUFSIZE)
197 memcpy(sc->sc_audiobuf + sc->sc_wpos, blk, blksize); 197 memcpy(sc->sc_audiobuf + sc->sc_wpos, blk, blksize);
198 else { 198 else {
199 l = PAD_BUFSIZE - sc->sc_wpos; 199 l = PAD_BUFSIZE - sc->sc_wpos;
200 memcpy(sc->sc_audiobuf + sc->sc_wpos, blk, l); 200 memcpy(sc->sc_audiobuf + sc->sc_wpos, blk, l);
201 memcpy(sc->sc_audiobuf, blk + l, blksize - l); 201 memcpy(sc->sc_audiobuf, blk + l, blksize - l);
202 } 202 }
203 203
204 sc->sc_wpos += blksize; 204 sc->sc_wpos += blksize;
205 if (sc->sc_wpos > PAD_BUFSIZE) 205 if (sc->sc_wpos > PAD_BUFSIZE)
206 sc->sc_wpos -= PAD_BUFSIZE; 206 sc->sc_wpos -= PAD_BUFSIZE;
207 207
208 sc->sc_buflen += blksize; 208 sc->sc_buflen += blksize;
209 209
210 return 0; 210 return 0;
211} 211}
212 212
213static int 213static int
214pad_get_block(pad_softc_t *sc, pad_block_t *pb, int blksize) 214pad_get_block(pad_softc_t *sc, pad_block_t *pb, int blksize)
215{ 215{
216 int l; 216 int l;
217 217
218 KASSERT(mutex_owned(&sc->sc_lock)); 218 KASSERT(mutex_owned(&sc->sc_lock));
219 KASSERT(pb != NULL); 219 KASSERT(pb != NULL);
220 220
221 if (sc->sc_buflen < blksize) 221 if (sc->sc_buflen < blksize)
222 return ERESTART; 222 return ERESTART;
223 223
224 pb->pb_ptr = (sc->sc_audiobuf + sc->sc_rpos); 224 pb->pb_ptr = (sc->sc_audiobuf + sc->sc_rpos);
225 if (sc->sc_rpos + blksize < PAD_BUFSIZE) { 225 if (sc->sc_rpos + blksize < PAD_BUFSIZE) {
226 pb->pb_len = blksize; 226 pb->pb_len = blksize;
227 sc->sc_rpos += blksize; 227 sc->sc_rpos += blksize;
228 } else { 228 } else {
229 l = PAD_BUFSIZE - sc->sc_rpos; 229 l = PAD_BUFSIZE - sc->sc_rpos;
230 pb->pb_len = l; 230 pb->pb_len = l;
231 sc->sc_rpos = 0; 231 sc->sc_rpos = 0;
232 } 232 }
233 sc->sc_buflen -= pb->pb_len; 233 sc->sc_buflen -= pb->pb_len;
234 234
235 return 0; 235 return 0;
236} 236}
237 237
238static int 238static int
239pad_match(device_t parent, cfdata_t data, void *opaque) 239pad_match(device_t parent, cfdata_t data, void *opaque)
240{ 240{
241 241
242 return 1; 242 return 1;
243} 243}
244 244
245static void 245static void
246pad_childdet(device_t self, device_t child) 246pad_childdet(device_t self, device_t child)
247{ 247{
248 pad_softc_t *sc = device_private(self); 248 pad_softc_t *sc = device_private(self);
249 249
250 sc->sc_audiodev = NULL; 250 sc->sc_audiodev = NULL;
251} 251}
252 252
253static void 253static void
254pad_attach(device_t parent, device_t self, void *opaque) 254pad_attach(device_t parent, device_t self, void *opaque)
255{ 255{
256 pad_softc_t *sc = device_private(self); 256 pad_softc_t *sc = device_private(self);
257 257
258 aprint_normal_dev(self, "outputs: 44100Hz, 16-bit, stereo\n"); 258 aprint_normal_dev(self, "outputs: 44100Hz, 16-bit, stereo\n");
259 259
260 sc->sc_dev = self; 260 sc->sc_dev = self;
261 sc->sc_open = 0; 261 sc->sc_open = 0;
262 if (auconv_create_encodings(pad_formats, PAD_NFORMATS, 262 if (auconv_create_encodings(pad_formats, PAD_NFORMATS,
263 &sc->sc_encodings) != 0) { 263 &sc->sc_encodings) != 0) {
264 aprint_error_dev(self, "couldn't create encodings\n"); 264 aprint_error_dev(self, "couldn't create encodings\n");
265 return; 265 return;
266 } 266 }
267 267
268 cv_init(&sc->sc_condvar, device_xname(self)); 268 cv_init(&sc->sc_condvar, device_xname(self));
269 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 269 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
270 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_NONE); 270 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_NONE);
271 271
272 sc->sc_swvol = 255; 272 sc->sc_swvol = 255;
273 sc->sc_buflen = 0; 273 sc->sc_buflen = 0;
274 sc->sc_rpos = sc->sc_wpos = 0; 274 sc->sc_rpos = sc->sc_wpos = 0;
275 sc->sc_audiodev = (void *)audio_attach_mi(&pad_hw_if, sc, sc->sc_dev); 275 sc->sc_audiodev = (void *)audio_attach_mi(&pad_hw_if, sc, sc->sc_dev);
276 276
277 if (!pmf_device_register(self, NULL, NULL)) 277 if (!pmf_device_register(self, NULL, NULL))
278 aprint_error_dev(self, "couldn't establish power handler\n"); 278 aprint_error_dev(self, "couldn't establish power handler\n");
279 279
280 pad_is_attached = true; 280 pad_is_attached = true;
281 return; 281 return;
282} 282}
283 283
284static int 284static int
285pad_detach(device_t self, int flags) 285pad_detach(device_t self, int flags)
286{ 286{
287 pad_softc_t *sc = device_private(self); 287 pad_softc_t *sc = device_private(self);
288 int cmaj, mn, rc; 288 int cmaj, mn, rc;
289 289
290 if (!pad_is_attached) 290 if (!pad_is_attached)
291 return ENXIO; 291 return ENXIO;
292 292
293 cmaj = cdevsw_lookup_major(&pad_cdevsw); 293 cmaj = cdevsw_lookup_major(&pad_cdevsw);
294 mn = device_unit(self); 294 mn = device_unit(self);
295 vdevgone(cmaj, mn, mn, VCHR); 295 vdevgone(cmaj, mn, mn, VCHR);
296 296
297 if ((rc = config_detach_children(self, flags)) != 0) 297 if ((rc = config_detach_children(self, flags)) != 0)
298 return rc; 298 return rc;
299 299
300 pmf_device_deregister(self); 300 pmf_device_deregister(self);
301 301
302 mutex_destroy(&sc->sc_lock); 302 mutex_destroy(&sc->sc_lock);
303 mutex_destroy(&sc->sc_intr_lock); 303 mutex_destroy(&sc->sc_intr_lock);
304 cv_destroy(&sc->sc_condvar); 304 cv_destroy(&sc->sc_condvar);
305 305
306 auconv_delete_encodings(sc->sc_encodings); 306 auconv_delete_encodings(sc->sc_encodings);
307 307
308 pad_is_attached = false; 308 pad_is_attached = false;
309 return 0; 309 return 0;
310} 310}
311 311
312int 312int
313pad_open(dev_t dev, int flags, int fmt, struct lwp *l) 313pad_open(dev_t dev, int flags, int fmt, struct lwp *l)
314{ 314{
315 pad_softc_t *sc; 315 pad_softc_t *sc;
316 316
317 sc = device_lookup_private(&pad_cd, PADUNIT(dev)); 317 sc = device_lookup_private(&pad_cd, PADUNIT(dev));
318 if (sc == NULL) 318 if (sc == NULL)
319 return ENXIO; 319 return ENXIO;
320 320
321 if (atomic_swap_uint(&sc->sc_open, 1) != 0) { 321 if (atomic_swap_uint(&sc->sc_open, 1) != 0) {
322 return EBUSY; 322 return EBUSY;
323 } 323 }
324  324
325 getmicrotime(&sc->sc_last); 
326 sc->sc_bytes_count = 0; 
327 sc->sc_remainder = 0; 
328 
329 return 0; 325 return 0;
330} 326}
331 327
332int 328int
333pad_close(dev_t dev, int flags, int fmt, struct lwp *l) 329pad_close(dev_t dev, int flags, int fmt, struct lwp *l)
334{ 330{
335 pad_softc_t *sc; 331 pad_softc_t *sc;
336 332
337 sc = device_lookup_private(&pad_cd, PADUNIT(dev)); 333 sc = device_lookup_private(&pad_cd, PADUNIT(dev));
338 if (sc == NULL) 334 if (sc == NULL)
339 return ENXIO; 335 return ENXIO;
340 336
341 KASSERT(sc->sc_open > 0); 337 KASSERT(sc->sc_open > 0);
342 sc->sc_open = 0; 338 sc->sc_open = 0;
343 339
344 return 0; 340 return 0;
345} 341}
346 342
347#define PAD_BYTES_PER_SEC (44100 * sizeof(int16_t) * 2) 343#define PAD_BYTES_PER_SEC (44100 * sizeof(int16_t) * 2)
348#define TIMENEXTREAD (PAD_BLKSIZE * 1000000 / PAD_BYTES_PER_SEC) 344#define BYTESTOSLEEP (int64_t)(PAD_BLKSIZE)
349#define BYTESTOSLEEP (PAD_BLKSIZE) 345#define TIMENEXTREAD (int64_t)(BYTESTOSLEEP * 1000000 / PAD_BYTES_PER_SEC)
350 346
351int 347int
352pad_read(dev_t dev, struct uio *uio, int flags) 348pad_read(dev_t dev, struct uio *uio, int flags)
353{ 349{
354 struct timeval now; 350 struct timeval now;
355 uint64_t nowusec, lastusec; 351 uint64_t nowusec, lastusec;
356 pad_softc_t *sc; 352 pad_softc_t *sc;
357 pad_block_t pb; 353 pad_block_t pb;
358 void (*intr)(void *); 354 void (*intr)(void *);
359 void *intrarg; 355 void *intrarg;
360 int err, wait_ticks; 356 int err, wait_ticks;
361 357
362 sc = device_lookup_private(&pad_cd, PADUNIT(dev)); 358 sc = device_lookup_private(&pad_cd, PADUNIT(dev));
363 if (sc == NULL) 359 if (sc == NULL)
364 return ENXIO; 360 return ENXIO;
365 361
366 err = 0; 362 err = 0;
367 363
368 while (uio->uio_resid > 0 && !err) { 364 while (uio->uio_resid > 0 && !err) {
369 mutex_enter(&sc->sc_lock); 365 mutex_enter(&sc->sc_lock);
370 intr = sc->sc_intr; 366 intr = sc->sc_intr;
371 intrarg = sc->sc_intrarg; 367 intrarg = sc->sc_intrarg;
372 368
373 getmicrotime(&now); 369 getmicrotime(&now);
374 nowusec = (now.tv_sec * 1000000) + now.tv_usec; 370 nowusec = (now.tv_sec * 1000000) + now.tv_usec;
375 lastusec = (sc->sc_last.tv_sec * 1000000) + 371 lastusec = (sc->sc_last.tv_sec * 1000000) +
376 sc->sc_last.tv_usec; 372 sc->sc_last.tv_usec;
377 if (lastusec + TIMENEXTREAD > nowusec && 373 if (lastusec + TIMENEXTREAD > nowusec) {
378 sc->sc_bytes_count >= BYTESTOSLEEP) { 374 if (sc->sc_bytes_count >= BYTESTOSLEEP) {
379 sc->sc_remainder += 375 sc->sc_remainder +=
380 ((lastusec + TIMENEXTREAD) - nowusec); 376 ((lastusec + TIMENEXTREAD) - nowusec);
 377 }
381  378
382 wait_ticks = (hz * sc->sc_remainder) / 1000000; 379 wait_ticks = (hz * sc->sc_remainder) / 1000000;
383 if (wait_ticks > 0) { 380 if (wait_ticks > 0) {
384 sc->sc_remainder -= wait_ticks * 1000000 / hz; 381 sc->sc_remainder -= wait_ticks * 1000000 / hz;
385 kpause("padwait", TRUE, wait_ticks, 382 kpause("padwait", TRUE, wait_ticks,
386 &sc->sc_lock); 383 &sc->sc_lock);
387 } 384 }
 385 }
388 386
 387 if (sc->sc_bytes_count >= BYTESTOSLEEP)
389 sc->sc_bytes_count -= BYTESTOSLEEP; 388 sc->sc_bytes_count -= BYTESTOSLEEP;
390 getmicrotime(&sc->sc_last); 
391 } else if (sc->sc_bytes_count >= BYTESTOSLEEP) { 
392 sc->sc_bytes_count -= BYTESTOSLEEP; 
393 getmicrotime(&sc->sc_last); 
394 } else if (lastusec + TIMENEXTREAD <= nowusec) { 
395 getmicrotime(&sc->sc_last); 
396 sc->sc_remainder = 0; 
397 } 
398 389
399 err = pad_get_block(sc, &pb, min(uio->uio_resid, PAD_BLKSIZE)); 390 err = pad_get_block(sc, &pb, min(uio->uio_resid, PAD_BLKSIZE));
400 if (!err) { 391 if (!err) {
 392 getmicrotime(&sc->sc_last);
401 sc->sc_bytes_count += pb.pb_len; 393 sc->sc_bytes_count += pb.pb_len;
402 mutex_exit(&sc->sc_lock); 394 mutex_exit(&sc->sc_lock);
403 err = uiomove(pb.pb_ptr, pb.pb_len, uio); 395 err = uiomove(pb.pb_ptr, pb.pb_len, uio);
404 continue; 396 continue;
405 } 397 }
406 398
407 if (intr) { 399 if (intr) {
408 mutex_enter(&sc->sc_intr_lock); 400 mutex_enter(&sc->sc_intr_lock);
409 kpreempt_disable(); 401 kpreempt_disable();
410 (*intr)(intrarg); 402 (*intr)(intrarg);
411 kpreempt_enable(); 403 kpreempt_enable();
412 mutex_exit(&sc->sc_intr_lock); 404 mutex_exit(&sc->sc_intr_lock);
413 intr = sc->sc_intr; 405 intr = sc->sc_intr;
414 intrarg = sc->sc_intrarg; 406 intrarg = sc->sc_intrarg;
415 err = 0; 407 err = 0;
416 mutex_exit(&sc->sc_lock); 408 mutex_exit(&sc->sc_lock);
417 continue; 409 continue;
418 } 410 }
419 err = cv_wait_sig(&sc->sc_condvar, &sc->sc_lock); 411 err = cv_wait_sig(&sc->sc_condvar, &sc->sc_lock);
420 if (err != 0) { 412 if (err != 0) {
421 mutex_exit(&sc->sc_lock); 413 mutex_exit(&sc->sc_lock);
422 break; 414 break;
423 } 415 }
424 416
425 mutex_exit(&sc->sc_lock); 417 mutex_exit(&sc->sc_lock);
426 } 418 }
427 419
428 return err; 420 return err;
429} 421}
430 422
431static int 423static int
432pad_audio_open(void *opaque, int flags) 424pad_audio_open(void *opaque, int flags)
433{ 425{
434 pad_softc_t *sc; 426 pad_softc_t *sc;
435 sc = opaque; 427 sc = opaque;
436 428
437 if (sc->sc_open == 0) 429 if (sc->sc_open == 0)
438 return EIO; 430 return EIO;
439 431
440 getmicrotime(&sc->sc_last); 432 getmicrotime(&sc->sc_last);
 433 sc->sc_bytes_count = 0;
441 sc->sc_remainder = 0; 434 sc->sc_remainder = 0;
442 435
443 return 0; 436 return 0;
444} 437}
445 438
446static int 439static int
447pad_query_encoding(void *opaque, struct audio_encoding *ae) 440pad_query_encoding(void *opaque, struct audio_encoding *ae)
448{ 441{
449 pad_softc_t *sc; 442 pad_softc_t *sc;
450 443
451 sc = (pad_softc_t *)opaque; 444 sc = (pad_softc_t *)opaque;
452 445
453 KASSERT(mutex_owned(&sc->sc_lock)); 446 KASSERT(mutex_owned(&sc->sc_lock));
454 447
455 return auconv_query_encoding(sc->sc_encodings, ae); 448 return auconv_query_encoding(sc->sc_encodings, ae);
456} 449}
457 450
458static int 451static int
459pad_set_params(void *opaque, int setmode, int usemode, 452pad_set_params(void *opaque, int setmode, int usemode,
460 audio_params_t *play, audio_params_t *rec, 453 audio_params_t *play, audio_params_t *rec,
461 stream_filter_list_t *pfil, stream_filter_list_t *rfil) 454 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
462{ 455{
463 pad_softc_t *sc __diagused; 456 pad_softc_t *sc __diagused;
464 457
465 sc = (pad_softc_t *)opaque; 458 sc = (pad_softc_t *)opaque;
466 459
467 KASSERT(mutex_owned(&sc->sc_lock)); 460 KASSERT(mutex_owned(&sc->sc_lock));
468 461
469 if (auconv_set_converter(pad_formats, PAD_NFORMATS, AUMODE_PLAY, 462 if (auconv_set_converter(pad_formats, PAD_NFORMATS, AUMODE_PLAY,
470 play, true, pfil) < 0) 463 play, true, pfil) < 0)
471 return EINVAL; 464 return EINVAL;
472 if (auconv_set_converter(pad_formats, PAD_NFORMATS, AUMODE_RECORD, 465 if (auconv_set_converter(pad_formats, PAD_NFORMATS, AUMODE_RECORD,
473 rec, true, rfil) < 0) 466 rec, true, rfil) < 0)
474 return EINVAL; 467 return EINVAL;
475 468
476 if (pfil->req_size > 0) 469 if (pfil->req_size > 0)
477 play = &pfil->filters[0].param; 470 play = &pfil->filters[0].param;
478 switch (play->encoding) { 471 switch (play->encoding) {
479 case AUDIO_ENCODING_SLINEAR_LE: 472 case AUDIO_ENCODING_SLINEAR_LE:
480 if (play->precision == 16 && play->validbits == 16) 473 if (play->precision == 16 && play->validbits == 16)
481 pfil->prepend(pfil, pad_swvol_filter_le, play); 474 pfil->prepend(pfil, pad_swvol_filter_le, play);
482 break; 475 break;
483 case AUDIO_ENCODING_SLINEAR_BE: 476 case AUDIO_ENCODING_SLINEAR_BE:
484 if (play->precision == 16 && play->validbits == 16) 477 if (play->precision == 16 && play->validbits == 16)
485 pfil->prepend(pfil, pad_swvol_filter_be, play); 478 pfil->prepend(pfil, pad_swvol_filter_be, play);
486 break; 479 break;
487 default: 480 default:
488 break; 481 break;
489 } 482 }
490 483
491 return 0; 484 return 0;
492} 485}
493 486
494static int 487static int
495pad_start_output(void *opaque, void *block, int blksize, 488pad_start_output(void *opaque, void *block, int blksize,
496 void (*intr)(void *), void *intrarg) 489 void (*intr)(void *), void *intrarg)
497{ 490{
498 pad_softc_t *sc; 491 pad_softc_t *sc;
499 int err; 492 int err;
500 493
501 sc = (pad_softc_t *)opaque; 494 sc = (pad_softc_t *)opaque;
502 495
503 KASSERT(mutex_owned(&sc->sc_lock)); 496 KASSERT(mutex_owned(&sc->sc_lock));
504 if (!sc->sc_open) 497 if (!sc->sc_open)
505 return EIO; 498 return EIO;
506 499
507 sc->sc_intr = intr; 500 sc->sc_intr = intr;
508 sc->sc_intrarg = intrarg; 501 sc->sc_intrarg = intrarg;
509 sc->sc_blksize = blksize; 502 sc->sc_blksize = blksize;
510 503
511 err = pad_add_block(sc, block, blksize); 504 err = pad_add_block(sc, block, blksize);
512 505
513 cv_broadcast(&sc->sc_condvar); 506 cv_broadcast(&sc->sc_condvar);
514 507
515 return err; 508 return err;
516} 509}
517 510
518static int 511static int
519pad_start_input(void *opaque, void *block, int blksize, 512pad_start_input(void *opaque, void *block, int blksize,
520 void (*intr)(void *), void *intrarg) 513 void (*intr)(void *), void *intrarg)
521{ 514{
522 pad_softc_t *sc __diagused; 515 pad_softc_t *sc __diagused;
523 516
524 sc = (pad_softc_t *)opaque; 517 sc = (pad_softc_t *)opaque;
525 518
526 KASSERT(mutex_owned(&sc->sc_lock)); 519 KASSERT(mutex_owned(&sc->sc_lock));
527 520
528 return EOPNOTSUPP; 521 return EOPNOTSUPP;
529} 522}
530 523
531static int 524static int
532pad_halt_output(void *opaque) 525pad_halt_output(void *opaque)
533{ 526{
534 pad_softc_t *sc; 527 pad_softc_t *sc;
535 528
536 sc = (pad_softc_t *)opaque; 529 sc = (pad_softc_t *)opaque;
537 530
538 KASSERT(mutex_owned(&sc->sc_lock)); 531 KASSERT(mutex_owned(&sc->sc_lock));
539 532
540 sc->sc_intr = NULL; 533 sc->sc_intr = NULL;
541 sc->sc_intrarg = NULL; 534 sc->sc_intrarg = NULL;
542 sc->sc_buflen = 0; 535 sc->sc_buflen = 0;
543 sc->sc_rpos = sc->sc_wpos = 0; 536 sc->sc_rpos = sc->sc_wpos = 0;
544 537
545 return 0; 538 return 0;
546} 539}
547 540
548static int 541static int
549pad_halt_input(void *opaque) 542pad_halt_input(void *opaque)
550{ 543{
551 pad_softc_t *sc __diagused; 544 pad_softc_t *sc __diagused;
552 545
553 sc = (pad_softc_t *)opaque; 546 sc = (pad_softc_t *)opaque;
554 547
555 KASSERT(mutex_owned(&sc->sc_lock)); 548 KASSERT(mutex_owned(&sc->sc_lock));
556 549
557 return 0; 550 return 0;
558} 551}
559 552
560static int 553static int
561pad_getdev(void *opaque, struct audio_device *ret) 554pad_getdev(void *opaque, struct audio_device *ret)
562{ 555{
563 strlcpy(ret->name, "Virtual Audio", sizeof(ret->name)); 556 strlcpy(ret->name, "Virtual Audio", sizeof(ret->name));
564 strlcpy(ret->version, osrelease, sizeof(ret->version)); 557 strlcpy(ret->version, osrelease, sizeof(ret->version));
565 strlcpy(ret->config, "pad", sizeof(ret->config)); 558 strlcpy(ret->config, "pad", sizeof(ret->config));
566 559
567 return 0; 560 return 0;
568} 561}
569 562
570static int 563static int
571pad_set_port(void *opaque, mixer_ctrl_t *mc) 564pad_set_port(void *opaque, mixer_ctrl_t *mc)
572{ 565{
573 pad_softc_t *sc; 566 pad_softc_t *sc;
574 567
575 sc = (pad_softc_t *)opaque; 568 sc = (pad_softc_t *)opaque;
576 569
577 KASSERT(mutex_owned(&sc->sc_lock)); 570 KASSERT(mutex_owned(&sc->sc_lock));
578 571
579 switch (mc->dev) { 572 switch (mc->dev) {
580 case PAD_OUTPUT_MASTER_VOLUME: 573 case PAD_OUTPUT_MASTER_VOLUME:
581 case PAD_INPUT_DAC_VOLUME: 574 case PAD_INPUT_DAC_VOLUME:
582 sc->sc_swvol = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 575 sc->sc_swvol = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
583 return 0; 576 return 0;
584 } 577 }
585 578
586 return ENXIO; 579 return ENXIO;
587} 580}
588 581
589static int 582static int
590pad_get_port(void *opaque, mixer_ctrl_t *mc) 583pad_get_port(void *opaque, mixer_ctrl_t *mc)
591{ 584{
592 pad_softc_t *sc; 585 pad_softc_t *sc;
593 586
594 sc = (pad_softc_t *)opaque; 587 sc = (pad_softc_t *)opaque;
595 588
596 KASSERT(mutex_owned(&sc->sc_lock)); 589 KASSERT(mutex_owned(&sc->sc_lock));
597 590
598 switch (mc->dev) { 591 switch (mc->dev) {
599 case PAD_OUTPUT_MASTER_VOLUME: 592 case PAD_OUTPUT_MASTER_VOLUME:
600 case PAD_INPUT_DAC_VOLUME: 593 case PAD_INPUT_DAC_VOLUME:
601 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_swvol; 594 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_swvol;
602 return 0; 595 return 0;
603 } 596 }
604 597
605 return ENXIO; 598 return ENXIO;
606} 599}
607 600
608static int 601static int
609pad_query_devinfo(void *opaque, mixer_devinfo_t *di) 602pad_query_devinfo(void *opaque, mixer_devinfo_t *di)
610{ 603{
611 pad_softc_t *sc __diagused; 604 pad_softc_t *sc __diagused;
612 605
613 sc = (pad_softc_t *)opaque; 606 sc = (pad_softc_t *)opaque;
614 607
615 KASSERT(mutex_owned(&sc->sc_lock)); 608 KASSERT(mutex_owned(&sc->sc_lock));
616 609
617 switch (di->index) { 610 switch (di->index) {
618 case PAD_OUTPUT_CLASS: 611 case PAD_OUTPUT_CLASS:
619 di->mixer_class = PAD_OUTPUT_CLASS; 612 di->mixer_class = PAD_OUTPUT_CLASS;
620 strcpy(di->label.name, AudioCoutputs); 613 strcpy(di->label.name, AudioCoutputs);
621 di->type = AUDIO_MIXER_CLASS; 614 di->type = AUDIO_MIXER_CLASS;
622 di->next = di->prev = AUDIO_MIXER_LAST; 615 di->next = di->prev = AUDIO_MIXER_LAST;
623 return 0; 616 return 0;
624 case PAD_INPUT_CLASS: 617 case PAD_INPUT_CLASS:
625 di->mixer_class = PAD_INPUT_CLASS; 618 di->mixer_class = PAD_INPUT_CLASS;
626 strcpy(di->label.name, AudioCinputs); 619 strcpy(di->label.name, AudioCinputs);
627 di->type = AUDIO_MIXER_CLASS; 620 di->type = AUDIO_MIXER_CLASS;
628 di->next = di->prev = AUDIO_MIXER_LAST; 621 di->next = di->prev = AUDIO_MIXER_LAST;
629 return 0; 622 return 0;
630 case PAD_OUTPUT_MASTER_VOLUME: 623 case PAD_OUTPUT_MASTER_VOLUME:
631 di->mixer_class = PAD_OUTPUT_CLASS; 624 di->mixer_class = PAD_OUTPUT_CLASS;
632 strcpy(di->label.name, AudioNmaster); 625 strcpy(di->label.name, AudioNmaster);
633 di->type = AUDIO_MIXER_VALUE; 626 di->type = AUDIO_MIXER_VALUE;
634 di->next = di->prev = AUDIO_MIXER_LAST; 627 di->next = di->prev = AUDIO_MIXER_LAST;
635 di->un.v.num_channels = 1; 628 di->un.v.num_channels = 1;
636 strcpy(di->un.v.units.name, AudioNvolume); 629 strcpy(di->un.v.units.name, AudioNvolume);
637 return 0; 630 return 0;
638 case PAD_INPUT_DAC_VOLUME: 631 case PAD_INPUT_DAC_VOLUME:
639 di->mixer_class = PAD_INPUT_CLASS; 632 di->mixer_class = PAD_INPUT_CLASS;
640 strcpy(di->label.name, AudioNdac); 633 strcpy(di->label.name, AudioNdac);
641 di->type = AUDIO_MIXER_VALUE; 634 di->type = AUDIO_MIXER_VALUE;
642 di->next = di->prev = AUDIO_MIXER_LAST; 635 di->next = di->prev = AUDIO_MIXER_LAST;
643 di->un.v.num_channels = 1; 636 di->un.v.num_channels = 1;
644 strcpy(di->un.v.units.name, AudioNvolume); 637 strcpy(di->un.v.units.name, AudioNvolume);
645 return 0; 638 return 0;
646 } 639 }
647 640
648 return ENXIO; 641 return ENXIO;
649} 642}
650 643
651static int 644static int
652pad_get_props(void *opaque) 645pad_get_props(void *opaque)
653{ 646{
654 pad_softc_t *sc __diagused; 647 pad_softc_t *sc __diagused;
655 648
656 sc = (pad_softc_t *)opaque; 649 sc = (pad_softc_t *)opaque;
657 650
658 KASSERT(mutex_owned(&sc->sc_lock)); 651 KASSERT(mutex_owned(&sc->sc_lock));
659 652
660 return 0; 653 return 0;
661} 654}
662 655
663static int 656static int
664pad_round_blocksize(void *opaque, int blksize, int mode, 657pad_round_blocksize(void *opaque, int blksize, int mode,
665 const audio_params_t *p) 658 const audio_params_t *p)
666{ 659{
667 pad_softc_t *sc __diagused; 660 pad_softc_t *sc __diagused;
668 661
669 sc = (pad_softc_t *)opaque; 662 sc = (pad_softc_t *)opaque;
670 KASSERT(mutex_owned(&sc->sc_lock)); 663 KASSERT(mutex_owned(&sc->sc_lock));
671 664
672 return PAD_BLKSIZE; 665 return PAD_BLKSIZE;
673} 666}
674 667
675static void 668static void
676pad_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread) 669pad_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread)
677{ 670{
678 pad_softc_t *sc; 671 pad_softc_t *sc;
679 672
680 sc = (pad_softc_t *)opaque; 673 sc = (pad_softc_t *)opaque;
681 674
682 *intr = &sc->sc_intr_lock; 675 *intr = &sc->sc_intr_lock;
683 *thread = &sc->sc_lock; 676 *thread = &sc->sc_lock;
684} 677}
685 678
686static stream_filter_t * 679static stream_filter_t *
687pad_swvol_filter_le(struct audio_softc *asc, 680pad_swvol_filter_le(struct audio_softc *asc,
688 const audio_params_t *from, const audio_params_t *to) 681 const audio_params_t *from, const audio_params_t *to)
689{ 682{
690 auvolconv_filter_t *this; 683 auvolconv_filter_t *this;
691 device_t dev = audio_get_device(asc); 684 device_t dev = audio_get_device(asc);
692 struct pad_softc *sc = device_private(dev); 685 struct pad_softc *sc = device_private(dev);
693 686
694 this = kmem_alloc(sizeof(auvolconv_filter_t), KM_SLEEP); 687 this = kmem_alloc(sizeof(auvolconv_filter_t), KM_SLEEP);
695 this->base.base.fetch_to = auvolconv_slinear16_le_fetch_to; 688 this->base.base.fetch_to = auvolconv_slinear16_le_fetch_to;
696 this->base.dtor = pad_swvol_dtor; 689 this->base.dtor = pad_swvol_dtor;
697 this->base.set_fetcher = stream_filter_set_fetcher; 690 this->base.set_fetcher = stream_filter_set_fetcher;
698 this->base.set_inputbuffer = stream_filter_set_inputbuffer; 691 this->base.set_inputbuffer = stream_filter_set_inputbuffer;
699 this->vol = &sc->sc_swvol; 692 this->vol = &sc->sc_swvol;
700 693
701 return (stream_filter_t *)this; 694 return (stream_filter_t *)this;
702} 695}
703 696
704static stream_filter_t * 697static stream_filter_t *
705pad_swvol_filter_be(struct audio_softc *asc, 698pad_swvol_filter_be(struct audio_softc *asc,
706 const audio_params_t *from, const audio_params_t *to) 699 const audio_params_t *from, const audio_params_t *to)
707{ 700{
708 auvolconv_filter_t *this; 701 auvolconv_filter_t *this;
709 device_t dev = audio_get_device(asc); 702 device_t dev = audio_get_device(asc);
710 struct pad_softc *sc = device_private(dev); 703 struct pad_softc *sc = device_private(dev);
711 704
712 this = kmem_alloc(sizeof(auvolconv_filter_t), KM_SLEEP); 705 this = kmem_alloc(sizeof(auvolconv_filter_t), KM_SLEEP);
713 this->base.base.fetch_to = auvolconv_slinear16_be_fetch_to; 706 this->base.base.fetch_to = auvolconv_slinear16_be_fetch_to;
714 this->base.dtor = pad_swvol_dtor; 707 this->base.dtor = pad_swvol_dtor;
715 this->base.set_fetcher = stream_filter_set_fetcher; 708 this->base.set_fetcher = stream_filter_set_fetcher;
716 this->base.set_inputbuffer = stream_filter_set_inputbuffer; 709 this->base.set_inputbuffer = stream_filter_set_inputbuffer;
717 this->vol = &sc->sc_swvol; 710 this->vol = &sc->sc_swvol;
718 711
719 return (stream_filter_t *)this; 712 return (stream_filter_t *)this;
720} 713}
721 714
722static void 715static void
723pad_swvol_dtor(stream_filter_t *this) 716pad_swvol_dtor(stream_filter_t *this)
724{ 717{
725 if (this) 718 if (this)
726 kmem_free(this, sizeof(auvolconv_filter_t)); 719 kmem_free(this, sizeof(auvolconv_filter_t));
727} 720}
728 721
729#ifdef _MODULE 722#ifdef _MODULE
730 723
731MODULE(MODULE_CLASS_DRIVER, pad, "audio"); 724MODULE(MODULE_CLASS_DRIVER, pad, "audio");
732 725
733static const struct cfiattrdata audiobuscf_iattrdata = { 726static const struct cfiattrdata audiobuscf_iattrdata = {
734 "audiobus", 0, { { NULL, NULL, 0 }, } 727 "audiobus", 0, { { NULL, NULL, 0 }, }
735}; 728};
736static const struct cfiattrdata * const pad_attrs[] = { 729static const struct cfiattrdata * const pad_attrs[] = {
737 &audiobuscf_iattrdata, NULL 730 &audiobuscf_iattrdata, NULL
738}; 731};
739 732
740CFDRIVER_DECL(pad, DV_DULL, pad_attrs); 733CFDRIVER_DECL(pad, DV_DULL, pad_attrs);
741extern struct cfattach pad_ca; 734extern struct cfattach pad_ca;
742static int padloc[] = { -1, -1 }; 735static int padloc[] = { -1, -1 };
743 736
744static struct cfdata pad_cfdata[] = { 737static struct cfdata pad_cfdata[] = {
745 { 738 {
746 .cf_name = "pad", 739 .cf_name = "pad",
747 .cf_atname = "pad", 740 .cf_atname = "pad",
748 .cf_unit = 0, 741 .cf_unit = 0,
749 .cf_fstate = FSTATE_STAR, 742 .cf_fstate = FSTATE_STAR,
750 .cf_loc = padloc, 743 .cf_loc = padloc,
751 .cf_flags = 0, 744 .cf_flags = 0,
752 .cf_pspec = NULL, 745 .cf_pspec = NULL,
753 }, 746 },
754 { NULL, NULL, 0, 0, NULL, 0, NULL } 747 { NULL, NULL, 0, 0, NULL, 0, NULL }
755}; 748};
756 749
757static int 750static int
758pad_modcmd(modcmd_t cmd, void *arg) 751pad_modcmd(modcmd_t cmd, void *arg)
759{ 752{
760 devmajor_t cmajor = NODEVMAJOR, bmajor = NODEVMAJOR; 753 devmajor_t cmajor = NODEVMAJOR, bmajor = NODEVMAJOR;
761 int error; 754 int error;
762 755
763 switch (cmd) { 756 switch (cmd) {
764 case MODULE_CMD_INIT: 757 case MODULE_CMD_INIT:
765 error = config_cfdriver_attach(&pad_cd); 758 error = config_cfdriver_attach(&pad_cd);
766 if (error) { 759 if (error) {
767 return error; 760 return error;
768 } 761 }
769 762
770 error = config_cfattach_attach(pad_cd.cd_name, &pad_ca); 763 error = config_cfattach_attach(pad_cd.cd_name, &pad_ca);
771 if (error) { 764 if (error) {
772 config_cfdriver_detach(&pad_cd); 765 config_cfdriver_detach(&pad_cd);
773 aprint_error("%s: unable to register cfattach\n", 766 aprint_error("%s: unable to register cfattach\n",
774 pad_cd.cd_name); 767 pad_cd.cd_name);
775 768
776 return error; 769 return error;
777 } 770 }
778 771
779 error = config_cfdata_attach(pad_cfdata, 1); 772 error = config_cfdata_attach(pad_cfdata, 1);
780 if (error) { 773 if (error) {
781 config_cfattach_detach(pad_cd.cd_name, &pad_ca); 774 config_cfattach_detach(pad_cd.cd_name, &pad_ca);
782 config_cfdriver_detach(&pad_cd); 775 config_cfdriver_detach(&pad_cd);
783 aprint_error("%s: unable to register cfdata\n", 776 aprint_error("%s: unable to register cfdata\n",
784 pad_cd.cd_name); 777 pad_cd.cd_name);
785 778
786 return error; 779 return error;
787 } 780 }
788 781
789 error = devsw_attach(pad_cd.cd_name, NULL, &bmajor, 782 error = devsw_attach(pad_cd.cd_name, NULL, &bmajor,
790 &pad_cdevsw, &cmajor); 783 &pad_cdevsw, &cmajor);
791 if (error) { 784 if (error) {
792 error = config_cfdata_detach(pad_cfdata); 785 error = config_cfdata_detach(pad_cfdata);
793 if (error) { 786 if (error) {
794 return error; 787 return error;
795 } 788 }
796 config_cfattach_detach(pad_cd.cd_name, &pad_ca); 789 config_cfattach_detach(pad_cd.cd_name, &pad_ca);
797 config_cfdriver_detach(&pad_cd); 790 config_cfdriver_detach(&pad_cd);
798 aprint_error("%s: unable to register devsw\n", 791 aprint_error("%s: unable to register devsw\n",
799 pad_cd.cd_name); 792 pad_cd.cd_name);
800 793
801 return error; 794 return error;
802 } 795 }
803 796
804 (void)config_attach_pseudo(pad_cfdata); 797 (void)config_attach_pseudo(pad_cfdata);
805 798
806 return 0; 799 return 0;
807 case MODULE_CMD_FINI: 800 case MODULE_CMD_FINI:
808 error = config_cfdata_detach(pad_cfdata); 801 error = config_cfdata_detach(pad_cfdata);
809 if (error) { 802 if (error) {
810 return error; 803 return error;
811 } 804 }
812 805
813 config_cfattach_detach(pad_cd.cd_name, &pad_ca); 806 config_cfattach_detach(pad_cd.cd_name, &pad_ca);
814 config_cfdriver_detach(&pad_cd); 807 config_cfdriver_detach(&pad_cd);
815 devsw_detach(NULL, &pad_cdevsw); 808 devsw_detach(NULL, &pad_cdevsw);
816 809
817 return 0; 810 return 0;
818 default: 811 default:
819 return ENOTTY; 812 return ENOTTY;
820 } 813 }
821} 814}
822 815
823#endif 816#endif

cvs diff -r1.8 -r1.8.2.1 src/sys/dev/pad/padvar.h (switch to unified diff)

--- src/sys/dev/pad/padvar.h 2017/05/27 10:02:26 1.8
+++ src/sys/dev/pad/padvar.h 2017/06/10 06:05:47 1.8.2.1
@@ -1,59 +1,59 @@ @@ -1,59 +1,59 @@
1/* $NetBSD: padvar.h,v 1.8 2017/05/27 10:02:26 nat Exp $ */ 1/* $NetBSD: padvar.h,v 1.8.2.1 2017/06/10 06:05:47 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#ifndef _SYS_DEV_PAD_PADVAR_H 29#ifndef _SYS_DEV_PAD_PADVAR_H
30#define _SYS_DEV_PAD_PADVAR_H 30#define _SYS_DEV_PAD_PADVAR_H
31 31
32typedef struct pad_softc { 32typedef struct pad_softc {
33 device_t sc_dev; 33 device_t sc_dev;
34 34
35 u_int sc_open; 35 u_int sc_open;
36 struct audio_encoding_set *sc_encodings; 36 struct audio_encoding_set *sc_encodings;
37 void (*sc_intr)(void *); 37 void (*sc_intr)(void *);
38 void *sc_intrarg; 38 void *sc_intrarg;
39 39
40 kcondvar_t sc_condvar; 40 kcondvar_t sc_condvar;
41 kmutex_t sc_lock; 41 kmutex_t sc_lock;
42 kmutex_t sc_intr_lock; 42 kmutex_t sc_intr_lock;
43 43
44 struct audio_softc *sc_audiodev; 44 struct audio_softc *sc_audiodev;
45 int sc_blksize; 45 int sc_blksize;
46 46
47#define PAD_BLKSIZE 1024 47#define PAD_BLKSIZE 8192
48#define PAD_BUFSIZE 65536 48#define PAD_BUFSIZE 65536
49 uint8_t sc_audiobuf[PAD_BUFSIZE]; 49 uint8_t sc_audiobuf[PAD_BUFSIZE];
50 uint32_t sc_buflen; 50 uint32_t sc_buflen;
51 uint32_t sc_rpos, sc_wpos; 51 uint32_t sc_rpos, sc_wpos;
52 52
53 uint8_t sc_swvol; 53 uint8_t sc_swvol;
54 struct timeval sc_last; 54 struct timeval sc_last;
55 int sc_bytes_count; 55 int sc_bytes_count;
56 uint32_t sc_remainder; 56 uint32_t sc_remainder;
57} pad_softc_t; 57} pad_softc_t;
58 58
59#endif /* !_SYS_DEV_PAD_PADVAR_H */ 59#endif /* !_SYS_DEV_PAD_PADVAR_H */