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 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Sun audio(7I) and mixer(7I) personality.
28  *
29  * There are some "undocumented" details of how legacy Sun audio
30  * interfaces work.  The following "rules" were derived from reading the
31  * legacy Sun mixer code, and to the best of our knowledge are not
32  * documented elsewhere.
33  *
34  * - We create a "fake" audio device, which behaves like a classic
35  *   exclusive audio device, for each PID, as determined during open(2).
36  *
37  * - Different processes don't interfere with each other.  Even though
38  *   they are running concurrently, they each think they have exclusive
39  *   control over the audio device.
40  *
41  * - Read and write directions operate independent of each other.  That
42  *   is, a device open for reading won't intefere with a future open for
43  *   writing, and vice versa.  This is true even within the same process.
44  *
45  * - Because the virtualization is by PID, strange behavior may occur
46  *   if a process tries to open an audio device at the same time it
47  *   has already received a file descriptor from another process (such
48  *   through inheritence via fork()).
49  *
50  * - The "fake" audio device has no control over physical settings.
51  *   It sees only the software attenuation-based volumes for play and
52  *   record, and has no support for alternate input or output ports or
53  *   access to the monitoring features of the hardware.
54  *
55  * - Explicit notificaton signals (SIGPOLL) are only ever sent up the
56  *   audioctl node -- never up a regular audio node.  (The stream head
57  *   may still issue SIGPOLL based on readability/writability of
58  *   course.)
59  *
60  * - Corollary: processes that want asynch. notifications will open
61  *   /dev/audioctl as well as /dev/audio.
62  *
63  * - We don't support the MIXER mode at all.
64  *
65  * - By corollary, a process is only allowed to open /dev/audio once
66  *   (in each direction.)
67  *
68  * - Attempts to open /dev/audio in duplex mode (O_RDWR) fail (EBUSY)
69  *   if the device cannot support duplex operation.
70  *
71  * - Attempts to open a device with FREAD set fail if the device is not
72  *   capable of recording.  (Likewise for FWRITE and playback.)
73  *
74  * - No data transfer is permitted for audioctl nodes.  (No actual
75  *   record or play.)
76  *
77  * - Sun audio does not support any formats other than linear and
78  *   ULAW/ALAW.  I.e. it will never support AC3 or other "opaque"
79  *   streams which require special handling.
80  *
81  * - Sun audio only supports stereo or monophonic data streams.
82  */
83 
84 #include <sys/types.h>
85 #include <sys/open.h>
86 #include <sys/errno.h>
87 #include <sys/audio.h>
88 #include <sys/mixer.h>
89 #include <sys/file.h>
90 #include <sys/stropts.h>
91 #include <sys/strsun.h>
92 #include <sys/sysmacros.h>
93 #include <sys/list.h>
94 #include <sys/note.h>
95 #include <sys/stat.h>
96 #include <sys/ddi.h>
97 #include <sys/sunddi.h>
98 #include "audio_client.h"
99 
100 typedef struct sclient sclient_t;
101 typedef struct sdev sdev_t;
102 typedef struct sproc sproc_t;
103 typedef struct sioc sioc_t;
104 
105 typedef enum {
106 	COPYIN,
107 	COPYOUT,
108 	IOCTL,
109 	ACK,
110 	NAK,
111 	FINI
112 } sioc_state_t;
113 
114 struct sioc {
115 	sclient_t		*i_sc;
116 	int			i_cmd;
117 	size_t			i_size;
118 	void			*i_data;
119 	mblk_t			*i_bcont;
120 	int			i_step;
121 	uint_t			i_model;
122 	sioc_state_t		i_state;
123 	mblk_t			*i_mp;
124 	caddr_t			i_addr;
125 	int			i_error;
126 };
127 
128 /* common structure shared between both audioctl and audio nodes */
129 struct sclient {
130 	sproc_t			*s_proc;
131 	sdev_t			*s_sdev;
132 	audio_client_t		*s_client;
133 	queue_t			*s_rq;
134 	queue_t			*s_wq;
135 	ldi_handle_t		s_lh;
136 	unsigned		s_eof;
137 	list_t			s_eofcnt;
138 	kmutex_t		s_lock;
139 	mblk_t			*s_draining;
140 };
141 
142 struct eofcnt {
143 	list_node_t		linkage;
144 	uint64_t		tail;
145 };
146 
147 struct sdev {
148 	audio_dev_t		*d_dev;
149 
150 	list_t			d_procs;
151 	kmutex_t		d_mx;
152 	kcondvar_t		d_cv;
153 };
154 
155 struct sproc {
156 	pid_t			p_id;
157 	struct audio_info	p_info;
158 	int			p_refcnt;
159 	int			p_oflag;
160 	list_node_t		p_linkage;
161 	sdev_t			*p_sdev;
162 	sclient_t		*p_writer;
163 	sclient_t		*p_reader;
164 };
165 
166 int sproc_hold(audio_client_t *, ldi_handle_t, queue_t *, int);
167 void sproc_release(sclient_t *);
168 static void sproc_update(sproc_t *);
169 
170 
171 static kmutex_t	sdev_lock;
172 static dev_info_t *sdev_dip;
173 
174 /*
175  * Alloc extra room for ioctl buffer, in case none was supplied or copyin was
176  * shorter than we need for the whole struct.  On failure, returns an
177  * appropriate errno, zero on success.  Any original data is preserved.
178  */
179 static int
180 sioc_alloc(sioc_t *ip, size_t size)
181 {
182 	mblk_t			*nmp;
183 
184 	/* if we already have enough, just use what we've got */
185 	if (ip->i_size >= size)
186 		return (0);
187 
188 	if ((nmp = allocb(size, BPRI_MED)) == NULL) {
189 		ip->i_state = NAK;
190 		ip->i_error = ENOMEM;
191 		return (ENOMEM);
192 	}
193 	bzero(nmp->b_rptr, size);
194 
195 	/* if there was already some data present, preserve it */
196 	if (ip->i_size != 0) {
197 		bcopy(ip->i_data, nmp->b_rptr, ip->i_size);
198 		freemsg(ip->i_bcont);
199 	}
200 	ip->i_bcont = nmp;
201 	ip->i_data = nmp->b_rptr;
202 	ip->i_size = size;
203 
204 	return (0);
205 }
206 
207 static void
208 sioc_copyin(sioc_t *ip, size_t size)
209 {
210 	ip->i_state = COPYIN;
211 	ip->i_size = size;
212 	if (ip->i_bcont != NULL) {
213 		freemsg(ip->i_bcont);
214 		ip->i_bcont = NULL;
215 	}
216 
217 	mcopyin(ip->i_mp, ip, size, ip->i_addr);
218 }
219 
220 static void
221 sioc_copyout(sioc_t *ip, size_t size)
222 {
223 	mblk_t			*bcont;
224 
225 	ASSERT(ip->i_size >= size);
226 
227 	bcont = ip->i_bcont;
228 
229 	ip->i_state = COPYOUT;
230 	ip->i_bcont = NULL;
231 
232 	mcopyout(ip->i_mp, ip, size, ip->i_addr, bcont);
233 }
234 
235 static void
236 sioc_error(sioc_t *ip, int error)
237 {
238 	ip->i_state = NAK;
239 	ip->i_error = error;
240 }
241 
242 static void
243 sioc_success(sioc_t *ip)
244 {
245 	ip->i_state = ACK;
246 }
247 
248 static void
249 sioc_fini(sioc_t *ip)
250 {
251 	if (ip->i_bcont != NULL)
252 		freemsg(ip->i_bcont);
253 
254 	kmem_free(ip, sizeof (*ip));
255 }
256 
257 static void
258 sioc_finish(sioc_t *ip)
259 {
260 	mblk_t		*mp;
261 	sclient_t	*sc;
262 
263 	sc = ip->i_sc;
264 	mp = ip->i_mp;
265 	ip->i_mp = NULL;
266 
267 	switch (ip->i_state) {
268 	case ACK:
269 		miocack(sc->s_wq, mp, 0, 0);
270 		break;
271 
272 	case IOCTL:	/* caller didn't use sioc_success */
273 		ip->i_error = ECANCELED;
274 		miocnak(sc->s_wq, mp, 0, ip->i_error);
275 		break;
276 
277 	case NAK:
278 		miocnak(sc->s_wq, mp, 0, ip->i_error);
279 		break;
280 
281 	case COPYOUT:
282 	case COPYIN:
283 		/* data copy to be done */
284 		qreply(sc->s_wq, mp);
285 		return;
286 
287 	case FINI:
288 		if (mp != NULL) {
289 			freemsg(mp);
290 		}
291 		break;
292 	}
293 
294 	sioc_fini(ip);
295 }
296 
297 static int
298 sun_compose_format(audio_prinfo_t *prinfo)
299 {
300 	switch (prinfo->precision) {
301 	case 8:
302 		switch (prinfo->encoding) {
303 		case AUDIO_ENCODING_ULAW:
304 			return (AUDIO_FORMAT_ULAW);
305 		case AUDIO_ENCODING_ALAW:
306 			return (AUDIO_FORMAT_ALAW);
307 		case AUDIO_ENCODING_LINEAR8:
308 			return (AUDIO_FORMAT_U8);
309 		case AUDIO_ENCODING_LINEAR:
310 			return (AUDIO_FORMAT_S8);
311 		}
312 		break;
313 	case 16:
314 		if (prinfo->encoding == AUDIO_ENCODING_LINEAR)
315 			return (AUDIO_FORMAT_S16_NE);
316 		break;
317 	case 32:
318 		if (prinfo->encoding == AUDIO_ENCODING_LINEAR)
319 			return (AUDIO_FORMAT_S32_NE);
320 		break;
321 	}
322 	return (AUDIO_FORMAT_NONE);
323 
324 }
325 
326 static void
327 sun_decompose_format(audio_prinfo_t *prinfo, int afmt)
328 {
329 	int	e, p;
330 
331 	/*
332 	 * N.B.: Even though some of the formats below can't be set by
333 	 * this personality, reporting them (using the closest match)
334 	 * allows this personality to roughly approximate settings for
335 	 * other streams.  It would be incredibly poor form for any
336 	 * personality to modify the format settings for a different
337 	 * personality, so we don't worry about that case.
338 	 */
339 
340 	switch (afmt) {
341 	case AUDIO_FORMAT_ULAW:
342 		e = AUDIO_ENCODING_ULAW;
343 		p = 8;
344 		break;
345 
346 	case AUDIO_FORMAT_ALAW:
347 		e = AUDIO_ENCODING_ALAW;
348 		p = 8;
349 		break;
350 
351 	case AUDIO_FORMAT_U8:
352 		e = AUDIO_ENCODING_LINEAR8;
353 		p = 8;
354 		break;
355 
356 	case AUDIO_FORMAT_S8:
357 		e = AUDIO_ENCODING_LINEAR;
358 		p = 8;
359 		break;
360 
361 	case AUDIO_FORMAT_S16_NE:
362 	case AUDIO_FORMAT_S16_OE:
363 	case AUDIO_FORMAT_U16_NE:
364 	case AUDIO_FORMAT_U16_OE:
365 		e = AUDIO_ENCODING_LINEAR;
366 		p = 16;
367 		break;
368 
369 	case AUDIO_FORMAT_S24_NE:
370 	case AUDIO_FORMAT_S24_OE:
371 	case AUDIO_FORMAT_S24_PACKED:
372 		e = AUDIO_ENCODING_LINEAR;
373 		p = 24;
374 		break;
375 
376 	case AUDIO_FORMAT_S32_NE:
377 	case AUDIO_FORMAT_S32_OE:
378 		e = AUDIO_ENCODING_LINEAR;
379 		p = 32;
380 		break;
381 
382 	default:
383 		/* all other formats (e.g. AC3) are uninterpreted */
384 		e = AUDIO_ENCODING_NONE;
385 		p = 32;
386 		break;
387 	}
388 
389 	prinfo->encoding = e;
390 	prinfo->precision = p;
391 }
392 
393 static sproc_t *
394 sproc_alloc(sclient_t *sc)
395 {
396 	audio_client_t	*c;
397 	audio_info_t	*info;
398 	audio_prinfo_t	*prinfo;
399 	uint32_t	caps;
400 	sproc_t		*proc;
401 
402 	c = sc->s_client;
403 	if ((proc = kmem_zalloc(sizeof (*proc), KM_NOSLEEP)) == NULL) {
404 		return (NULL);
405 	}
406 	info = &proc->p_info;
407 
408 	/*
409 	 * audio(7I) says: Upon the initial open() of the audio
410 	 * device, the driver resets the data format of the device to
411 	 * the default state of 8-bit, 8Khz, mono u-Law data.
412 	 */
413 	prinfo = &info->play;
414 	prinfo->channels =	1;
415 	prinfo->sample_rate =	8000;
416 	prinfo->encoding =	AUDIO_ENCODING_ULAW;
417 	prinfo->precision =	8;
418 	prinfo->gain =		AUDIO_MAX_GAIN;
419 	prinfo->balance =	AUDIO_MID_BALANCE;
420 	prinfo->buffer_size =	8192;
421 	prinfo->pause =		B_FALSE;
422 	prinfo->waiting =	B_FALSE;
423 	prinfo->open =		B_FALSE;
424 	prinfo->active =	B_FALSE;
425 	prinfo->samples =	0;
426 	prinfo->eof =		0;
427 	prinfo->error =		0;
428 	prinfo->minordev =	0;
429 	prinfo->port =		AUDIO_SPEAKER;
430 	prinfo->avail_ports =	AUDIO_SPEAKER;
431 	prinfo->mod_ports =	AUDIO_NONE;
432 	prinfo->_xxx =		0;
433 
434 	prinfo = &info->record;
435 	prinfo->channels =	1;
436 	prinfo->sample_rate =	8000;
437 	prinfo->encoding =	AUDIO_ENCODING_ULAW;
438 	prinfo->precision =	8;
439 	prinfo->gain =		AUDIO_MAX_GAIN;
440 	prinfo->balance =	AUDIO_MID_BALANCE;
441 	prinfo->buffer_size =	8192;
442 	prinfo->waiting =	B_FALSE;
443 	prinfo->open =  	B_FALSE;
444 	prinfo->active =	B_FALSE;
445 	prinfo->samples =	0;
446 	prinfo->eof =		0;
447 	prinfo->error =		0;
448 	prinfo->minordev =	0;
449 	prinfo->port =		AUDIO_MICROPHONE;
450 	prinfo->avail_ports =	AUDIO_MICROPHONE;
451 	prinfo->mod_ports =	AUDIO_MICROPHONE;
452 
453 	info->output_muted =	B_FALSE;
454 	/* pretend we don't have a software mixer - we don't support the API */
455 	info->hw_features =	0;
456 	info->sw_features =	0;
457 	info->sw_features_enabled = 0;
458 
459 	caps = auclnt_get_dev_capab(auclnt_get_dev(c));
460 	if (caps & AUDIO_CLIENT_CAP_PLAY)
461 		info->hw_features |= AUDIO_HWFEATURE_PLAY;
462 	if (caps & AUDIO_CLIENT_CAP_RECORD)
463 		info->hw_features |= AUDIO_HWFEATURE_RECORD;
464 	if (caps & AUDIO_CLIENT_CAP_DUPLEX)
465 		info->hw_features |= AUDIO_HWFEATURE_DUPLEX;
466 
467 	return (proc);
468 }
469 
470 static void
471 sproc_free(sproc_t *proc)
472 {
473 	kmem_free(proc, sizeof (*proc));
474 }
475 
476 int
477 sproc_hold(audio_client_t *c, ldi_handle_t lh, queue_t *rq, int oflag)
478 {
479 	pid_t		pid;
480 	sproc_t		*proc;
481 	sdev_t		*sdev;
482 	sclient_t	*sc;
483 	list_t		*l;
484 	audio_dev_t	*adev;
485 	int		rv;
486 
487 	adev = auclnt_get_dev(c);
488 
489 	/* first allocate and initialize the sclient private data */
490 	if ((sc = kmem_zalloc(sizeof (*sc), KM_NOSLEEP)) == NULL) {
491 		return (ENOMEM);
492 	}
493 
494 	mutex_init(&sc->s_lock, NULL, MUTEX_DRIVER, NULL);
495 	list_create(&sc->s_eofcnt, sizeof (struct eofcnt),
496 	    offsetof(struct eofcnt, linkage));
497 	auclnt_set_private(c, sc);
498 
499 	sdev = auclnt_get_dev_minor_data(adev, AUDIO_MINOR_DEVAUDIO);
500 	l = &sdev->d_procs;
501 	pid = auclnt_get_pid(c);
502 
503 	/* set a couple of common fields */
504 	sc->s_client = c;
505 	sc->s_sdev = sdev;
506 
507 	mutex_enter(&sdev->d_mx);
508 	for (proc = list_head(l); proc != NULL; proc = list_next(l, proc)) {
509 		if (proc->p_id == pid) {
510 			proc->p_refcnt++;
511 			break;
512 		}
513 	}
514 	if (proc == NULL) {
515 		if ((proc = sproc_alloc(sc)) == NULL) {
516 			rv = ENOMEM;
517 			goto failed;
518 		}
519 		proc->p_refcnt = 1;
520 		proc->p_id = pid;
521 		proc->p_sdev = sdev;
522 		list_insert_tail(l, proc);
523 	}
524 
525 	while (proc->p_oflag & oflag) {
526 
527 		if (oflag & (FNDELAY|FNONBLOCK)) {
528 			rv = EBUSY;
529 			goto failed;
530 		}
531 		if (oflag & FWRITE)
532 			proc->p_info.play.waiting++;
533 		if (oflag & FREAD)
534 			proc->p_info.record.waiting++;
535 		if (cv_wait_sig(&sdev->d_cv, &sdev->d_mx) == 0) {
536 			/* interrupted! */
537 			if (oflag & FWRITE)
538 				proc->p_info.play.waiting--;
539 			if (oflag & FREAD)
540 				proc->p_info.record.waiting--;
541 			rv = EINTR;
542 			goto failed;
543 		}
544 		if (oflag & FWRITE)
545 			proc->p_info.play.waiting--;
546 		if (oflag & FREAD)
547 			proc->p_info.record.waiting--;
548 	}
549 
550 	if (oflag & FWRITE) {
551 		audio_prinfo_t	*play = &proc->p_info.play;
552 		audio_stream_t	*sp = auclnt_output_stream(c);
553 
554 		if (((rv = auclnt_set_rate(sp, 8000)) != 0) ||
555 		    ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) ||
556 		    ((rv = auclnt_set_channels(sp, 1)) != 0)) {
557 			goto failed;
558 		}
559 
560 		auclnt_set_samples(sp, 0);
561 		auclnt_set_errors(sp, 0);
562 		play->eof = 0;
563 		play->buffer_size = 8192;
564 
565 		auclnt_set_gain(sp, ((play->gain * 100) / AUDIO_MAX_GAIN));
566 		auclnt_set_muted(sp, proc->p_info.output_muted);
567 		play->open = B_TRUE;
568 		proc->p_writer = sc;
569 		proc->p_oflag |= FWRITE;
570 	}
571 
572 	if (oflag & FREAD) {
573 		audio_prinfo_t	*rec = &proc->p_info.record;
574 		audio_stream_t	*sp = auclnt_input_stream(c);
575 
576 		if (((rv = auclnt_set_rate(sp, 8000)) != 0) ||
577 		    ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) ||
578 		    ((rv = auclnt_set_channels(sp, 1)) != 0)) {
579 			goto failed;
580 		}
581 
582 		auclnt_set_samples(sp, 0);
583 		auclnt_set_errors(sp, 0);
584 		rec->eof = 0;
585 		rec->buffer_size = 8192;
586 
587 		auclnt_set_gain(sp, ((rec->gain * 100) / AUDIO_MAX_GAIN));
588 		rec->open = B_TRUE;
589 		proc->p_reader = sc;
590 		proc->p_oflag |= FREAD;
591 	}
592 
593 	sc->s_lh = lh;
594 	sc->s_rq = rq;
595 	sc->s_wq = WR(rq);
596 	WR(rq)->q_ptr = rq->q_ptr = sc;
597 	/* we update the s_proc last to avoid a race */
598 	sc->s_proc = proc;
599 
600 	sproc_update(proc);
601 
602 	mutex_exit(&sdev->d_mx);
603 
604 	return (0);
605 
606 failed:
607 	mutex_exit(&sdev->d_mx);
608 	sproc_release(sc);
609 	return (rv);
610 
611 }
612 
613 static void
614 sun_clear_eof(sclient_t *sc)
615 {
616 	struct eofcnt *eof;
617 	mutex_enter(&sc->s_lock);
618 	while ((eof = list_remove_head(&sc->s_eofcnt)) != NULL) {
619 		kmem_free(eof, sizeof (*eof));
620 	}
621 	mutex_exit(&sc->s_lock);
622 }
623 
624 void
625 sproc_release(sclient_t *sc)
626 {
627 	sproc_t		*proc;
628 	sdev_t		*sdev;
629 	mblk_t		*mp;
630 
631 	proc = sc->s_proc;
632 	sdev = sc->s_sdev;
633 	sc->s_proc = NULL;
634 
635 	mutex_enter(&sdev->d_mx);
636 
637 	if (proc != NULL) {
638 		proc->p_refcnt--;
639 		ASSERT(proc->p_refcnt >= 0);
640 
641 		if (sc == proc->p_writer) {
642 			proc->p_oflag &= ~FWRITE;
643 			proc->p_writer = NULL;
644 		}
645 		if (sc == proc->p_reader) {
646 			proc->p_oflag &= ~FREAD;
647 			proc->p_reader = NULL;
648 		}
649 		cv_broadcast(&sdev->d_cv);
650 
651 		if (proc->p_refcnt == 0) {
652 			list_remove(&sdev->d_procs, proc);
653 			sproc_free(proc);
654 		}
655 		sc->s_proc = NULL;
656 	}
657 
658 	mutex_exit(&sdev->d_mx);
659 
660 	sun_clear_eof(sc);
661 
662 	while ((mp = sc->s_draining) != NULL) {
663 		sc->s_draining = mp->b_next;
664 		mp->b_next = NULL;
665 		freemsg(mp);
666 	}
667 
668 	mutex_destroy(&sc->s_lock);
669 	list_destroy(&sc->s_eofcnt);
670 	kmem_free(sc, sizeof (*sc));
671 }
672 
673 static void
674 sun_sendup(audio_client_t *c)
675 {
676 	audio_stream_t	*sp = auclnt_input_stream(c);
677 	sclient_t	*sc = auclnt_get_private(c);
678 	unsigned	framesz = auclnt_get_framesz(sp);
679 	queue_t		*rq = sc->s_rq;
680 	mblk_t		*mp;
681 	unsigned	nbytes = sc->s_proc->p_info.record.buffer_size;
682 	unsigned	count = nbytes / framesz;
683 
684 	/*
685 	 * Potentially send a message upstream with the record data.
686 	 * We collect this up in chunks of the buffer size requested
687 	 * by the client.
688 	 */
689 
690 	while (auclnt_get_count(sp) >= count) {
691 
692 		if ((!canputnext(rq)) ||
693 		    ((mp = allocb(nbytes, BPRI_MED)) == NULL)) {
694 			/*
695 			 * This will apply back pressure to the
696 			 * buffer.  We haven't yet lost any data, we
697 			 * just can't send it up.  The point at which
698 			 * we have an unrecoverable overrun is in the
699 			 * buffer, not in the streams queue.  So, no
700 			 * need to do anything right now.
701 			 *
702 			 * Note that since recording is enabled, we
703 			 * expect that the callback routine will be
704 			 * called repeatedly & regularly, so we don't
705 			 * have to worry about leaving data orphaned
706 			 * in the queue.
707 			 */
708 			break;
709 		}
710 
711 		(void) auclnt_consume_data(sp, (caddr_t)mp->b_wptr, count);
712 		mp->b_wptr += nbytes;
713 		putnext(rq, mp);
714 	}
715 }
716 
717 static int
718 sun_open(audio_client_t *c, int oflag)
719 {
720 	_NOTE(ARGUNUSED(c));
721 	_NOTE(ARGUNUSED(oflag));
722 	return (0);
723 }
724 
725 static void
726 sun_close(audio_client_t *c)
727 {
728 	_NOTE(ARGUNUSED(c));
729 }
730 
731 static void
732 sproc_update(sproc_t *proc)
733 {
734 	audio_info_t	*info;
735 	audio_stream_t	*sp;
736 	sclient_t	*sc;
737 
738 	info = &proc->p_info;
739 
740 	ASSERT(mutex_owned(&proc->p_sdev->d_mx));
741 
742 	if ((sc = proc->p_writer) != NULL) {
743 		sp = auclnt_output_stream(sc->s_client);
744 
745 		info->play.sample_rate = auclnt_get_rate(sp);
746 		info->play.channels = auclnt_get_channels(sp);
747 		sun_decompose_format(&info->play, auclnt_get_format(sp));
748 
749 		info->play.gain =
750 		    (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100;
751 		info->play.pause = auclnt_is_paused(sp);
752 		info->play.active = !info->play.pause;
753 		info->play.samples = auclnt_get_samples(sp);
754 		info->play.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE;
755 		info->output_muted = auclnt_get_muted(sp);
756 	}
757 
758 	if ((sc = proc->p_reader) != NULL) {
759 		sp = auclnt_input_stream(sc->s_client);
760 
761 		info->record.sample_rate = auclnt_get_rate(sp);
762 		info->record.channels = auclnt_get_channels(sp);
763 		sun_decompose_format(&info->record, auclnt_get_format(sp));
764 
765 		info->record.gain =
766 		    (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100;
767 		info->record.pause = auclnt_is_paused(sp);
768 		info->record.active = !info->record.pause;
769 		info->record.samples = auclnt_get_samples(sp);
770 		info->record.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE;
771 	}
772 }
773 
774 static void
775 sioc_getinfo(sioc_t *ip)
776 {
777 	sclient_t	*sc = ip->i_sc;
778 	sproc_t		*proc = sc->s_proc;
779 	int		rv;
780 
781 	switch (ip->i_step) {
782 	case 0:
783 		if ((rv = sioc_alloc(ip, sizeof (audio_info_t))) != 0) {
784 			sioc_error(ip, rv);
785 			break;
786 		}
787 
788 		mutex_enter(&sc->s_sdev->d_mx);
789 		sproc_update(proc);
790 		mutex_exit(&sc->s_sdev->d_mx);
791 
792 		bcopy(&proc->p_info, ip->i_data, sizeof (audio_info_t));
793 		sioc_copyout(ip, sizeof (audio_info_t));
794 		break;
795 	case 1:
796 		sioc_success(ip);
797 		break;
798 	}
799 
800 	ip->i_step++;
801 	sioc_finish(ip);
802 }
803 
804 #define	CHANGED(new, old, field)			\
805 	((new->field != ((uint32_t)~0)) && (new->field != old->field))
806 #define	CHANGED8(new, old, field)			\
807 	((new->field != ((uint8_t)~0)) && (new->field != old->field))
808 
809 static int
810 sun_setinfo(sclient_t *sc, audio_info_t *ninfo)
811 {
812 	sproc_t		*proc = sc->s_proc;
813 	audio_info_t	*oinfo = &proc->p_info;
814 	audio_prinfo_t	*npr;
815 	audio_prinfo_t	*opr;
816 
817 	int		pfmt = AUDIO_FORMAT_NONE;
818 	int		rfmt = AUDIO_FORMAT_NONE;
819 
820 	boolean_t	reader;
821 	boolean_t	writer;
822 	boolean_t	isctl;
823 	audio_stream_t	*sp;
824 	int		rv;
825 
826 	if (auclnt_get_minor_type(sc->s_client) == AUDIO_MINOR_DEVAUDIOCTL) {
827 		/* control node can do both read and write fields */
828 		isctl = B_TRUE;
829 		reader = B_TRUE;
830 		writer = B_TRUE;
831 	} else {
832 		isctl = B_FALSE;
833 		writer = sc == proc->p_writer;
834 		reader = sc == proc->p_reader;
835 	}
836 
837 	/*
838 	 * Start by validating settings.
839 	 */
840 	npr = &ninfo->play;
841 	opr = &oinfo->play;
842 
843 	if (writer && CHANGED(npr, opr, sample_rate)) {
844 		if ((isctl) ||
845 		    (npr->sample_rate < 5500) || (npr->sample_rate > 48000)) {
846 			return (EINVAL);
847 		}
848 	}
849 	if (writer && CHANGED(npr, opr, channels)) {
850 		if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) {
851 			return (EINVAL);
852 		}
853 	}
854 	if (writer &&
855 	    (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) {
856 		if (npr->encoding == (uint32_t)~0)
857 			npr->encoding = opr->encoding;
858 		if (npr->precision == (uint32_t)~0)
859 			npr->precision = opr->precision;
860 		pfmt = sun_compose_format(npr);
861 		if ((isctl) || (pfmt == AUDIO_FORMAT_NONE)) {
862 			return (EINVAL);
863 		}
864 	}
865 
866 	/* play fields that anyone can modify */
867 	if (CHANGED(npr, opr, gain)) {
868 		if (npr->gain > AUDIO_MAX_GAIN) {
869 			return (EINVAL);
870 		}
871 	}
872 
873 
874 	npr = &ninfo->record;
875 	opr = &oinfo->record;
876 
877 	if (reader && CHANGED(npr, opr, sample_rate)) {
878 		if ((isctl) ||
879 		    (npr->sample_rate < 5500) ||
880 		    (npr->sample_rate > 48000)) {
881 			return (EINVAL);
882 		}
883 	}
884 	if (reader && CHANGED(npr, opr, channels)) {
885 		if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) {
886 			return (EINVAL);
887 		}
888 	}
889 	if (reader &&
890 	    (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) {
891 		if (npr->encoding == (uint32_t)~0)
892 			npr->encoding = opr->encoding;
893 		if (npr->precision == (uint32_t)~0)
894 			npr->precision = opr->precision;
895 		rfmt = sun_compose_format(npr);
896 		if ((isctl) || (rfmt == AUDIO_FORMAT_NONE)) {
897 			return (EINVAL);
898 		}
899 	}
900 	if (reader && CHANGED(npr, opr, buffer_size)) {
901 		if (isctl) {
902 			return (EINVAL);
903 		}
904 		/* make sure we can support 16-bit stereo samples */
905 		if ((npr->buffer_size % 4) != 0) {
906 			npr->buffer_size = (npr->buffer_size + 3) & ~3;
907 		}
908 		/* limit the maximum buffer size somewhat */
909 		if (npr->buffer_size > 16384) {
910 			npr->buffer_size = 16384;
911 		}
912 	}
913 
914 	/* record fields that anyone can modify */
915 	if (CHANGED(npr, opr, gain)) {
916 		if (npr->gain > AUDIO_MAX_GAIN) {
917 			return (EINVAL);
918 		}
919 	}
920 
921 	/*
922 	 * Now apply the changes.
923 	 */
924 	if (proc->p_writer != NULL) {
925 		sp = auclnt_output_stream(proc->p_writer->s_client);
926 		npr = &ninfo->play;
927 		opr = &oinfo->play;
928 
929 		if (CHANGED(npr, opr, sample_rate)) {
930 			rv = auclnt_set_rate(sp, npr->sample_rate);
931 			if (rv != 0)
932 				return (rv);
933 		}
934 		if (CHANGED(npr, opr, channels)) {
935 			rv = auclnt_set_channels(sp, npr->channels);
936 			if (rv != 0)
937 				return (rv);
938 		}
939 		if (pfmt != AUDIO_FORMAT_NONE) {
940 			rv = auclnt_set_format(sp, pfmt);
941 			if (rv != 0)
942 				return (rv);
943 		}
944 		if (CHANGED(npr, opr, samples)) {
945 			auclnt_set_samples(sp, npr->samples);
946 		}
947 		if (CHANGED(npr, opr, eof)) {
948 			/*
949 			 * This ugly special case code is required to
950 			 * prevent problems with realaudio.
951 			 */
952 			if (npr->eof == 0) {
953 				sun_clear_eof(proc->p_writer);
954 			}
955 			opr->eof = npr->eof;
956 		}
957 		if (CHANGED8(npr, opr, pause)) {
958 			if (npr->pause) {
959 				auclnt_set_paused(sp);
960 			} else {
961 				auclnt_clear_paused(sp);
962 				/* qenable to start up the playback */
963 				qenable(proc->p_writer->s_wq);
964 			}
965 		}
966 		if (CHANGED8(npr, opr, waiting) && (npr->waiting)) {
967 			opr->waiting = npr->waiting;
968 		}
969 		if (CHANGED8(npr, opr, error)) {
970 			auclnt_set_errors(sp, npr->error);
971 		}
972 		if (CHANGED(npr, opr, gain)) {
973 			auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN);
974 		}
975 		if (CHANGED8(ninfo, oinfo, output_muted)) {
976 			auclnt_set_muted(sp, ninfo->output_muted);
977 		}
978 		if (CHANGED(npr, opr, buffer_size)) {
979 			/*
980 			 * No checks on the buffer size are performed
981 			 * for play side.  The value of the buffer size
982 			 * is meaningless for play side anyway.
983 			 */
984 			opr->buffer_size = npr->buffer_size;
985 		}
986 	} else {
987 		/* these vaalues are preserved even if /dev/audio not open */
988 		if (CHANGED(npr, opr, gain)) {
989 			opr->gain = npr->gain;
990 		}
991 		if (CHANGED8(ninfo, oinfo, output_muted)) {
992 			oinfo->output_muted = ninfo->output_muted;
993 		}
994 	}
995 
996 	if (proc->p_reader != NULL) {
997 		sp = auclnt_input_stream(proc->p_reader->s_client);
998 		npr = &ninfo->record;
999 		opr = &oinfo->record;
1000 
1001 		if (CHANGED(npr, opr, sample_rate)) {
1002 			rv = auclnt_set_rate(sp, npr->sample_rate);
1003 			if (rv != 0)
1004 				return (rv);
1005 		}
1006 		if (CHANGED(npr, opr, channels)) {
1007 			rv = auclnt_set_channels(sp, npr->channels);
1008 			if (rv != 0)
1009 				return (rv);
1010 		}
1011 		if (rfmt != AUDIO_FORMAT_NONE) {
1012 			rv = auclnt_set_format(sp, rfmt);
1013 			if (rv != 0)
1014 				return (rv);
1015 		}
1016 		if (CHANGED(npr, opr, samples)) {
1017 			auclnt_set_samples(sp, npr->samples);
1018 		}
1019 		if (CHANGED(npr, opr, eof)) {
1020 			opr->eof = npr->eof;
1021 		}
1022 		if (CHANGED8(npr, opr, pause)) {
1023 			if (npr->pause) {
1024 				auclnt_set_paused(sp);
1025 			} else {
1026 				auclnt_clear_paused(sp);
1027 				auclnt_start(sp);
1028 			}
1029 		}
1030 		if (CHANGED8(npr, opr, waiting) && (npr->waiting)) {
1031 			opr->waiting = npr->waiting;
1032 		}
1033 		if (CHANGED8(npr, opr, error)) {
1034 			auclnt_set_errors(sp, npr->error);
1035 		}
1036 		if (CHANGED(npr, opr, buffer_size)) {
1037 			opr->buffer_size = npr->buffer_size;
1038 		}
1039 		if (CHANGED(npr, opr, gain)) {
1040 			auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN);
1041 		}
1042 	} else {
1043 		/* these values are preserved even if /dev/audio not open */
1044 		if (CHANGED(npr, opr, gain)) {
1045 			opr->gain = npr->gain;
1046 		}
1047 	}
1048 
1049 	return (0);
1050 }
1051 
1052 static void
1053 sioc_setinfo(sioc_t *ip)
1054 {
1055 	int		rv;
1056 	sclient_t	*sc = ip->i_sc;
1057 	audio_info_t	*ninfo;
1058 
1059 	switch (ip->i_step) {
1060 	case 0:
1061 		sioc_copyin(ip, sizeof (audio_info_t));
1062 		break;
1063 
1064 	case 1:
1065 		ninfo = (audio_info_t *)ip->i_data;
1066 
1067 		mutex_enter(&sc->s_sdev->d_mx);
1068 		rv = sun_setinfo(ip->i_sc, ninfo);
1069 
1070 		if (rv != 0) {
1071 			sioc_error(ip, rv);
1072 		} else {
1073 			sproc_update(sc->s_proc);
1074 
1075 			bcopy(&sc->s_proc->p_info, ninfo, sizeof (*ninfo));
1076 			sioc_copyout(ip, sizeof (audio_info_t));
1077 		}
1078 		mutex_exit(&sc->s_sdev->d_mx);
1079 		break;
1080 
1081 	case 2:
1082 		sioc_success(ip);
1083 		break;
1084 	}
1085 
1086 	ip->i_step++;
1087 	sioc_finish(ip);
1088 }
1089 
1090 static void
1091 sioc_getdev(sioc_t *ip)
1092 {
1093 	int		rv;
1094 	sclient_t	*sc = ip->i_sc;
1095 	audio_client_t	*c = sc->s_client;
1096 	audio_dev_t	*d = auclnt_get_dev(c);
1097 
1098 	switch (ip->i_step) {
1099 	case 0:
1100 		rv = sioc_alloc(ip, sizeof (audio_device_t));
1101 		if (rv == 0) {
1102 			audio_device_t *a = ip->i_data;
1103 
1104 			(void) snprintf(a->name, sizeof (a->name),
1105 			    "SUNW,%s", auclnt_get_dev_name(d));
1106 			(void) strlcpy(a->config,
1107 			    auclnt_get_dev_description(d), sizeof (a->config));
1108 			(void) strlcpy(a->version,
1109 			    auclnt_get_dev_version(d),  sizeof (a->version));
1110 			sioc_copyout(ip, sizeof (*a));
1111 		} else {
1112 			sioc_error(ip, rv);
1113 		}
1114 		break;
1115 
1116 	case 1:
1117 		sioc_success(ip);
1118 		break;
1119 	}
1120 
1121 	ip->i_step++;
1122 	sioc_finish(ip);
1123 }
1124 
1125 static void
1126 sunstr_ioctl(sioc_t *ip)
1127 {
1128 	switch (ip->i_cmd) {
1129 	case AUDIO_GETINFO:
1130 		sioc_getinfo(ip);
1131 		break;
1132 
1133 	case AUDIO_SETINFO:
1134 		sioc_setinfo(ip);
1135 		break;
1136 
1137 	case AUDIO_GETDEV:
1138 		sioc_getdev(ip);
1139 		break;
1140 
1141 	case AUDIO_DIAG_LOOPBACK:
1142 		/* we don't support this one */
1143 		sioc_error(ip, ENOTTY);
1144 		sioc_finish(ip);
1145 		break;
1146 
1147 	case AUDIO_MIXERCTL_GET_MODE:
1148 	case AUDIO_MIXERCTL_SET_MODE:
1149 	case AUDIO_MIXERCTL_GET_CHINFO:
1150 	case AUDIO_MIXERCTL_SET_CHINFO:
1151 	case AUDIO_MIXERCTL_GETINFO:
1152 	case AUDIO_MIXERCTL_SETINFO:
1153 	case AUDIO_GET_NUM_CHS:
1154 	case AUDIO_GET_CH_NUMBER:
1155 	case AUDIO_GET_CH_TYPE:
1156 	case AUDIO_MIXER_SINGLE_OPEN:
1157 	case AUDIO_MIXER_MULTIPLE_OPEN:
1158 	case AUDIO_MIXER_GET_SAMPLE_RATES:
1159 	default:
1160 		sioc_error(ip, EINVAL);
1161 		sioc_finish(ip);
1162 		break;
1163 	}
1164 }
1165 
1166 static int
1167 sun_sigpoll(audio_client_t *c, void *arg)
1168 {
1169 	sproc_t		*proc = arg;
1170 	sclient_t	*sc;
1171 
1172 	if (auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIOCTL) {
1173 		sc = auclnt_get_private(c);
1174 		/* we only need to notify peers in our own process */
1175 		if ((sc != NULL) && (sc->s_proc == proc)) {
1176 			(void) putnextctl1(sc->s_rq, M_PCSIG, SIGPOLL);
1177 		}
1178 	}
1179 	return (AUDIO_WALK_CONTINUE);
1180 }
1181 
1182 static void
1183 sun_drain(audio_client_t *c)
1184 {
1185 	sclient_t	*sc = auclnt_get_private(c);
1186 	mblk_t		*mplist, *mp;
1187 
1188 	mutex_enter(&sc->s_lock);
1189 	mplist = sc->s_draining;
1190 	sc->s_draining = NULL;
1191 	mutex_exit(&sc->s_lock);
1192 
1193 	while ((mp = mplist) != NULL) {
1194 		mplist = mp->b_next;
1195 		mp->b_next = NULL;
1196 		miocack(sc->s_wq, mp, 0, 0);
1197 	}
1198 }
1199 
1200 static void
1201 sun_output(audio_client_t *c)
1202 {
1203 	sclient_t	*sc = auclnt_get_private(c);
1204 	sproc_t		*proc = sc->s_proc;
1205 	uint64_t	tail;
1206 	struct eofcnt	*eof;
1207 	int		eofs = 0;
1208 
1209 	tail = auclnt_get_tail(auclnt_output_stream(c));
1210 
1211 	/* get more data! (do this early) */
1212 	qenable(sc->s_wq);
1213 
1214 	mutex_enter(&sc->s_lock);
1215 	while (((eof = list_head(&sc->s_eofcnt)) != NULL) &&
1216 	    (eof->tail < tail)) {
1217 		list_remove(&sc->s_eofcnt, eof);
1218 		kmem_free(eof, sizeof (*eof));
1219 		eofs++;
1220 	}
1221 	proc->p_info.play.eof += eofs;
1222 	mutex_exit(&sc->s_lock);
1223 
1224 	if (eofs) {
1225 		auclnt_dev_walk_clients(auclnt_get_dev(c),
1226 		    sun_sigpoll, proc);
1227 	}
1228 }
1229 
1230 static void
1231 sun_input(audio_client_t *c)
1232 {
1233 	sun_sendup(c);
1234 }
1235 
1236 static int
1237 sun_create_minors(audio_dev_t *adev, void *notused)
1238 {
1239 	char		path[MAXPATHLEN];
1240 	minor_t		minor;
1241 	int		inst;
1242 	int		index;
1243 	const char	*driver;
1244 	unsigned	cap;
1245 
1246 	_NOTE(ARGUNUSED(notused));
1247 
1248 	ASSERT(mutex_owned(&sdev_lock));
1249 
1250 	/* don't create device nodes for sndstat device */
1251 	cap = auclnt_get_dev_capab(adev);
1252 	if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) {
1253 		return (AUDIO_WALK_CONTINUE);
1254 	}
1255 
1256 	index = auclnt_get_dev_index(adev);
1257 	inst = auclnt_get_dev_instance(adev);
1258 	driver = auclnt_get_dev_driver(adev);
1259 
1260 	if (sdev_dip != NULL) {
1261 
1262 		minor = AUDIO_MKMN(index, AUDIO_MINOR_DEVAUDIO);
1263 		(void) snprintf(path, sizeof (path), "sound,%s,audio%d",
1264 		    driver, inst);
1265 		(void) ddi_create_minor_node(sdev_dip, path, S_IFCHR, minor,
1266 		    DDI_NT_AUDIO, 0);
1267 
1268 		minor = AUDIO_MKMN(index, AUDIO_MINOR_DEVAUDIOCTL);
1269 		(void) snprintf(path, sizeof (path), "sound,%s,audioctl%d",
1270 		    driver, inst);
1271 		(void) ddi_create_minor_node(sdev_dip, path, S_IFCHR, minor,
1272 		    DDI_NT_AUDIO, 0);
1273 	}
1274 
1275 	return (AUDIO_WALK_CONTINUE);
1276 }
1277 
1278 static int
1279 sun_remove_minors(audio_dev_t *adev, void *notused)
1280 {
1281 	char		path[MAXPATHLEN];
1282 	int		inst;
1283 	const char	*driver;
1284 	unsigned	cap;
1285 
1286 	_NOTE(ARGUNUSED(notused));
1287 
1288 	ASSERT(mutex_owned(&sdev_lock));
1289 
1290 	cap = auclnt_get_dev_capab(adev);
1291 	/* if not a play or record device, don't bother creating minors */
1292 	if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) {
1293 		return (AUDIO_WALK_CONTINUE);
1294 	}
1295 
1296 	inst = auclnt_get_dev_instance(adev);
1297 	driver = auclnt_get_dev_driver(adev);
1298 
1299 	if (sdev_dip != NULL) {
1300 
1301 		(void) snprintf(path, sizeof (path), "sound,%s,audio%d",
1302 		    driver, inst);
1303 		ddi_remove_minor_node(sdev_dip, path);
1304 
1305 		(void) snprintf(path, sizeof (path), "sound,%s,audioctl%d",
1306 		    driver, inst);
1307 		ddi_remove_minor_node(sdev_dip, path);
1308 	}
1309 
1310 	return (AUDIO_WALK_CONTINUE);
1311 }
1312 
1313 static void *
1314 sun_dev_init(audio_dev_t *adev)
1315 {
1316 	sdev_t		*sdev;
1317 	unsigned	cap;
1318 
1319 	cap = auclnt_get_dev_capab(adev);
1320 	/* if not a play or record device, don't bother initializing it */
1321 	if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) {
1322 		return (NULL);
1323 	}
1324 
1325 	sdev = kmem_zalloc(sizeof (*sdev), KM_SLEEP);
1326 	sdev->d_dev = adev;
1327 	mutex_init(&sdev->d_mx, NULL, MUTEX_DRIVER, NULL);
1328 	cv_init(&sdev->d_cv, NULL, CV_DRIVER, NULL);
1329 	list_create(&sdev->d_procs, sizeof (struct sproc),
1330 	    offsetof(struct sproc, p_linkage));
1331 
1332 	mutex_enter(&sdev_lock);
1333 	(void) sun_create_minors(adev, NULL);
1334 	mutex_exit(&sdev_lock);
1335 
1336 	return (sdev);
1337 }
1338 
1339 static void
1340 sun_dev_fini(void *arg)
1341 {
1342 	sdev_t	*sdev = arg;
1343 
1344 	if (sdev != NULL) {
1345 
1346 		/* remove minor nodes */
1347 		mutex_enter(&sdev_lock);
1348 		(void) sun_remove_minors(sdev->d_dev, NULL);
1349 		mutex_exit(&sdev_lock);
1350 
1351 		mutex_destroy(&sdev->d_mx);
1352 		cv_destroy(&sdev->d_cv);
1353 		list_destroy(&sdev->d_procs);
1354 		kmem_free(sdev, sizeof (*sdev));
1355 	}
1356 }
1357 
1358 static struct audio_client_ops sun_ops = {
1359 	"internal,audio",
1360 	sun_dev_init,
1361 	sun_dev_fini,
1362 	sun_open,
1363 	sun_close,
1364 	NULL,	/* read */
1365 	NULL,	/* write */
1366 	NULL,	/* ioctl */
1367 	NULL,	/* chpoll */
1368 	NULL,	/* mmap */
1369 	sun_input,
1370 	sun_output,
1371 	NULL,	/* notify */
1372 	sun_drain,
1373 };
1374 
1375 static struct audio_client_ops sunctl_ops = {
1376 	"internal,audioctl",
1377 	NULL,	/* dev_init */
1378 	NULL,	/* dev_fini */
1379 	sun_open,
1380 	sun_close,
1381 	NULL,	/* read */
1382 	NULL,	/* write */
1383 	NULL,	/* ioctl */
1384 	NULL,	/* chpoll */
1385 	NULL,	/* mmap */
1386 	NULL,	/* output */
1387 	NULL,	/* input */
1388 	NULL,	/* notify */
1389 	NULL,	/* drain */
1390 };
1391 
1392 void
1393 auimpl_sun_init(void)
1394 {
1395 	mutex_init(&sdev_lock, NULL, MUTEX_DRIVER, NULL);
1396 	sdev_dip = NULL;
1397 	auclnt_register_ops(AUDIO_MINOR_DEVAUDIO, &sun_ops);
1398 	auclnt_register_ops(AUDIO_MINOR_DEVAUDIOCTL, &sunctl_ops);
1399 }
1400 
1401 /*
1402  * This is the operations entry points that are streams specific...
1403  * We map "instance" numbers.
1404  */
1405 
1406 static int
1407 sunstr_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *cr)
1408 {
1409 	int			rv;
1410 	minor_t			minor;
1411 	minor_t			index;
1412 	minor_t			type;
1413 	dev_t			physdev;
1414 	ldi_ident_t		lid;
1415 	ldi_handle_t		lh = NULL;
1416 	audio_client_t		*c = NULL;
1417 	audio_dev_t		*adev;
1418 	unsigned		fmt;
1419 	int			oflag;
1420 	boolean_t		isopen = B_FALSE;
1421 
1422 	if (sflag != 0) {
1423 		/* no direct clone or module opens */
1424 		return (EINVAL);
1425 	}
1426 
1427 	/*
1428 	 * NB: We reuse the partitioning that the core framework is
1429 	 * using for instance numbering.  This does mean that we are
1430 	 * limited to at most AUDIO_MN_INST_MASK devices, but this
1431 	 * number is sufficiently large (8192) that not to be a concern.
1432 	 */
1433 
1434 	minor = getminor(*devp);
1435 	index = (minor >> AUDIO_MN_INST_SHIFT) & AUDIO_MN_INST_MASK;
1436 	type = (minor >> AUDIO_MN_TYPE_SHIFT) & AUDIO_MN_TYPE_MASK;
1437 
1438 	/* can't directly open a cloned node! */
1439 	if (minor & AUDIO_MN_CLONE_MASK) {
1440 		return (ENXIO);
1441 	}
1442 
1443 	switch (type) {
1444 	case AUDIO_MINOR_DEVAUDIOCTL:
1445 		fmt = AUDIO_FORMAT_NONE;
1446 		oflag = flag & ~(FWRITE | FREAD);
1447 		break;
1448 	case AUDIO_MINOR_DEVAUDIO:
1449 		fmt = AUDIO_FORMAT_PCM;
1450 		oflag = flag;
1451 		break;
1452 	default:
1453 		/* these minor types are not legal */
1454 		return (ENXIO);
1455 	}
1456 
1457 	/* look up and hold the matching audio device */
1458 	adev = auclnt_hold_dev_by_index(index);
1459 	if (adev == NULL) {
1460 		return (ENXIO);
1461 	}
1462 	/* find the matching physical devt */
1463 	physdev = makedevice(ddi_driver_major(auclnt_get_dev_devinfo(adev)),
1464 	    AUDIO_MKMN(auclnt_get_dev_instance(adev), type));
1465 
1466 	if ((rv = ldi_ident_from_stream(rq, &lid)) == 0) {
1467 		rv = ldi_open_by_dev(&physdev, OTYP_CHR, flag, cr, &lh, lid);
1468 	}
1469 
1470 	/* ldi open is done, lh holds device, and we can release our hold */
1471 	auclnt_release_dev(adev);
1472 
1473 	if (rv != 0) {
1474 		goto fail;
1475 	}
1476 	/* phys layer clones a device for us */
1477 	ASSERT((getminor(physdev) & AUDIO_MN_CLONE_MASK) != 0);
1478 
1479 	/*
1480 	 * Note: We don't need to retain the hold on the client
1481 	 * structure, because the client is logically "held" by the
1482 	 * open LDI handle.  We're just using this hold_by_devt to
1483 	 * locate the associated client.
1484 	 */
1485 	c = auclnt_hold_by_devt(physdev);
1486 	ASSERT(c != NULL);
1487 	auclnt_release(c);
1488 
1489 	if ((rv = auclnt_open(c, fmt, oflag)) != 0) {
1490 		goto fail;
1491 	}
1492 	isopen = B_TRUE;
1493 
1494 	if ((rv = sproc_hold(c, lh, rq, oflag)) != 0) {
1495 		goto fail;
1496 	}
1497 
1498 	/* start up the input */
1499 	if (oflag & FREAD) {
1500 		auclnt_start(auclnt_input_stream(c));
1501 	}
1502 
1503 	/* we just reuse same minor number that phys layer used */
1504 	*devp = makedevice(getmajor(*devp), getminor(physdev));
1505 
1506 	qprocson(rq);
1507 
1508 	return (0);
1509 
1510 fail:
1511 	if (isopen) {
1512 		auclnt_close(c);
1513 	}
1514 	if (lh != NULL) {
1515 		(void) ldi_close(lh, flag, cr);
1516 	}
1517 
1518 	return (rv);
1519 }
1520 
1521 static int
1522 sunstr_close(queue_t *rq, int flag, cred_t *cr)
1523 {
1524 	sclient_t	*sc;
1525 	audio_client_t	*c;
1526 	int		rv;
1527 
1528 	sc = rq->q_ptr;
1529 	c = sc->s_client;
1530 
1531 	if ((auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIO) &&
1532 	    (ddi_can_receive_sig() || (ddi_get_pid() == 0))) {
1533 		rv = auclnt_drain(c);
1534 	}
1535 
1536 	auclnt_stop(auclnt_output_stream(c));
1537 	auclnt_stop(auclnt_input_stream(c));
1538 
1539 	auclnt_close(c);
1540 
1541 	qprocsoff(rq);
1542 
1543 	(void) ldi_close(sc->s_lh, flag, cr);
1544 
1545 	sproc_release(sc);
1546 
1547 	return (rv);
1548 }
1549 
1550 static void
1551 sunstr_miocdata(sclient_t *sc, mblk_t *mp)
1552 {
1553 	struct copyresp		*csp;
1554 	sioc_t			*ip;
1555 	mblk_t			*bcont;
1556 
1557 	csp = (void *)mp->b_rptr;
1558 
1559 	/*
1560 	 * If no state, then something "bad" has happened.
1561 	 */
1562 	if (((ip = (void *)csp->cp_private) == NULL) || (ip->i_sc != sc)) {
1563 		miocnak(sc->s_wq, mp, 0, EFAULT);
1564 		return;
1565 	}
1566 
1567 	/*
1568 	 * If we failed to transfer data to/from userland, then we are
1569 	 * done.  (Stream head will have notified userland.)
1570 	 */
1571 	if (csp->cp_rval != 0) {
1572 		ip->i_state = FINI;
1573 		ip->i_mp = mp;
1574 		sioc_finish(ip);
1575 		return;
1576 	}
1577 
1578 	/*
1579 	 * Buffer area for ioctl is attached to chain.
1580 	 * For an ioctl that didn't have any data to copyin,
1581 	 * we might need to allocate a new buffer area.
1582 	 */
1583 	bcont = mp->b_cont;
1584 	ip->i_bcont = bcont;
1585 	mp->b_cont = NULL;
1586 
1587 	if (bcont != NULL) {
1588 		ip->i_data = bcont->b_rptr;
1589 	}
1590 
1591 	/*
1592 	 * Meaty part of data processing.
1593 	 */
1594 	ip->i_state = IOCTL;
1595 	ip->i_mp = mp;
1596 
1597 	/* now, call the handler ioctl */
1598 	sunstr_ioctl(ip);
1599 }
1600 
1601 static void
1602 sunstr_mioctl(sclient_t *sc, mblk_t *mp)
1603 {
1604 	struct iocblk	*iocp = (void *)mp->b_rptr;
1605 	sioc_t		*ip;
1606 
1607 	/* BSD legacy here: we only support transparent ioctls */
1608 	if (iocp->ioc_count != TRANSPARENT) {
1609 		miocnak(sc->s_wq, mp, 0, EINVAL);
1610 		return;
1611 	}
1612 
1613 	ip = kmem_zalloc(sizeof (*ip), KM_NOSLEEP);
1614 	if (ip == NULL) {
1615 		miocnak(sc->s_wq, mp, 0, ENOMEM);
1616 		return;
1617 	}
1618 
1619 	/* make sure everything is setup in case we need to do copyin/out */
1620 	ip->i_sc = sc;
1621 	ip->i_model = iocp->ioc_flag;
1622 	ip->i_cmd = iocp->ioc_cmd;
1623 	ip->i_addr = *(caddr_t *)(void *)mp->b_cont->b_rptr;
1624 	ip->i_state = IOCTL;
1625 	ip->i_mp = mp;
1626 	freemsg(mp->b_cont);
1627 	mp->b_cont = NULL;
1628 
1629 	/* now, call the handler ioctl */
1630 	sunstr_ioctl(ip);
1631 }
1632 
1633 static int
1634 sunstr_wput(queue_t *wq, mblk_t *mp)
1635 {
1636 	sclient_t	*sc = wq->q_ptr;
1637 	struct iocblk	*iocp;
1638 
1639 	switch (DB_TYPE(mp)) {
1640 	case M_IOCTL:
1641 		/* Drain ioctl needs to be handled on the service queue */
1642 		iocp = (void *)mp->b_rptr;
1643 		if (iocp->ioc_cmd == AUDIO_DRAIN) {
1644 			if (auclnt_get_minor_type(sc->s_client) ==
1645 			    AUDIO_MINOR_DEVAUDIO) {
1646 				(void) putq(wq, mp);
1647 			} else {
1648 				miocnak(wq, mp, 0, EINVAL);
1649 			}
1650 		} else {
1651 			sunstr_mioctl(sc, mp);
1652 		}
1653 		break;
1654 
1655 	case M_IOCDATA:
1656 		sunstr_miocdata(sc, mp);
1657 		break;
1658 
1659 	case M_FLUSH:
1660 		/*
1661 		 * We don't flush the engine.  The reason is that
1662 		 * other streams might be using the engine.  This is
1663 		 * fundamentally no different from the case where the
1664 		 * engine hardware has data buffered in an
1665 		 * inaccessible FIFO.
1666 		 *
1667 		 * Clients that want to ensure no more data is coming
1668 		 * should stop the stream before flushing.
1669 		 */
1670 		if (*mp->b_rptr & FLUSHW) {
1671 			flushq(wq, FLUSHALL);
1672 			auclnt_flush(auclnt_output_stream(sc->s_client));
1673 			*mp->b_rptr &= ~FLUSHW;
1674 		}
1675 		if (*mp->b_rptr & FLUSHR) {
1676 			flushq(RD(wq), FLUSHALL);
1677 			auclnt_flush(auclnt_input_stream(sc->s_client));
1678 			qreply(wq, mp);
1679 		} else {
1680 			freemsg(mp);
1681 		}
1682 		break;
1683 
1684 	case M_DATA:
1685 		/*
1686 		 * If we don't have an engine, then we can't accept
1687 		 * write() data.  audio(7i) says we just ignore it,
1688 		 * so we toss it.
1689 		 */
1690 		if (auclnt_get_minor_type(sc->s_client) !=
1691 		    AUDIO_MINOR_DEVAUDIO) {
1692 			freemsg(mp);
1693 		} else {
1694 			/*
1695 			 * Defer processing to the queue.  This keeps
1696 			 * the data ordered, and allows the wsrv
1697 			 * routine to gather multiple mblks at once.
1698 			 */
1699 			if (mp->b_cont != NULL) {
1700 
1701 				/*
1702 				 * If we need to pullup, do it here to
1703 				 * simplify the rest of the processing
1704 				 * later.  This should rarely (if
1705 				 * ever) be necessary.
1706 				 */
1707 				mblk_t	*nmp;
1708 
1709 				if ((nmp = msgpullup(mp, -1)) == NULL) {
1710 					freemsg(mp);
1711 				} else {
1712 					freemsg(mp);
1713 					(void) putq(wq, nmp);
1714 				}
1715 			} else {
1716 				(void) putq(wq, mp);
1717 			}
1718 		}
1719 		break;
1720 
1721 	default:
1722 		freemsg(mp);
1723 		break;
1724 	}
1725 	return (0);
1726 }
1727 
1728 static int
1729 sunstr_wsrv(queue_t *wq)
1730 {
1731 	sclient_t	*sc = wq->q_ptr;
1732 	audio_client_t	*c = sc->s_client;
1733 	audio_stream_t	*sp;
1734 	mblk_t		*mp;
1735 	unsigned	framesz;
1736 
1737 	sp = auclnt_output_stream(c);
1738 
1739 	framesz = auclnt_get_framesz(sp);
1740 
1741 	while ((mp = getq(wq)) != NULL) {
1742 
1743 		unsigned	count;
1744 
1745 		/* got a message */
1746 
1747 		/* if its a drain ioctl, we need to process it here */
1748 		if (DB_TYPE(mp) == M_IOCTL) {
1749 			ASSERT((*(int *)(void *)mp->b_rptr) == AUDIO_DRAIN);
1750 			mutex_enter(&sc->s_lock);
1751 			mp->b_next = sc->s_draining;
1752 			sc->s_draining = mp;
1753 			mutex_exit(&sc->s_lock);
1754 
1755 			if (auclnt_start_drain(c) != 0) {
1756 				sun_drain(c);
1757 			}
1758 			continue;
1759 		}
1760 
1761 		ASSERT(DB_TYPE(mp) == M_DATA);
1762 
1763 		/*
1764 		 * Empty mblk require special handling, since they
1765 		 * indicate EOF.  We treat them separate from the main
1766 		 * processing loop.
1767 		 */
1768 		if (MBLKL(mp) == 0) {
1769 			struct eofcnt	*eof;
1770 
1771 			eof = kmem_zalloc(sizeof (*eof), KM_NOSLEEP);
1772 			if (eof != NULL) {
1773 				eof->tail = auclnt_get_head(sp);
1774 				mutex_enter(&sc->s_lock);
1775 				list_insert_tail(&sc->s_eofcnt, eof);
1776 				mutex_exit(&sc->s_lock);
1777 			}
1778 			freemsg(mp);
1779 			continue;
1780 		}
1781 
1782 		count = auclnt_produce_data(sp, (caddr_t)mp->b_rptr,
1783 		    MBLKL(mp) / framesz);
1784 
1785 		mp->b_rptr += count * framesz;
1786 
1787 		if (MBLKL(mp) >= framesz) {
1788 			(void) putbq(wq, mp);
1789 			break;
1790 		} else {
1791 			freemsg(mp);
1792 		}
1793 	}
1794 
1795 	/* if the stream isn't running yet, start it up */
1796 	if (!auclnt_is_paused(sp))
1797 		auclnt_start(sp);
1798 
1799 	return (0);
1800 }
1801 
1802 static int
1803 sunstr_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1804 {
1805 	if ((cmd != DDI_ATTACH) || (dip == NULL)) {
1806 		return (DDI_FAILURE);
1807 	}
1808 	if (ddi_get_instance(dip) != 0) {
1809 		return (DDI_FAILURE);
1810 	}
1811 
1812 	mutex_enter(&sdev_lock);
1813 	sdev_dip = dip;
1814 	auclnt_walk_devs(sun_create_minors, NULL);
1815 	mutex_exit(&sdev_lock);
1816 	ddi_report_dev(dip);
1817 
1818 	return (0);
1819 }
1820 
1821 static int
1822 sunstr_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1823 {
1824 	if ((cmd != DDI_DETACH) || (dip == NULL)) {
1825 		return (DDI_FAILURE);
1826 	}
1827 	if (ddi_get_instance(dip) != 0) {
1828 		return (DDI_FAILURE);
1829 	}
1830 
1831 	mutex_enter(&sdev_lock);
1832 	/* remove all minors */
1833 	auclnt_walk_devs(sun_remove_minors, NULL);
1834 	sdev_dip = NULL;
1835 	mutex_exit(&sdev_lock);
1836 
1837 	return (0);
1838 }
1839 
1840 static int
1841 sunstr_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
1842 {
1843 	int		error;
1844 
1845 	_NOTE(ARGUNUSED(dip));
1846 	_NOTE(ARGUNUSED(arg));
1847 
1848 	switch (cmd) {
1849 	case DDI_INFO_DEVT2DEVINFO:
1850 		*result = sdev_dip;
1851 		error = DDI_SUCCESS;
1852 		break;
1853 	case DDI_INFO_DEVT2INSTANCE:
1854 		*result = 0;
1855 		error = DDI_SUCCESS;
1856 		break;
1857 	default:
1858 		*result = NULL;
1859 		error = DDI_FAILURE;
1860 	}
1861 	return (error);
1862 }
1863 
1864 static struct module_info sunstr_minfo = {
1865 	0,		/* used for strlog(1M) only, which we don't use */
1866 	"austr",
1867 	0,		/* min pkt size */
1868 	2048,		/* max pkt size */
1869 	65536,		/* hi water */
1870 	32768,		/* lo water */
1871 };
1872 
1873 static struct qinit sunstr_rqinit = {
1874 	NULL,		/* qi_putp */
1875 	NULL,		/* qi_srvp */
1876 	sunstr_open,	/* qi_qopen */
1877 	sunstr_close,	/* qi_qclose */
1878 	NULL,		/* qi_qadmin */
1879 	&sunstr_minfo,	/* qi_minfo */
1880 	NULL,		/* qi_mstat */
1881 };
1882 
1883 static struct qinit sunstr_wqinit = {
1884 	sunstr_wput,	/* qi_putp */
1885 	sunstr_wsrv,	/* qi_srvp */
1886 	NULL,		/* qi_qopen */
1887 	NULL,		/* qi_qclose */
1888 	NULL,		/* qi_qadmin */
1889 	&sunstr_minfo,	/* qi_minfo */
1890 	NULL,		/* qi_mstat */
1891 };
1892 
1893 static struct streamtab sunstr_strtab = {
1894 	&sunstr_rqinit,
1895 	&sunstr_wqinit,
1896 	NULL,
1897 	NULL
1898 };
1899 
1900 struct cb_ops sunstr_cb_ops = {
1901 	nodev,		/* open */
1902 	nodev,		/* close */
1903 	nodev,		/* strategy */
1904 	nodev,		/* print */
1905 	nodev,		/* dump */
1906 	nodev,		/* read */
1907 	nodev,		/* write */
1908 	nodev,		/* ioctl */
1909 	nodev,		/* devmap */
1910 	nodev,		/* mmap */
1911 	nodev,		/* segmap */
1912 	nochpoll,	/* chpoll */
1913 	ddi_prop_op,	/* prop_op */
1914 	&sunstr_strtab,	/* str */
1915 	D_MP,		/* flag */
1916 	CB_REV, 	/* rev */
1917 	nodev,		/* aread */
1918 	nodev,		/* awrite */
1919 };
1920 
1921 static struct dev_ops sunstr_dev_ops = {
1922 	DEVO_REV,		/* rev */
1923 	0,			/* refcnt */
1924 	sunstr_getinfo,		/* getinfo */
1925 	nulldev,		/* identify */
1926 	nulldev,		/* probe */
1927 	sunstr_attach,		/* attach */
1928 	sunstr_detach,		/* detach */
1929 	nodev,			/* reset */
1930 	&sunstr_cb_ops,		/* cb_ops */
1931 	NULL,			/* bus_ops */
1932 	NULL,			/* power */
1933 };
1934 
1935 static struct modldrv sunstr_modldrv = {
1936 	&mod_driverops,
1937 	"Audio Streams Support",
1938 	&sunstr_dev_ops,
1939 };
1940 
1941 static struct modlinkage sunstr_modlinkage = {
1942 	MODREV_1,			/* MODREV_1 indicated by manual */
1943 	&sunstr_modldrv,
1944 	NULL
1945 };
1946 
1947 int
1948 sunstr_init(void)
1949 {
1950 	/*
1951 	 * NB: This *must* be called after the "audio" module's
1952 	 * _init routine has called auimpl_sun_init().
1953 	 */
1954 	return (mod_install(&sunstr_modlinkage));
1955 }
1956 
1957 int
1958 sunstr_fini(void)
1959 {
1960 	return (mod_remove(&sunstr_modlinkage));
1961 }
1962 
1963 int
1964 sunstr_info(struct modinfo *modinfop)
1965 {
1966 	return (mod_info(&sunstr_modlinkage, modinfop));
1967 }
1968