1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 /*
26  * Sun audio(7I) and mixer(7I) personality.
27  *
28  * There are some "undocumented" details of how legacy Sun audio
29  * interfaces work.  The following "rules" were derived from reading the
30  * legacy Sun mixer code, and to the best of our knowledge are not
31  * documented elsewhere.
32  *
33  * - We create a "fake" audio device, which behaves like a classic
34  *   exclusive audio device, for each PID, as determined during open(2).
35  *
36  * - Different processes don't interfere with each other.  Even though
37  *   they are running concurrently, they each think they have exclusive
38  *   control over the audio device.
39  *
40  * - Read and write directions operate independent of each other.  That
41  *   is, a device open for reading won't intefere with a future open for
42  *   writing, and vice versa.  This is true even within the same process.
43  *
44  * - Because the virtualization is by PID, strange behavior may occur
45  *   if a process tries to open an audio device at the same time it
46  *   has already received a file descriptor from another process (such
47  *   through inheritence via fork()).
48  *
49  * - The "fake" audio device has no control over physical settings.
50  *   It sees only the software attenuation-based volumes for play and
51  *   record, and has no support for alternate input or output ports or
52  *   access to the monitoring features of the hardware.
53  *
54  * - Explicit notificaton signals (SIGPOLL) are only ever sent up the
55  *   audioctl node -- never up a regular audio node.  (The stream head
56  *   may still issue SIGPOLL based on readability/writability of
57  *   course.)
58  *
59  * - Corollary: processes that want asynch. notifications will open
60  *   /dev/audioctl as well as /dev/audio.
61  *
62  * - We don't support the MIXER mode at all.
63  *
64  * - By corollary, a process is only allowed to open /dev/audio once
65  *   (in each direction.)
66  *
67  * - Attempts to open /dev/audio in duplex mode (O_RDWR) fail (EBUSY)
68  *   if the device cannot support duplex operation.
69  *
70  * - Attempts to open a device with FREAD set fail if the device is not
71  *   capable of recording.  (Likewise for FWRITE and playback.)
72  *
73  * - No data transfer is permitted for audioctl nodes.  (No actual
74  *   record or play.)
75  *
76  * - Sun audio does not support any formats other than linear and
77  *   ULAW/ALAW.  I.e. it will never support AC3 or other "opaque"
78  *   streams which require special handling.
79  *
80  * - Sun audio only supports stereo or monophonic data streams.
81  */
82 
83 #include <sys/types.h>
84 #include <sys/open.h>
85 #include <sys/errno.h>
86 #include <sys/audio.h>
87 #include <sys/mixer.h>
88 #include <sys/file.h>
89 #include <sys/stropts.h>
90 #include <sys/strsun.h>
91 #include <sys/sysmacros.h>
92 #include <sys/list.h>
93 #include <sys/note.h>
94 #include <sys/stat.h>
95 #include <sys/ddi.h>
96 #include <sys/sunddi.h>
97 #include "audio_client.h"
98 
99 typedef struct daclient daclient_t;
100 typedef struct dadev dadev_t;
101 typedef struct daproc daproc_t;
102 
103 /* common structure shared between both audioctl and audio nodes */
104 struct daclient {
105 	daproc_t		*dc_proc;
106 	dadev_t			*dc_dev;
107 	audio_client_t		*dc_client;
108 	queue_t			*dc_wq;
109 	unsigned		dc_eof;
110 	list_t			dc_eofcnt;
111 	kmutex_t		dc_lock;
112 	mblk_t			*dc_draining;
113 };
114 
115 struct eofcnt {
116 	list_node_t		linkage;
117 	uint64_t		tail;
118 };
119 
120 struct dadev {
121 	audio_dev_t		*d_dev;
122 
123 	list_t			d_procs;
124 	kmutex_t		d_mx;
125 	kcondvar_t		d_cv;
126 };
127 
128 struct daproc {
129 	pid_t			p_id;
130 	struct audio_info	p_info;
131 	int			p_refcnt;
132 	int			p_oflag;
133 	list_node_t		p_linkage;
134 	dadev_t			*p_dev;
135 	audio_client_t		*p_writer;
136 	audio_client_t		*p_reader;
137 };
138 
139 int devaudio_proc_hold(audio_client_t *, int);
140 void devaudio_proc_release(audio_client_t *);
141 static void devaudio_proc_update(daproc_t *);
142 
143 
144 static int
devaudio_compose_format(audio_prinfo_t * prinfo)145 devaudio_compose_format(audio_prinfo_t *prinfo)
146 {
147 	switch (prinfo->precision) {
148 	case 8:
149 		switch (prinfo->encoding) {
150 		case AUDIO_ENCODING_ULAW:
151 			return (AUDIO_FORMAT_ULAW);
152 		case AUDIO_ENCODING_ALAW:
153 			return (AUDIO_FORMAT_ALAW);
154 		case AUDIO_ENCODING_LINEAR8:
155 			return (AUDIO_FORMAT_U8);
156 		case AUDIO_ENCODING_LINEAR:
157 			return (AUDIO_FORMAT_S8);
158 		}
159 		break;
160 	case 16:
161 		if (prinfo->encoding == AUDIO_ENCODING_LINEAR)
162 			return (AUDIO_FORMAT_S16_NE);
163 		break;
164 	case 32:
165 		if (prinfo->encoding == AUDIO_ENCODING_LINEAR)
166 			return (AUDIO_FORMAT_S32_NE);
167 		break;
168 	}
169 	return (AUDIO_FORMAT_NONE);
170 
171 }
172 
173 static void
devaudio_decompose_format(audio_prinfo_t * prinfo,int afmt)174 devaudio_decompose_format(audio_prinfo_t *prinfo, int afmt)
175 {
176 	int	e, p;
177 
178 	/*
179 	 * N.B.: Even though some of the formats below can't be set by
180 	 * this personality, reporting them (using the closest match)
181 	 * allows this personality to roughly approximate settings for
182 	 * other streams.  It would be incredibly poor form for any
183 	 * personality to modify the format settings for a different
184 	 * personality, so we don't worry about that case.
185 	 */
186 
187 	switch (afmt) {
188 	case AUDIO_FORMAT_ULAW:
189 		e = AUDIO_ENCODING_ULAW;
190 		p = 8;
191 		break;
192 
193 	case AUDIO_FORMAT_ALAW:
194 		e = AUDIO_ENCODING_ALAW;
195 		p = 8;
196 		break;
197 
198 	case AUDIO_FORMAT_U8:
199 		e = AUDIO_ENCODING_LINEAR8;
200 		p = 8;
201 		break;
202 
203 	case AUDIO_FORMAT_S8:
204 		e = AUDIO_ENCODING_LINEAR;
205 		p = 8;
206 		break;
207 
208 	case AUDIO_FORMAT_S16_NE:
209 	case AUDIO_FORMAT_S16_OE:
210 	case AUDIO_FORMAT_U16_NE:
211 	case AUDIO_FORMAT_U16_OE:
212 		e = AUDIO_ENCODING_LINEAR;
213 		p = 16;
214 		break;
215 
216 	case AUDIO_FORMAT_S24_NE:
217 	case AUDIO_FORMAT_S24_OE:
218 	case AUDIO_FORMAT_S24_PACKED:
219 		e = AUDIO_ENCODING_LINEAR;
220 		p = 24;
221 		break;
222 
223 	case AUDIO_FORMAT_S32_NE:
224 	case AUDIO_FORMAT_S32_OE:
225 		e = AUDIO_ENCODING_LINEAR;
226 		p = 32;
227 		break;
228 
229 	default:
230 		/* all other formats (e.g. AC3) are uninterpreted */
231 		e = AUDIO_ENCODING_NONE;
232 		p = 32;
233 		break;
234 	}
235 
236 	prinfo->encoding = e;
237 	prinfo->precision = p;
238 }
239 
240 static daproc_t *
devaudio_proc_alloc(audio_client_t * c)241 devaudio_proc_alloc(audio_client_t *c)
242 {
243 	audio_info_t	*info;
244 	audio_prinfo_t	*prinfo;
245 	uint32_t	caps;
246 	daproc_t	*proc;
247 
248 	if ((proc = kmem_zalloc(sizeof (*proc), KM_NOSLEEP)) == NULL) {
249 		return (NULL);
250 	}
251 	info = &proc->p_info;
252 
253 	/*
254 	 * audio(7I) says: Upon the initial open() of the audio
255 	 * device, the driver resets the data format of the device to
256 	 * the default state of 8-bit, 8Khz, mono u-Law data.
257 	 */
258 	prinfo = &info->play;
259 	prinfo->channels =	1;
260 	prinfo->sample_rate =	8000;
261 	prinfo->encoding =	AUDIO_ENCODING_ULAW;
262 	prinfo->precision =	8;
263 	prinfo->gain =		AUDIO_MAX_GAIN;
264 	prinfo->balance =	AUDIO_MID_BALANCE;
265 	prinfo->buffer_size =	8192;
266 	prinfo->pause =		B_FALSE;
267 	prinfo->waiting =	B_FALSE;
268 	prinfo->open =		B_FALSE;
269 	prinfo->active =	B_FALSE;
270 	prinfo->samples =	0;
271 	prinfo->eof =		0;
272 	prinfo->error =		0;
273 	prinfo->minordev =	0;
274 	prinfo->port =		AUDIO_SPEAKER;
275 	prinfo->avail_ports =	AUDIO_SPEAKER;
276 	prinfo->mod_ports =	AUDIO_NONE;
277 	prinfo->_xxx =		0;
278 
279 	prinfo = &info->record;
280 	prinfo->channels =	1;
281 	prinfo->sample_rate =	8000;
282 	prinfo->encoding =	AUDIO_ENCODING_ULAW;
283 	prinfo->precision =	8;
284 	prinfo->gain =		AUDIO_MAX_GAIN;
285 	prinfo->balance =	AUDIO_MID_BALANCE;
286 	prinfo->buffer_size =	8192;
287 	prinfo->waiting =	B_FALSE;
288 	prinfo->open =  	B_FALSE;
289 	prinfo->active =	B_FALSE;
290 	prinfo->samples =	0;
291 	prinfo->eof =		0;
292 	prinfo->error =		0;
293 	prinfo->minordev =	0;
294 	prinfo->port =		AUDIO_MICROPHONE;
295 	prinfo->avail_ports =	AUDIO_MICROPHONE;
296 	prinfo->mod_ports =	AUDIO_MICROPHONE;
297 
298 	info->output_muted =	B_FALSE;
299 	/* pretend we don't have a software mixer - we don't support the API */
300 	info->hw_features =	0;
301 	info->sw_features =	0;
302 	info->sw_features_enabled = 0;
303 
304 	caps = auclnt_get_dev_capab(auclnt_get_dev(c));
305 	if (caps & AUDIO_CLIENT_CAP_PLAY)
306 		info->hw_features |= AUDIO_HWFEATURE_PLAY;
307 	if (caps & AUDIO_CLIENT_CAP_RECORD)
308 		info->hw_features |= AUDIO_HWFEATURE_RECORD;
309 	if (caps & AUDIO_CLIENT_CAP_DUPLEX)
310 		info->hw_features |= AUDIO_HWFEATURE_DUPLEX;
311 
312 	return (proc);
313 }
314 
315 static void
devaudio_proc_free(daproc_t * proc)316 devaudio_proc_free(daproc_t *proc)
317 {
318 	kmem_free(proc, sizeof (*proc));
319 }
320 
321 int
devaudio_proc_hold(audio_client_t * c,int oflag)322 devaudio_proc_hold(audio_client_t *c, int oflag)
323 {
324 	pid_t		pid;
325 	daproc_t	*proc;
326 	dadev_t		*dev;
327 	daclient_t	*dc;
328 	list_t		*l;
329 	audio_dev_t	*adev;
330 	int		rv;
331 
332 	adev = auclnt_get_dev(c);
333 
334 	/* first allocate and initialize the daclient private data */
335 	if ((dc = kmem_zalloc(sizeof (*dc), KM_NOSLEEP)) == NULL) {
336 		return (ENOMEM);
337 	}
338 
339 	mutex_init(&dc->dc_lock, NULL, MUTEX_DRIVER, NULL);
340 	list_create(&dc->dc_eofcnt, sizeof (struct eofcnt),
341 	    offsetof(struct eofcnt, linkage));
342 	auclnt_set_private(c, dc);
343 
344 	dev = auclnt_get_dev_minor_data(adev, AUDIO_MINOR_DEVAUDIO);
345 	l = &dev->d_procs;
346 	pid = auclnt_get_pid(c);
347 
348 	/* set a couple of common fields */
349 	dc->dc_client = c;
350 	dc->dc_dev = dev;
351 
352 	mutex_enter(&dev->d_mx);
353 	for (proc = list_head(l); proc != NULL; proc = list_next(l, proc)) {
354 		if (proc->p_id == pid) {
355 			proc->p_refcnt++;
356 			break;
357 		}
358 	}
359 	if (proc == NULL) {
360 		if ((proc = devaudio_proc_alloc(c)) == NULL) {
361 			rv = ENOMEM;
362 			goto failed;
363 		}
364 		proc->p_refcnt = 1;
365 		proc->p_id = pid;
366 		proc->p_dev = dev;
367 		list_insert_tail(l, proc);
368 	}
369 
370 	while (proc->p_oflag & oflag) {
371 
372 		if (oflag & (FNDELAY|FNONBLOCK)) {
373 			rv = EBUSY;
374 			goto failed;
375 		}
376 		if (oflag & FWRITE)
377 			proc->p_info.play.waiting++;
378 		if (oflag & FREAD)
379 			proc->p_info.record.waiting++;
380 		if (cv_wait_sig(&dev->d_cv, &dev->d_mx) == 0) {
381 			/* interrupted! */
382 			if (oflag & FWRITE)
383 				proc->p_info.play.waiting--;
384 			if (oflag & FREAD)
385 				proc->p_info.record.waiting--;
386 			rv = EINTR;
387 			goto failed;
388 		}
389 		if (oflag & FWRITE)
390 			proc->p_info.play.waiting--;
391 		if (oflag & FREAD)
392 			proc->p_info.record.waiting--;
393 	}
394 
395 	if (oflag & FWRITE) {
396 		audio_prinfo_t	*play = &proc->p_info.play;
397 		audio_stream_t	*sp = auclnt_output_stream(c);
398 
399 		if (((rv = auclnt_set_rate(sp, 8000)) != 0) ||
400 		    ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) ||
401 		    ((rv = auclnt_set_channels(sp, 1)) != 0)) {
402 			goto failed;
403 		}
404 
405 		auclnt_set_samples(sp, 0);
406 		auclnt_set_errors(sp, 0);
407 		play->eof = 0;
408 		play->buffer_size = 8192;
409 
410 		auclnt_set_gain(sp, ((play->gain * 100) / AUDIO_MAX_GAIN));
411 		auclnt_set_muted(sp, proc->p_info.output_muted);
412 		play->open = B_TRUE;
413 		proc->p_writer = c;
414 		proc->p_oflag |= FWRITE;
415 	}
416 
417 	if (oflag & FREAD) {
418 		audio_prinfo_t	*rec = &proc->p_info.record;
419 		audio_stream_t	*sp = auclnt_input_stream(c);
420 
421 		if (((rv = auclnt_set_rate(sp, 8000)) != 0) ||
422 		    ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) ||
423 		    ((rv = auclnt_set_channels(sp, 1)) != 0)) {
424 			goto failed;
425 		}
426 
427 		auclnt_set_samples(sp, 0);
428 		auclnt_set_errors(sp, 0);
429 		rec->eof = 0;
430 		rec->buffer_size = 8192;
431 
432 		auclnt_set_gain(sp, ((rec->gain * 100) / AUDIO_MAX_GAIN));
433 		rec->open = B_TRUE;
434 		proc->p_reader = c;
435 		proc->p_oflag |= FREAD;
436 	}
437 
438 
439 	dc->dc_wq = auclnt_get_wq(c);
440 
441 	/* we update the s_proc last to avoid a race */
442 	dc->dc_proc = proc;
443 
444 	devaudio_proc_update(proc);
445 
446 	mutex_exit(&dev->d_mx);
447 
448 	return (0);
449 
450 failed:
451 	mutex_exit(&dev->d_mx);
452 	devaudio_proc_release(c);
453 	return (rv);
454 
455 }
456 
457 static void
devaudio_clear_eof(audio_client_t * c)458 devaudio_clear_eof(audio_client_t *c)
459 {
460 	struct eofcnt	*eof;
461 	daclient_t	*dc;
462 
463 	dc = auclnt_get_private(c);
464 	mutex_enter(&dc->dc_lock);
465 	while ((eof = list_remove_head(&dc->dc_eofcnt)) != NULL) {
466 		kmem_free(eof, sizeof (*eof));
467 	}
468 	mutex_exit(&dc->dc_lock);
469 }
470 
471 void
devaudio_proc_release(audio_client_t * c)472 devaudio_proc_release(audio_client_t *c)
473 {
474 	daproc_t	*proc;
475 	dadev_t		*dev;
476 	mblk_t		*mp;
477 	daclient_t	*dc;
478 
479 	dc = auclnt_get_private(c);
480 	proc = dc->dc_proc;
481 	dev = dc->dc_dev;
482 	dc->dc_proc = NULL;
483 
484 	mutex_enter(&dev->d_mx);
485 
486 	if (proc != NULL) {
487 		proc->p_refcnt--;
488 		ASSERT(proc->p_refcnt >= 0);
489 
490 		if (c == proc->p_writer) {
491 			proc->p_oflag &= ~FWRITE;
492 			proc->p_writer = NULL;
493 		}
494 		if (c == proc->p_reader) {
495 			proc->p_oflag &= ~FREAD;
496 			proc->p_reader = NULL;
497 		}
498 		cv_broadcast(&dev->d_cv);
499 
500 		if (proc->p_refcnt == 0) {
501 			list_remove(&dev->d_procs, proc);
502 			devaudio_proc_free(proc);
503 		}
504 		dc->dc_proc = NULL;
505 	}
506 
507 	mutex_exit(&dev->d_mx);
508 
509 	devaudio_clear_eof(c);
510 
511 	while ((mp = dc->dc_draining) != NULL) {
512 		dc->dc_draining = mp->b_next;
513 		mp->b_next = NULL;
514 		freemsg(mp);
515 	}
516 
517 	mutex_destroy(&dc->dc_lock);
518 	list_destroy(&dc->dc_eofcnt);
519 	kmem_free(dc, sizeof (*dc));
520 }
521 
522 static void
devaudio_input(audio_client_t * c)523 devaudio_input(audio_client_t *c)
524 {
525 	audio_stream_t	*sp = auclnt_input_stream(c);
526 	daclient_t	*dc = auclnt_get_private(c);
527 	unsigned	framesz = auclnt_get_framesz(sp);
528 	queue_t		*rq = auclnt_get_rq(c);
529 	mblk_t		*mp;
530 	unsigned	nbytes = dc->dc_proc->p_info.record.buffer_size;
531 	unsigned	count = nbytes / framesz;
532 
533 	/*
534 	 * Potentially send a message upstream with the record data.
535 	 * We collect this up in chunks of the buffer size requested
536 	 * by the client.
537 	 */
538 
539 	while (auclnt_get_count(sp) >= count) {
540 
541 		if ((!canput(rq)) ||
542 		    ((mp = allocb(nbytes, BPRI_MED)) == NULL)) {
543 			/*
544 			 * This will apply back pressure to the
545 			 * buffer.  We haven't yet lost any data, we
546 			 * just can't send it up.  The point at which
547 			 * we have an unrecoverable overrun is in the
548 			 * buffer, not in the streams queue.  So, no
549 			 * need to do anything right now.
550 			 *
551 			 * Note that since recording is enabled, we
552 			 * expect that the callback routine will be
553 			 * called repeatedly & regularly, so we don't
554 			 * have to worry about leaving data orphaned
555 			 * in the queue.
556 			 */
557 			break;
558 		}
559 
560 		(void) auclnt_consume_data(sp, (caddr_t)mp->b_wptr, count);
561 		mp->b_wptr += nbytes;
562 		(void) putq(rq, mp);
563 	}
564 }
565 
566 static void
devaudio_proc_update(daproc_t * proc)567 devaudio_proc_update(daproc_t *proc)
568 {
569 	audio_info_t	*info;
570 	audio_stream_t	*sp;
571 	audio_client_t	*c;
572 
573 	info = &proc->p_info;
574 
575 	ASSERT(mutex_owned(&proc->p_dev->d_mx));
576 
577 	if ((c = proc->p_writer) != NULL) {
578 		sp = auclnt_output_stream(c);
579 
580 		info->play.sample_rate = auclnt_get_rate(sp);
581 		info->play.channels = auclnt_get_channels(sp);
582 		devaudio_decompose_format(&info->play, auclnt_get_format(sp));
583 
584 		info->play.gain =
585 		    (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100;
586 		info->play.pause = auclnt_is_paused(sp);
587 		info->play.active = auclnt_is_running(sp);
588 		info->play.samples = auclnt_get_samples(sp);
589 		info->play.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE;
590 		info->output_muted = auclnt_get_muted(sp);
591 	} else {
592 		info->play.encoding = AUDIO_ENCODING_NONE;
593 		info->play.precision = 0;
594 		info->play.sample_rate = 0;
595 		info->play.pause = B_FALSE;
596 		info->play.active = B_FALSE;
597 		info->play.error = B_FALSE;
598 		info->play.samples = 0;
599 	}
600 
601 	if ((c = proc->p_reader) != NULL) {
602 		sp = auclnt_input_stream(c);
603 
604 		info->record.sample_rate = auclnt_get_rate(sp);
605 		info->record.channels = auclnt_get_channels(sp);
606 		devaudio_decompose_format(&info->record, auclnt_get_format(sp));
607 
608 		info->record.gain =
609 		    (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100;
610 		info->record.pause = auclnt_is_paused(sp);
611 		info->record.active = auclnt_is_running(sp);
612 		info->record.samples = auclnt_get_samples(sp);
613 		info->record.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE;
614 	} else {
615 		info->record.encoding = AUDIO_ENCODING_NONE;
616 		info->record.precision = 0;
617 		info->record.sample_rate = 0;
618 		info->record.pause = B_FALSE;
619 		info->record.active = B_FALSE;
620 		info->record.error = B_FALSE;
621 		info->record.samples = 0;
622 	}
623 }
624 
625 static void
devaudio_ioc_getinfo(queue_t * wq,audio_client_t * c,mblk_t * mp)626 devaudio_ioc_getinfo(queue_t *wq, audio_client_t *c, mblk_t *mp)
627 {
628 	daclient_t	*dc = auclnt_get_private(c);
629 	daproc_t	*proc = dc->dc_proc;
630 	mblk_t		*bcont;
631 
632 	if ((bcont = allocb(sizeof (audio_info_t), BPRI_MED)) == NULL) {
633 		miocnak(wq, mp, 0, ENOMEM);
634 		return;
635 	}
636 
637 	mutex_enter(&dc->dc_dev->d_mx);
638 	devaudio_proc_update(proc);
639 	bcopy(&proc->p_info, bcont->b_wptr, sizeof (audio_info_t));
640 	mutex_exit(&dc->dc_dev->d_mx);
641 
642 	bcont->b_wptr += sizeof (audio_info_t);
643 
644 	mcopyout(mp, NULL, sizeof (audio_info_t), NULL, bcont);
645 	qreply(wq, mp);
646 }
647 
648 #define	CHANGED(new, old, field)			\
649 	((new->field != ((uint32_t)~0)) && (new->field != old->field))
650 #define	CHANGED8(new, old, field)			\
651 	((new->field != ((uint8_t)~0)) && (new->field != old->field))
652 
653 static void
devaudio_ioc_setinfo(queue_t * wq,audio_client_t * c,mblk_t * mp)654 devaudio_ioc_setinfo(queue_t *wq, audio_client_t *c, mblk_t *mp)
655 {
656 	daclient_t	*dc;
657 	daproc_t	*proc;
658 	audio_info_t	*oinfo;
659 	audio_info_t	*ninfo;
660 	audio_prinfo_t	*npr;
661 	audio_prinfo_t	*opr;
662 
663 	int		pfmt = AUDIO_FORMAT_NONE;
664 	int		rfmt = AUDIO_FORMAT_NONE;
665 
666 	boolean_t	reader;
667 	boolean_t	writer;
668 	boolean_t	isctl;
669 	audio_stream_t	*sp;
670 	int		rv;
671 	caddr_t		uaddr;
672 	mblk_t		*bcont;
673 
674 	struct copyresp	*csp;
675 
676 	if (DB_TYPE(mp) == M_IOCTL) {
677 		/* the special value "1" indicates that this is a copyin */
678 		uaddr = *(caddr_t *)(void *)mp->b_cont->b_rptr;
679 
680 		mcopyin(mp, uaddr, sizeof (audio_info_t), NULL);
681 		qreply(wq, mp);
682 		return;
683 	}
684 
685 	ASSERT(DB_TYPE(mp) == M_IOCDATA);
686 	if (((bcont = mp->b_cont) == NULL) ||
687 	    (MBLKL(mp->b_cont) != sizeof (audio_info_t))) {
688 		miocnak(wq, mp, 0, EINVAL);
689 		return;
690 	}
691 
692 	mp->b_cont = NULL;
693 	csp = (void *)mp->b_rptr;
694 	uaddr = (void *)csp->cp_private;
695 	dc = auclnt_get_private(c);
696 	ninfo = (void *)bcont->b_rptr;
697 
698 	mutex_enter(&dc->dc_dev->d_mx);
699 
700 	proc = dc->dc_proc;
701 	oinfo = &proc->p_info;
702 
703 	if (auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIOCTL) {
704 		/* control node can do both read and write fields */
705 		isctl = B_TRUE;
706 		reader = B_TRUE;
707 		writer = B_TRUE;
708 	} else {
709 		isctl = B_FALSE;
710 		writer = (c == proc->p_writer);
711 		reader = (c == proc->p_reader);
712 	}
713 
714 	/*
715 	 * Start by validating settings.
716 	 */
717 	npr = &ninfo->play;
718 	opr = &oinfo->play;
719 
720 	if (writer && CHANGED(npr, opr, sample_rate)) {
721 		if ((isctl) ||
722 		    (npr->sample_rate < 5500) || (npr->sample_rate > 48000)) {
723 			rv = EINVAL;
724 			goto err;
725 		}
726 	}
727 	if (writer && CHANGED(npr, opr, channels)) {
728 		if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) {
729 			rv = EINVAL;
730 			goto err;
731 		}
732 	}
733 	if (writer &&
734 	    (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) {
735 		if (npr->encoding == (uint32_t)~0)
736 			npr->encoding = opr->encoding;
737 		if (npr->precision == (uint32_t)~0)
738 			npr->precision = opr->precision;
739 		pfmt = devaudio_compose_format(npr);
740 		if ((isctl) || (pfmt == AUDIO_FORMAT_NONE)) {
741 			rv = EINVAL;
742 			goto err;
743 		}
744 	}
745 
746 	/* play fields that anyone can modify */
747 	if (CHANGED(npr, opr, gain)) {
748 		if (npr->gain > AUDIO_MAX_GAIN) {
749 			rv = EINVAL;
750 			goto err;
751 		}
752 	}
753 
754 
755 	npr = &ninfo->record;
756 	opr = &oinfo->record;
757 
758 	if (reader && CHANGED(npr, opr, sample_rate)) {
759 		if ((isctl) ||
760 		    (npr->sample_rate < 5500) || (npr->sample_rate > 48000)) {
761 			rv = EINVAL;
762 			goto err;
763 		}
764 	}
765 	if (reader && CHANGED(npr, opr, channels)) {
766 		if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) {
767 			rv = EINVAL;
768 			goto err;
769 		}
770 	}
771 	if (reader &&
772 	    (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) {
773 		if (npr->encoding == (uint32_t)~0)
774 			npr->encoding = opr->encoding;
775 		if (npr->precision == (uint32_t)~0)
776 			npr->precision = opr->precision;
777 		rfmt = devaudio_compose_format(npr);
778 		if ((isctl) || (rfmt == AUDIO_FORMAT_NONE)) {
779 			rv = EINVAL;
780 			goto err;
781 		}
782 	}
783 	if (reader && CHANGED(npr, opr, buffer_size)) {
784 		if (isctl) {
785 			rv = EINVAL;
786 			goto err;
787 		}
788 		/* make sure we can support 16-bit stereo samples */
789 		if ((npr->buffer_size % 4) != 0) {
790 			npr->buffer_size = (npr->buffer_size + 3) & ~3;
791 		}
792 		/* limit the maximum buffer size somewhat */
793 		if (npr->buffer_size > 16384) {
794 			npr->buffer_size = 16384;
795 		}
796 	}
797 
798 	/* record fields that anyone can modify */
799 	if (CHANGED(npr, opr, gain)) {
800 		if (npr->gain > AUDIO_MAX_GAIN) {
801 			rv = EINVAL;
802 			goto err;
803 		}
804 	}
805 
806 	/*
807 	 * Now apply the changes.
808 	 */
809 	if (proc->p_writer != NULL) {
810 		sp = auclnt_output_stream(proc->p_writer);
811 		npr = &ninfo->play;
812 		opr = &oinfo->play;
813 
814 		if (CHANGED(npr, opr, sample_rate)) {
815 			if ((rv = auclnt_set_rate(sp, npr->sample_rate)) != 0)
816 				goto err;
817 		}
818 		if (CHANGED(npr, opr, channels)) {
819 			if ((rv = auclnt_set_channels(sp, npr->channels)) != 0)
820 				goto err;
821 		}
822 		if (pfmt != AUDIO_FORMAT_NONE) {
823 			if ((rv = auclnt_set_format(sp, pfmt)) != 0)
824 				goto err;
825 		}
826 		if (CHANGED(npr, opr, samples)) {
827 			auclnt_set_samples(sp, npr->samples);
828 		}
829 		if (CHANGED(npr, opr, eof)) {
830 			/*
831 			 * This ugly special case code is required to
832 			 * prevent problems with realaudio.
833 			 */
834 			if (npr->eof == 0) {
835 				devaudio_clear_eof(proc->p_writer);
836 			}
837 			opr->eof = npr->eof;
838 		}
839 		if (CHANGED8(npr, opr, pause)) {
840 			if (npr->pause) {
841 				auclnt_set_paused(sp);
842 			} else {
843 				auclnt_clear_paused(sp);
844 
845 				/* qenable to start up the playback */
846 				qenable(auclnt_get_wq(proc->p_writer));
847 			}
848 		}
849 		if (CHANGED8(npr, opr, waiting) && (npr->waiting)) {
850 			opr->waiting = npr->waiting;
851 		}
852 		if (CHANGED8(npr, opr, error)) {
853 			auclnt_set_errors(sp, npr->error);
854 		}
855 		if (CHANGED(npr, opr, gain)) {
856 			auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN);
857 		}
858 		if (CHANGED8(ninfo, oinfo, output_muted)) {
859 			auclnt_set_muted(sp, ninfo->output_muted);
860 		}
861 		if (CHANGED(npr, opr, buffer_size)) {
862 			/*
863 			 * No checks on the buffer size are performed
864 			 * for play side.  The value of the buffer size
865 			 * is meaningless for play side anyway.
866 			 */
867 			opr->buffer_size = npr->buffer_size;
868 		}
869 	} else {
870 		/* these values are preserved even if /dev/audio not open */
871 		if (CHANGED(npr, opr, gain)) {
872 			opr->gain = npr->gain;
873 		}
874 		if (CHANGED8(ninfo, oinfo, output_muted)) {
875 			oinfo->output_muted = ninfo->output_muted;
876 		}
877 	}
878 
879 	if (proc->p_reader != NULL) {
880 		sp = auclnt_input_stream(proc->p_reader);
881 		npr = &ninfo->record;
882 		opr = &oinfo->record;
883 
884 		if (CHANGED(npr, opr, sample_rate)) {
885 			if ((rv = auclnt_set_rate(sp, npr->sample_rate)) != 0)
886 				goto err;
887 		}
888 		if (CHANGED(npr, opr, channels)) {
889 			if ((rv = auclnt_set_channels(sp, npr->channels)) != 0)
890 				goto err;
891 		}
892 		if (rfmt != AUDIO_FORMAT_NONE) {
893 			if ((rv = auclnt_set_format(sp, rfmt)) != 0)
894 				goto err;
895 		}
896 		if (CHANGED(npr, opr, samples)) {
897 			auclnt_set_samples(sp, npr->samples);
898 		}
899 		if (CHANGED(npr, opr, eof)) {
900 			opr->eof = npr->eof;
901 		}
902 		if (CHANGED8(npr, opr, pause)) {
903 			if (npr->pause) {
904 				auclnt_set_paused(sp);
905 			} else {
906 				auclnt_clear_paused(sp);
907 				auclnt_start(sp);
908 			}
909 		}
910 		if (CHANGED8(npr, opr, waiting) && (npr->waiting)) {
911 			opr->waiting = npr->waiting;
912 		}
913 		if (CHANGED8(npr, opr, error)) {
914 			auclnt_set_errors(sp, npr->error);
915 		}
916 		if (CHANGED(npr, opr, buffer_size)) {
917 			opr->buffer_size = npr->buffer_size;
918 		}
919 		if (CHANGED(npr, opr, gain)) {
920 			auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN);
921 		}
922 	} else {
923 		/* these values are preserved even if /dev/audio not open */
924 		if (CHANGED(npr, opr, gain)) {
925 			opr->gain = npr->gain;
926 		}
927 	}
928 
929 	devaudio_proc_update(dc->dc_proc);
930 	bcopy(&dc->dc_proc->p_info, ninfo, sizeof (*ninfo));
931 
932 	mutex_exit(&dc->dc_dev->d_mx);
933 	mcopyout(mp, NULL, sizeof (audio_info_t), uaddr, bcont);
934 	qreply(wq, mp);
935 	return;
936 
937 err:
938 	mutex_exit(&dc->dc_dev->d_mx);
939 	miocnak(wq, mp, 0, rv);
940 }
941 
942 static void
devaudio_ioc_getdev(queue_t * wq,audio_client_t * c,mblk_t * mp)943 devaudio_ioc_getdev(queue_t *wq, audio_client_t *c, mblk_t *mp)
944 {
945 	audio_dev_t	*d = auclnt_get_dev(c);
946 	mblk_t		*bcont;
947 	audio_device_t	*a;
948 
949 	if ((bcont = allocb(sizeof (*a), BPRI_MED)) == NULL) {
950 		miocnak(wq, mp, 0, ENOMEM);
951 		return;
952 	}
953 
954 	a = (void *)bcont->b_wptr;
955 	(void) snprintf(a->name, sizeof (a->name),
956 	    "SUNW,%s", auclnt_get_dev_name(d));
957 	(void) strlcpy(a->config,
958 	    auclnt_get_dev_description(d), sizeof (a->config));
959 	(void) strlcpy(a->version,
960 	    auclnt_get_dev_version(d),  sizeof (a->version));
961 	bcont->b_wptr += sizeof (*a);
962 
963 	mcopyout(mp, NULL, sizeof (*a), NULL, bcont);
964 	qreply(wq, mp);
965 }
966 
967 static int
devaudio_sigpoll(audio_client_t * c,void * arg)968 devaudio_sigpoll(audio_client_t *c, void *arg)
969 {
970 	pid_t		pid = (pid_t)(uintptr_t)arg;
971 
972 	if (auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIOCTL) {
973 		/* we only need to notify peers in our own process */
974 		if (auclnt_get_pid(c) == pid) {
975 			(void) putctl1(auclnt_get_rq(c), M_PCSIG, SIGPOLL);
976 		}
977 	}
978 	return (AUDIO_WALK_CONTINUE);
979 }
980 
981 static void
devaudio_drain(audio_client_t * c)982 devaudio_drain(audio_client_t *c)
983 {
984 	daclient_t	*dc = auclnt_get_private(c);
985 	mblk_t		*mplist, *mp;
986 
987 	mutex_enter(&dc->dc_lock);
988 	mplist = dc->dc_draining;
989 	dc->dc_draining = NULL;
990 	mutex_exit(&dc->dc_lock);
991 
992 	while ((mp = mplist) != NULL) {
993 		mplist = mp->b_next;
994 		mp->b_next = NULL;
995 		mioc2ack(mp, NULL, 0, 0);
996 		(void) putq(auclnt_get_rq(c), mp);
997 	}
998 }
999 
1000 static void
devaudio_output(audio_client_t * c)1001 devaudio_output(audio_client_t *c)
1002 {
1003 	daclient_t	*dc = auclnt_get_private(c);
1004 	daproc_t	*proc = dc->dc_proc;
1005 	uint64_t	tail;
1006 	struct eofcnt	*eof;
1007 	int		eofs = 0;
1008 
1009 	tail = auclnt_get_tail(auclnt_output_stream(c));
1010 
1011 	/* get more data! (do this early) */
1012 	qenable(auclnt_get_wq(c));
1013 
1014 	mutex_enter(&dc->dc_lock);
1015 	while (((eof = list_head(&dc->dc_eofcnt)) != NULL) &&
1016 	    (eof->tail <= tail)) {
1017 		list_remove(&dc->dc_eofcnt, eof);
1018 		kmem_free(eof, sizeof (*eof));
1019 		eofs++;
1020 	}
1021 	proc->p_info.play.eof += eofs;
1022 	mutex_exit(&dc->dc_lock);
1023 
1024 	if (eofs) {
1025 		auclnt_dev_walk_clients(auclnt_get_dev(c),
1026 		    devaudio_sigpoll, (void *)(uintptr_t)auclnt_get_pid(c));
1027 	}
1028 }
1029 
1030 static void *
devaudio_init(audio_dev_t * adev)1031 devaudio_init(audio_dev_t *adev)
1032 {
1033 	dadev_t		*dev;
1034 	unsigned	cap;
1035 
1036 	cap = auclnt_get_dev_capab(adev);
1037 	/* if not a play or record device, don't bother initializing it */
1038 	if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) {
1039 		return (NULL);
1040 	}
1041 
1042 	dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
1043 	dev->d_dev = adev;
1044 	mutex_init(&dev->d_mx, NULL, MUTEX_DRIVER, NULL);
1045 	cv_init(&dev->d_cv, NULL, CV_DRIVER, NULL);
1046 	list_create(&dev->d_procs, sizeof (struct daproc),
1047 	    offsetof(struct daproc, p_linkage));
1048 
1049 	return (dev);
1050 }
1051 
1052 static void
devaudio_fini(void * arg)1053 devaudio_fini(void *arg)
1054 {
1055 	dadev_t	*dev = arg;
1056 
1057 	if (dev != NULL) {
1058 
1059 		mutex_destroy(&dev->d_mx);
1060 		cv_destroy(&dev->d_cv);
1061 		list_destroy(&dev->d_procs);
1062 		kmem_free(dev, sizeof (*dev));
1063 	}
1064 }
1065 
1066 static int
devaudio_open(audio_client_t * c,int oflag)1067 devaudio_open(audio_client_t *c, int oflag)
1068 {
1069 	int	rv;
1070 
1071 	if ((rv = auclnt_open(c, oflag)) != 0) {
1072 		return (rv);
1073 	}
1074 
1075 	if ((rv = devaudio_proc_hold(c, oflag)) != 0) {
1076 		auclnt_close(c);
1077 		return (rv);
1078 	}
1079 
1080 	/* start up the input */
1081 	if (oflag & FREAD) {
1082 		auclnt_start(auclnt_input_stream(c));
1083 	}
1084 
1085 	return (0);
1086 }
1087 
1088 static int
devaudioctl_open(audio_client_t * c,int oflag)1089 devaudioctl_open(audio_client_t *c, int oflag)
1090 {
1091 	int	rv;
1092 
1093 	_NOTE(ARGUNUSED(oflag));
1094 
1095 	oflag &= ~(FWRITE | FREAD);
1096 
1097 	if ((rv = auclnt_open(c, 0)) != 0) {
1098 		return (rv);
1099 	}
1100 
1101 	if ((rv = devaudio_proc_hold(c, oflag)) != 0) {
1102 		auclnt_close(c);
1103 		return (rv);
1104 	}
1105 
1106 	return (0);
1107 }
1108 
1109 static void
devaudio_close(audio_client_t * c)1110 devaudio_close(audio_client_t *c)
1111 {
1112 	auclnt_stop(auclnt_output_stream(c));
1113 	auclnt_stop(auclnt_input_stream(c));
1114 
1115 	auclnt_close(c);
1116 	devaudio_proc_release(c);
1117 }
1118 
1119 static void
devaudioctl_close(audio_client_t * c)1120 devaudioctl_close(audio_client_t *c)
1121 {
1122 	auclnt_close(c);
1123 	devaudio_proc_release(c);
1124 }
1125 
1126 static void
devaudio_miocdata(audio_client_t * c,mblk_t * mp)1127 devaudio_miocdata(audio_client_t *c, mblk_t *mp)
1128 {
1129 	struct copyresp		*csp;
1130 	queue_t			*wq;
1131 
1132 	csp = (void *)mp->b_rptr;
1133 	wq = auclnt_get_wq(c);
1134 
1135 	/*
1136 	 * If a transfer error occurred, the framework already
1137 	 * MIOCNAK'd it.
1138 	 */
1139 	if (csp->cp_rval != 0) {
1140 		freemsg(mp);
1141 		return;
1142 	}
1143 
1144 	/*
1145 	 * If no state, then this is a response to M_COPYOUT, and we
1146 	 * are done.  (Audio ioctls just copyout a single structure at
1147 	 * completion of work.)
1148 	 */
1149 	if (csp->cp_private == NULL) {
1150 		miocack(wq, mp, 0, 0);
1151 		return;
1152 	}
1153 
1154 	/* now, call the handler ioctl */
1155 	switch (csp->cp_cmd) {
1156 	case AUDIO_SETINFO:
1157 		devaudio_ioc_setinfo(wq, c, mp);
1158 		break;
1159 	default:
1160 		miocnak(wq, mp, 0, EINVAL);
1161 		break;
1162 	}
1163 }
1164 
1165 static void
devaudio_mioctl(audio_client_t * c,mblk_t * mp)1166 devaudio_mioctl(audio_client_t *c, mblk_t *mp)
1167 {
1168 	struct iocblk	*iocp = (void *)mp->b_rptr;
1169 	queue_t		*wq = auclnt_get_wq(c);
1170 
1171 	/* BSD legacy here: we only support transparent ioctls */
1172 	if (iocp->ioc_count != TRANSPARENT) {
1173 		miocnak(wq, mp, 0, EINVAL);
1174 		return;
1175 	}
1176 
1177 	switch (iocp->ioc_cmd) {
1178 	case AUDIO_GETINFO:
1179 		devaudio_ioc_getinfo(wq, c, mp);
1180 		break;
1181 
1182 	case AUDIO_SETINFO:
1183 		devaudio_ioc_setinfo(wq, c, mp);
1184 		break;
1185 
1186 	case AUDIO_GETDEV:
1187 		devaudio_ioc_getdev(wq, c, mp);
1188 		break;
1189 
1190 	case AUDIO_DIAG_LOOPBACK:
1191 		/* we don't support this one */
1192 		miocnak(wq, mp, 0, ENOTTY);
1193 		break;
1194 
1195 	case AUDIO_MIXERCTL_GET_MODE:
1196 	case AUDIO_MIXERCTL_SET_MODE:
1197 	case AUDIO_MIXERCTL_GET_CHINFO:
1198 	case AUDIO_MIXERCTL_SET_CHINFO:
1199 	case AUDIO_MIXERCTL_GETINFO:
1200 	case AUDIO_MIXERCTL_SETINFO:
1201 	case AUDIO_GET_NUM_CHS:
1202 	case AUDIO_GET_CH_NUMBER:
1203 	case AUDIO_GET_CH_TYPE:
1204 	case AUDIO_MIXER_SINGLE_OPEN:
1205 	case AUDIO_MIXER_MULTIPLE_OPEN:
1206 	case AUDIO_MIXER_GET_SAMPLE_RATES:
1207 	default:
1208 		miocnak(wq, mp, 0, EINVAL);
1209 		break;
1210 	}
1211 }
1212 
1213 static void
devaudioctl_wput(audio_client_t * c,mblk_t * mp)1214 devaudioctl_wput(audio_client_t *c, mblk_t *mp)
1215 {
1216 	queue_t		*wq = auclnt_get_wq(c);
1217 
1218 	switch (DB_TYPE(mp)) {
1219 	case M_IOCTL:
1220 		/* Drain ioctl needs to be handled on the service queue */
1221 		devaudio_mioctl(c, mp);
1222 		break;
1223 
1224 	case M_IOCDATA:
1225 		devaudio_miocdata(c, mp);
1226 		break;
1227 
1228 	case M_FLUSH:
1229 		/*
1230 		 * We don't flush the engine.  The reason is that
1231 		 * other streams might be using the engine.  This is
1232 		 * fundamentally no different from the case where the
1233 		 * engine hardware has data buffered in an
1234 		 * inaccessible FIFO.
1235 		 *
1236 		 * Clients that want to ensure no more data is coming
1237 		 * should stop the stream before flushing.
1238 		 */
1239 		if (*mp->b_rptr & FLUSHW) {
1240 			*mp->b_rptr &= ~FLUSHW;
1241 		}
1242 		if (*mp->b_rptr & FLUSHR) {
1243 			qreply(wq, mp);
1244 		} else {
1245 			freemsg(mp);
1246 		}
1247 		break;
1248 
1249 	case M_DATA:
1250 		/*
1251 		 * No audio data on control nodes!
1252 		 */
1253 
1254 	default:
1255 		freemsg(mp);
1256 		break;
1257 	}
1258 }
1259 
1260 static void
devaudio_wput(audio_client_t * c,mblk_t * mp)1261 devaudio_wput(audio_client_t *c, mblk_t *mp)
1262 {
1263 	queue_t		*wq = auclnt_get_wq(c);
1264 
1265 	switch (DB_TYPE(mp)) {
1266 	case M_IOCTL:
1267 		/* Drain ioctl needs to be handled on the service queue */
1268 		if (*(int *)(void *)mp->b_rptr == AUDIO_DRAIN) {
1269 			(void) putq(wq, mp);
1270 		} else {
1271 			devaudio_mioctl(c, mp);
1272 		}
1273 		break;
1274 
1275 	case M_IOCDATA:
1276 		devaudio_miocdata(c, mp);
1277 		break;
1278 
1279 	case M_FLUSH:
1280 		/*
1281 		 * We don't flush the engine.  The reason is that
1282 		 * other streams might be using the engine.  This is
1283 		 * fundamentally no different from the case where the
1284 		 * engine hardware has data buffered in an
1285 		 * inaccessible FIFO.
1286 		 *
1287 		 * Clients that want to ensure no more data is coming
1288 		 * should stop the stream before flushing.
1289 		 */
1290 		if (*mp->b_rptr & FLUSHW) {
1291 			flushq(wq, FLUSHALL);
1292 			auclnt_flush(auclnt_output_stream(c));
1293 			*mp->b_rptr &= ~FLUSHW;
1294 		}
1295 		if (*mp->b_rptr & FLUSHR) {
1296 			flushq(RD(wq), FLUSHALL);
1297 			auclnt_flush(auclnt_input_stream(c));
1298 			qreply(wq, mp);
1299 		} else {
1300 			freemsg(mp);
1301 		}
1302 		break;
1303 
1304 	case M_DATA:
1305 		/*
1306 		 * Defer processing to the queue.  This keeps the data
1307 		 * ordered, and allows the wsrv routine to gather
1308 		 * multiple mblks at once.
1309 		 */
1310 		if (mp->b_cont != NULL) {
1311 
1312 			/*
1313 			 * If we need to pullup, do it here to
1314 			 * simplify the rest of the processing later.
1315 			 * This should rarely (if ever) be necessary.
1316 			 */
1317 			mblk_t	*nmp;
1318 
1319 			if ((nmp = msgpullup(mp, -1)) == NULL) {
1320 				freemsg(mp);
1321 			} else {
1322 				freemsg(mp);
1323 				(void) putq(wq, nmp);
1324 			}
1325 		} else {
1326 			(void) putq(wq, mp);
1327 		}
1328 		break;
1329 
1330 	default:
1331 		freemsg(mp);
1332 		break;
1333 	}
1334 }
1335 
1336 static void
devaudio_rsrv(audio_client_t * c)1337 devaudio_rsrv(audio_client_t *c)
1338 {
1339 	queue_t		*rq = auclnt_get_rq(c);
1340 	mblk_t		*mp;
1341 
1342 	while ((mp = getq(rq)) != NULL) {
1343 
1344 		if ((queclass(mp) != QPCTL) && (!canputnext(rq))) {
1345 			/*
1346 			 * Put it back in the queue so we can apply
1347 			 * backpressure properly.
1348 			 */
1349 			(void) putbq(rq, mp);
1350 			return;
1351 		}
1352 		putnext(rq, mp);
1353 	}
1354 }
1355 
1356 static void
devaudio_wsrv(audio_client_t * c)1357 devaudio_wsrv(audio_client_t *c)
1358 {
1359 	queue_t		*wq = auclnt_get_wq(c);
1360 	daclient_t	*dc = auclnt_get_private(c);
1361 	audio_stream_t	*sp;
1362 	mblk_t		*mp;
1363 	unsigned	framesz;
1364 
1365 	sp = auclnt_output_stream(c);
1366 
1367 	framesz = auclnt_get_framesz(sp);
1368 
1369 	while ((mp = getq(wq)) != NULL) {
1370 
1371 		unsigned	count;
1372 
1373 		/* got a message */
1374 
1375 		/* if its a drain ioctl, we need to process it here */
1376 		if (DB_TYPE(mp) == M_IOCTL) {
1377 			ASSERT((*(int *)(void *)mp->b_rptr) == AUDIO_DRAIN);
1378 			mutex_enter(&dc->dc_lock);
1379 			mp->b_next = dc->dc_draining;
1380 			dc->dc_draining = mp;
1381 			mutex_exit(&dc->dc_lock);
1382 
1383 			if (auclnt_start_drain(c) != 0) {
1384 				devaudio_drain(c);
1385 			}
1386 			continue;
1387 		}
1388 
1389 		ASSERT(DB_TYPE(mp) == M_DATA);
1390 
1391 		/*
1392 		 * Empty mblk require special handling, since they
1393 		 * indicate EOF.  We treat them separate from the main
1394 		 * processing loop.
1395 		 */
1396 		if (MBLKL(mp) == 0) {
1397 			struct eofcnt	*eof;
1398 
1399 			eof = kmem_zalloc(sizeof (*eof), KM_NOSLEEP);
1400 			if (eof != NULL) {
1401 				eof->tail = auclnt_get_head(sp);
1402 				mutex_enter(&dc->dc_lock);
1403 				list_insert_tail(&dc->dc_eofcnt, eof);
1404 				mutex_exit(&dc->dc_lock);
1405 			}
1406 			freemsg(mp);
1407 			continue;
1408 		}
1409 
1410 		count = auclnt_produce_data(sp, (caddr_t)mp->b_rptr,
1411 		    MBLKL(mp) / framesz);
1412 
1413 		mp->b_rptr += count * framesz;
1414 
1415 		if (MBLKL(mp) >= framesz) {
1416 			(void) putbq(wq, mp);
1417 			break;
1418 		} else {
1419 			freemsg(mp);
1420 		}
1421 	}
1422 
1423 	/* if the stream isn't running yet, start it up */
1424 	if (!auclnt_is_paused(sp))
1425 		auclnt_start(sp);
1426 }
1427 
1428 static struct audio_client_ops devaudio_ops = {
1429 	"sound,audio",
1430 	devaudio_init,
1431 	devaudio_fini,
1432 	devaudio_open,
1433 	devaudio_close,
1434 	NULL,	/* read */
1435 	NULL,	/* write */
1436 	NULL,	/* ioctl */
1437 	NULL,	/* chpoll */
1438 	NULL,	/* mmap */
1439 	devaudio_input,
1440 	devaudio_output,
1441 	devaudio_drain,
1442 	devaudio_wput,
1443 	devaudio_wsrv,
1444 	devaudio_rsrv
1445 };
1446 
1447 static struct audio_client_ops devaudioctl_ops = {
1448 	"sound,audioctl",
1449 	NULL,	/* dev_init */
1450 	NULL,	/* dev_fini */
1451 	devaudioctl_open,
1452 	devaudioctl_close,
1453 	NULL,	/* read */
1454 	NULL,	/* write */
1455 	NULL,	/* ioctl */
1456 	NULL,	/* chpoll */
1457 	NULL,	/* mmap */
1458 	NULL,	/* output */
1459 	NULL,	/* input */
1460 	NULL,	/* drain */
1461 	devaudioctl_wput,
1462 	NULL,
1463 	devaudio_rsrv
1464 };
1465 
1466 void
auimpl_sun_init(void)1467 auimpl_sun_init(void)
1468 {
1469 	auclnt_register_ops(AUDIO_MINOR_DEVAUDIO, &devaudio_ops);
1470 	auclnt_register_ops(AUDIO_MINOR_DEVAUDIOCTL, &devaudioctl_ops);
1471 }
1472